def poll(self): self.scraper.refresh(self.item.url) if self.scraper.find(self.item.failed_load_regex): print(f"failed loading {self.item.name}") return sold_out_match = self.scraper.find(self.item.sold_out_regex) if not sold_out_match: price = self.find_price() if price and price > self.item.max_price: print(f"Available but price too high: {price}") elif self.sold_out: now = str(dt.datetime.now()) print( f"{self.item.name} AVAILABLE at {now} for {price}: {self.item.url}" ) if not self.triggered: playsound.playsound(nc.sound) Notifier.send_email(self.item.name, "Item available", nc) self.scraper.save( nc.output_path, f"available_{self.item.name}_{now}.html") self.sold_out = False else: if not self.sold_out: now = str(dt.datetime.now()) print(f"{self.item.name} Sold out again at {now}") if not self.triggered: Notifier.send_email(self.item.name, "Item sold out", nc) self.scraper.save(nc.output_path, f"soldout_{self.item.name}_{now}.html") self.sold_out = True self.triggered = True
def on_left_down(self, event): Notifier.notify("Activated") Mbox('Little Finger', ' Activated\n\n Press F11 to Deactivate', 0) ## Notifier.notify("Activated Now") Little_Finger.comments() print('Tray icon was left-clicked.')
def __init__(self, parent, dependencies, module, gui): """ Initializes the TkDependencyManager object example values for dependencies: single dependency: { 'package': 'nmap', 'installer': 'apt-get' } multi dependency: [{ 'package': 'tk8.5-dev', 'installer': 'apt-get' }, { 'package': 'pillow', 'installer': 'pip', 'version': 'latest' }] @param parent Frame @param dependencies dict or list of dicts @param module: the name of the module which initialized the package manager @param gui reference to the GUI object """ self.widgets = {} self.variables = {} if(isinstance(dependencies, dict)): self.dependencies = [dependencies] elif(isinstance(dependencies, list)): self.dependencies = dependencies else: self.dependencies = dependencies self.module = module self.gui = gui self.notifier = Notifier() self.aptGet = { 'install': ['sudo','apt-get','-q','-y','install'], 'remove': ['sudo','apt-get','-q','-y','remove'] } self.pip = { 'install': ['sudo', 'pip','-q', 'install'], 'remove': ['sudo', 'pip','-q', 'uninstall'] } self.loadCache() self.colours = self.gui.colours self.images = self.gui.images self.fonts = self.gui.fonts self.widget = Frame(parent,bg=self.colours['bg'], borderwidth=0, highlightthickness=0) self.widget.grid(column=0,row=0,sticky='EW')
class GenericThread(threading.Thread): def __init__(self, name, callback, stopped=False, interval=0.1): """ Initializes a GenericThread object """ threading.Thread.__init__(self) if (name != None): self.setName(name) self.callback = callback self.stopped = stopped if (isinstance(interval, (int, float, long)) and interval > 0.0): self.interval = interval else: self.interval = 0.1 self.notifier = Notifier() self.daemon = True threading.Thread.start(self) def run(self): """ run this task """ try: while True: try: d, start = 0, time.time() except: pass else: if (not self.stopped): try: self.callback() except Exception as e: self.notifier.addNotice( 'Error in {0}: {1}\nStack Trace: {2}'.format( self.name, e, traceback.format_exc()), 'warning') d = time.time() - start if (d > 0 and d < self.interval): time.sleep(self.interval - d) elif (d == self.interval): time.sleep(self.interval) except (KeyboardInterrupt, SystemExit, EOFError): cleanup_stop_thread() sys.exit() def stop(self): """ stop tasks """ self.stopped = True def start(self): """ start task """ self.stopped = False
class TkNotifier(TkBlock): def __init__(self, parent, gui, **options): super(TkNotifier,self).__init__(parent, gui, **options) self.now = lambda: int(round(time.time() * 1000)) self.displayed = [] self.firstrun = True self.notifier = Notifier(log=Setting.get('notifier_log', False)) self.notifier.setCallback(self.update) self.addNotifier() self.notifier.addNotice('Welcome to AllMyServos') self.gui.scheduler.addTask('notifier_cleanup', self.cleanup, 15) def addNotifier(self): self.open() self.widgets['main'] = Tkinter.Frame(self.widget, bg=self.colours['bg'], borderwidth=0, highlightthickness=0) self.widgets['main'].grid(column=0,row=0,sticky='EW') self.widgets['main'].grid_columnconfigure(0, weight=1) self.widgets['frameLabel'] = Tkinter.Label(self.widgets['main'],text='Notifications', anchor=NW, bg=self.colours['bg'], fg=self.colours['headingfg']) self.widgets['frameLabel'].grid(column=0,row=self.gridrow,sticky='EW') self.variables['archive'] = Tkinter.BooleanVar() self.variables['archive'].set(Setting.get('notifier_archive', False)) self.widgets['archiveentry'] = Tkinter.Checkbutton(self.widgets['main'], text="Archive", variable=self.variables['archive'], command=self.OnToggleArchiveClick, bg=self.colours['inputbg'], fg=self.colours['inputfg'], activebackground=self.colours['activebg'], selectcolor=self.colours['inputbg']) self.widgets['archiveentry'].grid(column=1,row=self.gridrow,sticky='E') self.gridrow += 1 self.widgets['notices'] = Tkinter.Frame(self.widgets['main'], bg=self.colours['bg']) self.widgets['notices'].grid(column=0,row=self.gridrow,columnspan=2, sticky='EW') self.widgets['notices'].grid_columnconfigure(0, weight = 1) #self.widgets['notices'].grid_propagate(False) def update(self): if(len(self.displayed) <= 20): n = self.notifier.getNotice() self.displayed.append(TkNotice(self.widgets['notices'], self.gui, n['time'], n['text'], n['type'], self.width)) def cleanup(self): dlen = len(self.displayed) if(dlen > 0 and self.firstrun == False): removed = None try: if(self.displayed[0].time <= (self.now() - 10000)): self.displayed[0].remove() if(dlen == 1): self.displayed = [] else: self.displayed = self.displayed[1:] except: pass if(self.firstrun == True): self.firstrun = False def close(self): self.widget.grid_forget() def OnToggleArchiveClick(self): Setting.set('notifier_archive', self.variables['archive'].get())
def __init__(self, name, callback, stopped=False, interval=0.1): """ Initializes a GenericThread object """ threading.Thread.__init__(self) if (name != None): self.setName(name) self.callback = callback self.stopped = stopped if (isinstance(interval, (int, float, long)) and interval > 0.0): self.interval = interval else: self.interval = 0.1 self.notifier = Notifier() self.daemon = True threading.Thread.start(self)
def __init__(self, parent, gui, **options): """TkBlock is a base class. Any class containing Tkinter objects should extend it. - initializes common attributes - creates a wrapped widget which applies the settings from the theme profile - provides generic views for data - provides open and close functions @param parent @param gui @param options """ self.gui = gui self.parent = parent self.column, self.row, self.columnspan, self.rowspan, self.padx, self.pady, self.sticky, self.scrollable, self.rowweight, self.columnweight, self.menuindex, self.width, self.height = options[ 'column'], options['row'], options['columnspan'], options[ 'rowspan'], options['padx'], options['pady'], options[ 'sticky'], options['scrollable'], options[ 'rowweight'], options['columnweight'], options[ 'menuindex'], options['width'], options['height'] self.widgets, self.variables = {}, {} self.notifier = Notifier() # collect theme information from the gui self.colours = self.gui.colours self.fonts = self.gui.fonts self.images = self.gui.images self.initWidget() self.setup()
def __init__(self, parent, dependencies, module, gui): """ parent: a tkinter frame dependencies: required packages - examples: single dependency: { 'package': 'nmap', 'installer': 'apt-get' } multi dependency: [{ 'package': 'tk8.5-dev', 'installer': 'apt-get' }, { 'package': 'pillow', 'installer': 'pip', 'version': 'latest' }] module: the name of the module which initialized the package manager gui: reference to the main tkinter app """ self.widgets = {} self.variables = {} if isinstance(dependencies, dict): self.dependencies = [dependencies] elif isinstance(dependencies, list): self.dependencies = dependencies else: self.dependencies = dependencies self.module = module self.gui = gui self.notifier = Notifier() self.aptGet = { "install": ["sudo", "apt-get", "-q", "-y", "install"], "remove": ["sudo", "apt-get", "-q", "-y", "remove"], } self.pip = {"install": ["sudo", "pip", "-q", "install"], "remove": ["sudo", "pip", "-q", "uninstall"]} self.loadCache() self.colours = self.gui.colours self.images = self.gui.images self.fonts = self.gui.fonts self.widget = Frame(parent, bg=self.colours["bg"], borderwidth=0, highlightthickness=0) self.widget.grid(column=0, row=0, sticky="EW")
def __init__(self, parent): KSystemTray.__init__(self, parent) self.parent = parent self.iface = PisiIface.Iface() self.icon = self.loadIcon("package-manager") self.overlayIcon = self.icon.convertToImage() self.setPixmap(self.icon) self.timer = QTimer() self.timer.connect(self.timer, SIGNAL("timeout()"), self.checkUpdate) self.interval = 0 self.lastUpgrades = [] self.popupMenu = KPopupMenu(self.contextMenu()) self.contextMenu().insertItem(i18n("Update"), self.popupMenu) for repo in self.parent.mainwidget.command.getRepoList(): self.popupMenu.insertItem("%s" % repo) self.popupMenu.insertSeparator() self.id = self.popupMenu.insertItem(i18n("All")) self.notifier = Notifier() self.connect(self.popupMenu, SIGNAL("activated(int)"), self.slotUpdateRepo) self.connect(self.notifier, PYSIGNAL("showUpgrades"), self.showUpgrades)
def main(): app = QGuiApplication(argv) qmlRegisterType(Manager.Manager, 'BTManager', 1, 0, 'BTManager') qmlRegisterType(Notifier.Notifier, 'BTNotifier', 1, 0, 'BTNotifier') qmlRegisterType(Device.Device, 'Device', 1, 0, 'Device') print('Create my device') notifier = Notifier.Notifier() manager = Manager.Manager() manager.set_notifier(notifier) print('Bluetooth manager create') path = os.path.dirname(__file__) print('Detect run path') print('Run GUI') engine = QQmlApplicationEngine() engine.rootContext().setContextProperty('AppPath', path) engine.rootContext().setContextProperty('MyDevice', manager.my_device) engine.rootContext().setContextProperty('BTManager', manager) engine.rootContext().setContextProperty('BTNotifier', notifier) engine.load('ui/Main.qml') print('Start search for near by devices') manager.search(True) print('Execute app') exit(app.exec_())
def TRAD_InitiateNewTradingSession(self, startSession): self.TRAD_ResetTradingParameters() self.theTransactionManager.TRNM_InitiateNewTradingSession(startSession) if startSession is True: theNotifier.SendWhatsappMessage( "*Astibot: New trading session* started on the %s trading pair!" % self.theSettings.SETT_GetSettings()["strTradingPair"])
def newCategory(self, categoryName, logger=None): if not self.__categories.has_key(categoryName): self.__categories[categoryName] = Notifier.Notifier(categoryName, logger) self.setDconfigLevel(categoryName) else: print "Warning: DirectNotify: category '%s' already exists" % categoryName return self.getCategory(categoryName)
def newCategory(self, categoryName, logger=None): if categoryName not in self._DirectNotify__categories: self._DirectNotify__categories[categoryName] = Notifier.Notifier( categoryName, logger) self.setDconfigLevel(categoryName) return self.getCategory(categoryName)
def __init__(self, parent, gui, **options): """ Initializes TkNotifier object @param parent @param gui @param options """ super(TkNotifier,self).__init__(parent, gui, **options) self.now = lambda: int(round(time.time() * 1000)) self.displayed = [] self.firstrun = True self.notifier = Notifier(log=Setting.get('notifier_log', False)) self.notifier.setCallback(self.update) self.addNotifier() self.notifier.addNotice('Welcome to AllMyServos') self.gui.scheduler.addTask('notifier_cleanup', self.cleanup, 15)
def __init__(self, scheduler=None, kbthread=None, notifier=None): """ Initializes the camera object @param scheduler @param kbthread @param notifier """ self.now = lambda: int(round(time.time() * 1000)) if (scheduler != None): self.scheduler = scheduler else: self.scheduler = Scheduler.GetInstance() self.kbthread = Keyboard.KeyboardThread.GetInstance() if (notifier != None): self.notifier = notifier else: self.notifier = Notifier() self.viewfinder = { 'enabled': False, 'visible': False, 'window': (0, 0, 320, 240), 'fullscreen': False, 'element': None } self.patterns = { 'nic': re.compile(r'(?P<name>[^\s]+).?'), 'addr': re.compile(r'\s*inet\saddr:(?P<ip>[^\s]+).*'), 'overscan': re.compile(r'[^#]?disable_overscan=(?P<overscan>\d+).*'), 'overscan_left': re.compile(r'[^#]?overscan_left=(?P<left>\d+)'), 'overscan_right': re.compile(r'[^#]?overscan_right=(?P<right>\d+)'), 'overscan_top': re.compile(r'[^#]?overscan_top=(?P<top>\d+)'), 'overscan_bottom': re.compile(r'[^#]?overscan_bottom=(?P<bottom>\d+)'), 'start_x': re.compile(r'[^#]?start_x=(?P<start_x>\d+)'), 'gpu_mem': re.compile(r'[^#]?gpu_mem=(?P<gpu_mem>\d+)'), } self.initProfile() self.initInfo() self.initKb() self.callbacks = {} self.scheduler.addTask('cam_watcher', self.check, interval=0.5, stopped=not Setting.get('cam_autostart', False))
def setUp(self): self._data_manager = DataManager.DataManager() self._monitor_manager = MonitorManager.MonitorManager() self._monitor_1 = RamByteMonitor.RamByteMonitor() self._monitor_manager.add_monitor(self._monitor_1) self._notifier = Notifier.Notifier("shizuka.client.Mulder", testing=True)
class GenericThread(threading.Thread): def __init__(self, name, callback, stopped=False, interval=0.1): threading.Thread.__init__(self) if name != None: self.setName(name) self.callback = callback self.stopped = stopped if isinstance(interval, (int, float, long)) and interval > 0.0: self.interval = interval else: self.interval = 0.1 self.notifier = Notifier() self.daemon = True threading.Thread.start(self) def run(self): try: while True: try: d, start = 0, time.time() except: pass else: if not self.stopped: try: self.callback() except Exception as e: self.notifier.addNotice( "Error in {0}: {1}\nStack Trace: {2}".format(self.name, e, traceback.format_exc()), "warning", ) d = time.time() - start if d > 0 and d < self.interval: time.sleep(self.interval - d) elif d == self.interval: time.sleep(self.interval) except (KeyboardInterrupt, SystemExit, EOFError): cleanup_stop_thread() sys.exit() def stop(self): self.stopped = True def start(self): self.stopped = False
def newCategory(self, categoryName, logger=None): """newCategory(self, string) Make a new notify category named categoryName. Return new category if no such category exists, else return existing category """ if (categoryName not in self.__categories): self.__categories[categoryName] = Notifier.Notifier(categoryName, logger) self.setDconfigLevel(categoryName) return (self.getCategory(categoryName))
def __init__(self, parent, gui, **options): super(TkNotifier,self).__init__(parent, gui, **options) self.now = lambda: int(round(time.time() * 1000)) self.displayed = [] self.firstrun = True self.notifier = Notifier(log=Setting.get('notifier_log', False)) self.notifier.setCallback(self.update) self.addNotifier() self.notifier.addNotice('Welcome to AllMyServos') self.gui.scheduler.addTask('notifier_cleanup', self.cleanup, 15)
def loadModules(self): if self.moduleName == "notifier": self.module = Notifier() elif self.moduleName == "none": self.module = AFK() if self.module == None: return False return True
def __init__(self, parent=None): InfoDialog.__init__(self) self.parent = parent self.autoRestart = False self.notifier = Notifier() self.iface = PisiIface.Iface() self.timer = QTimer() self.timer.connect(self.timer, SIGNAL("timeout()"), self.updateNotification) self.connect(self.okButton, SIGNAL('clicked()'), self.accept) self.connect(self.cancelButton, SIGNAL('clicked()'), self.reject) self.connect(self.autoRestartCheckBox, SIGNAL("toggled(bool)"), self.setAutoRestart) self.connect(self.notifier, PYSIGNAL("cancelled"), self.rebootCancelled)
def __init__(self, name, callback, stopped=False, interval=0.1): threading.Thread.__init__(self) if name != None: self.setName(name) self.callback = callback self.stopped = stopped if isinstance(interval, (int, float, long)) and interval > 0.0: self.interval = interval else: self.interval = 0.1 self.notifier = Notifier() self.daemon = True threading.Thread.start(self)
def newCategory(self, categoryName, logger=None): """newCategory(self, string) Make a new notify category named categoryName. Return new category if no such category exists, else return existing category """ if (not self.__categories.has_key(categoryName)): self.__categories[categoryName] = Notifier.Notifier( categoryName, logger) self.setDconfigLevel(categoryName) else: print "Warning: DirectNotify: category '%s' already exists" % \ (categoryName) return (self.getCategory(categoryName))
class Info(InfoDialog): def __init__(self, parent=None): InfoDialog.__init__(self) self.parent = parent self.autoRestart = False self.notifier = Notifier() self.iface = PisiIface.Iface() self.timer = QTimer() self.timer.connect(self.timer, SIGNAL("timeout()"), self.updateNotification) self.connect(self.okButton, SIGNAL('clicked()'), self.accept) self.connect(self.cancelButton, SIGNAL('clicked()'), self.reject) self.connect(self.autoRestartCheckBox, SIGNAL("toggled(bool)"), self.setAutoRestart) self.connect(self.notifier, PYSIGNAL("cancelled"), self.rebootCancelled) def reset(self): self.counter = 10 self.autoRestart = False self.autoRestartCheckBox.setChecked(False) def setAutoRestart(self, enabled): self.autoRestart = enabled def autoRestartChecked(self): return self.autoRestart def showRequirements(self): self.reset() self.updateNotification() return self.exec_loop() def updateNotification(self): self.timer.stop() self.showNotification() if self.counter: self.timer.start(1000) self.counter -= 1 else: self.notifier.close() self.rebootSystem() def rebootSystem(self): os.system("dbus-send --system --dest=org.freedesktop.Hal --type=method_call " "--print-reply /org/freedesktop/Hal/devices/computer " "org.freedesktop.Hal.Device.SystemPowerManagement.Reboot") def rebootCancelled(self): self.timer.stop() self.notifier.close() self.reset() def showNotification(self): icon = getIconPath("package-manager") message = i18n("Your system will restart in %1 Seconds!").arg(self.counter) header = i18n("Reboot in progress") actions = ["cancel", unicode(i18n("Cancel"))] self.notifier.show(icon, header, message, actions)
def __init__(self, scheduler=None): """ Initializes a Network object @param scheduler """ if (scheduler != None): self.scheduler = scheduler else: self.scheduler = Scheduler.GetInstance() self.patterns = {} self.nodes = {} self.__initPatterns() self.nmapcachepath = os.path.join(Specification.Specification.filebase, 'network') self.nmapcachefile = 'nmap_cache.txt' self.nmapcommand = ['nmap', '192.168.0.0/24'] self.ifconfigcommand = ['ifconfig'] self.nics = [] self.myip = None self.ifconfigraw = None self.nmapraw = None self.mapping = False self.notifier = Notifier() self.scheduler.addTask('network_mapper', self.update, 30)
def __init__(self): """ Initializes the Command Line Interface """ self.s = Setting() self.notifier = Notifier() self.printLicense() self.initScheduler() self.initTrayIcon() self.initSpec() self.initMotionScheduler() self.initKbThread() self.initRPC() self.initCamera() self.printFooter() try: while(True): time.sleep(100) except KeyboardInterrupt: self.shutDown()
def __init__(self, scheduler=None): if scheduler != None: self.scheduler = scheduler else: self.scheduler = Scheduler() self.patterns = {} self.nodes = {} self.__initPatterns() self.nmapcachepath = os.path.join(Specification.Specification.filebase, "network") self.nmapcachefile = "nmap_cache.txt" self.nmapcommand = ["nmap", "192.168.0.0/24"] self.ifconfigcommand = ["ifconfig"] self.nics = [] self.myip = None self.ifconfigraw = None self.nmapraw = None self.mapping = False self.notifier = Notifier() self.scheduler.addTask("network_mapper", self.update, 30)
def main(): import MessageHandler import Notifier import threading logger.setLevel(logging.INFO) logger.info("Instantiating the different components we need.") #Instantiating the different components we need. client = Client() monman = MonitorManager.MonitorManager() cexec = CommandInterface.CommandInterface() notifier = Notifier.Notifier(client.get_client_id()) messagehandler = MessageHandler.MessageHandler(client.get_client_id()) logger.info("Setting the outgoing message queue.") #Setting the outgoing message queue client.set_message_queue(messagehandler) monman.set_message_queue(messagehandler) ##TODO THIS SHIT IS TEMPORARY. MAKE A LOCK FACTORY CLASS OR SOMETHING. ##SETTING LOCKS FOR THE MONITORS SO WHEN THEY ARE BEING MODIFIED THEY CANT BE POLLED. lock = threading.RLock() monman.set_lock(lock) notifier._data_manager.set_lock(lock) logger.info("Giving client access to crucial components") #Giving client access to crucial components client.set_monitor_manager(monman) client.set_command_executor(cexec) client.set_notifier(notifier) #making the client visible on the nameserver client.register_to_name_server() #Sending a "Hey I"m here!" message to the server. client.send_discovery() #Starting the outgoing message queue messagehandler.start() #Beginning the monitoring cycle. client.begin_monitoring()
import Notifier import StatusMonitor if __name__ == '__main__': # arguments if len(sys.argv) < 5: print( '''Usage: python amtrakstatusnotifier.py <train number> <station> <admin email> <email 1> [email 2]''' ) sys.exit(0x2fe3) trainNumber = int(sys.argv[1]) station = sys.argv[2] adminAddress = sys.argv[3] addresses = sys.argv[4:] # Monitor try: monitor = StatusMonitor.StatusMonitor() monitor.run(trainNumber, station, addresses) except Exception as error: traceback = traceback.TracebackException(type(error), error, error.__traceback__) message = 'Amtrak Status notifier raised an exception: {}\n\n{}'.format( error, ''.join(traceback.format())) # Save to file with open('error.log', 'w') as f: f.write(message) # Send to admin notifier = Notifier.Notifier() notifier.notify(None, adminAddress, 'Error!', message)
def comments(): #To collect data and create a dictionary w= pandas.read_csv("ES_codes.csv",encoding = "ISO-8859-1") Code={} s=0 for i in w.Codes[:]: Code.update({i:[]}) if str(w.com1[s])!='nan': Code[i].append(w.com1[s]) if str(w.com2[s])!='nan': Code[i].append(w.com2[s]) if str(w.com3[s])!='nan': Code[i].append(w.com3[s]) if str(w.com4[s])!='nan': Code[i].append(w.com4[s]) if str(w.com5[s])!='nan': Code[i].append(w.com5[s]) s=s+1 ################################################################################################################### ###############Recording and saving in object################ import keyboard def generate_events(): while True: yield keyboard.read_event() #print(keyboard.read_event()) strings = keyboard.get_typed_strings(generate_events()) #def excution(): while True: global Line if keyboard.read_key(suppress=False)=='f11': Notifier.notify("Deactivated") break Line=(next(strings)).strip() ############################################################## DataSet=Line.split(';') ###Input stings conevrsion to List if len(DataSet[0])!=0: LenD= len(DataSet) ###Dataset List Length Key=DataSet[0] ###item number of List print('key:',Key) if Key in Code: LenC=len(Code[Key]) ###Abbrivation List len k=LenC-LenD CharTyped="" for i in DataSet: CharTyped= CharTyped+str(i)##Length of Char typed by user print('LEN OF TYPE',len(CharTyped)+len(DataSet)) for i in range(len(CharTyped)+len(DataSet)): keyboard.press('backspace') time.sleep(0.05) print(k) print(len(Code[Key])) for i in range(k+1):DataSet.append('##') Input= 1 for i in Code[Key]: if len(Code[Key])==1 and k>-1: keyboard.write(str(i)) else: keyboard.write(str(i)+" #"+str(DataSet[Input])+" ") Input=Input+1 print("Exit Loop")
class TkDependencyManager(object): def __init__(self, parent, dependencies, module, gui): """ parent: a tkinter frame dependencies: required packages - examples: single dependency: { 'package': 'nmap', 'installer': 'apt-get' } multi dependency: [{ 'package': 'tk8.5-dev', 'installer': 'apt-get' }, { 'package': 'pillow', 'installer': 'pip', 'version': 'latest' }] module: the name of the module which initialized the package manager gui: reference to the main tkinter app """ self.widgets = {} self.variables = {} if isinstance(dependencies, dict): self.dependencies = [dependencies] elif isinstance(dependencies, list): self.dependencies = dependencies else: self.dependencies = dependencies self.module = module self.gui = gui self.notifier = Notifier() self.aptGet = { "install": ["sudo", "apt-get", "-q", "-y", "install"], "remove": ["sudo", "apt-get", "-q", "-y", "remove"], } self.pip = {"install": ["sudo", "pip", "-q", "install"], "remove": ["sudo", "pip", "-q", "uninstall"]} self.loadCache() self.colours = self.gui.colours self.images = self.gui.images self.fonts = self.gui.fonts self.widget = Frame(parent, bg=self.colours["bg"], borderwidth=0, highlightthickness=0) self.widget.grid(column=0, row=0, sticky="EW") def addManager(self): """ called by requesting module if install / upgrade is required """ self.gridrow = 0 self.checkDependencies() # === VIEWS ===# def checkDependencies(self): """ view - displays the result of the dependency checks """ self.open() self.widgets["tlabel"] = Tkinter.Label( self.widgets["tframe"], text="Dependencies / Installation", anchor=W, bg=self.colours["bg"], fg=self.colours["headingfg"], font=self.fonts["heading"], ) self.widgets["tlabel"].grid(column=0, row=self.gridrow, columnspan=2, sticky="EW") self.gridrow += 1 self.widgets["moduleLabel"] = Tkinter.Label( self.widgets["tframe"], text="Module", bg=self.colours["bg"], fg=self.colours["headingfg"], height=2 ) self.widgets["moduleLabel"].grid(column=0, row=self.gridrow, sticky="EW") self.widgets["moduleData"] = Tkinter.Label( self.widgets["tframe"], text=self.module, anchor="w", bg=self.colours["bg"], fg=self.colours["valuefg"], height=2, ) self.widgets["moduleData"].grid(column=1, row=self.gridrow, sticky="EW") self.gridrow += 1 self.widgets["dependencyLabel"] = Tkinter.Label( self.widgets["tframe"], text="Dependencies", bg=self.colours["bg"], fg=self.colours["headingfg"], height=2 ) self.widgets["dependencyLabel"].grid(column=0, row=self.gridrow, sticky="N") i = 0 for d in self.dependencies: self.widgets["pframe" + str(i)] = Tkinter.Frame(self.widgets["tframe"], bg=self.colours["rowaltbg"]) self.widgets["pframe" + str(i)].grid(column=1, row=self.gridrow, pady=10, sticky="EW") self.widgets["name{0}".format(i)] = Tkinter.Label( self.widgets["pframe" + str(i)], text=d["package"], bg=self.colours["rowbg"], fg=self.colours["headingfg"], height=2, ) self.widgets["name{0}".format(i)].grid(column=0, row=0, ipadx=15, sticky="EW") self.widgets["installerLabel{0}".format(i)] = Tkinter.Label( self.widgets["pframe" + str(i)], text="Installer", bg=self.colours["rowbg"], fg=self.colours["headingfg"], height=2, ) self.widgets["installerLabel{0}".format(i)].grid(column=1, row=0, ipadx=5, sticky="EW") self.widgets["installer{0}".format(i)] = Tkinter.Label( self.widgets["pframe" + str(i)], text=d["installer"], bg=self.colours["rowaltbg"], fg=self.colours["valuefg"], height=2, ) self.widgets["installer{0}".format(i)].grid(column=2, row=0, ipadx=5, sticky="W") self.widgets["installLabel{0}".format(i)] = Tkinter.Label( self.widgets["pframe" + str(i)], text="Install Command", bg=self.colours["rowbg"], fg=self.colours["headingfg"], height=2, ) self.widgets["installLabel{0}".format(i)].grid(column=1, row=1, ipadx=5, sticky="EW") self.widgets["i{0}".format(i)] = Tkinter.Label( self.widgets["pframe" + str(i)], text=d["icom"], bg=self.colours["rowaltbg"], fg=self.colours["valuefg"], height=1, ) self.widgets["i{0}".format(i)].grid(column=2, row=1, ipadx=5, sticky="W") self.widgets["removeLabel{0}".format(i)] = Tkinter.Label( self.widgets["pframe" + str(i)], text="Uninstall Command", bg=self.colours["rowbg"], fg=self.colours["headingfg"], height=2, ) self.widgets["removeLabel{0}".format(i)].grid(column=1, row=2, ipadx=5, sticky="EW") self.widgets["r{0}".format(i)] = Tkinter.Label( self.widgets["pframe" + str(i)], text=d["rcom"], bg=self.colours["rowaltbg"], fg=self.colours["valuefg"], height=1, ) self.widgets["r{0}".format(i)].grid(column=2, row=2, ipadx=5, sticky="W") status = "installed" if d["status"] == 0: status = "not installed" elif d["status"] == 1: status = "upgrade required" self.widgets["statusLabel{0}".format(i)] = Tkinter.Label( self.widgets["pframe" + str(i)], text="Status", bg=self.colours["rowbg"], fg=self.colours["headingfg"], height=2, ) self.widgets["statusLabel{0}".format(i)].grid(column=1, row=3, ipadx=5, sticky="EW") self.widgets["installed{0}".format(i)] = Tkinter.Label( self.widgets["pframe" + str(i)], text=status, bg=self.colours["rowaltbg"], fg=self.colours["valuefg"], height=2, ) self.widgets["installed{0}".format(i)].grid(column=2, row=3, ipadx=5, sticky="W") i += 1 self.gridrow += 1 self.widgets["optionsFrame"] = Tkinter.Frame(self.widgets["tframe"], bg=self.colours["bg"]) self.widgets["optionsFrame"].grid(column=0, row=self.gridrow, columnspan=2, sticky="EW") self.gridrow = 0 self.widgets["installLabel"] = Tkinter.Label( self.widgets["optionsFrame"], text="Install", bg=self.colours["bg"], fg=self.colours["fg"], height=2 ) self.widgets["installLabel"].grid(column=0, row=self.gridrow, sticky="EW") self.gridrow += 1 self.widgets["install"] = Tkinter.Button( self.widgets["optionsFrame"], text=u"Install", image=self.images["accept"], command=self.OnInstallClick, bg=self.colours["buttonbg"], activebackground=self.colours["buttonhighlightbg"], highlightbackground=self.colours["buttonborder"], ) self.widgets["install"].grid(column=0, row=self.gridrow) def success(self): """ view - displays in the event of a successful installation """ self.open() self.widgets["tlabel"] = Tkinter.Label( self.widgets["tframe"], text="Dependencies / Installation / Success", anchor=NW, bg=self.colours["bg"], fg=self.colours["headingfg"], font=self.fonts["heading"], ) self.widgets["tlabel"].grid(column=0, row=self.gridrow, columnspan=2, sticky="EW") self.gridrow += 1 self.widgets["moduleLabel"] = Tkinter.Label( self.widgets["tframe"], text="Module", bg=self.colours["bg"], fg=self.colours["headingfg"], height=2 ) self.widgets["moduleLabel"].grid(column=0, row=self.gridrow, sticky="EW") self.widgets["moduleData"] = Tkinter.Label( self.widgets["tframe"], text=self.module, anchor="w", bg=self.colours["bg"], fg=self.colours["valuefg"], height=2, ) self.widgets["moduleData"].grid(column=1, row=self.gridrow, ipadx=15, sticky="EW") self.gridrow += 1 self.widgets["dependencyLabel"] = Tkinter.Label( self.widgets["tframe"], text="Dependencies", bg=self.colours["bg"], fg=self.colours["headingfg"], height=2 ) self.widgets["dependencyLabel"].grid(column=0, row=self.gridrow, sticky="N") i = 0 for d in self.dependencies: self.widgets["pframe" + str(i)] = Tkinter.Frame(self.widgets["tframe"], bg=self.colours["rowaltbg"]) self.widgets["pframe" + str(i)].grid(column=1, row=self.gridrow, pady=10, sticky="EW") self.widgets["name{0}".format(i)] = Tkinter.Label( self.widgets["pframe" + str(i)], text=d["package"], bg=self.colours["rowbg"], fg=self.colours["headingfg"], height=2, ) self.widgets["name{0}".format(i)].grid(column=0, row=0, ipadx=15, sticky="EW") self.widgets["installerLabel{0}".format(i)] = Tkinter.Label( self.widgets["pframe" + str(i)], text="Installer", bg=self.colours["rowbg"], fg=self.colours["headingfg"], height=2, ) self.widgets["installerLabel{0}".format(i)].grid(column=1, row=0, ipadx=5, sticky="EW") self.widgets["installer{0}".format(i)] = Tkinter.Label( self.widgets["pframe" + str(i)], text=d["installer"], bg=self.colours["rowaltbg"], fg=self.colours["valuefg"], height=2, ) self.widgets["installer{0}".format(i)].grid(column=2, row=0, ipadx=5, sticky="W") self.widgets["installLabel{0}".format(i)] = Tkinter.Label( self.widgets["pframe" + str(i)], text="Install Command", bg=self.colours["rowbg"], fg=self.colours["headingfg"], height=2, ) self.widgets["installLabel{0}".format(i)].grid(column=1, row=1, ipadx=5, sticky="EW") self.widgets["i{0}".format(i)] = Tkinter.Label( self.widgets["pframe" + str(i)], text=d["icom"], bg=self.colours["rowaltbg"], fg=self.colours["valuefg"], height=1, ) self.widgets["i{0}".format(i)].grid(column=2, row=1, ipadx=5, sticky="W") self.widgets["removeLabel{0}".format(i)] = Tkinter.Label( self.widgets["pframe" + str(i)], text="Uninstall Command", bg=self.colours["rowbg"], fg=self.colours["headingfg"], height=2, ) self.widgets["removeLabel{0}".format(i)].grid(column=1, row=2, ipadx=5, sticky="EW") self.widgets["r{0}".format(i)] = Tkinter.Label( self.widgets["pframe" + str(i)], text=d["rcom"], bg=self.colours["rowaltbg"], fg=self.colours["valuefg"], height=1, ) self.widgets["r{0}".format(i)].grid(column=2, row=2, ipadx=5, sticky="W") status = "installed" if d["status"] == 0: status = "not installed" elif d["status"] == 1: status = "upgrade required" self.widgets["statusLabel{0}".format(i)] = Tkinter.Label( self.widgets["pframe" + str(i)], text="Status", bg=self.colours["rowbg"], fg=self.colours["headingfg"], height=2, ) self.widgets["statusLabel{0}".format(i)].grid(column=1, row=3, ipadx=5, sticky="EW") self.widgets["installed{0}".format(i)] = Tkinter.Label( self.widgets["pframe" + str(i)], text=status, bg=self.colours["rowaltbg"], fg=self.colours["valuefg"], height=2, ) self.widgets["installed{0}".format(i)].grid(column=2, row=3, ipadx=5, sticky="W") i += 1 self.gridrow += 1 self.widgets["info"] = Tkinter.Label( self.widgets["tframe"], text="All dependencies were installed successfully.", bg=self.colours["bg"], fg=self.colours["fg"], height=3, ) self.widgets["info"].grid(column=0, row=self.gridrow, columnspan=2, sticky="EW") self.gridrow += 1 self.widgets["info"] = Tkinter.Label( self.widgets["tframe"], text="Restart the interface and reopen the {0} module.".format(self.module), bg=self.colours["bg"], fg=self.colours["headingfg"], height=3, ) self.widgets["info"].grid(column=0, row=self.gridrow, columnspan=2, sticky="EW") def failure(self): """ view - displays in the event of an unsuccessful installation """ self.open() self.widgets["tlabel"] = Tkinter.Label( self.widgets["tframe"], text="Dependencies / Installation / Failure", anchor=NW, bg=self.colours["bg"], fg=self.colours["headingfg"], font=self.fonts["heading"], ) self.widgets["tlabel"].grid(column=0, row=self.gridrow, columnspan=2, sticky="EW") self.gridrow += 1 self.widgets["moduleLabel"] = Tkinter.Label( self.widgets["tframe"], text="Module", bg=self.colours["bg"], fg=self.colours["headingfg"], height=2 ) self.widgets["moduleLabel"].grid(column=0, row=self.gridrow, sticky="EW") self.widgets["moduleData"] = Tkinter.Label( self.widgets["tframe"], text=self.module, anchor="nw", bg=self.colours["bg"], fg=self.colours["valuefg"], height=2, ) self.widgets["moduleData"].grid(column=1, row=self.gridrow, sticky="EW") self.gridrow += 1 self.widgets["dependencyLabel"] = Tkinter.Label( self.widgets["tframe"], text="Dependencies", bg=self.colours["bg"], fg=self.colours["headingfg"], height=2 ) self.widgets["dependencyLabel"].grid(column=0, row=self.gridrow, sticky="N") i = 0 for d in self.dependencies: self.widgets["pframe" + str(i)] = Tkinter.Frame(self.widgets["tframe"], bg=self.colours["rowaltbg"]) self.widgets["pframe" + str(i)].grid(column=1, row=self.gridrow, pady=10, sticky="EW") self.widgets["name{0}".format(i)] = Tkinter.Label( self.widgets["pframe" + str(i)], text=d["package"], bg=self.colours["rowbg"], fg=self.colours["headingfg"], height=2, ) self.widgets["name{0}".format(i)].grid(column=0, row=0, ipadx=15, sticky="EW") self.widgets["installerLabel{0}".format(i)] = Tkinter.Label( self.widgets["pframe" + str(i)], text="Installer", bg=self.colours["rowbg"], fg=self.colours["headingfg"], height=2, ) self.widgets["installerLabel{0}".format(i)].grid(column=1, row=0, ipadx=5, sticky="EW") self.widgets["installer{0}".format(i)] = Tkinter.Label( self.widgets["pframe" + str(i)], text=d["installer"], bg=self.colours["rowaltbg"], fg=self.colours["valuefg"], height=2, ) self.widgets["installer{0}".format(i)].grid(column=2, row=0, ipadx=5, sticky="W") self.widgets["installLabel{0}".format(i)] = Tkinter.Label( self.widgets["pframe" + str(i)], text="Install Command", bg=self.colours["rowbg"], fg=self.colours["headingfg"], height=2, ) self.widgets["installLabel{0}".format(i)].grid(column=1, row=1, ipadx=5, sticky="EW") self.widgets["i{0}".format(i)] = Tkinter.Label( self.widgets["pframe" + str(i)], text=d["icom"], bg=self.colours["rowaltbg"], fg=self.colours["valuefg"], height=1, ) self.widgets["i{0}".format(i)].grid(column=2, row=1, ipadx=5, sticky="W") self.widgets["removeLabel{0}".format(i)] = Tkinter.Label( self.widgets["pframe" + str(i)], text="Uninstall Command", bg=self.colours["rowbg"], fg=self.colours["headingfg"], height=2, ) self.widgets["removeLabel{0}".format(i)].grid(column=1, row=2, ipadx=5, sticky="EW") self.widgets["r{0}".format(i)] = Tkinter.Label( self.widgets["pframe" + str(i)], text=d["rcom"], bg=self.colours["rowaltbg"], fg=self.colours["valuefg"], height=1, ) self.widgets["r{0}".format(i)].grid(column=2, row=2, ipadx=5, sticky="W") status = "installed" if d["status"] == 0: status = "not installed" elif d["status"] == 1: status = "upgrade required" self.widgets["statusLabel{0}".format(i)] = Tkinter.Label( self.widgets["pframe" + str(i)], text="Status", bg=self.colours["rowbg"], fg=self.colours["headingfg"], height=2, ) self.widgets["statusLabel{0}".format(i)].grid(column=1, row=3, ipadx=5, sticky="EW") self.widgets["installed{0}".format(i)] = Tkinter.Label( self.widgets["pframe" + str(i)], text=status, bg=self.colours["rowaltbg"], fg=self.colours["valuefg"], height=2, ) self.widgets["installed{0}".format(i)].grid(column=2, row=3, ipadx=5, sticky="W") i += 1 self.gridrow += 1 self.widgets["info"] = Tkinter.Label( self.widgets["tframe"], text="One or more dependencies failed to install.", bg=self.colours["bg"], fg=self.colours["fg"], height=3, ) self.widgets["info"].grid(column=0, row=self.gridrow, columnspan=2, sticky="EW") self.gridrow += 1 self.widgets["info"] = Tkinter.Label( self.widgets["tframe"], text="Please restart the interface and try again.", bg=self.colours["bg"], fg=self.colours["headingfg"], height=3, ) self.widgets["info"].grid(column=0, row=self.gridrow, columnspan=2, sticky="EW") # === ACTIONS ===# def OnInstallClick(self): """ action - performs installation """ self.close() fails = [] for k, v in enumerate(self.dependencies): if not self.isInstalled(v): if self.__installDependency(v): self.dependencies[k]["status"] = 2 self.notifier.addNotice("{0} installation complete".format(v["package"])) else: self.dependencies[k]["status"] = 0 self.notifier.addNotice("{0} installation failed".format(v["package"]), "error") fails.append(v) else: self.dependencies[k]["status"] = 2 if any(fails): self.failure() else: self.success() # === UTILS ===# def loadCache(self): """ initialises the dependency cache either with stored data or an empty dict """ self.cache = {} self.cachepath = os.path.join(os.getcwd(), "files", "Dependencies") self.cachefile = os.path.join(self.cachepath, "{}-cache.json".format(self.__safeName())) if os.path.isfile(self.cachefile): try: f = open(self.cachefile, "r") contents = f.read() f.close() self.cache = json.loads(contents) except: pass def installRequired(self): """ returns a bool indicating whether or not any dependencies require installation """ if "required" in self.cache.keys(): if not self.cache["required"]: return False # only use cached result if installation is not required required = False for d in self.dependencies: try: if d["status"] != 2: required = True except: d["status"] = self.isInstalled(d) if d["status"] != 2: required = True self.cache = {"dependencies": self.dependencies, "required": required} if not os.path.exists(self.cachepath): os.makedirs(self.cachepath) f = open(self.cachefile, "w") f.write(json.dumps(self.cache)) f.close() return required def isInstalled(self, dependency): """ returns status: 0 = not installed, 1 = upgrade required, 2 = installed """ status = 0 if dependency["installer"] == "apt-get": if len(dependency["package"]) > 0: dependency["icom"] = copy(self.aptGet["install"]) # install command dependency["icom"].append(dependency["package"]) dependency["rcom"] = copy(self.aptGet["remove"]) # remove command dependency["rcom"].append(dependency["package"]) p = Popen(["dpkg", "-s", dependency["package"]], stdout=PIPE, stderr=PIPE) o = p.communicate()[0] if p.returncode == 0: o = o.split("\n") pattern = re.compile(r"Status\:\s?(?P<status>.+)") for l in o: if pattern.match(l): status = 2 break elif dependency["installer"] == "pip": if len(dependency["package"]) > 0: dependency["icom"] = copy(self.pip["install"]) dependency["icom"].append(dependency["package"]) dependency["rcom"] = copy(self.pip["remove"]) dependency["rcom"].append(dependency["package"]) p = Popen(["pip", "search", dependency["package"]], stdout=PIPE) o = p.communicate()[0] if p.returncode == 0: o = o.split("\n") pattern = re.compile(r"(?P<package>[^\s]+)\s+-\s+(?P<description>.+)") installedpattern = re.compile(r".*installed:\s+(?P<version>.*)", re.IGNORECASE) packagematch = -1 line = 0 for l in o: matches = pattern.match(l) if matches: if matches.group("package").lower() == dependency["package"].lower(): packagematch = line matches = installedpattern.match(l) if matches and packagematch == line - 1: v = matches.group("version") dv = str(dependency["version"]) num = v.split(" ")[0] if dv == "latest" and "latest" in v: status = 2 elif dv != "latest" and StrictVersion(dv) <= StrictVersion(num): status = 2 else: status = 1 dependency["icom"].append("--upgrade") break line += 1 return status def __installDependency(self, dependency): if dependency["installer"] == "apt-get": return self.__installAptGetDependency(dependency) elif dependency["installer"] == "pip": return self.__installPipDependency(dependency) def __installAptGetDependency(self, dependency): installed = False try: if len(dependency["package"]) > 0: command = copy(self.aptGet["install"]) command.append(dependency["package"]) p = Popen(command, stdout=PIPE) o = p.communicate()[0] if p.returncode == 0: installed = True except: pass return installed def __installPipDependency(self, dependency): installed = False try: if len(dependency["package"]) > 0: command = copy(self.pip["install"]) command.append(dependency["package"]) try: if dependency["status"] == 1: command.append("--upgrade") except: pass p = Popen(command, stdout=PIPE) o = p.communicate()[0] if p.returncode == 0: installed = True except: pass return installed def __safeName(self): return self.module.replace(" ", "") def open(self): for k, v in self.widgets.iteritems(): v.grid_forget() self.widgets = {} self.widget.grid(column=0, row=0) self.gridrow = 0 self.widgets["tframe"] = Frame(self.widget, bg=self.colours["bg"]) self.widgets["tframe"].grid(column=0, row=0, sticky="EW") def close(self): self.widget.grid_forget()
class Tray(KSystemTray): def __init__(self, parent): KSystemTray.__init__(self, parent) self.parent = parent self.icon = self.loadIcon("package-manager") self.overlayIcon = self.icon.convertToImage() self.setPixmap(self.icon) self.timer = QTimer() self.timer.connect(self.timer, SIGNAL("timeout()"), self.checkUpdate) self.interval = 0 self.lastUpgrades = [] self.popupMenu = KPopupMenu(self.contextMenu()) self.contextMenu().insertItem(i18n("Update"), self.popupMenu) for repo in self.parent.mainwidget.command.getRepoList(): self.popupMenu.insertItem("%s" % repo) self.popupMenu.insertSeparator() self.id = self.popupMenu.insertItem(i18n("All")) self.notifier = Notifier() self.connect(self.popupMenu, SIGNAL("activated(int)"), self.slotUpdateRepo) self.connect(self.notifier, PYSIGNAL("showUpgrades"), self.showUpgrades) def slotUpdateRepo(self, id): if id == self.id: self.checkUpdate(forced=True) else: self.checkUpdate(repo=self.contextMenu().text(id), forced=True) def showPopup(self): from sets import Set as set upgrades = PisiIface.get_upgradable_packages() newUpgrades = set(upgrades) - set(self.lastUpgrades) self.lastUpgrades = upgrades if not len(upgrades) or not newUpgrades: return icon = getIconPath("package-manager") message = i18n("There are <b>%1</b> updates available!").arg(len(upgrades)) header = i18n("Updates Available!") self.notifier.show(icon, header, message, self.getPos()) def showUpgrades(self): self.parent.mainwidget.trayUpgradeSwitch() self.parent.show() def getPos(self): pt = self.mapToGlobal(QPoint(0,0)) screen = QDesktopWidget() incr = 0 if pt.y() < screen.screenGeometry().height()/2 and pt.y() < self.height(): incr = self.width() - 4 elif pt.y() > screen.screenGeometry().height() - self.height() - 80: incr = 0 else: incr = self.width() / 2 return (pt.x() + self.height()/2, pt.y() + incr) def updateInterval(self, min): # minutes to milliseconds conversion interval = min * 60 * 1000 if interval != self.interval: self.interval = interval self.timer.stop() if interval: self.timer.start(interval) # Executed when 'Update' is clicked on Tray def checkUpdate(self, repo = None, forced = False): manager = self.parent.mainwidget # timer interval check should not be run if any command is in progress if manager.command.inProgress(): return manager.trayUpdateCheck(repo, forced) # stolen from Akregator def updateTrayIcon(self): nofUpgrades = len(PisiIface.get_upgradable_packages()) if not nofUpgrades: self.setPixmap(self.icon) return oldW = self.pixmap().size().width() oldH = self.pixmap().size().height() uStr = QString.number(nofUpgrades); f = KGlobalSettings.generalFont() f.setBold(True); pointSize = f.pointSizeFloat() fm = QFontMetrics(f) w = fm.width(uStr) if w > oldW: pointSize *= float(oldW) / float(w) f.setPointSizeFloat(pointSize) pix = QPixmap(oldW, oldH) pix.fill(Qt.white) p = QPainter(pix) p.setFont(f) p.setPen(Qt.blue) p.drawText(pix.rect(), Qt.AlignCenter, uStr) pix.setMask(pix.createHeuristicMask()) img = QImage(pix.convertToImage()) overlayImg = QImage(self.overlayIcon.copy()) KIconEffect.overlay(overlayImg, img) icon = QPixmap() icon.convertFromImage(overlayImg) self.setPixmap(icon) # for cannot destroy paint device error p = None
def __init__(self): """ Initializes the Scheduler object """ self.tasks = {} self.notifier = Notifier()
def test_data_is_received_when_server_is_associated(self): self.server.register_to_name_server() notifier = Notifier.Notifier("shizuka.client.Mulder") results = notifier.get_polled_data() transmission_result = notifier.post_to_server(results) self.assertTrue(transmission_result)
class Network(object): def __init__(self, scheduler=None): if scheduler != None: self.scheduler = scheduler else: self.scheduler = Scheduler() self.patterns = {} self.nodes = {} self.__initPatterns() self.nmapcachepath = os.path.join(Specification.Specification.filebase, "network") self.nmapcachefile = "nmap_cache.txt" self.nmapcommand = ["nmap", "192.168.0.0/24"] self.ifconfigcommand = ["ifconfig"] self.nics = [] self.myip = None self.ifconfigraw = None self.nmapraw = None self.mapping = False self.notifier = Notifier() self.scheduler.addTask("network_mapper", self.update, 30) def __initPatterns(self): self.patterns["ifconfig"] = {} self.patterns["ifconfig"]["nic"] = re.compile(r"(?P<name>[^\s]+).?") self.patterns["ifconfig"]["addr"] = re.compile(r"\s*inet\saddr:(?P<ip>[^\s]+).*") self.patterns["nmap"] = {} self.patterns["nmap"]["start"] = re.compile( r"Starting\sNmap\s(?P<version>[^\s]+)\s\( http:\/\/nmap.org \)\sat\s(?P<year>\d+)-(?P<month>\d+)-(?P<day>\d+)\s(?P<hour>\d+):(?P<minute>\d+)\s(?P<timezone>\w+)" ) self.patterns["nmap"]["report"] = re.compile(r"Nmap\sscan\sreport\sfor\s(?P<ip>[^\s]+)") self.patterns["nmap"]["service"] = re.compile( r"(?P<port>[^\/]+)\/(?P<protocol>\w+)\s+(?P<state>\w+)\s+(?P<service>.+)" ) self.patterns["nmap"]["mac"] = re.compile(r"MAC\sAddress:\s+(?P<mac>[^\s]+)\s+\((?P<brand>[^\)]+)\)") def update(self): if self.ifconfigraw == None and self.mapping == False: self.mapping = True self.__ifconfig() self.mapping = False if not self.__loadNmapCache(): if self.myip != None and self.nmapraw == None and self.mapping == False: self.mapping = True self.nmapcommand[1] = self.__getBroadcast() self.__scanNetwork() self.__cacheNmap() self.mapping = False def __scanNetwork(self): result = False p = Popen(self.nmapcommand, stdout=PIPE) o = p.communicate()[0] if p.returncode == 0: result = True self.nmapraw = o res = self.__parseNmap() if res: self.notifier.addNotice("Nmap command complete") return result def __parseNmap(self): res = False if self.nmapraw != None: tmp = [] for l in self.nmapraw.split("\n"): match = self.patterns["nmap"]["report"].match(l) if match: tmp.append({"ip": match.group("ip"), "mac": "", "brand": "", "services": []}) match = self.patterns["nmap"]["service"].match(l) if match: tmp[len(tmp) - 1]["services"].append( { "port": match.group("port"), "protocol": match.group("protocol"), "state": match.group("state"), "service": match.group("service"), } ) match = self.patterns["nmap"]["mac"].match(l) if match: tmp[len(tmp) - 1]["mac"] = match.group("mac") tmp[len(tmp) - 1]["brand"] = match.group("brand") for t in tmp: self.nodes[t["ip"]] = t res = True return res def __parseDate(self, raw): date = None if raw != None and raw != "": linecount = 0 for l in raw.split("\n"): match = self.patterns["nmap"]["start"].match(l) if match: datestring = "{0}-{1}-{2} {3}:{4} {5}".format( match.group("year"), match.group("month"), match.group("day"), match.group("hour"), match.group("minute"), match.group("timezone"), ) tmpdate = datetime.datetime.strptime(datestring, "%Y-%m-%d %H:%M %Z") now = datetime.datetime.now() if tmpdate > now - datetime.timedelta(days=1): date = tmpdate break linecount += 1 if linecount >= 10: break return date def __cacheNmap(self): filepath = os.path.join(self.nmapcachepath, self.nmapcachefile) f = open(filepath, "w") f.write(self.nmapraw) f.close() def __loadNmapCache(self): if not os.path.exists(self.nmapcachepath): os.makedirs(self.nmapcachepath) return False filepath = os.path.join(self.nmapcachepath, self.nmapcachefile) if not os.path.exists(os.path.join(self.nmapcachepath, self.nmapcachefile)): return False if len(self.nodes) > 0: return False f = open(filepath, "r") data = f.read() f.close() date = self.__parseDate(data) if date: self.nmapraw = data parsed = self.__parseNmap() self.notifier.addNotice("Nmap cache loaded") return parsed return False def __ifconfig(self): result = False p = Popen(self.ifconfigcommand, stdout=PIPE) o = p.communicate()[0] if p.returncode == 0: result = True self.ifconfigraw = o res = self.__parseIfconfig() if res: self.notifier.addNotice("Ifconfig command complete") return result def __parseIfconfig(self): if self.ifconfigraw != None: for l in self.ifconfigraw.split("\n"): match = self.patterns["ifconfig"]["nic"].match(l) if match: self.nics.append({"name": match.group("name"), "ip": ""}) match = self.patterns["ifconfig"]["addr"].match(l) if match: self.nics[-1]["ip"] = match.group("ip") for n in self.nics: if n["name"] != "lo" and n["ip"] != "127.0.0.1": self.myip = n["ip"] break return True return False def __getBroadcast(self): ip = None if self.myip != None and self.myip != "127.0.0.1": parts = self.myip.split(".") if len(parts) == 4: ip = "{0}.{1}.{2}.{3}".format(parts[0], parts[1], parts[2], "0/24") return ip
class TkNotifier(TkBlock): def __init__(self, parent, gui, **options): """ Initializes TkNotifier object @param parent @param gui @param options """ super(TkNotifier,self).__init__(parent, gui, **options) self.now = lambda: int(round(time.time() * 1000)) self.displayed = [] self.firstrun = True self.notifier = Notifier(log=Setting.get('notifier_log', False)) self.notifier.setCallback(self.update) self.addNotifier() self.notifier.addNotice('Welcome to AllMyServos') self.gui.scheduler.addTask('notifier_cleanup', self.cleanup, 15) def addNotifier(self): """ view - notifier ui """ self.open() self.widgets['main'] = Tkinter.Frame(self.widget, bg=self.colours['bg'], borderwidth=0, highlightthickness=0) self.widgets['main'].grid(column=0,row=0,sticky='EW') self.widgets['main'].grid_columnconfigure(0, weight=1) self.widgets['frameLabel'] = Tkinter.Label(self.widgets['main'],text='Notifications', anchor=NW, bg=self.colours['bg'], fg=self.colours['headingfg']) self.widgets['frameLabel'].grid(column=0,row=self.gridrow,sticky='EW') self.variables['archive'] = Tkinter.BooleanVar() self.variables['archive'].set(Setting.get('notifier_archive', False)) self.widgets['archiveentry'] = Tkinter.Checkbutton(self.widgets['main'], text="Archive", variable=self.variables['archive'], command=self.OnToggleArchiveClick, bg=self.colours['inputbg'], fg=self.colours['inputfg'], activebackground=self.colours['activebg'], selectcolor=self.colours['inputbg']) self.widgets['archiveentry'].grid(column=1,row=self.gridrow,sticky='E') self.gridrow += 1 self.widgets['notices'] = Tkinter.Frame(self.widgets['main'], bg=self.colours['bg']) self.widgets['notices'].grid(column=0,row=self.gridrow,columnspan=2, sticky='EW') self.widgets['notices'].grid_columnconfigure(0, weight = 1) def update(self): """ callback to push notifications """ if(len(self.displayed) <= 20): n = self.notifier.getNotice() self.displayed.append(TkNotice(self.widgets['notices'], self.gui, n['time'], n['text'], n['type'], self.width)) def cleanup(self): """ remove notices after 10 seconds """ dlen = len(self.displayed) if(dlen > 0 and self.firstrun == False): removed = None try: if(self.displayed[0].time <= (self.now() - 10000)): self.displayed[0].remove() if(dlen == 1): self.displayed = [] else: self.displayed = self.displayed[1:] except: pass if(self.firstrun == True): self.firstrun = False def close(self): """ close the notifier """ self.widget.grid_forget() def OnToggleArchiveClick(self): """ action - toglle notification archive """ Setting.set('notifier_archive', self.variables['archive'].get())
class Camera(object): def __init__(self, scheduler=None, kbthread=None, notifier=None): """ Initializes the camera object @param scheduler @param kbthread @param notifier """ self.now = lambda: int(round(time.time() * 1000)) if (scheduler != None): self.scheduler = scheduler else: self.scheduler = Scheduler.GetInstance() self.kbthread = Keyboard.KeyboardThread.GetInstance() if (notifier != None): self.notifier = notifier else: self.notifier = Notifier() self.viewfinder = { 'enabled': False, 'visible': False, 'window': (0, 0, 320, 240), 'fullscreen': False, 'element': None } self.patterns = { 'nic': re.compile(r'(?P<name>[^\s]+).?'), 'addr': re.compile(r'\s*inet\saddr:(?P<ip>[^\s]+).*'), 'overscan': re.compile(r'[^#]?disable_overscan=(?P<overscan>\d+).*'), 'overscan_left': re.compile(r'[^#]?overscan_left=(?P<left>\d+)'), 'overscan_right': re.compile(r'[^#]?overscan_right=(?P<right>\d+)'), 'overscan_top': re.compile(r'[^#]?overscan_top=(?P<top>\d+)'), 'overscan_bottom': re.compile(r'[^#]?overscan_bottom=(?P<bottom>\d+)'), 'start_x': re.compile(r'[^#]?start_x=(?P<start_x>\d+)'), 'gpu_mem': re.compile(r'[^#]?gpu_mem=(?P<gpu_mem>\d+)'), } self.initProfile() self.initInfo() self.initKb() self.callbacks = {} self.scheduler.addTask('cam_watcher', self.check, interval=0.5, stopped=not Setting.get('cam_autostart', False)) def initProfile(self): """ Loads the current profile or sets up a default """ default_profile = Setting.get('cam_default_profile', '') if (default_profile == ''): self.cam_profile = CameraProfile() self.cam_profile.save() Setting.set('cam_default_profile', self.cam_profile.jbIndex) default_profile = self.cam_profile.jbIndex else: self.cam_profile = CameraProfile(default_profile) if (not self.cam_profile.blobExists()): self.cam_profile.save() def initInfo(self): """ Establishes information for the camera """ self.info = { 'cam_start': 0, 'streaming': { 'enabled': False, 'running': False, 'connected': False }, 'revision': 0, 'max_res': (0, 0), 'max_framerate': 0, 'still_res_modes': { '320x240': (320, 240), '640x480': (640, 480), '1024x768': (1024, 768), '1280x720': (1280, 720), '1440x900': (1440, 900), '1600x1200': (1600, 1200), '1920x1080': (1920, 1080), '2048x1536': (2048, 1536), '2560x1600': (2560, 1600), }, 'video_res_modes': { '320x240': (320, 240), '640x480': (640, 480), '1024x768': (1024, 768), '1280x720': (1280, 720), '1920x1080': (1920, 1080) }, 'fps_options': { '320x240': [15, 24, 30, 60, 90, 120], '640x480': [15, 24, 30, 60, 90], '1024x768': [15, 24, 30, 60], '1280x720': [15, 24, 30], '1920x1080': [15, 24, 30], }, 'exposure_modes': [ 'auto', 'night', 'nightpreview', 'backlight', 'spotlight', 'sports', 'snow', 'beach', 'verylong', 'fixedfps', 'antishake', 'fireworks', ], 'awb_modes': [ 'off', 'auto', 'sunlight', 'cloudy', 'shade', 'tungsten', 'fluorescent', 'incandescent', 'flash', 'horizon' ], 'effects': {}, 'sharpness_range': (-100, 100), 'contrast_range': (-100, 100), 'brightness_range': (0, 100), 'saturation_range': (-100, 100), 'zoom_range': (0, 1), 'awb_range': (0.0, 8.0), 'iso_range': [ 'Auto', '100', '200', '300', '400', '500', '600', '700', '800', ], 'rotations': [0, 90, 180, 270], 'formats': { 'video': { 'h264': 'h264', 'mjpeg': 'mjpg' }, 'still': { 'jpeg': 'jpg', 'png': 'png', 'gif': 'gif', 'bmp': 'bmp' } }, 'file_path': os.path.join(AmsEnvironment.FilePath(), 'camera'), 'overscan': { 'enabled': False, 'size': [48, 48, 48, 48] }, 'cam_config': { 'start_x': False, 'gpu_mem': 0, 'hardware': False } } camConfig = self.__getCamConfig() if ('overscan' in camConfig.keys()): self.info['overscan'] = camConfig['overscan'] if ('cam_config' in camConfig.keys()): self.info['cam_config'] = camConfig['cam_config'] if (self.info['cam_config']['start_x']): try: if (not hasattr(self, 'cam')): self.cam = PiCamera() self.info['cam_config']['hardware'] = True except: self.info['cam_config']['hardware'] = False if (self.info['cam_config']['hardware']): self.info['max_res'] = self.cam.MAX_RESOLUTION if (hasattr( self.cam, 'MAX_RESOLUTION')) else (0, 0) if (self.info['max_res'][0] == 2592): self.info['revision'] = 1 elif (self.info['max_res'][0] == 3280): self.info['revision'] = 2 self.info['max_framerate'] = self.cam.MAX_FRAMERATE if ( hasattr(self.cam, 'MAX_FRAMERATE')) else 0 self.info['exposure_modes'] = self.cam.EXPOSURE_MODES if ( hasattr(self.cam, 'EXPOSURE_MODES')) else {} self.info['effects'] = self.cam.IMAGE_EFFECTS if (hasattr( self.cam, 'IMAGE_EFFECTS')) else {} self.cam.close() def initKb(self): """ Initializes hex for keyboard events """ self.kbmap = { '0x43': self.toggleService, '0x3c': self.setStillMode, '0x3e': self.setVideoMode, '0x53': self.toggleStream, '0x20': self.toggleCapture } self.kbthread.addCallback('camera', self.camKb) def isAvailable(self): """ Confirms camera is enabled in raspi-config and the hardware was detected """ return (self.info['cam_config']['start_x'] and self.info['cam_config']['gpu_mem'] >= 128 and self.info['cam_config']['hardware']) def isRunning(self): """ True if either prviewing or recording @return bool """ return hasattr(self, 'cam') and (self.cam.previewing or self.cam.recording) def isPreviewing(self): """ True if previewing @return bool """ return hasattr(self, 'cam') and self.cam.previewing def isRecording(self): """ True if recording @return bool """ return hasattr(self, 'cam') and self.cam.recording def isStreaming(self): """ True if streaming @return bool """ return self.info['streaming']['running'] def isServiceRunning(self): """ True if camera service is running @return bool """ return self.scheduler.isRunning('cam_watcher') def start(self): """ Starts the camera service """ if (not self.isServiceRunning()): self.scheduler.startTask('cam_watcher') self.notifier.addNotice('Camera service started') def stop(self): """ Stops the camera service """ if (self.isServiceRunning()): self.scheduler.stopTask('cam_watcher') self.stopStream() self.check() self.notifier.addNotice('Camera service stopped') def toggleService(self): """ Toggle service Used for the keyboard so one key can start and stop service """ if (self.isServiceRunning()): self.stop() else: self.start() def setStillMode(self): """ Activates still capture mode """ self.cam_profile.jsonData['rec_mode'] = 'still' self.check() def setVideoMode(self): """ Activates video capture mode """ self.cam_profile.jsonData['rec_mode'] = 'video' self.check() def startCam(self, profile=None): """ Starts the camera hardware """ if (profile == None): if (hasattr(self, 'timelapse')): profile = self.timelapse.getCamProfile( ) #take timelapse profile if (profile == None): profile = self.cam_profile #take default profile if (hasattr(self, 'cam_profile')): self.cam = PiCamera(resolution=profile.getResolution(), framerate=profile.jsonData['fps']) else: self.cam = PiCamera() self.updateProfile(profile) self.info['cam_start'] = self.now() def stopCam(self): """ Stops the camera hardware """ if (not self.cam.closed): self.cam.close() self.info['cam_start'] = 0 def stopPreview(self): """ Stops the camera preview """ if (self.isPreviewing()): self.cam.stop_preview() def updateProfile(self, profile=None): """ Applies camera profile settings """ if (profile == None): profile = self.cam_profile.jsonData else: profile = profile.jsonData if (hasattr(self, 'cam') and profile != None): self.cam.led = profile['led'] self.cam.hflip = profile['fliph'] self.cam.vflip = profile['flipv'] self.cam.sharpness = int(profile['sharpness']) self.cam.contrast = int(profile['contrast']) self.cam.brightness = int(profile['brightness']) self.cam.saturation = int(profile['saturation']) self.cam.iso = int(profile['iso']) self.cam.rotation = int(profile['rotation']) self.cam.image_effect = profile['image_effect'] self.cam.exposure_mode = profile['exposure_mode'] self.cam.awb_mode = profile['awb_mode'] self.cam.awb_gains = (float(profile['awb_gains'][0]), float(profile['awb_gains'][1])) self.cam.video_stabilization = profile['video_stabilization'] self.cam.zoom = profile['zoom'] def toggleCapture(self): """ Captures a still or starts / stops video recording """ if (self.isServiceRunning()): if (self.cam_profile.getRecMode() == 'video'): if (not self.isRecording()): self.capture() else: self.stopCapture() else: self.capture() def capture(self, profile=None): """ Captures still / video based on the provided profile (or camera default) @param profile @return dict """ res = { 'captured': False, 'rec_mode': 'still', 'path': '', 'filename': '' } if (not self.cam.closed): if (profile == None): profile = self.cam_profile recmode = profile.getRecMode() currentPath = os.path.join(self.info['file_path'], recmode) currentPath = '{}/{}'.format(currentPath, datetime.date.today()) if (not os.path.exists(currentPath)): os.makedirs(currentPath) #setup directories res['rec_mode'] = recmode res['path'] = currentPath res['filename'] = filename = '{}-{}.{}'.format( 'Image' if recmode == 'still' else 'Clip', self.now(), self.info['formats'][recmode][profile.getFormat()]) if (recmode == 'still'): self.cam.capture(os.path.join(currentPath, filename)) res['captured'] = True else: self.cam.start_recording(os.path.join(currentPath, filename)) res['captured'] = True return res def stopCapture(self, profile=None): """ Stops video capture """ if (profile == None): profile = self.cam_profile if (profile.getRecMode() == 'video' and self.isRecording()): self.cam.stop_recording() return True return False def enableStream(self): """ Enables streaming """ self.info['streaming']['enabled'] = True self.notifier.addNotice('Stream enabled') def disableStream(self): """ Disables streaming """ self.info['streaming']['enabled'] = False self.notifier.addNotice('Stream disabled') def toggleStream(self): """ Enables / disables streaming """ if (not self.isRecording()): if (not self.isStreaming()): self.enableStream() else: self.disableStream() def startStream(self): """ Starts the stream """ self.info['streaming']['running'] = True self.server_socket = socket.socket() self.server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.server_socket.settimeout(0.8) self.server_socket.bind(('0.0.0.0', 8000)) self.server_socket.listen(0) def openStream(self): """ Attempts to open stream connection """ try: attempt = self.server_socket.accept() self.connection = attempt[0].makefile('wb') self.cam.start_recording(self.connection, format='h264') self.info['streaming']['connected'] = True self.notifier.addNotice('Stream connection established') except: self.info['streaming']['connected'] = False def stopStream(self): """ Stops the stream """ if (self.isStreaming()): try: self.cam.stop_recording( ) #stop recording trows an error if stream is stopped remotely except: pass try: if (hasattr(self, 'connection')): self.connection.close() except socket.error, e: if isinstance(e.args, tuple): if e[0] == errno.EPIPE: #could use notifier here to state connection was remotely closed pass self.server_socket.close() self.info['streaming']['enabled'] = False self.info['streaming']['running'] = False self.info['streaming']['connected'] = False
def notifier(db): notifier = Notifier.Notifier(db) return notifier
class Network(object): def __init__(self, scheduler=None): """ Initializes a Network object @param scheduler """ if (scheduler != None): self.scheduler = scheduler else: self.scheduler = Scheduler.GetInstance() self.patterns = {} self.nodes = {} self.__initPatterns() self.nmapcachepath = os.path.join(Specification.Specification.filebase, 'network') self.nmapcachefile = 'nmap_cache.txt' self.nmapcommand = ['nmap', '192.168.0.0/24'] self.ifconfigcommand = ['ifconfig'] self.nics = [] self.myip = None self.ifconfigraw = None self.nmapraw = None self.mapping = False self.notifier = Notifier() self.scheduler.addTask('network_mapper', self.update, 30) def __initPatterns(self): """ initialize regex patterns """ self.patterns['ifconfig'] = {} self.patterns['ifconfig']['nic'] = re.compile(r'(?P<name>[^\s]+).?') self.patterns['ifconfig']['addr'] = re.compile( r'\s*inet\saddr:(?P<ip>[^\s]+).*') self.patterns['nmap'] = {} self.patterns['nmap']['start'] = re.compile( r'Starting\sNmap\s(?P<version>[^\s]+)\s\( http:\/\/nmap.org \)\sat\s(?P<year>\d+)-(?P<month>\d+)-(?P<day>\d+)\s(?P<hour>\d+):(?P<minute>\d+)\s(?P<timezone>\w+)' ) self.patterns['nmap']['report'] = re.compile( r'Nmap\sscan\sreport\sfor\s(?P<ip>[^\s]+)') self.patterns['nmap']['service'] = re.compile( r'(?P<port>[^\/]+)\/(?P<protocol>\w+)\s+(?P<state>\w+)\s+(?P<service>.+)' ) self.patterns['nmap']['mac'] = re.compile( r'MAC\sAddress:\s+(?P<mac>[^\s]+)\s+\((?P<brand>[^\)]+)\)') def update(self): """ collect network information """ if (self.ifconfigraw == None and self.mapping == False): self.mapping = True self.__ifconfig() self.mapping = False if (not self.__loadNmapCache()): if (self.myip != None and self.nmapraw == None and self.mapping == False): self.mapping = True self.nmapcommand[1] = self.__getBroadcast() self.__scanNetwork() self.__cacheNmap() self.mapping = False def __scanNetwork(self): """ discover IP addresses on local network @return bool """ result = False p = Popen(self.nmapcommand, stdout=PIPE) o = p.communicate()[0] if (p.returncode == 0): result = True self.nmapraw = o res = self.__parseNmap() if (res): self.notifier.addNotice('Nmap command complete') return result def __parseNmap(self): """ parse nmap result @return bool """ res = False if (self.nmapraw != None): tmp = [] for l in self.nmapraw.split('\n'): match = self.patterns['nmap']['report'].match(l) if (match): tmp.append({ 'ip': match.group('ip'), 'mac': '', 'brand': '', 'services': [] }) match = self.patterns['nmap']['service'].match(l) if (match): tmp[len(tmp) - 1]['services'].append({ 'port': match.group('port'), 'protocol': match.group('protocol'), 'state': match.group('state'), 'service': match.group('service') }) match = self.patterns['nmap']['mac'].match(l) if (match): tmp[len(tmp) - 1]['mac'] = match.group('mac') tmp[len(tmp) - 1]['brand'] = match.group('brand') for t in tmp: self.nodes[t['ip']] = t res = True return res def __parseDate(self, raw): """ convert date string to datetime.datetime @param raw str @return datetime.datetime """ date = None if (raw != None and raw != ''): linecount = 0 for l in raw.split('\n'): match = self.patterns['nmap']['start'].match(l) if (match): datestring = '{0}-{1}-{2} {3}:{4} {5}'.format( match.group('year'), match.group('month'), match.group('day'), match.group('hour'), match.group('minute'), match.group('timezone')) tmpdate = datetime.datetime.strptime( datestring, '%Y-%m-%d %H:%M %Z') now = datetime.datetime.now() if (tmpdate > now - datetime.timedelta(days=1)): date = tmpdate break linecount += 1 if (linecount >= 10): break return date def __cacheNmap(self): """ save nmap cache """ filepath = os.path.join(self.nmapcachepath, self.nmapcachefile) f = open(filepath, 'w') f.write(self.nmapraw) f.close() def __loadNmapCache(self): """ load nmap cache @return dict """ if not os.path.exists(self.nmapcachepath): os.makedirs(self.nmapcachepath) return False filepath = os.path.join(self.nmapcachepath, self.nmapcachefile) if not os.path.exists( os.path.join(self.nmapcachepath, self.nmapcachefile)): return False if len(self.nodes) > 0: return False f = open(filepath, 'r') data = f.read() f.close() date = self.__parseDate(data) if (date): self.nmapraw = data parsed = self.__parseNmap() self.notifier.addNotice('Nmap cache loaded') return parsed return False def __ifconfig(self): """ perform ifconfig @return str """ result = False p = Popen(self.ifconfigcommand, stdout=PIPE) o = p.communicate()[0] if (p.returncode == 0): result = True self.ifconfigraw = o res = self.__parseIfconfig() if (res): self.notifier.addNotice('Ifconfig command complete') return result def __parseIfconfig(self): """ parse ifconfig result @return bool """ if (self.ifconfigraw != None): for l in self.ifconfigraw.split('\n'): match = self.patterns['ifconfig']['nic'].match(l) if (match): self.nics.append({'name': match.group('name'), 'ip': ''}) match = self.patterns['ifconfig']['addr'].match(l) if (match): self.nics[-1]['ip'] = match.group('ip') for n in self.nics: if (n['name'] != 'lo' and n['ip'] != '127.0.0.1'): self.myip = n['ip'] break return True return False def __getBroadcast(self): """ get network specific broadcast address @return str """ ip = None if (self.myip != None and self.myip != '127.0.0.1'): parts = self.myip.split('.') if (len(parts) == 4): ip = '{0}.{1}.{2}.{3}'.format(parts[0], parts[1], parts[2], '0/24') return ip
def initLogger(pLogger): # redirect logging to parent as it doesn't work in nested threads global _logger _logger = pLogger Notifier.initLogger(_logger) RetryMaker.initLogger(_logger)
class TkDependencyManager(object): def __init__(self, parent, dependencies, module, gui): """ Initializes the TkDependencyManager object example values for dependencies: single dependency: { 'package': 'nmap', 'installer': 'apt-get' } multi dependency: [{ 'package': 'tk8.5-dev', 'installer': 'apt-get' }, { 'package': 'pillow', 'installer': 'pip', 'version': 'latest' }] @param parent Frame @param dependencies dict or list of dicts @param module: the name of the module which initialized the package manager @param gui reference to the GUI object """ self.widgets = {} self.variables = {} if(isinstance(dependencies, dict)): self.dependencies = [dependencies] elif(isinstance(dependencies, list)): self.dependencies = dependencies else: self.dependencies = dependencies self.module = module self.gui = gui self.notifier = Notifier() self.aptGet = { 'install': ['sudo','apt-get','-q','-y','install'], 'remove': ['sudo','apt-get','-q','-y','remove'] } self.pip = { 'install': ['sudo', 'pip','-q', 'install'], 'remove': ['sudo', 'pip','-q', 'uninstall'] } self.loadCache() self.colours = self.gui.colours self.images = self.gui.images self.fonts = self.gui.fonts self.widget = Frame(parent,bg=self.colours['bg'], borderwidth=0, highlightthickness=0) self.widget.grid(column=0,row=0,sticky='EW') def addManager(self): """ called by requesting module if install / upgrade is required """ self.gridrow = 0 self.checkDependencies() #=== VIEWS ===# def checkDependencies(self): """ view - displays the result of the dependency checks """ self.open() self.widgets['tlabel'] = Tkinter.Label(self.widgets['tframe'],text='Dependencies / Installation', anchor=W, bg=self.colours['bg'], fg=self.colours['headingfg'], font=self.fonts['heading']) self.widgets['tlabel'].grid(column=0,row=self.gridrow, columnspan=2,sticky='EW') self.gridrow += 1 self.widgets['moduleLabel'] = Tkinter.Label(self.widgets['tframe'],text='Module', bg=self.colours['bg'], fg=self.colours['headingfg'], height=2) self.widgets['moduleLabel'].grid(column=0,row=self.gridrow,sticky='EW') self.widgets['moduleData'] = Tkinter.Label(self.widgets['tframe'],text=self.module, anchor='w', bg=self.colours['bg'], fg=self.colours['valuefg'], height=2) self.widgets['moduleData'].grid(column=1,row=self.gridrow,sticky='EW') self.gridrow += 1 self.widgets['dependencyLabel'] = Tkinter.Label(self.widgets['tframe'],text='Dependencies', bg=self.colours['bg'], fg=self.colours['headingfg'], height=2) self.widgets['dependencyLabel'].grid(column=0,row=self.gridrow,sticky='N') i = 0 for d in self.dependencies: self.widgets['pframe'+str(i)] = Tkinter.Frame(self.widgets['tframe'], bg=self.colours['rowaltbg']) self.widgets['pframe'+str(i)].grid(column=1,row=self.gridrow, pady=10, sticky='EW') self.widgets['name{0}'.format(i)] = Tkinter.Label(self.widgets['pframe'+str(i)],text=d['package'], bg=self.colours['rowbg'], fg=self.colours['headingfg'], height=2) self.widgets['name{0}'.format(i)].grid(column=0,row=0, ipadx=15,sticky='EW') self.widgets['installerLabel{0}'.format(i)] = Tkinter.Label(self.widgets['pframe'+str(i)],text='Installer', bg=self.colours['rowbg'], fg=self.colours['headingfg'], height=2) self.widgets['installerLabel{0}'.format(i)].grid(column=1,row=0,ipadx=5,sticky='EW') self.widgets['installer{0}'.format(i)] = Tkinter.Label(self.widgets['pframe'+str(i)],text=d['installer'], bg=self.colours['rowaltbg'], fg=self.colours['valuefg'], height=2) self.widgets['installer{0}'.format(i)].grid(column=2,row=0,ipadx=5,sticky='W') self.widgets['installLabel{0}'.format(i)] = Tkinter.Label(self.widgets['pframe'+str(i)],text='Install Command', bg=self.colours['rowbg'], fg=self.colours['headingfg'], height=2) self.widgets['installLabel{0}'.format(i)].grid(column=1,row=1,ipadx=5,sticky='EW') self.widgets['i{0}'.format(i)] = Tkinter.Label(self.widgets['pframe'+str(i)],text=d['icom'], bg=self.colours['rowaltbg'], fg=self.colours['valuefg'], height=1) self.widgets['i{0}'.format(i)].grid(column=2,row=1,ipadx=5,sticky='W') self.widgets['removeLabel{0}'.format(i)] = Tkinter.Label(self.widgets['pframe'+str(i)],text='Uninstall Command', bg=self.colours['rowbg'], fg=self.colours['headingfg'], height=2) self.widgets['removeLabel{0}'.format(i)].grid(column=1,row=2,ipadx=5,sticky='EW') self.widgets['r{0}'.format(i)] = Tkinter.Label(self.widgets['pframe'+str(i)],text=d['rcom'], bg=self.colours['rowaltbg'], fg=self.colours['valuefg'], height=1) self.widgets['r{0}'.format(i)].grid(column=2,row=2,ipadx=5,sticky='W') status = 'installed' if(d['status']==0): status = 'not installed' elif(d['status']==1): status = 'upgrade required' self.widgets['statusLabel{0}'.format(i)] = Tkinter.Label(self.widgets['pframe'+str(i)],text='Status', bg=self.colours['rowbg'], fg=self.colours['headingfg'], height=2) self.widgets['statusLabel{0}'.format(i)].grid(column=1,row=3,ipadx=5,sticky='EW') self.widgets['installed{0}'.format(i)] = Tkinter.Label(self.widgets['pframe'+str(i)],text=status, bg=self.colours['rowaltbg'], fg=self.colours['valuefg'], height=2) self.widgets['installed{0}'.format(i)].grid(column=2,row=3,ipadx=5,sticky='W') i+=1 self.gridrow += 1 self.widgets['optionsFrame'] = Tkinter.Frame(self.widgets['tframe'], bg=self.colours['bg']) self.widgets['optionsFrame'].grid(column=0,row=self.gridrow,columnspan=2, sticky='EW') self.gridrow = 0 self.widgets['installLabel'] = Tkinter.Label(self.widgets['optionsFrame'],text='Install', bg=self.colours['bg'], fg=self.colours['fg'], height=2) self.widgets['installLabel'].grid(column=0,row=self.gridrow,sticky='EW') self.gridrow += 1 self.widgets['install'] = Tkinter.Button(self.widgets['optionsFrame'],text=u"Install", image=self.images['accept'], command=self.OnInstallClick, bg=self.colours['buttonbg'], activebackground=self.colours['buttonhighlightbg'], highlightbackground=self.colours['buttonborder']) self.widgets['install'].grid(column=0,row=self.gridrow) def success(self): """ view - displays in the event of a successful installation """ self.open() self.widgets['tlabel'] = Tkinter.Label(self.widgets['tframe'],text='Dependencies / Installation / Success', anchor=NW, bg=self.colours['bg'], fg=self.colours['headingfg'], font=self.fonts['heading']) self.widgets['tlabel'].grid(column=0,row=self.gridrow,columnspan=2,sticky='EW') self.gridrow += 1 self.widgets['moduleLabel'] = Tkinter.Label(self.widgets['tframe'],text='Module', bg=self.colours['bg'], fg=self.colours['headingfg'], height=2) self.widgets['moduleLabel'].grid(column=0,row=self.gridrow,sticky='EW') self.widgets['moduleData'] = Tkinter.Label(self.widgets['tframe'],text=self.module, anchor='w', bg=self.colours['bg'], fg=self.colours['valuefg'], height=2) self.widgets['moduleData'].grid(column=1,row=self.gridrow, ipadx=15, sticky='EW') self.gridrow += 1 self.widgets['dependencyLabel'] = Tkinter.Label(self.widgets['tframe'],text='Dependencies', bg=self.colours['bg'], fg=self.colours['headingfg'], height=2) self.widgets['dependencyLabel'].grid(column=0,row=self.gridrow,sticky='N') i = 0 for d in self.dependencies: self.widgets['pframe'+str(i)] = Tkinter.Frame(self.widgets['tframe'], bg=self.colours['rowaltbg']) self.widgets['pframe'+str(i)].grid(column=1,row=self.gridrow, pady=10, sticky='EW') self.widgets['name{0}'.format(i)] = Tkinter.Label(self.widgets['pframe'+str(i)],text=d['package'], bg=self.colours['rowbg'], fg=self.colours['headingfg'], height=2) self.widgets['name{0}'.format(i)].grid(column=0,row=0, ipadx=15,sticky='EW') self.widgets['installerLabel{0}'.format(i)] = Tkinter.Label(self.widgets['pframe'+str(i)],text='Installer', bg=self.colours['rowbg'], fg=self.colours['headingfg'], height=2) self.widgets['installerLabel{0}'.format(i)].grid(column=1,row=0,ipadx=5,sticky='EW') self.widgets['installer{0}'.format(i)] = Tkinter.Label(self.widgets['pframe'+str(i)],text=d['installer'], bg=self.colours['rowaltbg'], fg=self.colours['valuefg'], height=2) self.widgets['installer{0}'.format(i)].grid(column=2,row=0,ipadx=5,sticky='W') self.widgets['installLabel{0}'.format(i)] = Tkinter.Label(self.widgets['pframe'+str(i)],text='Install Command', bg=self.colours['rowbg'], fg=self.colours['headingfg'], height=2) self.widgets['installLabel{0}'.format(i)].grid(column=1,row=1,ipadx=5,sticky='EW') self.widgets['i{0}'.format(i)] = Tkinter.Label(self.widgets['pframe'+str(i)],text=d['icom'], bg=self.colours['rowaltbg'], fg=self.colours['valuefg'], height=1) self.widgets['i{0}'.format(i)].grid(column=2,row=1,ipadx=5,sticky='W') self.widgets['removeLabel{0}'.format(i)] = Tkinter.Label(self.widgets['pframe'+str(i)],text='Uninstall Command', bg=self.colours['rowbg'], fg=self.colours['headingfg'], height=2) self.widgets['removeLabel{0}'.format(i)].grid(column=1,row=2,ipadx=5,sticky='EW') self.widgets['r{0}'.format(i)] = Tkinter.Label(self.widgets['pframe'+str(i)],text=d['rcom'], bg=self.colours['rowaltbg'], fg=self.colours['valuefg'], height=1) self.widgets['r{0}'.format(i)].grid(column=2,row=2,ipadx=5,sticky='W') status = 'installed' if(d['status']==0): status = 'not installed' elif(d['status']==1): status = 'upgrade required' self.widgets['statusLabel{0}'.format(i)] = Tkinter.Label(self.widgets['pframe'+str(i)],text='Status', bg=self.colours['rowbg'], fg=self.colours['headingfg'], height=2) self.widgets['statusLabel{0}'.format(i)].grid(column=1,row=3,ipadx=5,sticky='EW') self.widgets['installed{0}'.format(i)] = Tkinter.Label(self.widgets['pframe'+str(i)],text=status, bg=self.colours['rowaltbg'], fg=self.colours['valuefg'], height=2) self.widgets['installed{0}'.format(i)].grid(column=2,row=3,ipadx=5,sticky='W') i+=1 self.gridrow += 1 self.widgets['info'] = Tkinter.Label(self.widgets['tframe'],text='All dependencies were installed successfully.', bg=self.colours['bg'], fg=self.colours['fg'], height=3) self.widgets['info'].grid(column=0,row=self.gridrow, columnspan = 2, sticky='EW') self.gridrow += 1 self.widgets['info'] = Tkinter.Label(self.widgets['tframe'],text='Restart the interface and reopen the {0} module.'.format(self.module), bg=self.colours['bg'], fg=self.colours['headingfg'], height=3) self.widgets['info'].grid(column=0,row=self.gridrow, columnspan = 2, sticky='EW') def failure(self): """ view - displays in the event of an unsuccessful installation """ self.open() self.widgets['tlabel'] = Tkinter.Label(self.widgets['tframe'],text='Dependencies / Installation / Failure', anchor=NW, bg=self.colours['bg'], fg=self.colours['headingfg'], font=self.fonts['heading']) self.widgets['tlabel'].grid(column=0,row=self.gridrow,columnspan=2,sticky='EW') self.gridrow += 1 self.widgets['moduleLabel'] = Tkinter.Label(self.widgets['tframe'],text='Module', bg=self.colours['bg'], fg=self.colours['headingfg'], height=2) self.widgets['moduleLabel'].grid(column=0,row=self.gridrow,sticky='EW') self.widgets['moduleData'] = Tkinter.Label(self.widgets['tframe'],text=self.module, anchor='nw', bg=self.colours['bg'], fg=self.colours['valuefg'], height=2) self.widgets['moduleData'].grid(column=1,row=self.gridrow,sticky='EW') self.gridrow += 1 self.widgets['dependencyLabel'] = Tkinter.Label(self.widgets['tframe'],text='Dependencies', bg=self.colours['bg'], fg=self.colours['headingfg'], height=2) self.widgets['dependencyLabel'].grid(column=0,row=self.gridrow,sticky='N') i = 0 for d in self.dependencies: self.widgets['pframe'+str(i)] = Tkinter.Frame(self.widgets['tframe'], bg=self.colours['rowaltbg']) self.widgets['pframe'+str(i)].grid(column=1,row=self.gridrow, pady=10, sticky='EW') self.widgets['name{0}'.format(i)] = Tkinter.Label(self.widgets['pframe'+str(i)],text=d['package'], bg=self.colours['rowbg'], fg=self.colours['headingfg'], height=2) self.widgets['name{0}'.format(i)].grid(column=0,row=0, ipadx=15,sticky='EW') self.widgets['installerLabel{0}'.format(i)] = Tkinter.Label(self.widgets['pframe'+str(i)],text='Installer', bg=self.colours['rowbg'], fg=self.colours['headingfg'], height=2) self.widgets['installerLabel{0}'.format(i)].grid(column=1,row=0,ipadx=5,sticky='EW') self.widgets['installer{0}'.format(i)] = Tkinter.Label(self.widgets['pframe'+str(i)],text=d['installer'], bg=self.colours['rowaltbg'], fg=self.colours['valuefg'], height=2) self.widgets['installer{0}'.format(i)].grid(column=2,row=0,ipadx=5,sticky='W') self.widgets['installLabel{0}'.format(i)] = Tkinter.Label(self.widgets['pframe'+str(i)],text='Install Command', bg=self.colours['rowbg'], fg=self.colours['headingfg'], height=2) self.widgets['installLabel{0}'.format(i)].grid(column=1,row=1,ipadx=5,sticky='EW') self.widgets['i{0}'.format(i)] = Tkinter.Label(self.widgets['pframe'+str(i)],text=d['icom'], bg=self.colours['rowaltbg'], fg=self.colours['valuefg'], height=1) self.widgets['i{0}'.format(i)].grid(column=2,row=1,ipadx=5,sticky='W') self.widgets['removeLabel{0}'.format(i)] = Tkinter.Label(self.widgets['pframe'+str(i)],text='Uninstall Command', bg=self.colours['rowbg'], fg=self.colours['headingfg'], height=2) self.widgets['removeLabel{0}'.format(i)].grid(column=1,row=2,ipadx=5,sticky='EW') self.widgets['r{0}'.format(i)] = Tkinter.Label(self.widgets['pframe'+str(i)],text=d['rcom'], bg=self.colours['rowaltbg'], fg=self.colours['valuefg'], height=1) self.widgets['r{0}'.format(i)].grid(column=2,row=2,ipadx=5,sticky='W') status = 'installed' if(d['status']==0): status = 'not installed' elif(d['status']==1): status = 'upgrade required' self.widgets['statusLabel{0}'.format(i)] = Tkinter.Label(self.widgets['pframe'+str(i)],text='Status', bg=self.colours['rowbg'], fg=self.colours['headingfg'], height=2) self.widgets['statusLabel{0}'.format(i)].grid(column=1,row=3,ipadx=5,sticky='EW') self.widgets['installed{0}'.format(i)] = Tkinter.Label(self.widgets['pframe'+str(i)],text=status, bg=self.colours['rowaltbg'], fg=self.colours['valuefg'], height=2) self.widgets['installed{0}'.format(i)].grid(column=2,row=3,ipadx=5,sticky='W') i+=1 self.gridrow += 1 self.widgets['info'] = Tkinter.Label(self.widgets['tframe'],text='One or more dependencies failed to install.', bg=self.colours['bg'], fg=self.colours['fg'], height=3) self.widgets['info'].grid(column=0,row=self.gridrow, columnspan = 2, sticky='EW') self.gridrow += 1 self.widgets['info'] = Tkinter.Label(self.widgets['tframe'],text='Please restart the interface and try again.', bg=self.colours['bg'], fg=self.colours['headingfg'], height=3) self.widgets['info'].grid(column=0,row=self.gridrow, columnspan = 2, sticky='EW') #=== ACTIONS ===# def OnInstallClick(self): """ action - performs installation """ self.close() fails = [] for k, v in enumerate(self.dependencies): if(not self.isInstalled(v)): if(self.__installDependency(v)): self.dependencies[k]['status'] = 2 self.notifier.addNotice('{0} installation complete'.format(v['package'])) else: self.dependencies[k]['status'] = 0 self.notifier.addNotice('{0} installation failed'.format(v['package']), 'error') fails.append(v) else: self.dependencies[k]['status'] = 2 if(any(fails)): self.failure() else: self.success() #=== UTILS ===# def loadCache(self): """ initialises the dependency cache either with stored data or an empty dict """ self.cache = {} self.cachepath = os.path.join(AmsEnvironment.FilePath(), 'Dependencies') self.cachefile = os.path.join(self.cachepath, '{}-cache.json'.format(self.__safeName())) if os.path.isfile(self.cachefile): try: f = open(self.cachefile, 'r') contents = f.read() f.close() self.cache = json.loads(contents) except: pass def installRequired(self): """ returns a bool indicating whether or not any dependencies require installation @return bool """ if('required' in self.cache.keys()): if(not self.cache['required']): return False #only use cached result if installation is not required required = False for d in self.dependencies: try: if(d['status'] != 2): required = True except: d['status'] = self.isInstalled(d) if(d['status'] != 2): required = True self.cache = { 'dependencies': self.dependencies, 'required': required } if not os.path.exists(self.cachepath): os.makedirs(self.cachepath) f = open(self.cachefile, 'w') f.write(json.dumps(self.cache)) f.close() return required def isInstalled(self, dependency): """ returns status: 0 = not installed, 1 = upgrade required, 2 = installed @param dependency @return int """ status = 0 if(dependency['installer'] == 'apt-get'): if(len(dependency['package']) > 0): dependency['icom'] = copy(self.aptGet['install']) #install command dependency['icom'].append(dependency['package']) dependency['rcom'] = copy(self.aptGet['remove']) #remove command dependency['rcom'].append(dependency['package']) p = Popen(['dpkg','-s',dependency['package']], stdout=PIPE, stderr=PIPE) o = p.communicate()[0] if(p.returncode == 0): o = o.split('\n') pattern = re.compile(r'Status\:\s?(?P<status>.+)') for l in o: if(pattern.match(l)): status = 2 break elif(dependency['installer'] == 'pip'): if(len(dependency['package']) > 0): dependency['icom'] = copy(self.pip['install']) dependency['icom'].append(dependency['package']) dependency['rcom'] = copy(self.pip['remove']) dependency['rcom'].append(dependency['package']) p = Popen(['pip','search',dependency['package']], stdout=PIPE) o = p.communicate()[0] if(p.returncode == 0): o = o.split('\n') pattern = re.compile(r'(?P<package>[^\s]+)\s+-\s+(?P<description>.+)') installedpattern = re.compile(r'.*installed:\s+(?P<version>.*)',re.IGNORECASE) packagematch = -1 line = 0 for l in o: matches = pattern.match(l) if(matches): if(matches.group('package').lower() == dependency['package'].lower()): packagematch = line matches = installedpattern.match(l) if(matches and packagematch == line-1): v = matches.group('version') dv = str(dependency['version']) num = v.split(' ')[0] if(dv == 'latest' and 'latest' in v): status = 2 elif(dv != 'latest' and StrictVersion(dv) <= StrictVersion(num)): status = 2 else: status = 1 dependency['icom'].append('--upgrade') break line += 1 return status def __installDependency(self, dependency): """ installs required package via apt-get or pip @param dependency @return bool """ if(dependency['installer'] == 'apt-get'): return self.__installAptGetDependency(dependency) elif(dependency['installer'] == 'pip'): return self.__installPipDependency(dependency) def __installAptGetDependency(self, dependency): """ installs an apt-get dependency @param dependency @return bool """ installed = False try: if(len(dependency['package']) > 0): command = copy(self.aptGet['install']) command.append(dependency['package']) p = Popen(command, stdout=PIPE) o = p.communicate()[0] if(p.returncode == 0): installed = True except: pass return installed def __installPipDependency(self, dependency): """ installs a pip dependency @param dependency @return bool """ installed = False try: if(len(dependency['package']) > 0): command = copy(self.pip['install']) command.append(dependency['package']) try: if(dependency['status'] == 1): command.append('--upgrade') except: pass p = Popen(command, stdout=PIPE) o = p.communicate()[0] if(p.returncode == 0): installed = True except: pass return installed def __safeName(self): """ removes spaces from the module name @return str """ return self.module.replace(' ', '') def open(self): """ displays the dependency manager """ for k, v in self.widgets.iteritems(): v.grid_forget() self.widgets = {} self.widget.grid(column=0,row=0) self.gridrow = 0 self.widgets['tframe'] = Frame(self.widget,bg=self.colours['bg']) self.widgets['tframe'].grid(column=0,row=0,sticky='EW') def close(self): """ removes the dependency manager """ self.widget.grid_forget()
def run(self): try: _logger.debug('%s Start %s' % (self.pandaID,self.job.jobStatus)) flagComplete = True topUserDsList = [] usingMerger = False disableNotifier = False firstIndvDS = True finalStatusDS = [] for destinationDBlock in self.destinationDBlocks: dsList = [] _logger.debug('%s start %s' % (self.pandaID,destinationDBlock)) # ignore tid datasets if re.search('_tid[\d_]+$',destinationDBlock): _logger.debug('%s skip %s' % (self.pandaID,destinationDBlock)) continue # ignore HC datasets if re.search('^hc_test\.',destinationDBlock) != None or re.search('^user\.gangarbt\.',destinationDBlock) != None: if re.search('_sub\d+$',destinationDBlock) == None and re.search('\.lib$',destinationDBlock) == None: _logger.debug('%s skip HC %s' % (self.pandaID,destinationDBlock)) continue # query dataset if self.datasetMap.has_key(destinationDBlock): dataset = self.datasetMap[destinationDBlock] else: dataset = self.taskBuffer.queryDatasetWithMap({'name':destinationDBlock}) if dataset == None: _logger.error('%s Not found : %s' % (self.pandaID,destinationDBlock)) flagComplete = False continue # skip tobedeleted/tobeclosed if dataset.status in ['cleanup','tobeclosed','completed','deleted']: _logger.debug('%s skip %s due to %s' % (self.pandaID,destinationDBlock,dataset.status)) continue dsList.append(dataset) # sort dsList.sort() # count number of completed files notFinish = self.taskBuffer.countFilesWithMap({'destinationDBlock':destinationDBlock, 'status':'unknown'}) if notFinish < 0: _logger.error('%s Invalid DB return : %s' % (self.pandaID,notFinish)) flagComplete = False continue # check if completed _logger.debug('%s notFinish:%s' % (self.pandaID,notFinish)) if self.job.destinationSE == 'local' and self.job.prodSourceLabel in ['user','panda']: # close non-DQ2 destinationDBlock immediately finalStatus = 'closed' elif self.job.lockedby == 'jedi' and self.isTopLevelDS(destinationDBlock): # set it closed in order not to trigger DDM cleanup. It will be closed by JEDI finalStatus = 'closed' elif self.job.prodSourceLabel in ['user'] and "--mergeOutput" in self.job.jobParameters \ and self.job.processingType != 'usermerge': # merge output files if firstIndvDS: # set 'tobemerged' to only the first dataset to avoid triggering many Mergers for --individualOutDS finalStatus = 'tobemerged' firstIndvDS = False else: finalStatus = 'tobeclosed' # set merging to top dataset usingMerger = True # disable Notifier disableNotifier = True elif self.job.produceUnMerge(): finalStatus = 'doing' else: # set status to 'tobeclosed' to trigger DQ2 closing finalStatus = 'tobeclosed' if notFinish == 0 and EventServiceUtils.isEventServiceMerge(self.job): allInJobsetFinished = self.checkSubDatasetsInJobset() else: allInJobsetFinished = True if notFinish == 0 and allInJobsetFinished: _logger.debug('%s set %s to dataset : %s' % (self.pandaID,finalStatus,destinationDBlock)) # set status dataset.status = finalStatus # update dataset in DB retT = self.taskBuffer.updateDatasets(dsList,withLock=True,withCriteria="status<>:crStatus AND status<>:lockStatus ", criteriaMap={':crStatus':finalStatus,':lockStatus':'locked'}) if len(retT) > 0 and retT[0]==1: finalStatusDS += dsList # close user datasets if self.job.prodSourceLabel in ['user'] and self.job.destinationDBlock.endswith('/') \ and (dataset.name.startswith('user') or dataset.name.startswith('group')): # get top-level user dataset topUserDsName = re.sub('_sub\d+$','',dataset.name) # update if it is the first attempt if topUserDsName != dataset.name and not topUserDsName in topUserDsList and self.job.lockedby != 'jedi': topUserDs = self.taskBuffer.queryDatasetWithMap({'name':topUserDsName}) if topUserDs != None: # check status if topUserDs.status in ['completed','cleanup','tobeclosed','deleted', 'tobemerged','merging']: _logger.debug('%s skip %s due to status=%s' % (self.pandaID,topUserDsName,topUserDs.status)) else: # set status if self.job.processingType.startswith('gangarobot') or \ self.job.processingType.startswith('hammercloud'): # not trigger freezing for HC datasets so that files can be appended topUserDs.status = 'completed' elif not usingMerger: topUserDs.status = finalStatus else: topUserDs.status = 'merging' # append to avoid repetition topUserDsList.append(topUserDsName) # update DB retTopT = self.taskBuffer.updateDatasets([topUserDs],withLock=True,withCriteria="status<>:crStatus", criteriaMap={':crStatus':topUserDs.status}) if len(retTopT) > 0 and retTopT[0]==1: _logger.debug('%s set %s to top dataset : %s' % (self.pandaID,topUserDs.status,topUserDsName)) else: _logger.debug('%s failed to update top dataset : %s' % (self.pandaID,topUserDsName)) # get parent dataset for merge job if self.job.processingType == 'usermerge': tmpMatch = re.search('--parentDS ([^ \'\"]+)',self.job.jobParameters) if tmpMatch == None: _logger.error('%s failed to extract parentDS' % self.pandaID) else: unmergedDsName = tmpMatch.group(1) # update if it is the first attempt if not unmergedDsName in topUserDsList: unmergedDs = self.taskBuffer.queryDatasetWithMap({'name':unmergedDsName}) if unmergedDs == None: _logger.error('%s failed to get parentDS=%s from DB' % (self.pandaID,unmergedDsName)) else: # check status if unmergedDs.status in ['completed','cleanup','tobeclosed']: _logger.debug('%s skip %s due to status=%s' % (self.pandaID,unmergedDsName,unmergedDs.status)) else: # set status unmergedDs.status = finalStatus # append to avoid repetition topUserDsList.append(unmergedDsName) # update DB retTopT = self.taskBuffer.updateDatasets([unmergedDs],withLock=True,withCriteria="status<>:crStatus", criteriaMap={':crStatus':unmergedDs.status}) if len(retTopT) > 0 and retTopT[0]==1: _logger.debug('%s set %s to parent dataset : %s' % (self.pandaID,unmergedDs.status,unmergedDsName)) else: _logger.debug('%s failed to update parent dataset : %s' % (self.pandaID,unmergedDsName)) # start Activator if re.search('_sub\d+$',dataset.name) == None: if self.job.prodSourceLabel=='panda' and self.job.processingType in ['merge','unmerge']: # don't trigger Activator for merge jobs pass else: if self.job.jobStatus == 'finished': aThr = Activator(self.taskBuffer,dataset) aThr.start() aThr.join() else: # unset flag since another thread already updated #flagComplete = False pass else: # update dataset in DB self.taskBuffer.updateDatasets(dsList,withLock=True,withCriteria="status<>:crStatus AND status<>:lockStatus ", criteriaMap={':crStatus':finalStatus,':lockStatus':'locked'}) # unset flag flagComplete = False # end _logger.debug('%s end %s' % (self.pandaID,destinationDBlock)) # special actions for vo if flagComplete: closerPluginClass = panda_config.getPlugin('closer_plugins',self.job.VO) if closerPluginClass == None and self.job.VO == 'atlas': # use ATLAS plugin for ATLAS from CloserAtlasPlugin import CloserAtlasPlugin closerPluginClass = CloserAtlasPlugin if closerPluginClass != None: closerPlugin = closerPluginClass(self.job,finalStatusDS,_logger) closerPlugin.execute() # change pending jobs to failed finalizedFlag = True if flagComplete and self.job.prodSourceLabel=='user': _logger.debug('%s finalize %s %s' % (self.pandaID,self.job.prodUserName,self.job.jobDefinitionID)) finalizedFlag = self.taskBuffer.finalizePendingJobs(self.job.prodUserName,self.job.jobDefinitionID) _logger.debug('%s finalized with %s' % (self.pandaID,finalizedFlag)) # update unmerged datasets in JEDI to trigger merging if flagComplete and self.job.produceUnMerge() and finalStatusDS != []: if finalizedFlag: tmpStat = self.taskBuffer.updateUnmergedDatasets(self.job,finalStatusDS) _logger.debug('%s updated unmerged datasets with %s' % (self.pandaID,tmpStat)) # start notifier _logger.debug('%s source:%s complete:%s' % (self.pandaID,self.job.prodSourceLabel,flagComplete)) if (self.job.jobStatus != 'transferring') and ((flagComplete and self.job.prodSourceLabel=='user') or \ (self.job.jobStatus=='failed' and self.job.prodSourceLabel=='panda')) and \ self.job.lockedby != 'jedi': # don't send email for merge jobs if (not disableNotifier) and not self.job.processingType in ['merge','unmerge']: useNotifier = True summaryInfo = {} # check all jobDefIDs in jobsetID if not self.job.jobsetID in [0,None,'NULL']: useNotifier,summaryInfo = self.taskBuffer.checkDatasetStatusForNotifier(self.job.jobsetID,self.job.jobDefinitionID, self.job.prodUserName) _logger.debug('%s useNotifier:%s' % (self.pandaID,useNotifier)) if useNotifier: _logger.debug('%s start Notifier' % self.pandaID) nThr = Notifier.Notifier(self.taskBuffer,self.job,self.destinationDBlocks,summaryInfo) nThr.run() _logger.debug('%s end Notifier' % self.pandaID) _logger.debug('%s End' % self.pandaID) except: errType,errValue = sys.exc_info()[:2] _logger.error("%s %s" % (errType,errValue))