You can subscribe to this list here.
2003 |
Jan
|
Feb
(20) |
Mar
(122) |
Apr
(16) |
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
---|---|---|---|---|---|---|---|---|---|---|---|---|
2004 |
Jan
|
Feb
|
Mar
(1) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: <bel...@us...> - 2003-03-28 21:09:40
|
Update of /cvsroot/btplusplus/BT++/src/WebTemplates In directory sc8-pr-cvs1:/tmp/cvs-serv17312/src/WebTemplates Modified Files: config.tmpl torrent.tmpl Log Message: Implemented InfoManager for tracker info (namely seeds/downloaders). It manages updates so only one request is sent per tracker if multiple torrents use the same one. Some minor fixes. Index: config.tmpl =================================================================== RCS file: /cvsroot/btplusplus/BT++/src/WebTemplates/config.tmpl,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** config.tmpl 16 Mar 2003 01:17:58 -0000 1.3 --- config.tmpl 28 Mar 2003 21:09:35 -0000 1.4 *************** *** 133,136 **** --- 133,141 ---- </tr> <tr> + <td>Refresh info from tracker (UL/DL) every (minutes)<br> + (Please don't make this too low. Each Refresh takes an http request to the tracker)</td> + <td width=5%><input type=text style="width:100%" name=Display_RefreshInfo value="<TMPL_VAR display_refreshinfo>"></td> + </tr> + <tr> <td> Log Level (default = 1)<br> Index: torrent.tmpl =================================================================== RCS file: /cvsroot/btplusplus/BT++/src/WebTemplates/torrent.tmpl,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** torrent.tmpl 16 Mar 2003 01:45:19 -0000 1.4 --- torrent.tmpl 28 Mar 2003 21:09:35 -0000 1.5 *************** *** 16,19 **** --- 16,20 ---- <th>Size</th> <th>Speed</th> + <th nowrap>UL/DL</th> <th>ETA</th> </tr> *************** *** 27,31 **** <tr bgcolor=#BFD8BC> </TMPL_IF> ! <td><button type=submit name=command <TMPL_IF Hashing>disabled</TMPL_IF><TMPL_IF Allocating>disabled</TMPL_IF> value=<TMPL_VAR Command>><TMPL_VAR Command></button></td> <td> <table> --- 28,32 ---- <tr bgcolor=#BFD8BC> </TMPL_IF> ! <td><button type=submit name=command value=<TMPL_VAR Command>><TMPL_VAR Command></button></td> <td> <table> *************** *** 41,45 **** <table width=100%> <tr> ! <td><TMPL_VAR FileName></td> </tr> <tr> --- 42,51 ---- <table width=100%> <tr> ! <TMPL_IF Seedless> ! <td style="font-color:red"> ! <TMPL_ELSE> ! <td> ! </TMPL_IF> ! <TMPL_VAR FileName></td> </tr> <tr> *************** *** 53,60 **** <TMPL_IF Hashing> <td bgcolor=#CC6666 width=<TMPL_VAR PercentDone>% style="font-size:2px"> </td> ! <td bgcolor=#6666CC width=<TMPL_VAR PercentLeft>% style="font-size:2px"> </td> <TMPL_ELSE> ! <td bgcolor=#66CC66 width=<TMPL_VAR PercentDone>% style="font-size:2px"> </td> ! <td bgcolor=#CC6666 width=<TMPL_VAR PercentLeft>% style="font-size:2px"> </td> </TMPL_IF> </TMPL_IF> --- 59,71 ---- <TMPL_IF Hashing> <td bgcolor=#CC6666 width=<TMPL_VAR PercentDone>% style="font-size:2px"> </td> ! <td bgcolor=#6666CC width=<TMPL_VAR PercentLeft>% style="font-size:2px"> </td> <TMPL_ELSE> ! <TMPL_IF Allocating> ! <td bgcolor=#CC6666 width=<TMPL_VAR PercentDone>% style="font-size:2px"> </td> ! <td bgcolor=#CCCC66 width=<TMPL_VAR PercentLeft>% style="font-size:2px"> </td> ! <TMPL_ELSE> ! <td bgcolor=#66CC66 width=<TMPL_VAR PercentDone>% style="font-size:2px"> </td> ! <td bgcolor=#CC6666 width=<TMPL_VAR PercentLeft>% style="font-size:2px"> </td> ! </TMPL_IF> </TMPL_IF> </TMPL_IF> *************** *** 70,73 **** --- 81,85 ---- <td align=center nowrap><TMPL_VAR FileSize></td> <td align=center nowrap><TMPL_VAR SpeedDown> <b>down</b><br> <TMPL_VAR SpeedUp> <b>up</b></td> + <td align=center nowrap><TMPL_VAR Uploaders> / <TMPL_VAR Downloaders></td> <td align=center nowrap><TMPL_VAR ETA></td> </tr> *************** *** 84,87 **** --- 96,100 ---- <th>Size</th> <th>Speed</th> + <th nowrap>UL/DL</th> <th>Status</th> </tr> *************** *** 95,98 **** --- 108,112 ---- <td align=center nowrap><TMPL_VAR FileSize></td> <td align=center nowrap><TMPL_VAR SpeedUp></td> + <td align=center nowrap><TMPL_VAR Uploaders> / <TMPL_VAR Downloaders></td> <td align=center><TMPL_VAR Status></td> </tr> |
From: <bel...@us...> - 2003-03-28 21:09:38
|
Update of /cvsroot/btplusplus/BT++/src/WebServer In directory sc8-pr-cvs1:/tmp/cvs-serv17312/src/WebServer Modified Files: BTWebServer.py HTTPConfigFile.py Log Message: Implemented InfoManager for tracker info (namely seeds/downloaders). It manages updates so only one request is sent per tracker if multiple torrents use the same one. Some minor fixes. Index: BTWebServer.py =================================================================== RCS file: /cvsroot/btplusplus/BT++/src/WebServer/BTWebServer.py,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** BTWebServer.py 25 Mar 2003 00:27:02 -0000 1.11 --- BTWebServer.py 28 Mar 2003 21:09:34 -0000 1.12 *************** *** 12,15 **** --- 12,17 ---- from htmltmpl import TemplateManager, TemplateProcessor from SeedManager import SeedManager + from InfoManager import InfoManager + from core.CurrentRateMeasure import GlobalMeasure import socket *************** *** 53,56 **** --- 55,60 ---- ########################################################################################################### ########################################################################################################### + UpMeasure = GlobalMeasure( 20.0, # MAX RATE PERIOD, + 5.0 ) # UPLOAD RATE FUDGE WebLog = [] *************** *** 105,109 **** '', '' ], ! log = WebLogit ) def MoveToHistory(loader): --- 109,114 ---- '', '' ], ! log = WebLogit, ! upmeasure = UpMeasure ) def MoveToHistory(loader): *************** *** 159,166 **** Config.Get('Paths', 'History') ], log = WebLogit, ! finish = MoveToHistory ) WTLoaders.Update() WTSeeds.Update() ########################################################################################################### ########################################################################################################### --- 164,177 ---- Config.Get('Paths', 'History') ], log = WebLogit, ! finish = MoveToHistory, ! upmeasure = UpMeasure ) WTLoaders.Update() WTSeeds.Update() + WTInfo = InfoManager(log = WebLogit, update = int(HTTPConfig.Get('Display', 'RefreshInfo'))) + WTInfo.AddManager(WTLoaders) + WTInfo.AddManager(WTSeeds) + WTInfo.Update() + ########################################################################################################### ########################################################################################################### *************** *** 170,174 **** class BTHTTPHandler(BaseHTTPRequestHandler): ! server_version = "BTHTTP/" + __version__ def do_GET(self): --- 181,193 ---- class BTHTTPHandler(BaseHTTPRequestHandler): ! server_version = "WTHTTP/" + __version__ ! ! def Update(self): ! WTLoaders.Update() ! WTSeeds.Update() ! WTInfo.Update() ! ! def UpdateConfig(self): ! WTInfo.UpdateUpdate(int(HTTPConfig.Get('Display', 'RefreshInfo'))) def do_GET(self): *************** *** 179,184 **** self.wfile.write(tproc.process(templateRoot)) elif self.requested == 'torrents': ! WTLoaders.Update() ! WTSeeds.Update() sleep(0.5) self.send_torrents() --- 198,202 ---- self.wfile.write(tproc.process(templateRoot)) elif self.requested == 'torrents': ! self.Update() sleep(0.5) self.send_torrents() *************** *** 262,269 **** Config.Save() HTTPConfig.Save() WebLogit("Configuration Changed.", loglevel = LOG_TRIVIAL) ! WTLoaders.Update() ! WTSeeds.Update() sleep(0.5) self.send_torrents() --- 280,287 ---- Config.Save() HTTPConfig.Save() + self.UpdateConfig() WebLogit("Configuration Changed.", loglevel = LOG_TRIVIAL) ! self.Update() sleep(0.5) self.send_torrents() *************** *** 317,321 **** LoaderInfo['FileName'] = loader.Config['File'] LoaderInfo['Status'] = loader.Info['Status'] ! LoaderInfo['Hashing'] = (loader.Info['Status']=='Hashing') LoaderInfo['Allocating'] = (loader.Info['Status']=='Allocating') LoaderInfo['Finished'] = loader.IsFinished() --- 335,339 ---- LoaderInfo['FileName'] = loader.Config['File'] LoaderInfo['Status'] = loader.Info['Status'] ! LoaderInfo['Hashing'] = (loader.Info['Status']=='Hashing') LoaderInfo['Allocating'] = (loader.Info['Status']=='Allocating') LoaderInfo['Finished'] = loader.IsFinished() *************** *** 336,339 **** --- 354,360 ---- LoaderInfo['SpeedUp'] = '%.1f' % loader.Info['SpeedUp'] LoaderInfo['ETA'] = loader.Info['ETA'] + LoaderInfo['Uploaders'] = loader.Info['complete'] + LoaderInfo['Downloaders'] = loader.Info['incomplete'] + LoaderInfo['Seedless'] = (loader.Info['complete'] == 0) LoaderInfos.append(LoaderInfo) SeedInfos = [] *************** *** 349,370 **** else: LoaderInfo['Status'] = loader.Info['Status'] - ## LoaderInfo['Hashing'] = (loader.Info['Status']=='Hashing') - ## LoaderInfo['Finished'] = loader.IsFinished() - ## LoaderInfo['Auto'] = (c <= Config.Get('Download', 'MaxSimDown')) - ## LoaderInfo['Preparing'] = (loader.Info['FractionDone'] == -1) - ## LoaderInfo['PercentDone'] = '%d' % (loader.Info['FractionDone']*100) - ## LoaderInfo['PercentLeft'] = '%d' % (loader.Info['FractionRemain']*100) - ## LoaderInfo['PercentDonePrec'] = '%.1f' % (loader.Info['FractionDone']*100) - ## LoaderInfo['PercentLeftPrec'] = '%.1f' % (loader.Info['FractionRemain']*100) LoaderInfo['FileSize'] = '%.2f MB' % (float(loader.Config['Size']) / 1024 / 1024) - ## if loader.Info['FractionDone'] == -1: - ## LoaderInfo['FileSizeDone'] = '?' - ## LoaderInfo['FileSizeLeft'] = LoaderInfo['FileSize'] - ## else: - ## LoaderInfo['FileSizeDone'] = ('%.2f MB' % (loader.Info['FractionDone'] * loader.Config['Size'] / 1024 / 1024)) - ## LoaderInfo['FileSizeLeft'] = ('%.2f MB' % (loader.Info['FractionRemain'] * loader.Config['Size'] / 1024 / 1024)) - ## LoaderInfo['SpeedDown'] = '%.1f' % loader.Info['SpeedDown'] LoaderInfo['SpeedUp'] = '%.1f' % loader.Info['SpeedUp'] ! ## LoaderInfo['ETA'] = loader.Info['ETA'] SeedInfos.append(LoaderInfo) tproc.set("Loaders", LoaderInfos) --- 370,377 ---- else: LoaderInfo['Status'] = loader.Info['Status'] LoaderInfo['FileSize'] = '%.2f MB' % (float(loader.Config['Size']) / 1024 / 1024) LoaderInfo['SpeedUp'] = '%.1f' % loader.Info['SpeedUp'] ! LoaderInfo['Uploaders'] = loader.Info['complete'] ! LoaderInfo['Downloaders'] = loader.Info['incomplete'] SeedInfos.append(LoaderInfo) tproc.set("Loaders", LoaderInfos) *************** *** 395,398 **** --- 402,406 ---- tproc.set('access_validips', HTTPConfig.Get('Access', 'ValidIPs')) tproc.set('display_refresh', HTTPConfig.Get('Display', 'Refresh')) + tproc.set('display_refreshinfo', HTTPConfig.Get('Display', 'RefreshInfo')) tproc.set('display_loglevel', HTTPConfig.Get('Display', 'LogLevel')) tproc.set('display_logcount', HTTPConfig.Get('Display', 'LogCount')) Index: HTTPConfigFile.py =================================================================== RCS file: /cvsroot/btplusplus/BT++/src/WebServer/HTTPConfigFile.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** HTTPConfigFile.py 16 Mar 2003 01:17:58 -0000 1.5 --- HTTPConfigFile.py 28 Mar 2003 21:09:35 -0000 1.6 *************** *** 12,15 **** --- 12,16 ---- 'Display': { 'Refresh': '10', + 'RefreshInfo': '5', 'LogLevel': '1', 'LogCount': '200' |
From: <bel...@us...> - 2003-03-28 20:41:24
|
Update of /cvsroot/btplusplus/BT++/src In directory sc8-pr-cvs1:/tmp/cvs-serv31397 Added Files: .cvsignore Log Message: Updated by TortoiseCVS --- NEW FILE: .cvsignore --- *.pyc |
From: <sir...@us...> - 2003-03-28 16:51:21
|
Update of /cvsroot/btplusplus/BT++/dist In directory sc8-pr-cvs1:/tmp/cvs-serv24924/dist Modified Files: README.txt CHANGELOG.txt BT++.nsi Log Message: 0.5.1 Index: README.txt =================================================================== RCS file: /cvsroot/btplusplus/BT++/dist/README.txt,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** README.txt 16 Mar 2003 01:17:57 -0000 1.10 --- README.txt 28 Mar 2003 16:51:03 -0000 1.11 *************** *** 65,74 **** Unix / Linux: 1 - Install Python(http://www.python.org) ! 2 - Install wxWindows+wxPython(http://www.wxpython.org) 3 - Unpack the tar.gz / tar.bz either 4 - go to the src directory and use 'python BT++.py' to start BT++ (on some systems with both python 1.x and 2.x you might have to use ! 'python2' instead of 'python') or 4 - make BT++.py in the src directory executable ('chmod +x BT++.py') --- 65,74 ---- Unix / Linux: 1 - Install Python(http://www.python.org) ! 2 - Install wxWindows + wxPython(http://www.wxpython.org) 3 - Unpack the tar.gz / tar.bz either 4 - go to the src directory and use 'python BT++.py' to start BT++ (on some systems with both python 1.x and 2.x you might have to use ! 'python2' instead of 'python') or 4 - make BT++.py in the src directory executable ('chmod +x BT++.py') *************** *** 81,85 **** When starting the tool the first time it will create four subdirectories. ! In the one, called 'torrent', you have to put the downloaded torrent files. Files that are currently downloaded are put in the 'temp' dir and moved to 'incoming' after they are finished. 'history' will contain all --- 81,85 ---- When starting the tool the first time it will create four subdirectories. ! In the one called 'torrent', you have to put the downloaded torrent files. Files that are currently downloaded are put in the 'temp' dir and moved to 'incoming' after they are finished. 'history' will contain all *************** *** 91,94 **** There is some kind of priority implemented. If set to auto download BT++ will start the downloads at the top of the list first. You can move items ! by draging and droping the number at the very left of the grid, or by ! using the 'Move Up/Down' options in the right-click-popup. --- 91,98 ---- There is some kind of priority implemented. If set to auto download BT++ will start the downloads at the top of the list first. You can move items ! by using the 'Move Up/Down' options in the right-click-popup. ! ! If you want to use BT++ for seeding torrents simply put the torrent you ! want to seed into the history directory and the finished file in the ! incoming directory. This will make the torrent appear in the history tab ! in BT++. Resume the file to start uploading. Index: CHANGELOG.txt =================================================================== RCS file: /cvsroot/btplusplus/BT++/dist/CHANGELOG.txt,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** CHANGELOG.txt 9 Mar 2003 12:11:55 -0000 1.1 --- CHANGELOG.txt 28 Mar 2003 16:51:03 -0000 1.2 *************** *** 1,2 **** --- 1,22 ---- + [0.5.1 (alpha)] + + - Updated to wxPython 2.4.0.7 (false/true deprecated). + - Updated to BT 3.2 (some Loader changes + core). + - Implemented seed number control. + - Fixed: If last torrent completed it wasn't removed from list + - Added shell command to BT++.py + - Fixed pause. + - Fixed cancel. + - Fixed pause while hashing. + - Fixed little bug in 'Add Torrent'. + - Fixed problem with spaces in 'Add Torrent'. + - Improved downloading code for 'Add Torrent'. + - Abstraction of seed management. + - Global upload limit fixed. + - Fixed bug in lock/unlock. + - Added clear button to the log tab. + - Fixed stupid logging bug. + - Added colors to the log. + [0.5.0 (alpha)] Index: BT++.nsi =================================================================== RCS file: /cvsroot/btplusplus/BT++/dist/BT++.nsi,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** BT++.nsi 10 Mar 2003 18:42:20 -0000 1.11 --- BT++.nsi 28 Mar 2003 16:51:03 -0000 1.12 *************** *** 1,4 **** !define MUI_PRODUCT "BitTorrent++" ! !define MUI_VERSION "0.5.0" !include "${NSISDIR}\Contrib\Modern UI\System.nsh" --- 1,4 ---- !define MUI_PRODUCT "BitTorrent++" ! !define MUI_VERSION "0.5.1" !include "${NSISDIR}\Contrib\Modern UI\System.nsh" *************** *** 45,49 **** File "..\build\BT++\select.pyd" File "..\build\BT++\wxc.pyd" ! File "..\build\BT++\wxmsw240h.dll" File "..\build\BT++\zlib.pyd" File "README.txt" --- 45,49 ---- File "..\build\BT++\select.pyd" File "..\build\BT++\wxc.pyd" ! File "..\build\BT++\wxmsw24h.dll" File "..\build\BT++\zlib.pyd" File "README.txt" |
From: <sir...@us...> - 2003-03-28 16:51:17
|
Update of /cvsroot/btplusplus/BT++/src In directory sc8-pr-cvs1:/tmp/cvs-serv24924/src Modified Files: Version.py Log Message: 0.5.1 Index: Version.py =================================================================== RCS file: /cvsroot/btplusplus/BT++/src/Version.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** Version.py 9 Mar 2003 11:51:34 -0000 1.2 --- Version.py 28 Mar 2003 16:51:02 -0000 1.3 *************** *** 1 **** ! CurrentVersion = '0.5.0' --- 1 ---- ! CurrentVersion = '0.5.1' |
From: <sir...@us...> - 2003-03-28 15:58:34
|
Update of /cvsroot/btplusplus/BT++/src/core In directory sc8-pr-cvs1:/tmp/cvs-serv23971/src/core Modified Files: Connecter.py Log Message: - Fixed a crashbug. Index: Connecter.py =================================================================== RCS file: /cvsroot/btplusplus/BT++/src/core/Connecter.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** Connecter.py 28 Mar 2003 12:44:28 -0000 1.2 --- Connecter.py 28 Mar 2003 15:58:24 -0000 1.3 *************** *** 151,156 **** c = self.connections[connection] d = c.download - del c.upload - del c.download del self.connections[connection] d.disconnected() --- 151,154 ---- |
From: <sir...@us...> - 2003-03-28 14:58:33
|
Update of /cvsroot/btplusplus/BT++/src In directory sc8-pr-cvs1:/tmp/cvs-serv22207/src Modified Files: Loader.py Log Message: - Removed debug output thing. Index: Loader.py =================================================================== RCS file: /cvsroot/btplusplus/BT++/src/Loader.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** Loader.py 28 Mar 2003 14:47:27 -0000 1.6 --- Loader.py 28 Mar 2003 14:58:27 -0000 1.7 *************** *** 497,502 **** self.FlagEnd ) - self.Log('Here') - self.Obj['DownloaderFeedback'] = \ DownloaderFeedback( self.Obj['Choker'], --- 497,500 ---- |
From: <sir...@us...> - 2003-03-28 14:47:34
|
Update of /cvsroot/btplusplus/BT++/src In directory sc8-pr-cvs1:/tmp/cvs-serv17351/src Modified Files: Loader.py Log Message: - Fixed pause while hashing. - Fixed little bug in 'Add Torrent'. Index: Loader.py =================================================================== RCS file: /cvsroot/btplusplus/BT++/src/Loader.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** Loader.py 28 Mar 2003 13:38:05 -0000 1.5 --- Loader.py 28 Mar 2003 14:47:27 -0000 1.6 *************** *** 50,53 **** --- 50,56 ---- self.FlagHash.clear() + self.ThrHashing = None + self.ThrDownload = None + self.Info = {} self.Config = {} *************** *** 64,70 **** raise - self.ThrHashing = Thread( target = self.ProcessFiles ) - self.ThrHashing.setDaemon(false) - ########################################################################################################### ########################################################################################################### --- 67,70 ---- *************** *** 93,96 **** --- 93,97 ---- self.Config['Filename'] = path.join(self.Config['DirTemp'], torinfo['name']) self.Config['Pieces'] = torinfo['pieces'] + self.Config['Pieces'] = [self.Config['Pieces'][x:x+20] for x in xrange(0, len(self.Config['Pieces']), 20)] self.Config['PiecesLen'] = torinfo['piece length'] self.Config['InfoHash'] = sha(bencode(torinfo)).digest() *************** *** 140,153 **** def StartHashing(self): self.ThrHashing.start() self.OnTrivialInfo('Hashing started') def StartDownload( self ): - if self.Hashed == false: - self.StartHashing() - self.FlagEnd.clear() self.Paused = false self.UserPause = false self.ThrDownload = Thread( target = self.Download ) --- 141,156 ---- def StartHashing(self): + self.ThrHashing = Thread( target = self.ProcessFiles ) + self.ThrHashing.setDaemon(false) self.ThrHashing.start() self.OnTrivialInfo('Hashing started') def StartDownload( self ): self.FlagEnd.clear() self.Paused = false self.UserPause = false + + if self.Hashed == false: + self.StartHashing() self.ThrDownload = Thread( target = self.Download ) *************** *** 157,164 **** def PauseDownload( self, user = false ): ! if self.ThrHashing.isAlive(): self.FlagHash.clear() self.Hashed = false self.FlagEnd.set() self.Paused = true --- 160,172 ---- def PauseDownload( self, user = false ): ! if self.ThrHashing != None and self.ThrHashing.isAlive(): self.FlagHash.clear() self.Hashed = false + self.Obj['Storage'] = None + self.Obj['StorageWrapper'] = None + + self.UpdateStatus( fractionDone = -1 ) + self.FlagEnd.set() self.Paused = true *************** *** 169,173 **** upRate = 0, activity = 'Paused' ) ! self.OnTrivialInfo('Download Paused') --- 177,181 ---- upRate = 0, activity = 'Paused' ) ! self.OnTrivialInfo('Download Paused') *************** *** 191,195 **** def IsHashing(self): ! return self.ThrHashing.isAlive() def HasHashed(self): --- 199,206 ---- def IsHashing(self): ! if self.ThrHashing == None: ! return False ! else: ! return self.ThrHashing.isAlive() def HasHashed(self): *************** *** 326,331 **** return - self.Config['Pieces'] = [self.Config['Pieces'][x:x+20] for x in xrange(0, len(self.Config['Pieces']), 20)] - try: self.Obj['Storage'] = \ --- 337,340 ---- *************** *** 383,387 **** while 1: self.FlagHash.wait(2.0) ! if not self.ThrHashing.isAlive(): break --- 392,396 ---- while 1: self.FlagHash.wait(2.0) ! if self.ThrHashing == None or not self.ThrHashing.isAlive(): break |
From: <sir...@us...> - 2003-03-28 14:47:34
|
Update of /cvsroot/btplusplus/BT++/src/DlgAddTor In directory sc8-pr-cvs1:/tmp/cvs-serv17351/src/DlgAddTor Modified Files: DlgAddTor.py Log Message: - Fixed pause while hashing. - Fixed little bug in 'Add Torrent'. Index: DlgAddTor.py =================================================================== RCS file: /cvsroot/btplusplus/BT++/src/DlgAddTor/DlgAddTor.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** DlgAddTor.py 10 Mar 2003 18:44:51 -0000 1.2 --- DlgAddTor.py 28 Mar 2003 14:47:26 -0000 1.3 *************** *** 82,90 **** e = i.find('\n', s) - 1 ! file = i[s:e] else: spl = urlparse(url) file = path.split(spl[2])[1] ! if file == '': raise --- 82,94 ---- e = i.find('\n', s) - 1 ! if s == 8: ! spl = urlparse(url) ! file = path.split(spl[2])[1] ! else: ! file = i[s:e] else: spl = urlparse(url) file = path.split(spl[2])[1] ! if file == '': raise |
From: <sir...@us...> - 2003-03-28 13:38:08
|
Update of /cvsroot/btplusplus/BT++/src/TabTrans In directory sc8-pr-cvs1:/tmp/cvs-serv17547/src/TabTrans Modified Files: Grid.py Log Message: - Fixed pause. - Fixed cancel. Index: Grid.py =================================================================== RCS file: /cvsroot/btplusplus/BT++/src/TabTrans/Grid.py,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** Grid.py 16 Mar 2003 01:17:58 -0000 1.12 --- Grid.py 28 Mar 2003 13:38:04 -0000 1.13 *************** *** 138,141 **** --- 138,142 ---- try: l.PauseDownload() + l.Obj['Storage'].close() unlink( l.Config['TorFull'] ) except: *************** *** 149,153 **** loaders = self.GetLoaders(self.Selection['Set']) for l in loaders: ! l.PauseDownload() ########################################################################################################### --- 150,154 ---- loaders = self.GetLoaders(self.Selection['Set']) for l in loaders: ! l.PauseDownload(true) ########################################################################################################### |
From: <sir...@us...> - 2003-03-28 13:38:08
|
Update of /cvsroot/btplusplus/BT++/src/core In directory sc8-pr-cvs1:/tmp/cvs-serv17547/src/core Modified Files: Storage.py Log Message: - Fixed pause. - Fixed cancel. Index: Storage.py =================================================================== RCS file: /cvsroot/btplusplus/BT++/src/core/Storage.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** Storage.py 28 Mar 2003 12:44:28 -0000 1.3 --- Storage.py 28 Mar 2003 13:38:04 -0000 1.4 *************** *** 62,66 **** if time() - tstart > alloc_pause: if not hit: ! statusfunc(activity = 'allocating') hit = true statusfunc(fractionDone = float(so_far + i - l)/total) --- 62,66 ---- if time() - tstart > alloc_pause: if not hit: ! statusfunc(activity = 'Allocating') hit = true statusfunc(fractionDone = float(so_far + i - l)/total) *************** *** 72,75 **** --- 72,79 ---- for file, old in self.handles.items(): self.handles[file] = open(file, 'rb') + old.close() + + def close(self): + for file, old in self.handles.items(): old.close() |
From: <sir...@us...> - 2003-03-28 13:38:08
|
Update of /cvsroot/btplusplus/BT++/src In directory sc8-pr-cvs1:/tmp/cvs-serv17547/src Modified Files: LoaderManager.py Loader.py Log Message: - Fixed pause. - Fixed cancel. Index: LoaderManager.py =================================================================== RCS file: /cvsroot/btplusplus/BT++/src/LoaderManager.py,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** LoaderManager.py 28 Mar 2003 12:51:07 -0000 1.8 --- LoaderManager.py 28 Mar 2003 13:38:04 -0000 1.9 *************** *** 227,231 **** break ! if not loader.IsRunning() and not loader.IsFinished(): dwcnt = dwcnt - 1 loader.StartDownload() --- 227,231 ---- break ! if not loader.IsRunning() and not loader.IsUserPaused() and not loader.IsFinished(): dwcnt = dwcnt - 1 loader.StartDownload() Index: Loader.py =================================================================== RCS file: /cvsroot/btplusplus/BT++/src/Loader.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** Loader.py 28 Mar 2003 12:44:25 -0000 1.4 --- Loader.py 28 Mar 2003 13:38:05 -0000 1.5 *************** *** 42,48 **** self.FlagHash = Event() ! self.Hashed = false ! self.Paused = true ! self.Finished = false self.FlagEnd.clear() --- 42,49 ---- self.FlagHash = Event() ! self.Hashed = false ! self.Paused = true ! self.UserPause = false ! self.Finished = false self.FlagEnd.clear() *************** *** 147,151 **** self.FlagEnd.clear() ! self.Paused = false self.ThrDownload = Thread( target = self.Download ) --- 148,153 ---- self.FlagEnd.clear() ! self.Paused = false ! self.UserPause = false self.ThrDownload = Thread( target = self.Download ) *************** *** 154,158 **** self.OnTrivialInfo('Download started') ! def PauseDownload( self ): if self.ThrHashing.isAlive(): self.FlagHash.clear() --- 156,160 ---- self.OnTrivialInfo('Download started') ! def PauseDownload( self, user = false ): if self.ThrHashing.isAlive(): self.FlagHash.clear() *************** *** 160,164 **** self.FlagEnd.set() ! self.Paused = true self.UpdateStatus( timeEst = -1, --- 162,167 ---- self.FlagEnd.set() ! self.Paused = true ! self.UserPause = user self.UpdateStatus( timeEst = -1, *************** *** 180,183 **** --- 183,189 ---- def IsRunning(self): return not self.Paused + + def IsUserPaused(self): + return self.UserPause def IsFinished(self): |
From: <sir...@us...> - 2003-03-28 12:51:10
|
Update of /cvsroot/btplusplus/BT++/src In directory sc8-pr-cvs1:/tmp/cvs-serv27674/src Modified Files: Managers.py LoaderManager.py Log Message: - Global upload limit fixed (again... I forgot something). Index: Managers.py =================================================================== RCS file: /cvsroot/btplusplus/BT++/src/Managers.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** Managers.py 28 Mar 2003 12:48:11 -0000 1.2 --- Managers.py 28 Mar 2003 12:51:07 -0000 1.3 *************** *** 2,5 **** --- 2,6 ---- from SeedManager import SeedManager from ConfigFile import Config + from core.CurrentRateMeasure import GlobalMeasure UpMeasure = GlobalMeasure( 20.0, # MAX RATE PERIOD, Index: LoaderManager.py =================================================================== RCS file: /cvsroot/btplusplus/BT++/src/LoaderManager.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** LoaderManager.py 28 Mar 2003 12:48:11 -0000 1.7 --- LoaderManager.py 28 Mar 2003 12:51:07 -0000 1.8 *************** *** 2,6 **** from ConfigFile import ConfigFile, Config from Loader import Loader - from core.CurrentRateMeasure import GlobalMeasure from BTConstants import * --- 2,5 ---- |
From: <sir...@us...> - 2003-03-28 12:48:17
|
Update of /cvsroot/btplusplus/BT++/src In directory sc8-pr-cvs1:/tmp/cvs-serv25572/src Modified Files: Managers.py LoaderManager.py Log Message: - Global upload limit fixed. Index: Managers.py =================================================================== RCS file: /cvsroot/btplusplus/BT++/src/Managers.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** Managers.py 28 Mar 2003 12:44:25 -0000 1.1 --- Managers.py 28 Mar 2003 12:48:11 -0000 1.2 *************** *** 3,13 **** from ConfigFile import Config ManagerUp = SeedManager ( [ Config.Get('Paths', 'History'), Config.Get('Paths', 'Incoming'), '', ! '' ] ) ManagerDown = LoaderManager( [ Config.Get('Paths', 'Torrent'), Config.Get('Paths', 'Temp'), Config.Get('Paths', 'Incoming'), ! Config.Get('Paths', 'History') ] ) --- 3,18 ---- from ConfigFile import Config + UpMeasure = GlobalMeasure( 20.0, # MAX RATE PERIOD, + 5.0 ) # UPLOAD RATE FUDGE + ManagerUp = SeedManager ( [ Config.Get('Paths', 'History'), Config.Get('Paths', 'Incoming'), '', ! '' ], ! upmeasure = UpMeasure ) ManagerDown = LoaderManager( [ Config.Get('Paths', 'Torrent'), Config.Get('Paths', 'Temp'), Config.Get('Paths', 'Incoming'), ! Config.Get('Paths', 'History') ], ! upmeasure = UpMeasure ) Index: LoaderManager.py =================================================================== RCS file: /cvsroot/btplusplus/BT++/src/LoaderManager.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** LoaderManager.py 16 Mar 2003 01:17:58 -0000 1.6 --- LoaderManager.py 28 Mar 2003 12:48:11 -0000 1.7 *************** *** 18,22 **** DirTorFinish = '' ! def __init__(self, dirs, refresh = None, log = None, finish = None): self.Log = log self.Refresh = refresh --- 18,22 ---- DirTorFinish = '' ! def __init__(self, dirs, refresh = None, log = None, finish = None, upmeasure = None): self.Log = log self.Refresh = refresh *************** *** 28,33 **** self.DirTorFinish = dirs[3] ! self.UpMeasure = GlobalMeasure( 20.0, # MAX RATE PERIOD, ! 5.0 ) # UPLOAD RATE FUDGE def CreateNewLoader(self, torrent): --- 28,36 ---- self.DirTorFinish = dirs[3] ! if upmeasure == None: ! self.UpMeasure = GlobalMeasure( 20.0, # MAX RATE PERIOD, ! 5.0 ) # UPLOAD RATE FUDGE ! else: ! self.UpMeasure = upmeasure def CreateNewLoader(self, torrent): |
Update of /cvsroot/btplusplus/BT++/src/core In directory sc8-pr-cvs1:/tmp/cvs-serv23881/src/core Modified Files: Choker.py Connecter.py CurrentRateMeasure.py DownloaderFeedback.py Encrypter.py HTTPHandler.py NatCheck.py PiecePicker.py RateMeasure.py RawServer.py Rerequester.py Storage.py StorageWrapper.py Uploader.py __init__.py btformats.py download.py testtest.py track.py Added Files: zurllib.py Log Message: - Updated to wxPython 2.4.0.7 (no source changes). - Updated to BT 3.2 (some Loader changes + core). - Moved some stuff. --- NEW FILE: zurllib.py --- # # zurllib.py # # This is (hopefully) a drop-in for urllib which will request gzip/deflate # compression and then decompress the output if a compressed response is # received while maintaining the API. # # by Robert Stone 2/22/2003 # from urllib import * from urllib2 import * from gzip import GzipFile from StringIO import StringIO import pprint DEBUG=0 class HTTPContentEncodingHandler(HTTPHandler): """Inherit and add gzip/deflate/etc support to HTTP gets.""" def http_open(self, req): # add the Accept-Encoding header to the request # support gzip encoding (identity is assumed) req.add_header("Accept-Encoding","gzip") if DEBUG: print "Sending:" print req.headers print "\n" fp = HTTPHandler.http_open(self,req) headers = fp.headers if DEBUG: pprint.pprint(headers.dict) url = fp.url return addinfourldecompress(fp, headers, url) class addinfourldecompress(addinfourl): """Do gzip decompression if necessary. Do addinfourl stuff too.""" def __init__(self, fp, headers, url): # we need to do something more sophisticated here to deal with # multiple values? What about other weird crap like q-values? # basically this only works for the most simplistic case and will # break in some other cases, but for now we only care about making # this work with the BT tracker so.... if headers.has_key('content-encoding') and headers['content-encoding'] == 'gzip': if DEBUG: print "Contents of Content-encoding: " + headers['Content-encoding'] + "\n" self.gzip = 1 self.rawfp = fp fp = GzipStream(fp) else: self.gzip = 0 return addinfourl.__init__(self, fp, headers, url) def close(self): self.fp.close() if self.gzip: self.rawfp.close() def iscompressed(self): return self.gzip class GzipStream(StringIO): """Magically decompress a file object. This is not the most efficient way to do this but GzipFile() wants to seek, etc, which won't work for a stream such as that from a socket. So we copy the whole shebang info a StringIO object, decompress that then let people access the decompressed output as a StringIO object. The disadvantage is memory use and the advantage is random access. Will mess with fixing this later. """ def __init__(self,fp): self.fp = fp # this is nasty and needs to be fixed at some point # copy everything into a StringIO (compressed) compressed = StringIO() r = fp.read() while r: compressed.write(r) r = fp.read() # now, unzip (gz) the StringIO to a string compressed.seek(0,0) gz = GzipFile(fileobj = compressed) str = '' r = gz.read() while r: str += r r = gz.read() # close our utility files compressed.close() gz.close() # init our stringio selves with the string StringIO.__init__(self, str) del str def close(self): self.fp.close() return StringIO.close(self) def test(): """Test this module. At the moment this is lame. """ print "Running unit tests.\n" def printcomp(fp): try: if fp.iscompressed(): print "GET was compressed.\n" else: print "GET was uncompressed.\n" except: print "no iscompressed function! this shouldn't happen" print "Trying to GET a compressed document...\n" fp = urlopen('http://a.scarywater.net/hng/index.shtml') print fp.read() printcomp(fp) fp.close() print "Trying to GET an unknown document...\n" fp = urlopen('http://www.otaku.org/') print fp.read() printcomp(fp) fp.close() # # Install the HTTPContentEncodingHandler that we've defined above. # install_opener(build_opener(HTTPContentEncodingHandler)) if __name__ == '__main__': test() Index: Choker.py =================================================================== RCS file: /cvsroot/btplusplus/BT++/src/core/Choker.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** Choker.py 19 Feb 2003 20:40:37 -0000 1.1 --- Choker.py 28 Mar 2003 12:44:27 -0000 1.2 *************** *** 7,15 **** class Choker: ! def __init__(self, max_uploads, schedule): self.max_uploads = max_uploads self.schedule = schedule self.connections = [] self.count = 0 schedule(self._round_robin, 10) --- 7,16 ---- class Choker: ! def __init__(self, max_uploads, schedule, done = lambda: false): self.max_uploads = max_uploads self.schedule = schedule self.connections = [] self.count = 0 + self.done = done schedule(self._round_robin, 10) *************** *** 20,70 **** for i in xrange(len(self.connections)): u = self.connections[i].get_upload() ! if u.get_hit() or u.is_choked(): self.connections = self.connections[i:] + self.connections[:i] break ! self._rechoke() ! for c in self.connections: ! c.get_upload().set_not_hit() else: ! self._rechoke() ! def _rechoke(self): preferred = [] for c in self.connections: ! d = c.get_download() ! if not d.is_snubbed() and c.get_upload().is_interested(): ! preferred.append((d.get_rate(), c)) preferred.sort() - preferred.reverse() del preferred[self.max_uploads - 1:] - if self.max_uploads == 0: - preferred = [] preferred = [x[1] for x in preferred] - for c in preferred: - c.get_upload().unchoke() count = len(preferred) for c in self.connections: - if c in preferred: - continue u = c.get_upload() ! if count < self.max_uploads: u.unchoke() - if u.is_interested(): - count += 1 else: ! u.choke() def connection_made(self, connection, p = None): if p is None: p = randrange(-2, len(self.connections) + 1) ! if p <= 0: ! self.connections.insert(0, connection) ! else: ! self.connections.insert(p, connection) self._rechoke() def connection_lost(self, connection): self.connections.remove(connection) ! self._rechoke() def interested(self, connection): --- 21,71 ---- for i in xrange(len(self.connections)): u = self.connections[i].get_upload() ! if u.is_choked() and u.is_interested(): self.connections = self.connections[i:] + self.connections[:i] break ! self._rechoke() ! ! def _snubbed(self, c): ! if self.done(): ! return false ! return c.get_download().is_snubbed() ! ! def _rate(self, c): ! if self.done(): ! return c.get_upload().get_rate() else: ! return c.get_download().get_rate() ! def _rechoke(self): preferred = [] for c in self.connections: ! if not self._snubbed(c) and c.get_upload().is_interested(): ! preferred.append((-self._rate(c), c)) preferred.sort() del preferred[self.max_uploads - 1:] preferred = [x[1] for x in preferred] count = len(preferred) for c in self.connections: u = c.get_upload() ! if c in preferred: u.unchoke() else: ! if count < self.max_uploads: ! u.unchoke() ! if u.is_interested(): ! count += 1 ! else: ! u.choke() def connection_made(self, connection, p = None): if p is None: p = randrange(-2, len(self.connections) + 1) ! self.connections.insert(max(p, 0), connection) self._rechoke() def connection_lost(self, connection): self.connections.remove(connection) ! if connection.get_upload().is_interested() and not connection.get_upload().is_choked(): ! self._rechoke() def interested(self, connection): *************** *** 110,124 **** self.i = false self.c = true - self.hit = true def choke(self): if not self.c: self.c = true ! self.hit = true ! def unchoke(self): if self.c: self.c = false - self.hit = true def is_choked(self): --- 111,122 ---- self.i = false self.c = true def choke(self): if not self.c: self.c = true ! def unchoke(self): if self.c: self.c = false def is_choked(self): *************** *** 128,137 **** return self.i - def set_not_hit(self): - self.hit = false - - def get_hit(self): - return self.hit - def test_round_robin_with_no_downloads(): s = DummyScheduler() --- 126,129 ---- *************** *** 237,241 **** assert not c2.u.c ! def test_interrupt_by_connection_lost(): s = DummyScheduler() choker = Choker(1, s) --- 229,233 ---- assert not c2.u.c ! def test_skip_not_interested(): s = DummyScheduler() choker = Choker(1, s) *************** *** 244,261 **** c3 = DummyConnection(2) c1.u.i = true - c2.u.i = true c3.u.i = true ! choker.connection_made(c1) ! choker.connection_made(c2, 1) ! choker.connection_made(c3, 2) ! f = s.s[0][0] ! f() assert not c1.u.c assert c2.u.c ! assert c3.u.c ! f() assert not c1.u.c assert c2.u.c assert c3.u.c f() assert not c1.u.c --- 236,250 ---- c3 = DummyConnection(2) c1.u.i = true c3.u.i = true ! choker.connection_made(c2) ! assert not c2.u.c ! choker.connection_made(c1, 0) assert not c1.u.c assert c2.u.c ! choker.connection_made(c3, 2) assert not c1.u.c assert c2.u.c assert c3.u.c + f = s.s[0][0] f() assert not c1.u.c *************** *** 267,279 **** assert c3.u.c f() ! assert not c1.u.c assert c2.u.c ! assert c3.u.c ! choker.connection_lost(c1) ! assert not c2.u.c ! assert c3.u.c ! f() ! assert not c2.u.c ! assert c3.u.c def test_connection_lost_no_interrupt(): --- 256,262 ---- assert c3.u.c f() ! assert c1.u.c assert c2.u.c ! assert not c3.u.c def test_connection_lost_no_interrupt(): *************** *** 299,355 **** assert c3.u.c f() ! assert not c1.u.c ! assert c2.u.c assert c3.u.c f() ! assert not c1.u.c ! assert c2.u.c assert c3.u.c f() ! assert not c1.u.c ! assert c2.u.c ! assert c3.u.c ! choker.connection_lost(c2) ! assert not c1.u.c assert c3.u.c ! f() assert c1.u.c ! assert not c3.u.c ! ! def test_interrupt_by_connection_made(): ! s = DummyScheduler() ! choker = Choker(1, s) ! c1 = DummyConnection(0) ! c2 = DummyConnection(1) ! c3 = DummyConnection(2) ! c1.u.i = true ! c2.u.i = true ! c3.u.i = true ! choker.connection_made(c1) ! choker.connection_made(c2, 1) ! f = s.s[0][0] ! f() ! assert not c1.u.c ! assert c2.u.c ! f() ! assert not c1.u.c ! assert c2.u.c ! f() ! assert not c1.u.c ! assert c2.u.c f() assert not c1.u.c assert c2.u.c ! f() assert not c1.u.c - assert c2.u.c - choker.connection_made(c3, 0) - assert c1.u.c - assert c2.u.c - assert not c3.u.c - f() - assert c1.u.c - assert c2.u.c - assert not c3.u.c def test_connection_made_no_interrupt(): --- 282,304 ---- assert c3.u.c f() ! assert c1.u.c ! assert not c2.u.c assert c3.u.c f() ! assert c1.u.c ! assert not c2.u.c assert c3.u.c f() ! assert c1.u.c ! assert not c2.u.c assert c3.u.c ! choker.connection_lost(c3) assert c1.u.c ! assert not c2.u.c f() assert not c1.u.c assert c2.u.c ! choker.connection_lost(c2) assert not c1.u.c def test_connection_made_no_interrupt(): *************** *** 365,375 **** choker.connection_made(c2, 1) f = s.s[0][0] - f() - assert not c1.u.c - assert c2.u.c - f() - assert not c1.u.c - assert c2.u.c - f() assert not c1.u.c assert c2.u.c --- 314,317 ---- *************** *** 399,409 **** choker.connection_made(c2, 1) f = s.s[0][0] - f() - assert not c1.u.c - assert c2.u.c - f() - assert not c1.u.c - assert c2.u.c - f() assert not c1.u.c assert c2.u.c --- 341,344 ---- *************** *** 473,486 **** assert c11.u.c - #uninterested - #interested snubbed, - #uninterested, - #interested first priority, - #uninterested, - #interested snubbed, - #uninterested, - #interested third priority snubbed, - #uninterested zeroth priority, - #interested second priority - #uninterested --- 408,410 ---- Index: Connecter.py =================================================================== RCS file: /cvsroot/btplusplus/BT++/src/core/Connecter.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** Connecter.py 19 Feb 2003 20:40:37 -0000 1.1 --- Connecter.py 28 Mar 2003 12:44:28 -0000 1.2 *************** *** 40,43 **** --- 40,46 ---- return self.connection.get_ip() + def get_id(self): + return self.connection.get_id() + def close(self): self.connection.close() Index: CurrentRateMeasure.py =================================================================== RCS file: /cvsroot/btplusplus/BT++/src/core/CurrentRateMeasure.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** CurrentRateMeasure.py 19 Feb 2003 20:40:37 -0000 1.1 --- CurrentRateMeasure.py 28 Mar 2003 12:44:28 -0000 1.2 *************** *** 57,61 **** if self.ratesince < t - self.max_rate_period: self.ratesince = t - self.max_rate_period - def add_measure(self, m): self.Measures.append( m ) --- 57,60 ---- Index: DownloaderFeedback.py =================================================================== RCS file: /cvsroot/btplusplus/BT++/src/core/DownloaderFeedback.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** DownloaderFeedback.py 19 Feb 2003 20:40:37 -0000 1.1 --- DownloaderFeedback.py 28 Mar 2003 12:44:28 -0000 1.2 *************** *** 16,20 **** file_length, finflag, ! interval ): self.choker = choker self.add_task = add_task --- 16,21 ---- file_length, finflag, ! interval, ! sp ): self.choker = choker self.add_task = add_task *************** *** 27,36 **** self.finflag = finflag self.interval = interval self.display() def spew(self): s = StringIO() ! for c in self.choker.connections: s.write('%20s ' % c.get_ip()) if c.is_locally_initiated(): s.write('l') --- 28,53 ---- self.finflag = finflag self.interval = interval + self.sp = sp + self.lastids = [] self.display() + def _rotate(self): + cs = self.choker.connections + for id in self.lastids: + for i in xrange(len(cs)): + if cs[i].get_id() == id: + return cs[i:] + cs[:i] + return cs + def spew(self): s = StringIO() ! cs = self._rotate() ! self.lastids = [c.get_id() for c in cs] ! for c in cs: s.write('%20s ' % c.get_ip()) + if c is self.choker.connections[0]: + s.write('*') + else: + s.write(' ') if c.is_locally_initiated(): s.write('l') *************** *** 67,71 **** def display(self): self.add_task(self.display, self.interval) ! #self.spew() if self.finflag.isSet(): self.statusfunc(upRate = self.upfunc()) --- 84,89 ---- def display(self): self.add_task(self.display, self.interval) ! if self.sp: ! self.spew() if self.finflag.isSet(): self.statusfunc(upRate = self.upfunc()) Index: Encrypter.py =================================================================== RCS file: /cvsroot/btplusplus/BT++/src/core/Encrypter.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** Encrypter.py 19 Feb 2003 20:40:37 -0000 1.1 --- Encrypter.py 28 Mar 2003 12:44:28 -0000 1.2 *************** *** 37,40 **** --- 37,43 ---- return self.connection.get_ip() + def get_id(self): + return self.id + def is_locally_initiated(self): return self.locally_initiated Index: HTTPHandler.py =================================================================== RCS file: /cvsroot/btplusplus/BT++/src/core/HTTPHandler.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** HTTPHandler.py 19 Feb 2003 20:40:36 -0000 1.1 --- HTTPHandler.py 28 Mar 2003 12:44:28 -0000 1.2 *************** *** 5,11 **** --- 5,14 ---- from sys import stdout import time + from gzip import GzipFile true = 1 false = 0 + DEBUG = false + weekdays = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] *************** *** 65,68 **** --- 68,87 ---- if data == '': self.donereading = true + # check for Accept-Encoding: header, pick a + if self.headers.has_key('accept-encoding'): + ae = self.headers['accept-encoding'] + if DEBUG: + print "Got Accept-Encoding: " + ae + "\n" + else: + #identity assumed if no header + ae = 'identity' + # this eventually needs to support multple acceptable types + # q-values and all that fancy HTTP crap + # for now assume we're only communicating with our own client + if ae == 'gzip': + self.encoding = 'gzip' + else: + #default to identity. + self.encoding = 'identity' r = self.handler.getfunc(self, self.path, self.headers) if r is not None: *************** *** 74,77 **** --- 93,98 ---- return None self.headers[data[:i].strip().lower()] = data[i+1:].strip() + if DEBUG: + print data[:i].strip() + ": " + data[i+1:].strip() return self.read_header *************** *** 79,86 **** if self.closed: return year, month, day, hour, minute, second, a, b, c = time.localtime(time.time()) ! print '%s - - [%02d/%3s/%04d:%02d:%02d:%02d] "%s" %i %i' % ( ! self.connection.get_ip(), day, months[month], year, hour, minute, ! second, self.header, responsecode, len(data)) t = time.time() if t - self.handler.lastflush > self.handler.minflush: --- 100,131 ---- if self.closed: return + if self.encoding == 'gzip': + #transform data using gzip compression + #this is nasty but i'm unsure of a better way at the moment + compressed = StringIO() + gz = GzipFile(fileobj = compressed, mode = 'wb', compresslevel = 9) + gz.write(data) + gz.close() + compressed.seek(0,0) + cdata = compressed.read() + compressed.close() + if len(cdata) >= len(data): + self.encoding = 'identity' + else: + if DEBUG: + print "Compressed: %i Uncompressed: %i\n" % (len(cdata),len(data)) + data = cdata + headers['Content-Encoding'] = 'gzip' + + # i'm abusing the identd field here, but this should be ok + if self.encoding == 'identity': + ident = '-' + else: + ident = self.encoding + year, month, day, hour, minute, second, a, b, c = time.localtime(time.time()) ! print '%s %s - [%02d/%3s/%04d:%02d:%02d:%02d] "%s" %i %i' % ( ! self.connection.get_ip(), ident, day, months[month], year, hour, ! minute, second, self.header, responsecode, len(data)) t = time.time() if t - self.handler.lastflush > self.handler.minflush: Index: NatCheck.py =================================================================== RCS file: /cvsroot/btplusplus/BT++/src/core/NatCheck.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** NatCheck.py 19 Feb 2003 20:40:36 -0000 1.1 --- NatCheck.py 28 Mar 2003 12:44:28 -0000 1.2 *************** *** 17,20 **** --- 17,22 ---- self.downloadid = downloadid self.peerid = peerid + self.ip = ip + self.port = port self.closed = false self.buffer = StringIO() *************** *** 32,37 **** def answer(self, result): self.closed = true ! self.connection.close() ! self.resultfunc(result) def read_header_len(self, s): --- 34,42 ---- def answer(self, result): self.closed = true ! try: ! self.connection.close() ! except AttributeError: ! pass ! self.resultfunc(result, self.downloadid, self.peerid, self.ip, self.port) def read_header_len(self, s): *************** *** 82,86 **** if not self.closed: self.closed = true ! self.resultfunc(false) def connection_flushed(self, connection): --- 87,91 ---- if not self.closed: self.closed = true ! self.resultfunc(false, self.downloadid, self.peerid, self.ip, self.port) def connection_flushed(self, connection): Index: PiecePicker.py =================================================================== RCS file: /cvsroot/btplusplus/BT++/src/core/PiecePicker.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** PiecePicker.py 19 Feb 2003 20:40:36 -0000 1.1 --- PiecePicker.py 28 Mar 2003 12:44:28 -0000 1.2 *************** *** 2,6 **** # see LICENSE-BitTorrent.txt for license information ! from random import randrange true = 1 false = 0 --- 2,6 ---- # see LICENSE-BitTorrent.txt for license information ! from random import randrange, shuffle true = 1 false = 0 *************** *** 36,39 **** --- 36,58 ---- return last + class RandomPicker: + def __init__(self, picker): + self.picker = picker + self.fixedpos = 0 + self.l = None + + def next(self): + if self.fixedpos < len(self.picker.fixed): + self.fixedpos += 1 + return self.picker.fixed[self.fixedpos - 1] + if self.l is None: + self.l = [] + for x in self.picker.interests[1:]: + self.l.extend(x) + shuffle(self.l) + if not self.l: + raise StopIteration + return self.l.pop() + class PiecePicker: def __init__(self, numpieces): *************** *** 43,51 **** self.interestpos = range(numpieces) self.fixed = [] # this is a total hack to support python2.1 but supports for ... in def __getitem__(self, key): if key == 0: ! self.picker = SinglePicker(self) try: return self.picker.next() --- 62,71 ---- self.interestpos = range(numpieces) self.fixed = [] + self.got_any = false # this is a total hack to support python2.1 but supports for ... in def __getitem__(self, key): if key == 0: ! self.picker = self.__iter__() try: return self.picker.next() *************** *** 93,101 **** def complete(self, piece): self.came_in(piece) self.fixed.remove(piece) def __iter__(self): ! return SinglePicker(self) def test_came_in(): --- 113,125 ---- def complete(self, piece): + self.got_any = true self.came_in(piece) self.fixed.remove(piece) def __iter__(self): ! if self.got_any: ! return SinglePicker(self) ! else: ! return RandomPicker(self) def test_came_in(): *************** *** 116,119 **** --- 140,155 ---- def test_change_interest(): p = PiecePicker(8) + p.got_have(0) + p.got_have(2) + p.got_have(4) + p.got_have(6) + p.lost_have(2) + p.lost_have(6) + v = [i for i in p] + assert v == [0, 4] or v == [4, 0] + + def test_change_interest2(): + p = PiecePicker(9) + p.complete(8) p.got_have(0) p.got_have(2) Index: RateMeasure.py =================================================================== RCS file: /cvsroot/btplusplus/BT++/src/core/RateMeasure.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** RateMeasure.py 19 Feb 2003 20:40:36 -0000 1.1 --- RateMeasure.py 28 Mar 2003 12:44:28 -0000 1.2 *************** *** 25,28 **** --- 25,31 ---- self.update(time(), amount) + def data_rejected(self, amount): + self.left += amount + def get_time_left(self): if not self.got_anything: *************** *** 35,44 **** def get_size_left(self): return self.left ! def update(self, t, amount): self.left -= amount - self.rate = ((self.rate * (self.last - self.start)) + amount) / (t - self.start) - self.last = t try: self.remaining = self.left / self.rate if self.start < self.last - self.remaining: --- 38,47 ---- def get_size_left(self): return self.left ! def update(self, t, amount): self.left -= amount try: + self.rate = ((self.rate * (self.last - self.start)) + amount) / (t - self.start) + self.last = t self.remaining = self.left / self.rate if self.start < self.last - self.remaining: Index: RawServer.py =================================================================== RCS file: /cvsroot/btplusplus/BT++/src/core/RawServer.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** RawServer.py 19 Feb 2003 20:40:36 -0000 1.1 --- RawServer.py 28 Mar 2003 12:44:28 -0000 1.2 *************** *** 210,215 **** if self.doneflag.isSet(): return - else: - print_exc() except KeyboardInterrupt: print_exc() --- 210,213 ---- Index: Rerequester.py =================================================================== RCS file: /cvsroot/btplusplus/BT++/src/core/Rerequester.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** Rerequester.py 19 Feb 2003 20:40:35 -0000 1.1 --- Rerequester.py 28 Mar 2003 12:44:28 -0000 1.2 *************** *** 2,6 **** # see LICENSE-BitTorrent.txt for license information ! from urllib import urlopen, quote from btformats import check_peers from bencode import bdecode --- 2,6 ---- # see LICENSE-BitTorrent.txt for license information ! from zurllib import urlopen, quote from btformats import check_peers from bencode import bdecode *************** *** 13,17 **** def __init__(self, url, interval, sched, howmany, minpeers, connect, externalsched, amount_left, up, down, ! port, ip, myid, infohash, timeout, errorfunc): self.url = ('%s?info_hash=%s&peer_id=%s&port=%s' % (url, quote(infohash), quote(myid), str(port))) --- 13,17 ---- def __init__(self, url, interval, sched, howmany, minpeers, connect, externalsched, amount_left, up, down, ! port, ip, myid, infohash, timeout, errorfunc, maxpeers, doneflag): self.url = ('%s?info_hash=%s&peer_id=%s&port=%s' % (url, quote(infohash), quote(myid), str(port))) *************** *** 19,22 **** --- 19,24 ---- self.url += '&ip=' + quote(ip) self.interval = interval + self.last = None + self.trackerid = None self.announce_interval = 30 * 60 self.sched = sched *************** *** 30,33 **** --- 32,37 ---- self.timeout = timeout self.errorfunc = errorfunc + self.maxpeers = maxpeers + self.doneflag = doneflag self.last_failed = true self.sched(self.c, interval / 2) *************** *** 48,51 **** --- 52,61 ---- (self.url, str(self.up()), str(self.down()), str(self.amount_left()))) + if self.last is not None: + s += '&last=' + quote(str(self.last)) + if self.trackerid is not None: + s += '&trackerid=' + quote(str(self.trackerid)) + if self.howmany() >= self.maxpeers: + s += '&numwant=0' if event != 3: s += '&event=' + ['started', 'completed', 'stopped'][event] *************** *** 86,90 **** self.errorfunc('rejected by tracker - ' + r['failure reason']) else: ! self.announce_interval = r['interval'] for x in r['peers']: self.connect((x['ip'], x['port']), x['peer id']) --- 96,111 ---- self.errorfunc('rejected by tracker - ' + r['failure reason']) else: ! self.announce_interval = r.get('interval', self.announce_interval) ! self.interval = r.get('min interval', self.interval) ! self.trackerid = r.get('tracker id', self.trackerid) ! self.last = r.get('last') ! ps = len(r['peers']) + self.howmany() ! if ps < self.maxpeers: ! if self.doneflag.isSet(): ! if r.get('num peers', 1000) - r.get('done peers', 0) > ps * 1.2: ! self.last = None ! else: ! if r.get('num peers', 1000) > ps * 1.2: ! self.last = None for x in r['peers']: self.connect((x['ip'], x['port']), x['peer id']) Index: Storage.py =================================================================== RCS file: /cvsroot/btplusplus/BT++/src/core/Storage.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** Storage.py 22 Feb 2003 16:14:54 -0000 1.2 --- Storage.py 28 Mar 2003 12:44:28 -0000 1.3 *************** *** 3,7 **** from sha import sha - from threading import Event from cStringIO import StringIO from time import time --- 3,6 ---- *************** *** 15,22 **** def __init__(self, files, open, exists, getsize, statusfunc, alloc_pause = 3): # can raise IOError and ValueError - self.isopen = false self.ranges = [] ! total = 0 ! so_far = 0 for file, length in files: if length != 0: --- 14,20 ---- def __init__(self, files, open, exists, getsize, statusfunc, alloc_pause = 3): # can raise IOError and ValueError self.ranges = [] ! total = 0l ! so_far = 0l for file, length in files: if length != 0: *************** *** 34,50 **** else: open(file, 'wb').close() - self.total_length = total self.handles = {} self.preexisting = false for file, length in files: if exists(file): ! self.handles[file] = open(file, 'rb+') self.preexisting = true else: self.handles[file] = open(file, 'wb+') ! ! self.isopen = true ! if total > so_far: interval = max(2 ** 20, long(total / 100)) --- 32,46 ---- else: open(file, 'wb').close() self.total_length = total self.handles = {} + self.whandles = {} self.preexisting = false for file, length in files: if exists(file): ! self.handles[file] = open(file, 'rb') self.preexisting = true else: self.handles[file] = open(file, 'wb+') ! self.whandles[file] = 1 if total > so_far: interval = max(2 ** 20, long(total / 100)) *************** *** 57,70 **** if l == length: continue h = self.handles[file] ! for i in range(l, length, interval)[1:] + [length-1]: h.seek(i) h.write(chr(1)) if time() - tstart > alloc_pause: if not hit: ! statusfunc(activity = 'Allocating', fractionDone = -1) hit = true statusfunc(fractionDone = float(so_far + i - l)/total) so_far += length - l def set_readonly(self): --- 53,70 ---- if l == length: continue + if self.preexisting: + self.handles[file] = open(file,'rb+') + self.whandles[file] = 1 h = self.handles[file] ! for i in lrange(l, length, interval)[1:] + [length-1]: h.seek(i) h.write(chr(1)) if time() - tstart > alloc_pause: if not hit: ! statusfunc(activity = 'allocating') hit = true statusfunc(fractionDone = float(so_far + i - l)/total) so_far += length - l + statusfunc(fractionDone = 1.0) def set_readonly(self): *************** *** 92,98 **** def read(self, pos, amount): - if self.isopen == false: - return - r = StringIO() for file, pos, end in self._intervals(pos, amount): --- 92,95 ---- *************** *** 104,112 **** def write(self, pos, s): # might raise an IOError - if self.isopen == false: - return - total = 0 for file, begin, end in self._intervals(pos, len(s)): h = self.handles[file] h.seek(begin) --- 101,109 ---- def write(self, pos, s): # might raise an IOError total = 0 for file, begin, end in self._intervals(pos, len(s)): + if not self.whandles.has_key(file): + self.handles[file] = open(file, 'rb+') + self.whandles[file] = 1 h = self.handles[file] h.seek(begin) *************** *** 114,121 **** total += end - begin ! def close(self): ! for file in self.handles: ! self.handles[file].close() ! self.isopen = false # everything below is for testing --- 111,120 ---- total += end - begin ! def lrange(a, b, c): ! r = [] ! while a < b: ! r.append(a) ! a += c ! return r # everything below is for testing Index: StorageWrapper.py =================================================================== RCS file: /cvsroot/btplusplus/BT++/src/core/StorageWrapper.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** StorageWrapper.py 19 Feb 2003 20:40:33 -0000 1.1 --- StorageWrapper.py 28 Mar 2003 12:44:28 -0000 1.2 *************** *** 10,18 **** pass class StorageWrapper: ! def __init__( self, storage, request_size, hashes, ! piece_length, finished, failed, ! statusfunc = dummy_status, flag = Event(), ! check_hashes = true): self.check_hashes = check_hashes self.storage = storage --- 10,21 ---- pass + def dummy_data_flunked(size): + pass + class StorageWrapper: ! def __init__(self, storage, request_size, hashes, ! piece_length, finished, failed, ! statusfunc = dummy_status, flag = Event(), check_hashes = true, ! data_flunked = dummy_data_flunked): self.check_hashes = check_hashes self.storage = storage *************** *** 20,23 **** --- 23,27 ---- self.hashes = hashes self.piece_length = piece_length + self.data_flunked = data_flunked self.total_length = storage.get_total_length() self.amount_left = self.total_length *************** *** 35,40 **** finished() return if storage.was_preexisting(): ! statusfunc(activity = 'Hashing', fractionDone = 0.0) for i in xrange(len(hashes)): self._check_single(i) --- 39,46 ---- finished() return + self.done_checking = false if storage.was_preexisting(): ! statusfunc(activity = 'Hashing', ! fractionDone = 0) for i in xrange(len(hashes)): self._check_single(i) *************** *** 45,48 **** --- 51,55 ---- for i in xrange(len(hashes)): self._check_single(i, false) + self.done_checking = true def get_amount_left(self): *************** *** 58,75 **** high = self.total_length length = high - low ! if check and (not self.check_hashes or sha(self.storage.read(low, length)).digest() == self.hashes[index]): ! self.have[index] = true ! self.amount_left -= length ! if self.amount_left == 0: ! self.finished() ! else: ! l = self.inactive_requests[index] ! x = 0 ! while x + self.request_size < length: ! l.append((x, self.request_size)) ! self.total_inactive += 1 ! x += self.request_size ! l.append((x, length - x)) self.total_inactive += 1 def is_everything_pending(self): --- 65,86 ---- high = self.total_length length = high - low ! if check: ! if not self.check_hashes or sha(self.storage.read(low, length)).digest() == self.hashes[index]: ! self.have[index] = true ! self.amount_left -= length ! if self.amount_left == 0: ! self.finished() ! return ! else: ! if self.done_checking: ! self.data_flunked(length) ! l = self.inactive_requests[index] ! x = 0 ! while x + self.request_size < length: ! l.append((x, self.request_size)) self.total_inactive += 1 + x += self.request_size + l.append((x, length - x)) + self.total_inactive += 1 def is_everything_pending(self): Index: Uploader.py =================================================================== RCS file: /cvsroot/btplusplus/BT++/src/core/Uploader.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** Uploader.py 19 Feb 2003 20:40:25 -0000 1.1 --- Uploader.py 28 Mar 2003 12:44:28 -0000 1.2 *************** *** 19,32 **** self.buffer = [] self.measure = Measure(max_rate_period, fudge) - self.hit = true if storage.do_I_have_anything(): connection.send_bitfield(storage.get_have_list()) - def set_not_hit(self): - self.hit = false - - def get_hit(self): - return self.hit - def got_not_interested(self): if self.interested: --- 19,25 ---- *************** *** 70,74 **** del self.buffer[:] self.connection.send_choke() - self.hit = true def unchoke(self): --- 63,66 ---- *************** *** 76,80 **** self.choked = false self.connection.send_unchoke() - self.hit = true def is_choked(self): --- 68,71 ---- Index: __init__.py =================================================================== RCS file: /cvsroot/btplusplus/BT++/src/core/__init__.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** __init__.py 19 Feb 2003 20:40:37 -0000 1.1 --- __init__.py 28 Mar 2003 12:44:28 -0000 1.2 *************** *** 1 **** ! version = '3.1' --- 1 ---- ! version = '3.2' Index: btformats.py =================================================================== RCS file: /cvsroot/btplusplus/BT++/src/core/btformats.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** btformats.py 19 Feb 2003 20:40:37 -0000 1.1 --- btformats.py 28 Mar 2003 12:44:28 -0000 1.2 *************** *** 80,85 **** if type(id) != StringType or len(id) != 20: raise ValueError ! interval = message.get('interval') if type(interval) not in ints or interval <= 0: raise ValueError ! --- 80,98 ---- if type(id) != StringType or len(id) != 20: raise ValueError ! interval = message.get('interval', 1) if type(interval) not in ints or interval <= 0: raise ValueError ! minint = message.get('min interval', 1) ! if type(minint) not in ints or minint <= 0: ! raise ValueError ! if type(message.get('tracker id', '')) != StringType: ! raise ValueError ! npeers = message.get('num peers', 0) ! if type(npeers) not in ints or npeers < 0: ! raise ValueError ! dpeers = message.get('done peers', 0) ! if type(dpeers) not in ints or dpeers < 0: ! raise ValueError ! last = message.get('last', 0) ! if type(last) not in ints or last < 0: ! raise ValueError Index: download.py =================================================================== RCS file: /cvsroot/btplusplus/BT++/src/core/download.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** download.py 19 Feb 2003 20:40:37 -0000 1.1 --- download.py 28 Mar 2003 12:44:28 -0000 1.2 *************** *** 2,6 **** # see LICENSE-BitTorrent.txt for license information ! from urllib import urlopen from urlparse import urljoin from btformats import check_message --- 2,6 ---- # see LICENSE-BitTorrent.txt for license information ! from zurllib import urlopen from urlparse import urljoin from btformats import check_message *************** *** 45,49 **** "ip to report you have to the tracker."), ('minport', None, 6881, 'minimum port to listen on, counts up if unavailable'), ! ('maxport', None, 7881, 'maximum port to listen on'), ('responsefile', None, '', 'file the server response was stored in, alternative to url'), --- 45,49 ---- "ip to report you have to the tracker."), ('minport', None, 6881, 'minimum port to listen on, counts up if unavailable'), ! ('maxport', None, 6999, 'maximum port to listen on'), ('responsefile', None, '', 'file the server response was stored in, alternative to url'), *************** *** 78,85 **** ('max_upload_rate', None, 0, 'maximum kB/s to upload at, 0 means no limit'), ! ('alloc_pause', None, 0.0, 'seconds to wait before displaying allocation feedback'), ('snub_time', None, 60.0, "seconds to wait for data to come in over a connection before assuming it's semi-permanently choked"), ] --- 78,87 ---- ('max_upload_rate', None, 0, 'maximum kB/s to upload at, 0 means no limit'), ! ('alloc_pause', None, 3.0, 'seconds to wait before displaying allocation feedback'), ('snub_time', None, 60.0, "seconds to wait for data to come in over a connection before assuming it's semi-permanently choked"), + ('spew', None, 0, + "whether to display diagnostic info to stdout"), ] *************** *** 88,92 **** errorfunc('arguments are -\n' + formatDefinitions(defaults, cols)) return - try: config, garbage = parseargs(params, defaults, 0, 0) --- 90,93 ---- *************** *** 96,100 **** errorfunc('error: ' + str(e) + '\nrun with no args for parameter explanations') return ! try: if config['responsefile'] != '': --- 97,101 ---- errorfunc('error: ' + str(e) + '\nrun with no args for parameter explanations') return ! try: if config['responsefile'] != '': *************** *** 167,171 **** finflag = Event() ann = [None] ! myid = sha(repr(time()) + ' ' + str(getpid())).digest() seed(myid) pieces = [info['pieces'][x:x+20] for x in xrange(0, --- 168,172 ---- finflag = Event() ann = [None] ! myid = (chr(0) * 12) + sha(repr(time()) + ' ' + str(getpid())).digest()[-8:] seed(myid) pieces = [info['pieces'][x:x+20] for x in xrange(0, *************** *** 175,179 **** if reason is not None: errorfunc(reason) - try: try: --- 176,179 ---- *************** *** 193,205 **** ann[0](1) finfunc() storagewrapper = StorageWrapper(storage, config['download_slice_size'], pieces, info['piece length'], finished, failed, ! statusfunc, doneflag, config['check_hashes']) except ValueError, e: failed('bad data - ' + str(e)) except IOError, e: failed('IOError - ' + str(e)) - if doneflag.isSet(): return --- 193,209 ---- ann[0](1) finfunc() + rm = [None] + def data_flunked(amount, rm = rm, errorfunc = errorfunc): + if rm[0] is not None: + rm[0](amount) + errorfunc('a piece failed hash check, re-downloading it') storagewrapper = StorageWrapper(storage, config['download_slice_size'], pieces, info['piece length'], finished, failed, ! statusfunc, doneflag, config['check_hashes'], data_flunked) except ValueError, e: failed('bad data - ' + str(e)) except IOError, e: failed('IOError - ' + str(e)) if doneflag.isSet(): return *************** *** 217,221 **** return ! choker = Choker(config['max_uploads'], rawserver.add_task) upmeasure = Measure(config['max_rate_period'], config['upload_rate_fudge']) --- 221,225 ---- return ! choker = Choker(config['max_uploads'], rawserver.add_task, finflag.isSet) upmeasure = Measure(config['max_rate_period'], config['upload_rate_fudge']) *************** *** 229,232 **** --- 233,237 ---- max_slice_length, max_rate_period, fudge) ratemeasure = RateMeasure(storagewrapper.get_amount_left()) + rm[0] = ratemeasure.data_rejected downloader = Downloader(storagewrapper, PiecePicker(len(pieces)), config['request_backlog'], config['max_rate_period'], *************** *** 245,255 **** rawserver.external_add_task, storagewrapper.get_amount_left, upmeasure.get_total, downmeasure.get_total, listen_port, ! config['ip'], myid, infohash, config['http_timeout'], errorfunc) DownloaderFeedback(choker, rawserver.add_task, statusfunc, upmeasure.get_rate, downmeasure.get_rate, ratemeasure.get_time_left, ratemeasure.get_size_left, file_length, finflag, ! config['display_interval']) ! statusfunc(activity = 'Downloading') ann[0] = rerequest.announce rerequest.d(0) --- 250,261 ---- rawserver.external_add_task, storagewrapper.get_amount_left, upmeasure.get_total, downmeasure.get_total, listen_port, ! config['ip'], myid, infohash, config['http_timeout'], errorfunc, ! config['max_initiate'], doneflag) DownloaderFeedback(choker, rawserver.add_task, statusfunc, upmeasure.get_rate, downmeasure.get_rate, ratemeasure.get_time_left, ratemeasure.get_size_left, file_length, finflag, ! config['display_interval'], config['spew']) ! statusfunc(activity = 'connecting to peers') ann[0] = rerequest.announce rerequest.d(0) Index: testtest.py =================================================================== RCS file: /cvsroot/btplusplus/BT++/src/core/testtest.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** testtest.py 19 Feb 2003 20:40:32 -0000 1.1 --- testtest.py 28 Mar 2003 12:44:28 -0000 1.2 *************** *** 10,14 **** # Written by Bram Cohen ! # see LICENSE.txt for license information import traceback --- 10,14 ---- # Written by Bram Cohen ! # see LICENSE-BitTorrent.txt for license information import traceback Index: track.py =================================================================== RCS file: /cvsroot/btplusplus/BT++/src/core/track.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** track.py 19 Feb 2003 20:40:27 -0000 1.1 --- track.py 28 Mar 2003 12:44:28 -0000 1.2 *************** *** 8,12 **** from threading import Event from bencode import bencode, bdecode ! from urllib import urlopen, quote, unquote from urlparse import urlparse from os.path import exists --- 8,12 ---- from threading import Event from bencode import bencode, bdecode ! from zurllib import urlopen, quote, unquote from urlparse import urlparse from os.path import exists *************** *** 33,37 **** ('timeout_check_interval', None, 5, 'time to wait between checking if any connections have timed out'), ! ('nat_check', None, 0, 'whether to check back and ban downloaders behind NAT'), ('min_time_between_log_flushes', None, 3.0, --- 33,37 ---- ('timeout_check_interval', None, 5, 'time to wait between checking if any connections have timed out'), ! ('nat_check', None, 1, 'whether to check back and ban downloaders behind NAT'), ('min_time_between_log_flushes', None, 3.0, *************** *** 68,72 **** if f[-8:] == '.torrent': try: ! d = bdecode(open(os.path.join(dir,f)).read()) h = sha(bencode(d['info'])).digest() a[h] = d['info'].get('name', f) --- 68,72 ---- if f[-8:] == '.torrent': try: ! d = bdecode(open(os.path.join(dir,f), 'rb').read()) h = sha(bencode(d['info'])).digest() a[h] = d['info'].get('name', f) *************** *** 191,195 **** if self.allowed != None: if not self.allowed.has_key(infohash): ! return (400, 'Not Authorized', {'Content-Type': 'text/plain'}, bencode({'failure reason': 'Requested download is not authorized for use with this tracker.'})) ip = connection.get_ip() --- 191,195 ---- if self.allowed != None: if not self.allowed.has_key(infohash): ! return (400, 'Not Authorized', {'Content-Type': 'text/plain', 'Pragma': 'no-cache'}, bencode({'failure reason': 'Requested download is not authorized for use with this tracker.'})) ip = connection.get_ip() *************** *** 205,246 **** if len(myid) != 20: raise ValueError, 'id not of length 20' except ValueError, e: return (400, 'Bad Request', {'Content-Type': 'text/plain'}, 'you sent me garbage - ' + str(e)) ! def respond(result, self = self, infohash = infohash, myid = myid, ! ip = ip, port = port, left = left, params = params, ! connection = connection): ! if not result: ! connection.answer((200, 'OK', {'Content-Type': 'text/plain', 'Pragma': 'no-cache'}, bencode({'failure reason': ! 'You are behind NAT. Please open port 6881 or download from elsewhere'}))) ! return ! peers = self.downloads.setdefault(infohash, {}) ! ts = self.times.setdefault(infohash, {}) ! if params.get('event', '') != 'stopped': ! ts[myid] = time() ! if not peers.has_key(myid): ! peers[myid] = {'ip': ip, 'port': port, 'left': left} ! else: ! peers[myid]['left'] = left else: ! if peers.has_key(myid) and peers[myid]['ip'] == ip: ! del peers[myid] ! del ts[myid] ! data = {'interval': self.reannounce_interval} ! cache = self.cached.setdefault(infohash, []) ! if len(cache) < self.response_size: ! for key, value in self.downloads.setdefault( ! infohash, {}).items(): cache.append({'peer id': key, 'ip': value['ip'], 'port': value['port']}) ! shuffle(cache) ! data['peers'] = cache[-self.response_size:] ! del cache[-self.response_size:] ! connection.answer((200, 'OK', {'Content-Type': 'text/plain', 'Pragma': 'no-cache'}, bencode(data))) ! if (not self.natcheck or params.get('event') == 'stopped' or ! self.downloads.get(infohash, {}).has_key(myid)): ! respond(true) ! else: ! NatCheck(respond, infohash, myid, ip, port, self.rawserver) def save_dfile(self): --- 205,246 ---- if len(myid) != 20: raise ValueError, 'id not of length 20' + rsize = self.response_size + if params.has_key('num want'): + rsize = int(params['num want']) except ValueError, e: return (400, 'Bad Request', {'Content-Type': 'text/plain'}, 'you sent me garbage - ' + str(e)) ! peers = self.downloads.setdefault(infohash, {}) ! ts = self.times.setdefault(infohash, {}) ! if params.get('event', '') != 'stopped': ! ts[myid] = time() ! if not peers.has_key(myid): ! peers[myid] = {'ip': ip, 'port': port, 'left': left} else: ! peers[myid]['left'] = left ! else: ! if peers.has_key(myid) and peers[myid]['ip'] == ip: ! del peers[myid] ! del ts[myid] ! data = {'interval': self.reannounce_interval} ! cache = self.cached.setdefault(infohash, []) ! if len(cache) < rsize: ! for key, value in self.downloads.setdefault( ! infohash, {}).items(): ! if not value.get('nat'): cache.append({'peer id': key, 'ip': value['ip'], 'port': value['port']}) ! shuffle(cache) ! data['peers'] = cache[-rsize:] ! del cache[-rsize:] ! connection.answer((200, 'OK', {'Content-Type': 'text/plain', 'Pragma': 'no-cache'}, bencode(data))) ! if self.natcheck: ! NatCheck(self.connectback_result, infohash, myid, ip, port, self.rawserver) ! ! def connectback_result(self, result, downloadid, peerid, ip, port): ! if not result: ! record = self.downloads.get(downloadid, {}).get(peerid) ! if record and record['ip'] == ip and record['port'] == port: ! record['nat'] = 1 def save_dfile(self): |
From: <sir...@us...> - 2003-03-28 12:44:31
|
Update of /cvsroot/btplusplus/BT++/src/DlgMain In directory sc8-pr-cvs1:/tmp/cvs-serv23881/src/DlgMain Modified Files: StatusBar.py Log Message: - Updated to wxPython 2.4.0.7 (no source changes). - Updated to BT 3.2 (some Loader changes + core). - Moved some stuff. Index: StatusBar.py =================================================================== RCS file: /cvsroot/btplusplus/BT++/src/DlgMain/StatusBar.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** StatusBar.py 19 Feb 2003 20:37:07 -0000 1.1 --- StatusBar.py 28 Mar 2003 12:44:27 -0000 1.2 *************** *** 7,11 **** self.Parent = parent self.SetFieldsCount(2) ! self.SetStatusWidths( [-1,130] ) self.Thread = TimedUpdate(0.5, self.Update) --- 7,11 ---- self.Parent = parent self.SetFieldsCount(2) ! self.SetStatusWidths( [-1,160] ) self.Thread = TimedUpdate(0.5, self.Update) |
From: <sir...@us...> - 2003-03-28 12:44:31
|
Update of /cvsroot/btplusplus/BT++/src/TabHistory In directory sc8-pr-cvs1:/tmp/cvs-serv23881/src/TabHistory Modified Files: Grid.py Removed Files: HistLoaderManager.py Log Message: - Updated to wxPython 2.4.0.7 (no source changes). - Updated to BT 3.2 (some Loader changes + core). - Moved some stuff. Index: Grid.py =================================================================== RCS file: /cvsroot/btplusplus/BT++/src/TabHistory/Grid.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** Grid.py 9 Mar 2003 12:10:02 -0000 1.1 --- Grid.py 28 Mar 2003 12:44:27 -0000 1.2 *************** *** 10,14 **** import TabTrans.GridTable ! from HistLoaderManager import ManagerUp class HistGrid(TabTrans.Grid.Grid): --- 10,14 ---- import TabTrans.GridTable ! from Managers import ManagerUp class HistGrid(TabTrans.Grid.Grid): --- HistLoaderManager.py DELETED --- |
From: <sir...@us...> - 2003-03-28 12:44:31
|
Update of /cvsroot/btplusplus/BT++/src/TabTrans In directory sc8-pr-cvs1:/tmp/cvs-serv23881/src/TabTrans Modified Files: GridTable.py Log Message: - Updated to wxPython 2.4.0.7 (no source changes). - Updated to BT 3.2 (some Loader changes + core). - Moved some stuff. Index: GridTable.py =================================================================== RCS file: /cvsroot/btplusplus/BT++/src/TabTrans/GridTable.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** GridTable.py 9 Mar 2003 12:10:02 -0000 1.7 --- GridTable.py 28 Mar 2003 12:44:27 -0000 1.8 *************** *** 7,11 **** import Renderer ! from TabHistory.HistLoaderManager import ManagerUp class GridTable: --- 7,11 ---- import Renderer ! from Managers import ManagerDown class GridTable: *************** *** 30,41 **** def __init__(self, grid): self.Grid = grid ! self.Manager = LoaderManager( [ Config.Get('Paths', 'Torrent'), ! Config.Get('Paths', 'Temp'), ! Config.Get('Paths', 'Incoming'), ! Config.Get('Paths', 'History') ], ! self.Refresh, ! Log, ! self.MoveToHistory ) def Update(self): self.Manager.Update() --- 30,39 ---- def __init__(self, grid): self.Grid = grid ! self.Manager = ManagerDown + self.Manager.Refresh = self.Refresh + self.Manager.Log = Log + self.Manager.Finish = self.MoveToHistory + def Update(self): self.Manager.Update() |
From: <sir...@us...> - 2003-03-28 12:44:31
|
Update of /cvsroot/btplusplus/BT++/src In directory sc8-pr-cvs1:/tmp/cvs-serv23881/src Modified Files: BT++.py ConfigFile.py Loader.py Added Files: Managers.py Log Message: - Updated to wxPython 2.4.0.7 (no source changes). - Updated to BT 3.2 (some Loader changes + core). - Moved some stuff. --- NEW FILE: Managers.py --- from LoaderManager import LoaderManager from SeedManager import SeedManager from ConfigFile import Config ManagerUp = SeedManager ( [ Config.Get('Paths', 'History'), Config.Get('Paths', 'Incoming'), '', '' ] ) ManagerDown = LoaderManager( [ Config.Get('Paths', 'Torrent'), Config.Get('Paths', 'Temp'), Config.Get('Paths', 'Incoming'), Config.Get('Paths', 'History') ] ) Index: BT++.py =================================================================== RCS file: /cvsroot/btplusplus/BT++/src/BT++.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** BT++.py 16 Mar 2003 01:17:57 -0000 1.3 --- BT++.py 28 Mar 2003 12:44:25 -0000 1.4 *************** *** 53,57 **** # Copy torrent file ! if len(argv) == 2: try: copyfile(argv[1], path.join(Config.Get('Paths', 'Torrent'), path.split(argv[1])[1])) --- 53,57 ---- # Copy torrent file ! if len(argv) > 1: try: copyfile(argv[1], path.join(Config.Get('Paths', 'Torrent'), path.split(argv[1])[1])) Index: ConfigFile.py =================================================================== RCS file: /cvsroot/btplusplus/BT++/src/ConfigFile.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** ConfigFile.py 9 Mar 2003 12:10:03 -0000 1.5 --- ConfigFile.py 28 Mar 2003 12:44:25 -0000 1.6 *************** *** 39,43 **** 'GridCol1': 80, 'GridCol2': 80, ! 'GridCol3': 70, 'GridCol4': 120, 'GridCol5': 70, --- 39,43 ---- 'GridCol1': 80, 'GridCol2': 80, ! 'GridCol3': 90, 'GridCol4': 120, 'GridCol5': 70, Index: Loader.py =================================================================== RCS file: /cvsroot/btplusplus/BT++/src/Loader.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** Loader.py 11 Mar 2003 01:07:07 -0000 1.3 --- Loader.py 28 Mar 2003 12:44:25 -0000 1.4 *************** *** 341,344 **** --- 341,350 ---- try: + rm = [None] + def data_flunked(amount, rm = rm, errorfunc = None): + if rm[0] is not None: + rm[0](amount) + self.OnTrivialInfo('A piece failed hash check, re-downloading it.') + self.Obj['StorageWrapper'] = \ StorageWrapper( self.Obj['Storage'], *************** *** 350,354 **** self.UpdateStatus, self.FlagEnd, ! 1 ) # HASHING except: self.OnError('Trouble creating StorageWrapper.') --- 356,361 ---- self.UpdateStatus, self.FlagEnd, ! 1, # HASHING ! data_flunked ) except: self.OnError('Trouble creating StorageWrapper.') *************** *** 454,458 **** self.Config['InfoHash'], 40 ) # MAX INITIATE ! self.Obj['Rerequester'] = \ Rerequester( self.Config['Tracker'], --- 461,465 ---- self.Config['InfoHash'], 40 ) # MAX INITIATE ! self.Obj['Rerequester'] = \ Rerequester( self.Config['Tracker'], *************** *** 471,475 **** self.Config['InfoHash'], 60, # HTTP TIMEOUT, ! self.OnError ) self.Obj['DownloaderFeedback'] = \ --- 478,486 ---- self.Config['InfoHash'], 60, # HTTP TIMEOUT, ! self.OnError, ! 40, # MAX INITIATE ! self.FlagEnd ) ! ! self.Log('Here') self.Obj['DownloaderFeedback'] = \ *************** *** 483,487 **** self.Config['Size'], self.FlagEnd, ! 2.0 ) # DISPLAY INTERVAL self.UpdateStatus(activity = 'Downloading') --- 494,499 ---- self.Config['Size'], self.FlagEnd, ! 2.0, # DISPLAY INTERVAL ! 0 ) # STDOUT DISPLAY self.UpdateStatus(activity = 'Downloading') *************** *** 490,492 **** self.Obj['RawServer'].listen_forever( self.Obj['Encrypter'] ) self.Obj['Rerequester'].announce(2) - \ No newline at end of file --- 502,503 ---- |
From: <bel...@us...> - 2003-03-25 00:37:06
|
Update of /cvsroot/btplusplus/BT++/dist In directory sc8-pr-cvs1:/tmp/cvs-serv28655/dist Modified Files: LICENSE.rtf Added Files: CHANGELOG_WT.txt WT++.nsi Log Message: Release stuff for WT++ Updated License to include WT++ --- NEW FILE: CHANGELOG_WT.txt --- [0.5.1 (alpha)] - first public release --- NEW FILE: WT++.nsi --- !define MUI_PRODUCT "WebTorrent++" !define MUI_VERSION "0.5.1" !include "${NSISDIR}\Contrib\Modern UI\System.nsh" ;-------------------------------- ;Configuration ;Use bz2 compression SetCompressor bzip2 !define MUI_WELCOMEPAGE !define MUI_LICENSEPAGE !define MUI_COMPONENTSPAGE !define MUI_DIRECTORYPAGE !define MUI_FINISHPAGE !define MUI_UNINSTALLER ;Language !insertmacro MUI_LANGUAGE "English" ;General OutFile "WT++-${MUI_VERSION}-bin.exe" ;Text for License window LicenseData "LICENSE.rtf" ;Folder-selection page InstallDir "$PROGRAMFILES\${MUI_PRODUCT}" ;-------------------------------- ;Installer Sections Section "" SecCopyUI SetOutPath "$INSTDIR" File "..\build\WT++\_socket.pyd" File "..\build\WT++\_sre.pyd" File "..\build\WT++\_winreg.pyd" File "..\build\WT++\WT++.exe" File "..\build\WT++\python22.dll" File "..\build\WT++\select.pyd" File "README_WT.txt" File "CHANGELOG_WT.txt" File "LICENSE.rtf" SetOutPath "$INSTDIR\WebTemplates" File "..\src\WebTemplates\config.tmpl" File "..\src\WebTemplates\dl_fail.tmpl" File "..\src\WebTemplates\exit.tmpl" File "..\src\WebTemplates\log.tmpl" File "..\src\WebTemplates\menu.tmpl" File "..\src\WebTemplates\root.tmpl" File "..\src\WebTemplates\torrent.tmpl" SectionEnd Section "Uninstaller" Uninst WriteUninstaller "$INSTDIR\Uninstall.exe" WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\WebTorrent++" "DisplayName" "WebTorrent++ ${MUI_VERSION}" WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\WebTorrent++" "UninstallString" '"$INSTDIR\Uninstall.exe"' SectionEnd Section "Startmenu Shortcuts" Start CreateDirectory "$SMPROGRAMS\WebTorrent++" CreateShortCut "$SMPROGRAMS\WebTorrent++\WebTorrent++.lnk" "$INSTDIR\WT++.exe" CreateShortCut "$SMPROGRAMS\WebTorrent++\WebTorrent++ Readme.lnk" "$INSTDIR\README_WT.txt" CreateShortCut "$SMPROGRAMS\WebTorrent++\WebTorrent++ Changelog.lnk" "$INSTDIR\CHANGELOG_WT.txt" CreateShortCut "$SMPROGRAMS\WebTorrent++\License.lnk" "$INSTDIR\LICENSE.rtf" IfFileExists "$INSTDIR\Uninstall.exe" "" +2 CreateShortCut "$SMPROGRAMS\WebTorrent++\WebTorrent++ Uninstall.lnk" "$INSTDIR\Uninstall.exe" SectionEnd ;-------------------------------- ;Display the Finish header !insertmacro MUI_SECTIONS_FINISHHEADER ;-------------------------------- ;Descriptions !insertmacro MUI_FUNCTIONS_DESCRIPTION_BEGIN !insertmacro MUI_DESCRIPTION_TEXT ${Uninst} "Create a uninstaller." !insertmacro MUI_DESCRIPTION_TEXT ${Start} "Create shortcuts in the startmenu." !insertmacro MUI_FUNCTIONS_DESCRIPTION_END ;-------------------------------- ;Unistaller actions Section "Uninstall" DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\WebTorrent++" RMDir /r "$SMPROGRAMS\WebTorrent++" Delete "$INSTDIR\_socket.pyd" Delete "$INSTDIR\_sre.pyd" Delete "$INSTDIR\_winreg.pyd" Delete "$INSTDIR\WT++.exe" Delete "$INSTDIR\python22.dll" Delete "$INSTDIR\select.pyd" Delete "$INSTDIR\WebTemplates\config.tmpl" Delete "$INSTDIR\WebTemplates\dl_fail.tmpl" Delete "$INSTDIR\WebTemplates\exit.tmpl" Delete "$INSTDIR\WebTemplates\log.tmpl" Delete "$INSTDIR\WebTemplates\menu.tmpl" Delete "$INSTDIR\WebTemplates\root.tmpl" Delete "$INSTDIR\WebTemplates\torrent.tmpl" Delete "$INSTDIR\README_WT.txt" Delete "$INSTDIR\CHANGELOG_WT.txt" Delete "$INSTDIR\LICENSE.rtf" Delete "$INSTDIR\Uninstall.exe" SectionEnd Index: LICENSE.rtf =================================================================== RCS file: /cvsroot/btplusplus/BT++/dist/LICENSE.rtf,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** LICENSE.rtf 6 Feb 2003 19:06:32 -0000 1.1 --- LICENSE.rtf 25 Mar 2003 00:37:01 -0000 1.2 *************** *** 1,400 **** ! {\rtf1\ansi\ansicpg1252\uc1\deff0\stshfdbch0\stshfloch0\stshfhich0\stshfbi0\deflang1031\deflangfe1031{\fonttbl{\f0\froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f1\fswiss\fcharset0\fprq2{\*\panose 020b0604020202020204}Arial;} ! {\f36\froman\fcharset238\fprq2 Times New Roman CE;}{\f37\froman\fcharset204\fprq2 Times New Roman Cyr;}{\f39\froman\fcharset161\fprq2 Times New Roman Greek;}{\f40\froman\fcharset162\fprq2 Times New Roman Tur;} ! {\f41\froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\f42\froman\fcharset178\fprq2 Times New Roman (Arabic);}{\f43\froman\fcharset186\fprq2 Times New Roman Baltic;}{\f44\froman\fcharset163\fprq2 Times New Roman (Vietnamese);} ! {\f46\fswiss\fcharset238\fprq2 Arial CE;}{\f47\fswiss\fcharset204\fprq2 Arial Cyr;}{\f49\fswiss\fcharset161\fprq2 Arial Greek;}{\f50\fswiss\fcharset162\fprq2 Arial Tur;}{\f51\fswiss\fcharset177\fprq2 Arial (Hebrew);} ! {\f52\fswiss\fcharset178\fprq2 Arial (Arabic);}{\f53\fswiss\fcharset186\fprq2 Arial Baltic;}{\f54\fswiss\fcharset163\fprq2 Arial (Vietnamese);}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0; ! \red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128; ! \red192\green192\blue192;}{\stylesheet{\ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \fs24\lang1031\langfe1031\cgrid\langnp1031\langfenp1031 \snext0 Normal;}{\*\cs10 \additive \ssemihidden Default Paragraph Font;}{\* ! \ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tscellwidthfts0\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv ! \ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \fs20\lang1024\langfe1024\cgrid\langnp1024\langfenp1024 \snext11 \ssemihidden Normal Table;}}{\*\listtable{\list\listtemplateid1781933688\listhybrid{\listlevel\levelnfc4\levelnfcn4 ! \leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\leveltext\leveltemplateid67567639\'02\'00);}{\levelnumbers\'01;}\fi-360\li1004\jclisttab\tx1004\lin1004 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0 ! \levelstartat1\levelspace360\levelindent0{\leveltext\leveltemplateid67567641\'02\'01.;}{\levelnumbers\'01;}\fi-360\li1724\jclisttab\tx1724\lin1724 }{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\levelspace360\levelindent0 ! {\leveltext\leveltemplateid67567643\'02\'02.;}{\levelnumbers\'01;}\fi-180\li2444\jclisttab\tx2444\lin2444 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\leveltext\leveltemplateid67567631 ! \'02\'03.;}{\levelnumbers\'01;}\fi-360\li3164\jclisttab\tx3164\lin3164 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\leveltext\leveltemplateid67567641\'02\'04.;}{\levelnumbers\'01;} ! \fi-360\li3884\jclisttab\tx3884\lin3884 }{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\levelspace360\levelindent0{\leveltext\leveltemplateid67567643\'02\'05.;}{\levelnumbers\'01;}\fi-180\li4604\jclisttab\tx4604\lin4604 } ! {\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\leveltext\leveltemplateid67567631\'02\'06.;}{\levelnumbers\'01;}\fi-360\li5324\jclisttab\tx5324\lin5324 }{\listlevel\levelnfc4\levelnfcn4\leveljc0 ! \leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\leveltext\leveltemplateid67567641\'02\'07.;}{\levelnumbers\'01;}\fi-360\li6044\jclisttab\tx6044\lin6044 }{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1 ! \levelspace360\levelindent0{\leveltext\leveltemplateid67567643\'02\'08.;}{\levelnumbers\'01;}\fi-180\li6764\jclisttab\tx6764\lin6764 }{\listname ;}\listid435056598}{\list\listtemplateid-1240303896\listhybrid{\listlevel\levelnfc4\levelnfcn4\leveljc0 ! \leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\leveltext\leveltemplateid67567639\'02\'00);}{\levelnumbers\'01;}\fi-360\li720\jclisttab\tx720\lin720 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1 ! \levelspace360\levelindent0{\leveltext\leveltemplateid67567641\'02\'01.;}{\levelnumbers\'01;}\fi-360\li1440\jclisttab\tx1440\lin1440 }{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\levelspace360\levelindent0{\leveltext ! \leveltemplateid67567643\'02\'02.;}{\levelnumbers\'01;}\fi-180\li2160\jclisttab\tx2160\lin2160 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\leveltext\leveltemplateid67567631 ! \'02\'03.;}{\levelnumbers\'01;}\fi-360\li2880\jclisttab\tx2880\lin2880 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\leveltext\leveltemplateid67567641\'02\'04.;}{\levelnumbers\'01;} ! \fi-360\li3600\jclisttab\tx3600\lin3600 }{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\levelspace360\levelindent0{\leveltext\leveltemplateid67567643\'02\'05.;}{\levelnumbers\'01;}\fi-180\li4320\jclisttab\tx4320\lin4320 } ! {\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\leveltext\leveltemplateid67567631\'02\'06.;}{\levelnumbers\'01;}\fi-360\li5040\jclisttab\tx5040\lin5040 }{\listlevel\levelnfc4\levelnfcn4\leveljc0 ! \leveljcn0\levelfollow0\levelstartat1\levelspace360\levelindent0{\leveltext\leveltemplateid67567641\'02\'07.;}{\levelnumbers\'01;}\fi-360\li5760\jclisttab\tx5760\lin5760 }{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1 ! \levelspace360\levelindent0{\leveltext\leveltemplateid67567643\'02\'08.;}{\levelnumbers\'01;}\fi-180\li6480\jclisttab\tx6480\lin6480 }{\listname ;}\listid969094496}}{\*\listoverridetable{\listoverride\listid435056598\listoverridecount0\ls1} ! {\listoverride\listid969094496\listoverridecount0\ls2}}{\*\rsidtbl \rsid2299944\rsid3746437\rsid6106872\rsid6226993\rsid11213307\rsid11802965\rsid13308893\rsid15034262}{\*\generator Microsoft Word 10.0.2627;}{\info{\author SirElvis}{\operator SirElvis} ! {\creatim\yr2003\mo2\dy6\hr18\min33}{\revtim\yr2003\mo2\dy6\hr19\min6}{\version8}{\edmins0}{\nofpages6}{\nofwords2585}{\nofchars16286}{\nofcharsws18834}{\vern16437}}\margl1417\margr1417\margt1417\margb1134 ! \widowctrl\ftnbj\aenddoc\hyphhotz425\noxlattoyen\expshrtn\noultrlspc\dntblnsbdb\nospaceforul\hyphcaps0\horzdoc\dghspace120\dgvspace120\dghorigin1701\dgvorigin1984\dghshow0\dgvshow3\jcompress\viewkind1\viewscale100\nolnhtadjtbl\rsidroot15034262 \fet0 ! \sectd \linex0\sectdefaultcl\sftnbj {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl4 ! \pnlcltr\pnstart1\pnindent720\pnhang {\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (} ! {\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}\pard\plain \ql \li0\ri0\nowidctlpar\faauto\rin0\lin0\itap0 ! \fs24\lang1031\langfe1031\cgrid\langnp1031\langfenp1031 {\b\f1\fs26\ul\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid11802965 MIT License (for the original BitTorrent)}{\f1\fs26\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid11802965 ! ! \par }{\f1\fs32\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 ! \par }\pard \qj \li0\ri0\nowidctlpar\faauto\rin0\lin0\itap0\pararsid15034262 {\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 ! Unless otherwise noted, all files are released under the MIT license, exceptions contain licensing information in them. \par \par Copyright (C) 2001-2002 Bram Cohen \par ! \par Permission is hereby granted, free of charge, to any person}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 ! obtaining a copy of this software and associated documentation files}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 ! (the "Software"), to deal in the Software without restriction,}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 ! including without limitation the rights to use, copy, modify, merge,}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 publ ! ish, distribute, sublicense, and/or sell copies of the Software,}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 ! and to permit persons to whom the Software is furnished to do so,}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 subject to the following conditions: \par ! \par The above copyright notice and this permission notice shall be}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 included in all copies o ! r substantial portions of the Software. \par ! \par The Software is provided "AS IS", without warranty of any kind,}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 ! express or implied, including but not limited to the warranties of}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262 merchantability, }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 fitness for a particular purpose and}{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 noninfringement. In no event shall the}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid3746437 }{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 authors or copyright holders}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 ! be liable for any claim, damages or other liability, whether in an}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 ! action of contract, tort or otherwise, arising from, out of or in}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 ! connection with the Software or the use or other dealings in the}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 Software. ! \par }\pard \ql \li0\ri0\nowidctlpar\faauto\rin0\lin0\itap0 {\f1\fs32\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 ! \par }{\b\f1\fs26\ul\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid11802965 GPL (for BitTorrent++) ! \par }{\f1\fs32\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 ! \par }\pard \qc \li0\ri0\nowidctlpar\faauto\rin0\lin0\itap0\pararsid15034262 {\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 GNU GENERAL PUBLIC LICENSE \par Version 2, June 1991 ! \par }\pard \ql \li0\ri0\nowidctlpar\faauto\rin0\lin0\itap0 {\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 ! \par }\pard \qc \li0\ri0\nowidctlpar\faauto\rin0\lin0\itap0\pararsid15034262 {\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 Copyright (C) 1989, 1991 Free Software Foundation, Inc. ! \par 59 Temple Place, Suite 330, Boston, ! \par }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid3746437 MA }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 02111-1307 USA ! \par }\pard \ql \li0\ri0\nowidctlpar\faauto\rin0\lin0\itap0 {\f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262 ! \par }\pard \qj \li0\ri0\nowidctlpar\faauto\rin0\lin0\itap0\pararsid15034262 {\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 Everyone is permitted to copy and distribute verbatim copies of this license docu ! ment, but changing it is not allowed. \par ! \par }\pard \qc \li0\ri0\nowidctlpar\faauto\rin0\lin0\itap0\pararsid15034262 {\b\f1\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 Preamble ! \par }\pard \qj \li0\ri0\nowidctlpar\faauto\rin0\lin0\itap0\pararsid15034262 {\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 ! \par The licenses for most software are designed to take away your}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 ! freedom to share and change it. By contrast, the GNU General Public}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 ! License is intended to guarantee your freedom to share and change free}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 ! software--to make sure the software is free for all its users. This}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 ! General Public License applies to most of the Free Software}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 ! Foundation's software and to any other program whose authors commit to}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 ! using it. (Some other Free Software Foundation software is covered by}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 ! the GNU Library General Public License instead.) You can apply it to}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 your programs, too. \par ! \par When we speak of free software, we are referring to freedom, not}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 ! price. Our General Public Licenses are designed to make sure that you}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 ! have the freedom to distribute copies of free software (and charge for}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 ! this service if you wish), that you receive source code or can get it}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 ! if you want it, that you can change the software or use pieces of it}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 in new free programs; and that you know you ca ! n do these things. \par ! \par To protect your rights, we need to make restrictions that forbid}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 ! anyone to deny you these rights or to ask you to surrender the rights.}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 ! These restrictions translate to certain responsibilities for you if you}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 distribute copies of the sof tware, or if you modify it. - \par }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid6106872 - \par }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 For example, if you distribute copies of such a program, whether}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262 }{ - \f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 gratis or for a fee, you must give the recipients all the rights that}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262 }{ - \f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 you have. You must make sure that they, too, receive or can get the}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262 }{ - \f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 source}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 code. And you mus - t show them these terms so they know their}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 rights. \par ! \par We protect your rights with two steps: (1) copyright the software, and}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 ! (2) offer you this license which gives you legal permission to copy,}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 distribute and/or modify the software. \par ! \par Also, for each author's protection and ours, we want to make certain}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 ! that everyone understands that there is no warranty for this free}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 ! software. If the software is modified by someone else and passed on, we}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 ! want its recipients to know that what they have is not the original, so}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 t ! hat any problems introduced by others will not reflect on the original}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 authors' reputations. \par ! \par Finally, any free program is threatened constantly by software}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 ! patents. We wish to avoid the danger that redistributors of a free}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 program will individually obtain ! patent licenses, in effect making the}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 program proprietary. To prevent this, we have made it clear that any}{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 patent must be licensed for everyone's free use or not licensed at all. \par ! \par The precise terms and conditions for copying, distribution and}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 modification follow. \par \par ! \par }\pard \qc \li0\ri0\nowidctlpar\faauto\rin0\lin0\itap0\pararsid15034262 {\b\f1\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 GNU GENERAL PUBLIC LICENSE \par TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION ! \par }\pard \qj \li0\ri0\nowidctlpar\faauto\rin0\lin0\itap0\pararsid15034262 {\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 ! \par }{\b\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid6226993 0}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid6226993 . This License applies to any program or other work which contains}{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262\charrsid6226993 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid6226993 a notice placed by the copyright holder saying it may be distributed}{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262\charrsid6226993 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid6226993 under the terms of this General Public License. The "Program", below,}{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262\charrsid6226993 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid6226993 refers to any such program or work, and a "work based on the Program"}{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262\charrsid6226993 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid6226993 means either the Program or any derivative work under copyright law:}{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262\charrsid6226993 T}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid6226993 hat is to say, a work containing the Program or a portion of it,}{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262\charrsid6226993 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid6226993 either verbatim or with modifications and/or translated into another}{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262\charrsid6226993 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid6226993 language. (Hereinafter, translation is included without limitation in}{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262\charrsid6226993 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid6226993 the term "modification")}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262\charrsid6226993 . }{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid6226993 Each licensee is addressed as "you". \par ! \par Activities other than copying, distribution and modification are not}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262\charrsid6226993 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid6226993 covered by this Licens}{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid3746437 e; they are outside its scope. }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid6226993 The act of}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262\charrsid6226993 }{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid6226993 running the Program is not restricted, and the output from the Program}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262\charrsid6226993 }{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid6226993 is covered only if its contents constitute a work based on the}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262\charrsid6226993 }{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid6226993 Program (independent of having been made by running the Program).}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262\charrsid6226993 }{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid6226993 Whether that is true depends on what the Program does. \par ! \par }{\b\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid6226993 1}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid6226993 . You may copy and distribute verbatim copies of the Program's}{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262\charrsid6226993 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid6226993 source code as you receive it, in any medium, provided that you}{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262\charrsid6226993 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid6226993 conspicuously and appropriately publish on each copy an appropriate}{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262\charrsid6226993 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid6226993 copyright notice and disclaimer of warranty; keep intact all the}{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262\charrsid6226993 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid6226993 notices that refer to this License and to the absence of any warranty;}{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262\charrsid6226993 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid6226993 and give any other recipients of the Program a copy of this License}{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262\charrsid6226993 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid6226993 along with the Program. \par ! \par You may charge a fee for the physical act of transferring a copy, and}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid15034262\charrsid6226993 you may at your option offer }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid6226993 ! warranty protection in exchange for a fee. ! \par }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 ! \par }{\b\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid6226993 2}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 . You may modify your copy or copies of the Program or any portion}{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid6226993 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 of it, thus forming a work based on the Program, and copy and}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid6226993 }{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 distribute such modifications or work under the terms of Section 1}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid6226993 }{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 above, provided that you also meet all of these conditions: \par ! \par {\listtext\pard\plain\f1\fs20\lang2057\langfe1031\langnp2057\insrsid6226993\charrsid15034262 \hich\af1\dbch\af0\loch\f1 a)\tab}}\pard \qj \fi-360\li709\ri0\nowidctlpar\jclisttab\tx709\faauto\ls1\rin0\lin709\itap0\pararsid6226993 { ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid6226993\charrsid15034262 You must cause the modified files to carry prominent notices}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid6226993 }{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid6226993\charrsid15034262 stating that you changed the files and the date of any change.}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid6226993 ! \par }\pard \qj \li349\ri0\nowidctlpar\faauto\rin0\lin349\itap0\pararsid6226993 {\f1\fs20\lang2057\langfe1031\langnp2057\insrsid6226993 ! \par {\listtext\pard\plain\f1\fs20\lang2057\langfe1031\langnp2057\insrsid6226993 \hich\af1\dbch\af0\loch\f1 b)\tab}}\pard \qj \fi-360\li709\ri0\nowidctlpar\jclisttab\tx709\faauto\ls1\rin0\lin709\itap0\pararsid6106872 { ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid6226993 Y}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid6226993\charrsid15034262 ou must cause any work that you distribute or publish, that in}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid6226993 }{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid6226993\charrsid15034262 whole or in p}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid6226993 art contains or is derived from }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid6226993\charrsid15034262 ! the Program or any}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid6226993 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid6226993\charrsid15034262 part thereof, to be licensed as a whole at no charge to all third}{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid6226993 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid6226993\charrsid15034262 parties under the terms of this License.}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid6106872 ! \par }\pard \qj \li0\ri0\nowidctlpar\faauto\rin0\lin0\itap0\pararsid6106872 {\f1\fs20\lang2057\langfe1031\langnp2057\insrsid6106872 ! \par {\listtext\pard\plain\f1\fs20\lang2057\langfe1031\langnp2057\insrsid6106872\charrsid15034262 \hich\af1\dbch\af0\loch\f1 c)\tab}}\pard \qj \fi-360\li709\ri0\nowidctlpar\jclisttab\tx709\faauto\ls1\rin0\lin709\itap0\pararsid6226993 { ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid6106872\charrsid15034262 If the modified program normally reads commands interactively}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid6106872 }{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid6106872\charrsid15034262 when run, you must cause it, when started running for such}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid6106872 }{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid6106872\charrsid15034262 interactive use in the most ordinary way, to print or display an}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid6106872 }{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid6106872\charrsid15034262 announcement including an appropriate copyright notice and a}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid6106872 }{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid6106872\charrsid15034262 notice that there is no warranty (or else, saying that you provide}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid6106872 }{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid6106872\charrsid15034262 a warranty) and that users may redistribute the program under}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid6106872 }{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid6106872\charrsid15034262 these conditions, and telling the user how to view a copy of this}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid6106872 }{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid6106872\charrsid15034262 License. (Exception: if the Program itself is interactive but}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid6106872 }{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid6106872\charrsid15034262 does not normally print such an announcement, your work based on}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid6106872 }{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid6106872\charrsid15034262 the Program is not required to print an announcement)}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid6106872 . ! \par }\pard \qj \li0\ri0\nowidctlpar\faauto\rin0\lin0\itap0\pararsid15034262 {\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 ! \par These requirements apply to the modified work as a whole. If}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid6106872 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 identifiable sections of that work ! are not derived from the Program,}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid6106872 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 and can be reasonably considered independent and separate works in}{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid6106872 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 themselves, then this License, and its terms, do not apply to those}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid6106872 ! }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 sections when you dist}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid3746437 ribute them as separate works. }{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 But when you}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid6106872 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 dist ! ribute the same sections as part of a whole which is a work based}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid6106872 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 ! on the Program, the distribution of the whole must be on the terms of}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid6106872 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 ! this License, whose permissions for other licensees extend to the}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid6106872 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 entire whole, and thus to each and every part regardle ! ss of who wrote it. \par ! \par Thus, it is not the intent of this section to claim rights or contest}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid6106872 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 ! your rights to work written entirely by you; rather, the intent is to}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid6106872 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 ! exercise the right to control the distribution of derivative or}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid6106872 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 collective works based on the Program. \par ! \par In addition, mere aggregation of another work not based on the Program}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid6106872 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 ! with the Program (or with a work based on the Program) on a volume of}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid6106872 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 ! a storage or distribution medium does not bring the other work under}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid6106872 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 the scope of this License. \par ! \par }{\b\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid6106872 3}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 . You may copy and distribute the Program (or a work based on it,}{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid6106872 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 under Section 2) in object code or executable form under the terms of}{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid6106872 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 Sections 1 and 2 above provided that you also do one of the following: ! \par }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965 ! \par {\listtext\pard\plain\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893\charrsid15034262 \hich\af1\dbch\af0\loch\f1 a)\tab}}\pard \qj \fi-360\li720\ri0\nowidctlpar\jclisttab\tx720\faauto\ls2\rin0\lin720\itap0\pararsid13308893 { ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893\charrsid15034262 Accompany it with the complete corresponding machine-readable}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893\charrsid15034262 source code, which must be distributed under the terms of Sections}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893\charrsid15034262 1 and 2 above on a medium customarily used for software interchange; or,}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid6106872 ! \par }\pard \qj \li360\ri0\nowidctlpar\faauto\rin0\lin360\itap0\pararsid13308893 {\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 ! \par {\listtext\pard\plain\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893\charrsid15034262 \hich\af1\dbch\af0\loch\f1 b)\tab}}\pard \qj \fi-360\li720\ri0\nowidctlpar\jclisttab\tx720\faauto\ls2\rin0\lin720\itap0\pararsid13308893 { ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893\charrsid15034262 Accompany it with a written offer, valid for at least three}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893\charrsid15034262 years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 ! }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893\charrsid15034262 machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium}{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893\charrsid15034262 customarily used for software interchange; or,}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 ! \par }\pard \qj \li0\ri0\nowidctlpar\faauto\rin0\lin0\itap0\pararsid13308893 {\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 ! \par {\listtext\pard\plain\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 \hich\af1\dbch\af0\loch\f1 c)\tab}}\pard \qj \fi-360\li720\ri0\nowidctlpar\jclisttab\tx720\faauto\ls2\rin0\lin720\itap0\pararsid13308893 { ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 A}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893\charrsid15034262 ccompany it with the information you received as to the offer to distrib}{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 ute corresponding source code. }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893\charrsid15034262 ! (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893\charrsid15034262 an offer, in accord with Subsection b above.) ! \par }\pard \qj \li0\ri0\nowidctlpar\faauto\rin0\lin0\itap0\pararsid15034262 {\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 ! \par }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 The source code for a work means the preferred form of the work for}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid3746437 making modifications to it. }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 For an executable work, complete source}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 ! }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 code means all the source code for all modules it contains, plus any}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 associated interface definition files, plus the scripts used to}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 control compilation and installation of the e}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid3746437 xecutable. }{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 However, as a}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 ! special exception, the source code distributed need not include}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 ! anything that is normally distributed (in either source or binary}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 ! form) with the major components (compiler, kernel, and so on) of the}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 ! operating system on which the executable runs, unless that component}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 itself accompanies the executable. \par ! \par If distribution of executable or object code is made by offering}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 ! access to copy from a designated place, then offering equivalent}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 ! access to copy the source code from the same place counts as}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 ! distribution of the source code, even though third parties are not}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 com ! pelled to copy the source along with the object code. \par ! \par }{\b\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid13308893 4}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 . You may not copy, modify, sublicense, or distribute the Program}{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 exc}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 ept as expressly provided under }{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 this License. Any attempt}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 ! otherwise to copy, modify, sublicense or distribute the Program is}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 void, ! and will automatically terminate your rights under this License.}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 ! However, parties who have received copies, or rights, from you under}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 ! this License will not have their licenses terminated so long as such \par parties remain in full compliance. \par ! \par }{\b\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid13308893 5}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 . You are not required to accept this License, since you have not}{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid3746437 signed it.}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 ! However, nothing else grants you permission to modify or}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 distribute the P}{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid3746437 rogram or its derivative works.}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 These actions are}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 prohibited by law if }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid3746437 you do not accept this License.}{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 Therefore, by}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 ! modifying or distributing the Program (or any work based on the}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 ! Program), you indicate your acceptance of this License to do so, and}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 all its terms and}{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 conditions for copying, distributing or modifying}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 the Program or works based on it. \par ! \par }{\b\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid13308893 6}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 . Each time you redistribute the Program (or any work based on the}{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 Program), the recipient automatically receives a license from the}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 ! }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 original licensor to copy, distribute or modify the Program subject to}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid3746437 these terms and conditions.}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 You may not impose any further}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 restrictions on the recipients' exercise of the rights granted herein.}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 You are not responsible for enforcing compliance by third parties to}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 this License. \par ! \par }{\b\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid13308893 7}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 . If, as a consequence of a court judgment or allegation of patent}{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 infringement or for any other reason (not limited to patent issues),}{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 conditions are imposed on you (whether by court order, agreement or}{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 otherwise) that contradict the conditions of this License, they do not}{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 excuse you from the conditions of this License. If you cannot}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 distribute so as to satisfy simultaneously your obligations under this}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 License and any other pertinent obligations, then as a consequence you}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 may not distribute the Program at all. For example, if a patent}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 license would not permit royalty-free redistribution of the Program by}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 all those who receive copies directly or indirectly through you, then}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 the only way you could satisfy both it and this License would be to}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 refrain entirely from distribution of the Program. \par ! \par If any portion of this section is held invalid or unenforceable under}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 any pa ! rticular circumstance, the balance of the section is intended to}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 ! apply and the section as a whole is intended to apply in other}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 circumstances. \par ! \par It is not the purpose of this section to induce you to infringe any}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 patents or other property right claims or to ! contest validity of any}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 such claims; this section has the sole purpose of protecting the}{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 integrity of the free software distribution system, which is}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 implemented by public license practices. Many people have made}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 generous contributions to the wide range of software distributed}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 through that system in reliance on consistent application of that}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 system; it is up to the author/donor to decide if he or she is willing}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 to distribute software through any other system and a licensee cannot}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 impose that choice. \par ! \par This section is intended to make thoroughly clear what is believed to}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 be a consequence of the rest of this License. \par ! \par }{\b\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid13308893 8}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 . If the distribution and/or use of the Program is restricted in}{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 certain co}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 untries either by patents or by }{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 copyrighted interfaces, the}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 ori ! ginal copyright holder who places the Program under this License}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 ! may add an explicit geographical distribution limitation excluding}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 ! those countries, so that distribution is permitted only in or among}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 ! countries not thus excluded. In such case, this License incorporates}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 ! the limitation as if written in the body of this License. \par ! \par }{\b\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid13308893 9}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 . The Free Software Foundation may publish revised and/or new versions}{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 of the General Public License }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 from time to time. Such new versions will}{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 be similar in spirit to the present version, but may differ in detail to}{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 address new problems or concerns. \par ! \par Each version is given a distinguishing version number. If the Program}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 ! specifies a version number of this License which applies to it and "any}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 later version", you have the option of followi ! ng the terms and conditions}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 either of that version or of any later version published by the Free}{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 Software Foundation. If the Program does not specify a version number of}{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 this License, you may choose any version ever published by the Free Software}{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 Foundation. \par ! \par }{\b\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid13308893 10}{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 . If you wish to incorporate parts of the Program into other free}{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 programs whose distribution conditions are different, write to the author}{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 to ask for permission. For software which is copyrighted by the Free}{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 Software Foundation, write to the Free Software Foundation; we sometimes}{ ! \f1\fs20\lang2057\langfe1031\langnp2057\insrsid13308893 }{\f1\fs20\lang2057\langfe1031\langnp2057\insrsid11802965\charrsid15034262 make exceptions for this. Our decision will be guided by th... [truncated message content] |
From: <bel...@us...> - 2003-03-25 00:27:06
|
Update of /cvsroot/btplusplus/BT++/src In directory sc8-pr-cvs1:/tmp/cvs-serv24607/src Modified Files: Build_WT.py Added Files: WT++.pyw Log Message: Made build work for windows. Use WT++.pyw for windows since readline doesn't work there. Fixed a bug(?) in htmltmpl on Windows. Fixed menu.tmpl for Opera7 --- NEW FILE: WT++.pyw --- #!/usr/bin/python from sys import argv, version, exit from os import path, chdir from shutil import copyfile from ConfigFile import Config from WebServer.BTWebServer import BTWebServer, BTWait, WTLoaders, WTSeeds from threading import * assert version >= '2', "Install Python 2.0 or greater" if __name__ == '__main__': # Change to the directory of BT++ chdir( path.abspath( path.dirname(argv[0]) ) ) # Copy torrent file if len(argv) == 2: try: copyfile(argv[1], path.join(Config.Get('Paths', 'Torrent'), path.split(argv[1])[1])) except: pass print ("Started") httpd = BTWebServer() httpdth = Thread(target = httpd.server) httpdth.setDaemon(1) httpdth.start() BTWait.wait() WTLoaders.ShutDown() WTSeeds.ShutDown() Index: Build_WT.py =================================================================== RCS file: /cvsroot/btplusplus/BT++/src/Build_WT.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** Build_WT.py 28 Feb 2003 21:25:33 -0000 1.1 --- Build_WT.py 25 Mar 2003 00:27:02 -0000 1.2 *************** *** 9,11 **** author_email='bel...@us...', url='http://www.sf.net/projects/bt++/', ! scripts=['WT++.py'] ) --- 9,11 ---- author_email='bel...@us...', url='http://www.sf.net/projects/bt++/', ! scripts=['WT++.pyw'] ) |
From: <bel...@us...> - 2003-03-25 00:27:06
|
Update of /cvsroot/btplusplus/BT++/src/WebServer In directory sc8-pr-cvs1:/tmp/cvs-serv24607/src/WebServer Modified Files: BTWebServer.py htmltmpl.py Log Message: Made build work for windows. Use WT++.pyw for windows since readline doesn't work there. Fixed a bug(?) in htmltmpl on Windows. Fixed menu.tmpl for Opera7 Index: BTWebServer.py =================================================================== RCS file: /cvsroot/btplusplus/BT++/src/WebServer/BTWebServer.py,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** BTWebServer.py 16 Mar 2003 01:45:18 -0000 1.10 --- BTWebServer.py 25 Mar 2003 00:27:02 -0000 1.11 *************** *** 41,70 **** except: pass - try: remove("WebTemplates/root.tmplc") - except: pass templateRoot = TemplateManager().prepare("WebTemplates/root.tmpl") - - try: remove("WebTemplates/menu.tmplc") - except: pass templateMenu = TemplateManager().prepare("WebTemplates/menu.tmpl") - - try: remove("WebTemplates/exit.tmplc") - except: pass templateExit = TemplateManager().prepare("WebTemplates/exit.tmpl") - - try: remove("WebTemplates/dl_fail.tmplc") - except: pass templateDLFail = TemplateManager().prepare("WebTemplates/dl_fail.tmpl") - - try: remove("WebTemplates/torrent.tmplc") - except: pass templateTorrent = TemplateManager().prepare("WebTemplates/torrent.tmpl") - - try: remove("WebTemplates/log.tmplc") - except: pass templateLog = TemplateManager().prepare("WebTemplates/log.tmpl") - - try: remove("WebTemplates/config.tmplc") - except: pass templateConfig = TemplateManager().prepare("WebTemplates/config.tmpl") --- 41,50 ---- Index: htmltmpl.py =================================================================== RCS file: /cvsroot/btplusplus/BT++/src/WebServer/htmltmpl.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** htmltmpl.py 27 Feb 2003 00:44:40 -0000 1.1 --- htmltmpl.py 25 Mar 2003 00:27:03 -0000 1.2 *************** *** 19,22 **** --- 19,25 ---- Copyright (c) 2001 Tomas Styblo, tr...@cp... + + Modified 3/2003 Tobias Minich, bel...@us... + Locking produced some errors on Windows @name htmltmpl *************** *** 282,286 **** msvcrt.locking(fd, msvcrt.LK_LOCK, 1) elif lock == LOCK_UN: ! msvcrt.locking(fd, msvcrt.LK_UNLCK, 1) else: raise TemplateError, "BUG: bad lock in lock_file" --- 285,292 ---- msvcrt.locking(fd, msvcrt.LK_LOCK, 1) elif lock == LOCK_UN: ! ## Modified by Tobias Minich ! ## original didn't seem to work on Windows ! try: msvcrt.locking(fd, msvcrt.LK_UNLCK, 1) ! except: pass else: raise TemplateError, "BUG: bad lock in lock_file" |
From: <bel...@us...> - 2003-03-25 00:27:06
|
Update of /cvsroot/btplusplus/BT++/src/WebTemplates In directory sc8-pr-cvs1:/tmp/cvs-serv24607/src/WebTemplates Modified Files: menu.tmpl Log Message: Made build work for windows. Use WT++.pyw for windows since readline doesn't work there. Fixed a bug(?) in htmltmpl on Windows. Fixed menu.tmpl for Opera7 Index: menu.tmpl =================================================================== RCS file: /cvsroot/btplusplus/BT++/src/WebTemplates/menu.tmpl,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** menu.tmpl 16 Mar 2003 01:17:58 -0000 1.2 --- menu.tmpl 25 Mar 2003 00:27:03 -0000 1.3 *************** *** 19,23 **** <tr> <td width=100%><input type=text style="width:100%" name=torr title="Paste Torrent URLs here"></td> ! <td nowrap><input type=hidden name=command value=Add><button type=submit>Add</button><button type=reset>Clear</button></td> </tr> </table> --- 19,26 ---- <tr> <td width=100%><input type=text style="width:100%" name=torr title="Paste Torrent URLs here"></td> ! <td><table cellpadding=0><tr> ! <td><input type=hidden name=command value=Add><button type=submit>Add</button></td> ! <td><button type=reset>Clear</button></td> ! </tr></table></td> </tr> </table> |
From: <bel...@us...> - 2003-03-16 01:45:25
|
Update of /cvsroot/btplusplus/BT++/src/WebServer In directory sc8-pr-cvs1:/tmp/cvs-serv21902/src/WebServer Modified Files: BTWebServer.py Log Message: Disabled 'Pause' if hashing or allocating (leads to crash atm) Index: BTWebServer.py =================================================================== RCS file: /cvsroot/btplusplus/BT++/src/WebServer/BTWebServer.py,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** BTWebServer.py 16 Mar 2003 01:17:58 -0000 1.9 --- BTWebServer.py 16 Mar 2003 01:45:18 -0000 1.10 *************** *** 338,341 **** --- 338,342 ---- LoaderInfo['Status'] = loader.Info['Status'] LoaderInfo['Hashing'] = (loader.Info['Status']=='Hashing') + LoaderInfo['Allocating'] = (loader.Info['Status']=='Allocating') LoaderInfo['Finished'] = loader.IsFinished() LoaderInfo['Auto'] = (c <= Config.Get('Download', 'MaxSimDown')) |
From: <bel...@us...> - 2003-03-16 01:45:24
|
Update of /cvsroot/btplusplus/BT++/src/WebTemplates In directory sc8-pr-cvs1:/tmp/cvs-serv21902/src/WebTemplates Modified Files: torrent.tmpl Log Message: Disabled 'Pause' if hashing or allocating (leads to crash atm) Index: torrent.tmpl =================================================================== RCS file: /cvsroot/btplusplus/BT++/src/WebTemplates/torrent.tmpl,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** torrent.tmpl 16 Mar 2003 01:17:58 -0000 1.3 --- torrent.tmpl 16 Mar 2003 01:45:19 -0000 1.4 *************** *** 27,31 **** <tr bgcolor=#BFD8BC> </TMPL_IF> ! <td><button type=submit name=command value=<TMPL_VAR Command>><TMPL_VAR Command></button></td> <td> <table> --- 27,31 ---- <tr bgcolor=#BFD8BC> </TMPL_IF> ! <td><button type=submit name=command <TMPL_IF Hashing>disabled</TMPL_IF><TMPL_IF Allocating>disabled</TMPL_IF> value=<TMPL_VAR Command>><TMPL_VAR Command></button></td> <td> <table> |