def run(args_list): global _CurrentProcess if _CurrentProcess is not None: dhnio.Dprint(4, 'run_upnpc.run WARNING only one process at once') return None if dhnio.Windows(): cmdargs = ['upnpc.exe'] elif dhnio.Linux(): cmdargs = ['upnpc'] else: return None cmdargs += args_list if dhnio.Windows(): # if we run from svn - upnpc.exe is in the p2p folder if not os.path.isfile(cmdargs[0]): if os.path.isfile(os.path.join('p2p', cmdargs[0])): cmdargs[0] = os.path.join('p2p', cmdargs[0]) else: dhnio.Dprint(1, 'run_upnpc.run ERROR can not find executable file ' + cmdargs[0]) return None dhnio.Dprint(6, 'run_upnpc.run is going to execute: %s' % cmdargs) try: if dhnio.Windows() and dhnio.isFrozen(): import win32pipe _CurrentProcess = win32pipe.popen(subprocess.list2cmdline(cmdargs)) else: _CurrentProcess = nonblocking.Popen(cmdargs, shell=False, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,) except OSError: dhnio.Dprint(1, 'run_upnpc.run ERROR can not start executable file ' + cmdargs[0]) return None except: dhnio.DprintException() return None try: if dhnio.Windows() and dhnio.isFrozen(): out_data = _CurrentProcess.read() returncode = _CurrentProcess.close() or 0 else: out_data = _CurrentProcess.communicate()[0] returncode = _CurrentProcess.returncode except: dhnio.DprintException() return None dhnio.Dprint(6, 'run_upnpc.run %s finished with return code: %s' % (str(_CurrentProcess), str(returncode))) _CurrentProcess = None return out_data
def backuptarfile(filepath, compress=None): """ Almost same - returns file descriptor for process that makes tar archive. But tar archive is created from single file, not folder. """ if not os.path.isfile(filepath): dhnio.Dprint(1, 'backup_tar.backuptarfile ERROR %s not found' % filepath) return None if compress is None: compress = 'none' # dhnio.Dprint(14, "backup_tar.backuptarfile %s compress=%s" % (filepath, compress)) if dhnio.Windows(): if dhnio.isFrozen(): commandpath = "dhnbackup.exe" cmdargs = [commandpath, 'nosubdirs', compress, filepath] else: commandpath = "dhnbackup.py" cmdargs = [sys.executable, commandpath, 'nosubdirs', compress, filepath] else: commandpath = "dhnbackup.py" cmdargs = [sys.executable, commandpath, 'nosubdirs', compress, filepath] if not os.path.isfile(commandpath): dhnio.Dprint(1, 'backup_tar.backuptarfile ERROR %s not found' % commandpath) return None # dhnio.Dprint(12, "backup_tar.backuptarfile going to execute %s" % str(cmdargs)) # p = run(cmdargs) p = child_process.pipe(cmdargs) return p
def backuptar(directorypath, recursive_subfolders=True, compress=None): """ Returns file descriptor for process that makes tar archive. In other words executes a child process and create a Pipe to communicate with it. """ if not os.path.isdir(directorypath): dhnio.Dprint(1, 'backup_tar.backuptar ERROR %s not found' % directorypath) return None subdirs = 'subdirs' if not recursive_subfolders: subdirs = 'nosubdirs' if compress is None: compress = 'none' # dhnio.Dprint(14, "backup_tar.backuptar %s %s compress=%s" % (directorypath, subdirs, compress)) if dhnio.Windows(): if dhnio.isFrozen(): commandpath = "dhnbackup.exe" cmdargs = [commandpath, subdirs, compress, directorypath] else: commandpath = "dhnbackup.py" cmdargs = [sys.executable, commandpath, subdirs, compress, directorypath] else: commandpath = "dhnbackup.py" cmdargs = [sys.executable, commandpath, subdirs, compress, directorypath] if not os.path.isfile(commandpath): dhnio.Dprint(1, 'backup_tar.backuptar ERROR %s not found' % commandpath) return None # dhnio.Dprint(14, "backup_tar.backuptar going to execute %s" % str(cmdargs)) # p = run(cmdargs) p = child_process.pipe(cmdargs) return p
def init(): dhnio.Dprint(4, 'dhnupdate.init') update_shedule_file(settings.getUpdatesSheduleData()) if not dhnio.isFrozen() or not dhnio.Windows(): dhnio.Dprint(6, 'dhnupdate.init finishing') return if not os.path.isfile(settings.VersionFile()): dhnio.WriteFile(settings.VersionFile(), '') SetLocalDir(dhnio.getExecutableDir()) if settings.getUpdatesMode() != settings.getUpdatesModeValues()[2]: dhnio.Dprint(6, 'dhnupdate.init starting the loop') reactor.callLater(0, loop, True) else: dhnio.Dprint(6, 'dhnupdate.init skip, update mode is: %s' % settings.getUpdatesMode())
def run(Tester): global _CurrentProcess # dhnio.Dprint(8, 'localtester.run ' + str(Tester)) if dhnio.isFrozen() and dhnio.Windows(): commandpath = "dhntester.exe" cmdargs = [commandpath, Tester] else: commandpath = "dhntester.py" cmdargs = [sys.executable, commandpath, Tester] if not os.path.isfile(commandpath): dhnio.Dprint(1, "localtester.run ERROR %s not found" % commandpath) return None dhnio.Dprint(14, "localtester.run execute: %s" % cmdargs) try: if dhnio.Windows(): import win32process _CurrentProcess = nonblocking.Popen( cmdargs, shell=False, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=False, creationflags=win32process.CREATE_NO_WINDOW, ) else: _CurrentProcess = nonblocking.Popen( cmdargs, shell=False, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=False, ) except: dhnio.Dprint(1, "localtester.run ERROR executing: %s" % str(cmdargs)) dhnio.DprintException() return None return _CurrentProcess
def extracttar(tarfile, outdir): """ Opposite method, run dhnbackup to extract files and folders from ".tar" file. """ if not os.path.isfile(tarfile): dhnio.Dprint(1, 'backup_tar.extracttar ERROR %s not found' % tarfile) return None # dhnio.Dprint(12, "backup_tar.extracttar %s %s" % (tarfile, outdir)) if dhnio.Windows(): if dhnio.isFrozen(): commandpath = 'dhnbackup.exe' cmdargs = [commandpath, 'extract', tarfile, outdir] else: commandpath = "dhnbackup.py" cmdargs = [sys.executable, commandpath, 'extract', tarfile, outdir] else: commandpath = "dhnbackup.py" cmdargs = [sys.executable, commandpath, 'extract', tarfile, outdir] if not os.path.isfile(commandpath): dhnio.Dprint(1, 'backup_tar.extracttar ERROR %s is not found' % commandpath) return None # p = run(cmdargs) p = child_process.pipe(cmdargs) return p
def cmd_uninstall(opts, args, overDict): if not dhnio.Windows(): print 'This command can be used only under OS Windows.' return 0 if not dhnio.isFrozen(): print 'You are running DataHaven.NET from sources, uninstall command is available only for binary version.' return 0 def do_uninstall(): dhnio.Dprint(0, 'command_line.do_uninstall') # batfilename = misc.MakeBatFileToUninstall() # misc.UpdateRegistryUninstall(True) # misc.RunBatFile(batfilename, 'c:/out2.txt') def kill(): dhnio.Dprint(0, 'kill') total_count = 0 found = False while True: appList = dhnio.find_process([ 'dhnmain.exe', 'dhnmain.py', 'dhn.py', 'regexp:^/usr/bin/python\ +/usr/bin/datahaven.*$', 'dhnview.exe', 'dhnview.py', 'dhnbackup.exe', 'dhnbackup.py', 'dhntester.exe', 'dhntester.py', 'dhnstarter.exe', ]) if len(appList) > 0: found = True for pid in appList: dhnio.Dprint(0, 'trying to stop pid %d' % pid) dhnio.kill_process(pid) if len(appList) == 0: if found: dhnio.Dprint(0, 'DataHaven.NET stopped\n') else: dhnio.Dprint(0, 'DataHaven.NET was not started\n') return 0 total_count += 1 if total_count > 10: dhnio.Dprint(0, 'some DataHaven.NET process found, but can not stop it\n') return 1 time.sleep(1) def wait_then_kill(x): dhnio.Dprint(0, 'wait_then_kill') total_count = 0 #while True: def _try(): dhnio.Dprint(0, '_try') appList = dhnio.find_process([ 'dhnmain.exe', 'dhnview.exe', 'dhnbackup.exe', 'dhntester.exe', 'dhnstarter.exe', ]) dhnio.Dprint(0, 'appList:' + str(appList)) if len(appList) == 0: dhnio.Dprint(0, 'finished') reactor.stop() do_uninstall() return 0 total_count += 1 dhnio.Dprint(0, '%d' % total_count) if total_count > 10: dhnio.Dprint(0, 'not responding') ret = kill() reactor.stop() if ret == 0: do_uninstall() return ret reactor.callLater(1, _try) _try() # time.sleep(1) appList = dhnio.find_process([ 'dhnmain.exe', 'dhnview.exe', 'dhnbackup.exe', 'dhntester.exe', 'dhnstarter.exe', ]) if len(appList) == 0: dhnio.Dprint(0, 'uninstalling DataHaven.NET ... ') do_uninstall() return 0 dhnio.Dprint(0, 'found DataHaven.NET processes ... ') try: url = webcontrol._PAGE_ROOT+'?action=exit' run_url_command(url).addCallback(wait_then_kill) #reactor.addSystemEventTrigger('before', 'shutdown', do_uninstall) reactor.run() return 0 except: dhnio.DprintException() ret = kill() if ret == 0: do_uninstall() return ret
def main(): """ THIS IS THE ENTRY POINT OF THE PROGRAM! """ try: import lib.dhnio as dhnio except: dirpath = os.path.dirname(os.path.abspath(sys.argv[0])) sys.path.insert(0, os.path.abspath('datahaven')) sys.path.insert(0, os.path.abspath(os.path.join(dirpath, '..'))) sys.path.insert(0, os.path.abspath(os.path.join(dirpath, '..', '..'))) try: import lib.dhnio as dhnio except: return 1 # init IO module, update locale dhnio.init() # TODO # sys.excepthook = dhnio.ExceptionHook if not dhnio.isFrozen(): from twisted.internet.defer import setDebugging setDebugging(True) # ask dhnio to count time for each line from that moment, not absolute time dhnio.LifeBegins() pars = parser() (opts, args) = pars.parse_args() if opts.no_logs: dhnio.DisableLogs() #---logpath--- logpath = '' if dhnio.Windows(): logpath = os.path.join(os.environ['APPDATA'], 'DataHaven.NET', 'logs', 'dhnmainstart.log') elif dhnio.Linux(): old_path = os.path.join(os.path.expanduser('~'), 'datahavennet') if os.path.isdir(old_path): logpath = os.path.join(old_path, 'logs', 'dhnmainstart.log') else: logpath = os.path.join(os.path.expanduser('~'), '.datahaven', 'logs', 'dhnmainstart.log') if opts.output: logpath = opts.output if logpath != '': dhnio.OpenLogFile(logpath) dhnio.Dprint(2, 'dhnmain.main log file opened ' + logpath) if dhnio.Windows() and dhnio.isFrozen(): dhnio.StdOutRedirectingStart() dhnio.Dprint(2, 'dhnmain.main redirecting started') if opts.debug or str(opts.debug) == '0': dhnio.SetDebug(opts.debug) if opts.quite and not opts.verbose: dhnio.DisableOutput() if opts.verbose: copyright() dhnio.Dprint(2, 'dhnmain.main started ' + time.asctime()) overDict = override_options(opts, args) cmd = '' if len(args) > 0: cmd = args[0].lower() dhnio.Dprint(2, 'dhnmain.main args=%s' % str(args)) #---start--- if cmd == '' or cmd == 'start' or cmd == 'go': appList = dhnio.find_process([ 'dhnmain.exe', 'dhnmain.py', 'dhn.py', 'regexp:^/usr/bin/python\ +/usr/bin/datahaven.*$', ]) # pid = -1 # try: # if dhnio.Windows(): # dhn_data_path = os.path.join(os.environ.get('APPDATA', os.path.join(os.path.expanduser('~'), 'Application Data')), 'DataHaven.NET') # pid_path = os.path.join(dhn_data_path, 'metadata', 'processid') # else: # pid_path = os.path.join(os.path.expanduser('~'), '.datahaven', 'metadata', 'processid') # if os.path.isfile(pid_path): # pid = int(dhnio.ReadBinaryFile(pid_path).strip()) # except: # dhnio.DprintException() # this is extra protection for Debian release # I am nut sure how process name can looks on different systems # check the process ID from previous start # it file exists and we found this PID in the currently running apps - DHN is working # if file not exists we don't want to start if found some other jobs with same name # PREPRO probably in future we can switch to this line: # if len(appList) > 0 and pid != -1 and pid in appList # because if we do not have pid - the process is not working # but old versions do not have pid file so we need to wait till # all users be updated to this version - revision 7520+ # if len(appList) > 0 and ( ( pid != -1 and pid in appList ) or ( pid == -1 ) ): if len(appList) > 0: dhnio.Dprint(0, 'DataHaven.NET already started, found another process: %s' % str(appList)) dhnio.shutdown() return 0 ret = run('', opts, args, overDict) dhnio.shutdown() return ret #---restart--- elif cmd == 'restart': appList = dhnio.find_process([ 'dhnmain.exe', 'dhnmain.py', 'dhn.py', 'regexp:^/usr/bin/python\ +/usr/bin/datahaven.*$', ]) if len(appList) > 0: dhnio.Dprint(0, 'found main DataHaven.NET process: %s, sending "restart" command ... ' % str(appList), '') def done(x): dhnio.Dprint(0, 'DONE\n', '') from twisted.internet import reactor if reactor.running and not reactor._stopped: reactor.stop() def failed(x): dhnio.Dprint(0, 'FAILED, killing previous process and do restart\n', '') try: kill() except: dhnio.DprintException() from twisted.internet import reactor import lib.misc as misc reactor.addSystemEventTrigger('after','shutdown', misc.DoRestart) reactor.stop() try: from twisted.internet import reactor from command_line import run_url_command d = run_url_command('?action=restart', False) d.addCallback(done) d.addErrback(failed) reactor.run() dhnio.shutdown() return 0 except: dhnio.DprintException() dhnio.shutdown() return 1 else: ret = run('', opts, args, overDict) dhnio.shutdown() return ret #---show--- elif cmd == 'show' or cmd == 'open': appList_dhnview = dhnio.find_process([ 'dhnview.exe', 'dhnview.py', ]) appList = dhnio.find_process([ 'dhnmain.exe', 'dhnmain.py', 'dhn.py', 'regexp:^/usr/bin/python\ +/usr/bin/datahaven.*$', ]) if len(appList_dhnview) > 0: if len(appList) == 0: for pid in appList_dhnview: dhnio.kill_process(pid) else: dhnio.Dprint(0, 'DataHaven.NET GUI already opened, found another process: %s' % str(appList)) dhnio.shutdown() return 0 if len(appList) == 0: ret = run('show', opts, args, overDict) dhnio.shutdown() return ret dhnio.Dprint(0, 'found main DataHaven.NET process: %s, start the GUI\n' % str(appList)) ret = show() dhnio.shutdown() return ret #---stop--- elif cmd == 'stop' or cmd == 'kill' or cmd == 'shutdown': appList = dhnio.find_process([ 'dhnmain.exe', 'dhnmain.py', 'dhn.py', 'regexp:^/usr/bin/python\ +/usr/bin/datahaven.*$', ]) if len(appList) > 0: dhnio.Dprint(0, 'found main DataHaven.NET process: %s, sending command "exit" ... ' % str(appList), '') try: from twisted.internet import reactor from command_line import run_url_command url = '?action=exit' run_url_command(url, False).addBoth(wait_then_kill) reactor.run() dhnio.shutdown() return 0 except: dhnio.DprintException() ret = kill() dhnio.shutdown() return ret else: dhnio.Dprint(0, 'DataHaven.NET is not running at the moment') dhnio.shutdown() return 0 #---uninstall--- elif cmd == 'uninstall': def do_spawn(x=None): from lib.settings import WindowsStarterFileName starter_filepath = os.path.join(dhnio.getExecutableDir(), WindowsStarterFileName()) dhnio.Dprint(0, "dhnmain.main dhnstarter.exe path: %s " % starter_filepath) if not os.path.isfile(starter_filepath): dhnio.Dprint(0, "dhnmain.main ERROR %s not found" % starter_filepath) dhnio.shutdown() return 1 cmdargs = [os.path.basename(starter_filepath), 'uninstall'] dhnio.Dprint(0, "dhnmain.main os.spawnve cmdargs="+str(cmdargs)) ret = os.spawnve(os.P_DETACH, starter_filepath, cmdargs, os.environ) dhnio.shutdown() return ret def do_reactor_stop_and_spawn(x=None): reactor.stop() ret = do_spawn() dhnio.shutdown() return ret dhnio.Dprint(0, 'dhnmain.main UNINSTALL!') if not dhnio.Windows(): dhnio.Dprint(0, 'This command can be used only under OS Windows.') dhnio.shutdown() return 0 if not dhnio.isFrozen(): dhnio.Dprint(0, 'You are running DataHaven.NET from sources, uninstall command is available only for binary version.') dhnio.shutdown() return 0 appList = dhnio.find_process(['dhnmain.exe',]) if len(appList) > 0: dhnio.Dprint(0, 'found main DataHaven.NET process... ', '') try: from twisted.internet import reactor from command_line import run_url_command url = '?action=exit' run_url_command(url).addBoth(do_reactor_stop_and_spawn) reactor.run() dhnio.shutdown() return 0 except: dhnio.DprintException() ret = do_spawn() dhnio.shutdown() return ret #---command_line--- import command_line ret = command_line.run(opts, args, overDict, pars) if ret == 2: print usage() dhnio.shutdown() return ret
def run(UI='', options=None, args=None, overDict=None): """ In the method `main()` program firstly checks the command line arguments and then calls this method to start the whole process. This initialize some low level modules and finally create an instance of `initializer()` state machine and send it an event "run". """ import lib.dhnio as dhnio dhnio.Dprint(6, 'dhnmain.run sys.path=%s' % str(sys.path)) #---USE_TRAY_ICON--- try: from dhnicon import USE_TRAY_ICON dhnio.Dprint(4, 'dhnmain.run USE_TRAY_ICON='+str(USE_TRAY_ICON)) if dhnio.Linux() and not dhnio.X11_is_running(): USE_TRAY_ICON = False if USE_TRAY_ICON: from twisted.internet import wxreactor wxreactor.install() except: USE_TRAY_ICON = False dhnio.DprintException() if USE_TRAY_ICON: if dhnio.Linux(): icons_dict = { 'red': 'icon-red-24x24.png', 'green': 'icon-green-24x24.png', 'gray': 'icon-gray-24x24.png', } else: icons_dict = { 'red': 'icon-red.png', 'green': 'icon-green.png', 'gray': 'icon-gray.png', } import dhnicon icons_path = str(os.path.abspath(os.path.join(dhnio.getExecutableDir(), 'icons'))) dhnio.Dprint(4, 'dhnmain.run call dhnicon.init(%s)' % icons_path) dhnicon.init(icons_path, icons_dict) def _tray_control_func(cmd): if cmd == 'exit': #import dhninit #dhninit.shutdown_exit() import shutdowner shutdowner.A('stop', 'exit') dhnicon.SetControlFunc(_tray_control_func) dhnio.Dprint(4, 'dhnmain.run want to import twisted.internet.reactor') try: from twisted.internet import reactor except: dhnio.DprintException() sys.exit('Error initializing reactor in dhnmain.py\n') #---settings--- import lib.settings as settings if overDict: settings.override_dict(overDict) settings.init() if not options or options.debug is None: dhnio.SetDebug(settings.getDebugLevel()) #---logfile---- if dhnio.EnableLog and dhnio.LogFile is not None: dhnio.Dprint(2, 'dhnmain.run want to switch log files') if dhnio.Windows() and dhnio.isFrozen(): dhnio.StdOutRedirectingStop() dhnio.CloseLogFile() dhnio.OpenLogFile(settings.MainLogFilename()+'-'+time.strftime('%y%m%d%H%M%S')+'.log') if dhnio.Windows() and dhnio.isFrozen(): dhnio.StdOutRedirectingStart() #---memdebug--- if settings.uconfig('logs.memdebug-enable') == 'True': try: import lib.memdebug as memdebug memdebug_port = int(settings.uconfig('logs.memdebug-port')) memdebug.start(memdebug_port) reactor.addSystemEventTrigger('before', 'shutdown', memdebug.stop) dhnio.Dprint(2, 'dhnmain.run memdebug web server started on port %d' % memdebug_port) except: dhnio.DprintException() #---process ID--- try: pid = os.getpid() pid_file_path = os.path.join(settings.MetaDataDir(), 'processid') dhnio.WriteFile(pid_file_path, str(pid)) dhnio.Dprint(2, 'dhnmain.run wrote process id [%s] in the file %s' % (str(pid), pid_file_path)) except: dhnio.DprintException() # #---reactor.callLater patch--- # if dhnio.Debug(12): # patchReactorCallLater(reactor) # monitorDelayedCalls(reactor) dhnio.Dprint(2,"dhnmain.run UI=[%s]" % UI) if dhnio.Debug(10): dhnio.Dprint(0, '\n' + dhnio.osinfofull()) dhnio.Dprint(4, 'dhnmain.run import automats') #---START!--- import lib.automat as automat automat.LifeBegins(dhnio.LifeBeginsTime) automat.OpenLogFile(settings.AutomatsLog()) import initializer import shutdowner dhnio.Dprint(4, 'dhnmain.run send event "run" to initializer()') #reactor.callLater(0, initializer.A, 'run', UI) initializer.A('run', UI) #reactor.addSystemEventTrigger('before', 'shutdown', lambda : initializer.A('reactor-stopped')) dhnio.Dprint(2, 'dhnmain.run calling reactor.run()') reactor.run() dhnio.Dprint(2, 'dhnmain.run reactor stopped') # this will call initializer() without reactor.callLater(0, ... ) # we do not have any timers initializer() so do not worry #initializer.A('reactor-stopped', use_reactor = False) shutdowner.A('reactor-stopped') dhnio.Dprint(2, 'dhnmain.run finished, EXIT') automat.objects().clear() automat.CloseLogFile() ## import threading ## dhnio.Dprint(0, 'threads:') ## for t in threading.enumerate(): ## dhnio.Dprint(0, ' '+str(t)) dhnio.CloseLogFile() if dhnio.Windows() and dhnio.isFrozen(): dhnio.StdOutRedirectingStop() return 0