| Server IP : 182.53.201.61 / Your IP : 216.73.217.175 Web Server : Apache/2.2.15 (Fedora) System : Linux km10.dyndns.org 2.6.31.5-127.fc12.i686.PAE #1 SMP Sat Nov 7 21:25:57 EST 2009 i686 User : apache ( 48) PHP Version : 5.3.3 Disable Function : NONE MySQL : ON | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : ON Directory : /usr/lib/python2.6/site-packages/BitTorrent/ |
Upload File : |
# The contents of this file are subject to the BitTorrent Open Source License
# Version 1.1 (the License). You may not copy or use this file, in either
# source code or executable form, except in compliance with the License. You
# may obtain a copy of the License at http://www.bittorrent.com/license/.
#
# Software distributed under the License is distributed on an AS IS basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
# written by Matt Chisholm
import os
import sys
import zurllib
import pickle
import threading
from sha import sha
DEBUG = False
from BitTorrent import ERROR, WARNING, BTFailure, version, app_name
from BitTorrent import GetTorrent
from BitTorrent.bencode import bdecode, bencode
from BitTorrent.platform import os_version, spawn, get_temp_dir, doc_root, is_frozen_exe, osx
from BitTorrent.ConvertedMetainfo import ConvertedMetainfo
if osx:
from Foundation import NSAutoreleasePool
if is_frozen_exe or DEBUG:
# needed for py2exe to include the public key lib
from Crypto.PublicKey import DSA
version_host = 'http://version.bittorrent.com/'
download_url = 'http://bittorrent.com/download.html'
# based on Version() class from ShellTools package by Matt Chisholm,
# used with permission
class Version(list):
def __str__(self):
return '.'.join(map(str, self))
def is_beta(self):
return self[1] % 2 == 1
def from_str(self, text):
return Version( [int(t) for t in text.split('.')] )
def name(self):
if self.is_beta():
return 'beta'
else:
return 'stable'
from_str = classmethod(from_str)
currentversion = Version.from_str(version)
availableversion = None
class Updater(object):
def __init__(self, threadwrap, newversionfunc, startfunc, installfunc,
errorfunc, test_new_version='', test_current_version=''):
self.threadwrap = threadwrap # for calling back to UI from thread
self.newversionfunc = newversionfunc # alert to new version UI function
self.startfunc = startfunc # start torrent UI function
self.installfunc = installfunc # install torrent UI function
self.errorfunc = errorfunc # report error UI function
self.infohash = None
self.version = currentversion
self.currentversion = currentversion
self.asked_for_install = False
self.version_site = version_host
if os.name == 'nt':
self.version_site += 'win32/'
if os_version not in ('XP', '2000', '2003'):
self.version_site += 'legacy/'
elif osx:
self.version_site += 'osx/'
self.debug_mode = DEBUG
if test_new_version:
test_new_version = Version.from_str(test_new_version)
self.debug_mode = True
def _hack_get_available(url):
return test_new_version
self._get_available = _hack_get_available
if test_current_version:
self.debug_mode = True
self.currentversion = Version.from_str(test_current_version)
def debug(self, message):
if self.debug_mode:
self.threadwrap(self.errorfunc, WARNING, message)
def _get_available(self, url):
self.debug('Updater.get_available() hitting url %s' % url)
try:
u = zurllib.urlopen(url)
s = u.read()
s = s.strip()
except:
raise BTFailure(_("Could not get latest version from %s")%url)
try:
assert len(s) == 5
availableversion = Version.from_str(s)
except:
raise BTFailure(_("Could not parse new version string from %s")%url)
return availableversion
def get_available(self):
url = self.version_site + self.currentversion.name()
availableversion = self._get_available(url)
if availableversion.is_beta():
if availableversion[1] != self.currentversion[1]:
availableversion = self.currentversion
if self.currentversion.is_beta():
stable_url = self.version_site + 'stable'
available_stable_version = self._get_available(stable_url)
if available_stable_version > availableversion:
availableversion = available_stable_version
self.version = availableversion
self.debug('Updater.get_available() got %s' % str(self.version))
return self.version
def get(self):
self.debug('Version check skipped for RPM package')
return
try:
self.get_available()
except BTFailure, e:
self.threadwrap(self.errorfunc, WARNING, e)
return
if self.version <= self.currentversion:
self.debug('Updater.get() not updating old version %s' % str(self.version))
return
if not self.can_install():
self.debug('Updater.get() cannot install on this os')
return
self.installer_name = self.calc_installer_name()
self.installer_url = self.version_site + self.installer_name + '.torrent'
self.installer_dir = self.calc_installer_dir()
self.torrentfile = None
torrentfile, terrors = GetTorrent.get_url(self.installer_url)
signature = None
try:
signfile = zurllib.urlopen(self.installer_url + '.sign')
except:
self.debug('Updater.get() failed to get signfile %s.sign' % self.installer_url)
else:
try:
signature = pickle.load(signfile)
except:
self.debug('Updater.get() failed to load signfile %s' % signfile)
if terrors:
self.threadwrap(self.errorfunc, WARNING, '\n'.join(terrors))
if torrentfile and signature:
public_key_file = open('/etc/pki/bittorrent/public.key', 'rb')
public_key = pickle.load(public_key_file)
h = sha(torrentfile).digest()
if public_key.verify(h, signature):
self.torrentfile = torrentfile
b = bdecode(torrentfile)
self.infohash = sha(bencode(b['info'])).digest()
self.total_size = b['info']['length']
self.debug('Updater.get() got torrent file and signature')
else:
self.debug('Updater.get() torrent file signature failed to verify.')
pass
else:
self.debug('Updater.get() doesn\'t have torrentfile %s and signature %s' %
(str(type(torrentfile)), str(type(signature))))
def installer_path(self):
if self.installer_dir is not None:
return os.path.join(self.installer_dir,
self.installer_name)
else:
return None
def check(self):
t = threading.Thread(target=self._check,
args=())
t.setDaemon(True)
t.start()
def _check(self):
if osx:
pool = NSAutoreleasePool.alloc().init()
self.get()
if self.version > self.currentversion:
self.threadwrap(self.newversionfunc, self.version, download_url)
def can_install(self):
if self.debug_mode:
return True
if os.name == 'nt':
return True
elif osx:
return True
else:
return False
def calc_installer_name(self):
if os.name == 'nt':
ext = 'exe'
elif osx:
ext = 'dmg'
elif os.name == 'posix' and self.debug_mode:
ext = 'tar.gz'
else:
return
parts = [app_name, str(self.version)]
if self.version.is_beta():
parts.append('Beta')
name = '-'.join(parts)
name += '.' + ext
return name
def set_installer_dir(self, path):
self.installer_dir = path
def calc_installer_dir(self):
if hasattr(self, 'installer_dir'):
return self.installer_dir
temp_dir = get_temp_dir()
if temp_dir is not None:
return temp_dir
else:
self.errorfunc(WARNING,
_("Could not find a suitable temporary location to "
"save the %s %s installer.") % (app_name, self.version))
def installer_downloaded(self):
if self.installer_path() and os.access(self.installer_path(), os.F_OK):
size = os.stat(self.installer_path())[6]
if size == self.total_size:
return True
else:
#print 'installer is wrong size, is', size, 'should be', self.total_size
return False
else:
#print 'installer does not exist'
return False
def download(self):
if self.torrentfile is not None:
self.startfunc(self.torrentfile, self.installer_path())
else:
self.errorfunc(WARNING, _("No torrent file available for %s %s "
"installer.")%(app_name, self.version))
def start_install(self):
if not self.asked_for_install:
if self.installer_downloaded():
self.asked_for_install = True
self.installfunc()
else:
self.errorfunc(WARNING,
_("%s %s installer appears to be incomplete, "
"missing, or corrupt.")%(app_name,
self.version))
def launch_installer(self, torrentqueue):
if os.name == 'nt':
spawn(torrentqueue, self.installer_path(), "/S")
else:
self.errorfunc(WARNING, _("Cannot launch installer on this OS"))