From f5e8f98fd10bd96cc961d49f1b3fbebd148a58f3 Mon Sep 17 00:00:00 2001 From: Adriana Draghici Date: Fri, 27 Nov 2009 13:11:13 +0000 Subject: [PATCH] Tribler: status message are written into a file, instead of stderr --- tribler-mod/SingleDownload.py | 306 ++++++++++++++++++ .../Core/APIImplementation/SingleDownload.py | 22 +- tribler-mod/Tribler/Tools/cmdlinedl.py | 14 +- tribler-mod/cmdlinedl.py | 14 +- tribler-mod/scripts/README | 7 +- 5 files changed, 350 insertions(+), 13 deletions(-) create mode 100644 tribler-mod/SingleDownload.py diff --git a/tribler-mod/SingleDownload.py b/tribler-mod/SingleDownload.py new file mode 100644 index 0000000..d13c6c4 --- /dev/null +++ b/tribler-mod/SingleDownload.py @@ -0,0 +1,306 @@ +from time import localtime, strftime + + + +# Written by Arno Bakker +# see LICENSE.txt for license information + +import sys +import os +import time +import copy +import sha +import pickle +import socket +import binascii +from types import StringType,ListType,IntType +from traceback import print_exc,print_stack +from threading import Event + +from Tribler.Core.simpledefs import * +from Tribler.Core.exceptions import * +from Tribler.Core.BitTornado.__init__ import createPeerID +from Tribler.Core.BitTornado.download_bt1 import BT1Download +from Tribler.Core.BitTornado.bencode import bencode,bdecode +from Tribler.Core.Video.VideoStatus import VideoStatus + + +SPECIAL_VALUE = 481 + +DEBUG = True #False + + +# Transfers' status info is output into status_file. +FILE_NAME = "status_msg.log" #+ strftime("_%d_%b_%Y_%H_%M_%S", localtime()) + ".log" +status_file = open(FILE_NAME, 'w'); + +class SingleDownload: + """ This class is accessed solely by the network thread """ + + def __init__(self,infohash,metainfo,kvconfig,multihandler,get_extip_func,listenport,videoanalyserpath,vodfileindex,set_error_func,pstate,lmvodeventcallback,lmhashcheckcompletecallback): + + self.dow = None + self.set_error_func = set_error_func + self.videoinfo = None + self.videostatus = None + self.lmvodeventcallback = lmvodeventcallback + self.lmhashcheckcompletecallback = lmhashcheckcompletecallback + self.logmsgs = [] + self._hashcheckfunc = None + self._getstatsfunc = None + try: + self.dldoneflag = Event() + self.dlrawserver = multihandler.newRawServer(infohash,self.dldoneflag) + self.lmvodeventcallback = lmvodeventcallback + + if pstate is not None: + self.hashcheckfrac = pstate['dlstate']['progress'] + else: + self.hashcheckfrac = 0.0 + + self.peerid = createPeerID() + #print >>sys.stderr, strftime("%d-%m-%Y %H:%M:%S", localtime())," ","SingleDownload: __init__: My peer ID is",`peerid` + + self.dow = BT1Download(self.hashcheckprogressfunc, + self.finishedfunc, + self.fatalerrorfunc, + self.nonfatalerrorfunc, + self.logerrorfunc, + self.dldoneflag, + kvconfig, + metainfo, + infohash, + self.peerid, + self.dlrawserver, + get_extip_func, + listenport, + videoanalyserpath + ) + + file = self.dow.saveAs(self.save_as) + #if DEBUG: + # print >>sys.stderr, strftime("%d-%m-%Y %H:%M:%S", localtime())," ","SingleDownload: dow.saveAs returned",file + + # Set local filename in vodfileindex + if vodfileindex is not None: + index = vodfileindex['index'] + if index == -1: + index = 0 + vodfileindex['outpath'] = self.dow.get_dest(index) + self.videoinfo = vodfileindex + if 'live' in metainfo['info']: + authparams = metainfo['info']['live'] + else: + authparams = None + self.videostatus = VideoStatus(metainfo['info']['piece length'],self.dow.files,vodfileindex,authparams) + self.videoinfo['status'] = self.videostatus + self.dow.set_videoinfo(vodfileindex,self.videostatus) + + #if DEBUG: + # print >>sys.stderr, strftime("%d-%m-%Y %H:%M:%S", localtime())," ","SingleDownload: setting vodfileindex",vodfileindex + + if pstate is None: + resumedata = None + else: + # Restarting download + resumedata=pstate['engineresumedata'] + self._hashcheckfunc = self.dow.initFiles(resumedata=resumedata) + + + except Exception,e: + self.fatalerrorfunc(e) + + def get_bt1download(self): + return self.dow + + def save_as(self,name,length,saveas,isdir): + """ Return the local filename to which to save the file 'name' in the torrent """ + if DEBUG: + print >>status_file, strftime("%d-%m-%Y %H:%M:%S", localtime())," ","SingleDownload: save_as(",`name`,length,`saveas`,isdir,")" + # status_file.close() + try: + if not os.access(saveas,os.F_OK): + os.mkdir(saveas) + path = os.path.join(saveas,name) + if isdir and not os.path.isdir(path): + os.mkdir(path) + return path + except Exception,e: + self.fatalerrorfunc(e) + + def perform_hashcheck(self,complete_callback): + """ Called by any thread """ + if DEBUG: + print >>status_file, strftime("%d-%m-%Y %H:%M:%S", localtime())," ","SingleDownload: perform_hashcheck()" # ,self.videoinfo + #status_file.close() + try: + """ Schedules actually hashcheck on network thread """ + self._getstatsfunc = SPECIAL_VALUE # signal we're hashchecking + # Already set, should be same + self.lmhashcheckcompletecallback = complete_callback + self._hashcheckfunc(self.lmhashcheckcompletecallback) + except Exception,e: + self.fatalerrorfunc(e) + + def hashcheck_done(self): + """ Called by LaunchMany when hashcheck complete and the Download can be + resumed + + Called by network thread + """ + if DEBUG: + print >>status_file, strftime("%d-%m-%Y %H:%M:%S", localtime())," ","SingleDownload: hashcheck_done()" + try: + self.dow.startEngine(vodeventfunc = self.lmvodeventcallback) + self._getstatsfunc = self.dow.startStats() # not possible earlier + self.dow.startRerequester() + self.dlrawserver.start_listening(self.dow.getPortHandler()) + except Exception,e: + self.fatalerrorfunc(e) + + + # DownloadConfigInterface methods + def set_max_speed(self,direct,speed,callback): + if self.dow is not None: + if DEBUG: + print >>sys.stderr, strftime("%d-%m-%Y %H:%M:%S", localtime())," ","SingleDownload: set_max_speed",`self.dow.response['info']['name']`,direct,speed + if direct == UPLOAD: + self.dow.setUploadRate(speed,networkcalling=True) + else: + self.dow.setDownloadRate(speed,networkcalling=True) + if callback is not None: + callback(direct,speed) + + def set_max_conns_to_initiate(self,nconns,callback): + if self.dow is not None: + if DEBUG: + print >>sys.stderr, strftime("%d-%m-%Y %H:%M:%S", localtime())," ","SingleDownload: set_max_conns_to_initiate",`self.dow.response['info']['name']`,direct,speed + self.dow.setInitiate(nconns,networkcalling=True) + if callback is not None: + callback(nconns) + + + def set_max_conns(self,nconns,callback): + if self.dow is not None: + if DEBUG: + print >>sys.stderr, strftime("%d-%m-%Y %H:%M:%S", localtime())," ","SingleDownload: set_max_conns",`self.dow.response['info']['name']`,direct,speed + self.dow.setMaxConns(nconns,networkcalling=True) + if callback is not None: + callback(nconns) + + + # + # For DownloadState + # + def get_stats(self,getpeerlist): + logmsgs = self.logmsgs[:] # copy + coopdl_helpers = [] + coopdl_coordinator = None + if self.dow is not None: + if not self.dow.helper is None: + coopdl_coordinator = self.dow.helper.get_coordinator_permid() + if self.dow.coordinator is not None: + # No coordinator when you're a helper + peerreclist = self.dow.coordinator.network_get_asked_helpers_copy() + for peerrec in peerreclist: + coopdl_helpers.append(peerrec['permid']) + if self._getstatsfunc is None: + return (DLSTATUS_WAITING4HASHCHECK,None,logmsgs,coopdl_helpers,coopdl_coordinator) + elif self._getstatsfunc == SPECIAL_VALUE: + stats = {} + stats['frac'] = self.hashcheckfrac + return (DLSTATUS_HASHCHECKING,stats,logmsgs,coopdl_helpers,coopdl_coordinator) + else: + return (None,self._getstatsfunc(getpeerlist=getpeerlist),logmsgs,coopdl_helpers,coopdl_coordinator) + + def get_infohash(self): + return self.infohash + + # + # Persistent State + # + def checkpoint(self): + if self.dow is not None: + return self.dow.checkpoint() + else: + return None + + def shutdown(self): + if DEBUG: + print >>status_file, strftime("%d-%m-%Y %H:%M:%S", localtime())," ","SingleDownload: shutdown" + #status_file.close() + resumedata = None + if self.dow is not None: + self.dldoneflag.set() + self.dlrawserver.shutdown() + resumedata = self.dow.shutdown() + self.dow = None + #if DEBUG: + # print >>sys.stderr, strftime("%d-%m-%Y %H:%M:%S", localtime())," ","SingleDownload: stopped dow" + + if self._getstatsfunc is None or self._getstatsfunc == SPECIAL_VALUE: + # Hashchecking or waiting for while being shutdown, signal LaunchMany + # so it can schedule a new one. + self.lmhashcheckcompletecallback(success=False) + return resumedata + + # + # Cooperative download + # + def ask_coopdl_helpers(self,peerreclist): + if self.dow is not None: + self.dow.coordinator.network_request_help(peerreclist) + + def stop_coopdl_helpers(self,peerreclist): + if self.dow is not None: + self.dow.coordinator.network_stop_help(peerreclist,force=True) + + def get_coopdl_role_object(self,role): + # Used by Coordinator/HelperMessageHandler indirectly + if self.dow is not None: + if role == COOPDL_ROLE_COORDINATOR: + return self.dow.coordinator + else: + return self.dow.helper + else: + return None + + # + # Internal methods + # + def hashcheckprogressfunc(self,activity = '', fractionDone = 0.0): + """ Allegedly only used by StorageWrapper during hashchecking """ + #print >>sys.stderr, strftime("%d-%m-%Y %H:%M:%S", localtime())," ","SingleDownload::statusfunc called",activity,fractionDone + self.hashcheckfrac = fractionDone + + def finishedfunc(self): + """ Download is complete """ + if DEBUG: + print >>status_file, strftime("%d-%m-%Y %H:%M:%S", localtime())," ","SingleDownload::finishedfunc called: Download is complete *******************************" + #status_file.close() + pass + + def fatalerrorfunc(self,data): + print >>sys.stderr, strftime("%d-%m-%Y %H:%M:%S", localtime())," ","SingleDownload::fatalerrorfunc called",data + if type(data) == StringType: + print >>sys.stderr, strftime("%d-%m-%Y %H:%M:%S", localtime())," ","LEGACY CORE FATAL ERROR",data + print_stack() + self.set_error_func(TriblerLegacyException(data)) + else: + print_exc() + self.set_error_func(data) + self.shutdown() + + def nonfatalerrorfunc(self,e): + print >>sys.stderr, strftime("%d-%m-%Y %H:%M:%S", localtime())," ","SingleDownload::nonfatalerrorfunc called",e + # Could log this somewhere, or phase it out (only used in Rerequester) + + def logerrorfunc(self,msg): + t = time.time() + self.logmsgs.append((t,msg)) + + # Keep max 10 log entries, API user should save them if he wants + # complete history + if len(self.logmsgs) > 10: + self.logmsgs.pop(0) + diff --git a/tribler-mod/Tribler/Core/APIImplementation/SingleDownload.py b/tribler-mod/Tribler/Core/APIImplementation/SingleDownload.py index 6e644f2..d13c6c4 100644 --- a/tribler-mod/Tribler/Core/APIImplementation/SingleDownload.py +++ b/tribler-mod/Tribler/Core/APIImplementation/SingleDownload.py @@ -1,4 +1,7 @@ from time import localtime, strftime + + + # Written by Arno Bakker # see LICENSE.txt for license information @@ -26,6 +29,11 @@ SPECIAL_VALUE = 481 DEBUG = True #False + +# Transfers' status info is output into status_file. +FILE_NAME = "status_msg.log" #+ strftime("_%d_%b_%Y_%H_%M_%S", localtime()) + ".log" +status_file = open(FILE_NAME, 'w'); + class SingleDownload: """ This class is accessed solely by the network thread """ @@ -108,7 +116,8 @@ class SingleDownload: def save_as(self,name,length,saveas,isdir): """ Return the local filename to which to save the file 'name' in the torrent """ if DEBUG: - print >>sys.stderr, strftime("%d-%m-%Y %H:%M:%S", localtime())," ","SingleDownload: save_as(",`name`,length,`saveas`,isdir,")" + print >>status_file, strftime("%d-%m-%Y %H:%M:%S", localtime())," ","SingleDownload: save_as(",`name`,length,`saveas`,isdir,")" + # status_file.close() try: if not os.access(saveas,os.F_OK): os.mkdir(saveas) @@ -122,7 +131,8 @@ class SingleDownload: def perform_hashcheck(self,complete_callback): """ Called by any thread """ if DEBUG: - print >>sys.stderr, strftime("%d-%m-%Y %H:%M:%S", localtime())," ","SingleDownload: perform_hashcheck()" # ,self.videoinfo + print >>status_file, strftime("%d-%m-%Y %H:%M:%S", localtime())," ","SingleDownload: perform_hashcheck()" # ,self.videoinfo + #status_file.close() try: """ Schedules actually hashcheck on network thread """ self._getstatsfunc = SPECIAL_VALUE # signal we're hashchecking @@ -139,7 +149,7 @@ class SingleDownload: Called by network thread """ if DEBUG: - print >>sys.stderr, strftime("%d-%m-%Y %H:%M:%S", localtime())," ","SingleDownload: hashcheck_done()" + print >>status_file, strftime("%d-%m-%Y %H:%M:%S", localtime())," ","SingleDownload: hashcheck_done()" try: self.dow.startEngine(vodeventfunc = self.lmvodeventcallback) self._getstatsfunc = self.dow.startStats() # not possible earlier @@ -217,7 +227,8 @@ class SingleDownload: def shutdown(self): if DEBUG: - print >>sys.stderr, strftime("%d-%m-%Y %H:%M:%S", localtime())," ","SingleDownload: shutdown" + print >>status_file, strftime("%d-%m-%Y %H:%M:%S", localtime())," ","SingleDownload: shutdown" + #status_file.close() resumedata = None if self.dow is not None: self.dldoneflag.set() @@ -265,7 +276,8 @@ class SingleDownload: def finishedfunc(self): """ Download is complete """ if DEBUG: - print >>sys.stderr, strftime("%d-%m-%Y %H:%M:%S", localtime())," ","SingleDownload::finishedfunc called: Download is complete *******************************" + print >>status_file, strftime("%d-%m-%Y %H:%M:%S", localtime())," ","SingleDownload::finishedfunc called: Download is complete *******************************" + #status_file.close() pass def fatalerrorfunc(self,data): diff --git a/tribler-mod/Tribler/Tools/cmdlinedl.py b/tribler-mod/Tribler/Tools/cmdlinedl.py index 2649edd..0911d0b 100644 --- a/tribler-mod/Tribler/Tools/cmdlinedl.py +++ b/tribler-mod/Tribler/Tools/cmdlinedl.py @@ -1,5 +1,4 @@ from time import localtime, strftime -from time import localtime, strftime # Written by Arno Bakker # see LICENSE.txt for license information @@ -22,6 +21,10 @@ from Tribler.Core.API import * from Tribler.Core.BitTornado.__init__ import version, report_email +# Transfers' status info is output into status_file. +FILE_NAME = "status_msg.log" #+ strftime("_%d_%b_%Y_%H_%M_%S", localtime()) + ".log" +status_file = open(FILE_NAME, 'w'); + def usage(): print "Usage: python cmdlinedl.py [options] torrent_file" print "Options:" @@ -38,13 +41,17 @@ def usage(): print print "Report bugs to <" + report_email + ">" + def print_version(): print version, "<" + report_email + ">" + + + def state_callback(ds): d = ds.get_download() -# print >>sys.stderr, strftime("%d-%m-%Y %H:%M:%S", localtime())," ", strftime("%d %b %Y %H:%M:%S", localtime())," ",`d.get_def().get_name()`,dlstatus_strings[ds.get_status()],ds.get_progress(),"%",ds.get_error(),"up",ds.get_current_speed(UPLOAD),"down",ds.get_current_speed(DOWNLOAD) - print >>sys.stderr, strftime("%d-%m-%Y %H:%M:%S", localtime())," ", strftime("%d %b %Y %H:%M:%S", localtime())," ", '%s %s %5.2f%% %s up %8.2fKB/s down %8.2fKB/s eta %d peers %d' % \ +# print >>sys.stderr, strftime("%d %b %Y %H:%M:%S", localtime())," ",`d.get_def().get_name()`,dlstatus_strings[ds.get_status()],ds.get_progress(),"%",ds.get_error(),"up",ds.get_current_speed(UPLOAD),"down",ds.get_current_speed(DOWNLOAD) + print >>status_file, strftime("%d %b %Y %H:%M:%S", localtime())," ", '%s %s %5.2f%% %s up %8.2fKB/s down %8.2fKB/s eta %d peers %d' % \ (d.get_def().get_name(), \ dlstatus_strings[ds.get_status()], \ ds.get_progress() * 100, \ @@ -137,3 +144,4 @@ def main(): if __name__ == "__main__": main() + status_file.close(); diff --git a/tribler-mod/cmdlinedl.py b/tribler-mod/cmdlinedl.py index 2649edd..0911d0b 100644 --- a/tribler-mod/cmdlinedl.py +++ b/tribler-mod/cmdlinedl.py @@ -1,5 +1,4 @@ from time import localtime, strftime -from time import localtime, strftime # Written by Arno Bakker # see LICENSE.txt for license information @@ -22,6 +21,10 @@ from Tribler.Core.API import * from Tribler.Core.BitTornado.__init__ import version, report_email +# Transfers' status info is output into status_file. +FILE_NAME = "status_msg.log" #+ strftime("_%d_%b_%Y_%H_%M_%S", localtime()) + ".log" +status_file = open(FILE_NAME, 'w'); + def usage(): print "Usage: python cmdlinedl.py [options] torrent_file" print "Options:" @@ -38,13 +41,17 @@ def usage(): print print "Report bugs to <" + report_email + ">" + def print_version(): print version, "<" + report_email + ">" + + + def state_callback(ds): d = ds.get_download() -# print >>sys.stderr, strftime("%d-%m-%Y %H:%M:%S", localtime())," ", strftime("%d %b %Y %H:%M:%S", localtime())," ",`d.get_def().get_name()`,dlstatus_strings[ds.get_status()],ds.get_progress(),"%",ds.get_error(),"up",ds.get_current_speed(UPLOAD),"down",ds.get_current_speed(DOWNLOAD) - print >>sys.stderr, strftime("%d-%m-%Y %H:%M:%S", localtime())," ", strftime("%d %b %Y %H:%M:%S", localtime())," ", '%s %s %5.2f%% %s up %8.2fKB/s down %8.2fKB/s eta %d peers %d' % \ +# print >>sys.stderr, strftime("%d %b %Y %H:%M:%S", localtime())," ",`d.get_def().get_name()`,dlstatus_strings[ds.get_status()],ds.get_progress(),"%",ds.get_error(),"up",ds.get_current_speed(UPLOAD),"down",ds.get_current_speed(DOWNLOAD) + print >>status_file, strftime("%d %b %Y %H:%M:%S", localtime())," ", '%s %s %5.2f%% %s up %8.2fKB/s down %8.2fKB/s eta %d peers %d' % \ (d.get_def().get_name(), \ dlstatus_strings[ds.get_status()], \ ds.get_progress() * 100, \ @@ -137,3 +144,4 @@ def main(): if __name__ == "__main__": main() + status_file.close(); diff --git a/tribler-mod/scripts/README b/tribler-mod/scripts/README index 5854c2a..e9f3062 100644 --- a/tribler-mod/scripts/README +++ b/tribler-mod/scripts/README @@ -30,5 +30,8 @@ Fisierele modified_files_* contin pe fiecare linie calea catre un fisier ce treb Liniile care nu contin cel putin un "/" sunt ignorate. ======= - -Fisierul cmdlinedl.py este modificat pt a afisa eta si numarul de peers. +Fisiere modificate "de mana": + - cmdlinedl.py este modificat - pt a afisa eta si numarul de peers. + - pt a scrie intr-un fisier "status_msg.log" in loc de stderr + - Core/APIImplementation/SingleDownload.py - pt a scrie informatii de status in fisierul "status_msg.log" in loc de stderr + -- 2.20.1