def onoff(self, sender): """ Turns aircon on or off. Checks state first. """ logger.debug("Attempting to toggle AC state.") if self.current_state["aircons"]["ac1"]["info"]["state"] == "on": logger.debug("Last know state of AC was on.") logger.info("Turning AC off.") target = self.base_target + 'setAircon?json={"ac1":{"info":{"state":"off"}}}' else: logger.debug("Last know state of AC was off.") logger.info("Turning AC on.") target = self.base_target + 'setAircon?json={"ac1":{"info":{"state":"on"}}}' logger.debug("Built target URL {}".format(target)) request = self.send_command(target) if request.json()["ack"] == True: logger.debug("Sleeping for 5 seconds before requesting another update.") time.sleep(5) self.get_state() if self.current_state["aircons"]["ac1"]["info"]["state"] == "on": logger.debug("AC is currently on.") rumps.notification(title="MyAir", message="AC turned on successfully") else: logger.debug("AC is currently off.") rumps.notification(title="MyAir", message="AC turned off successfully")
def connect(self, *args): """ Called via our connect thread... Attempt to create a new connection with our Connect class and store the value to our self.connection instance variable """ # With the potential dropped internet connections, sessions ending and more, # which have caused errors, it's easier and safer if we attempt to create a # new instance of Connect which provides a clean session. Future improvements # could be made to rectify this action to help memory/performance. self.connection = Connect() self.title = GumpyTitles.CONNECTING try: self.connection.connect() rumps.notification(GumpyTitles.CONNECTION_SUCCESS, '', 'Have a cookie') # This explicitly calls get_tickets method on a rumps.Timer (new thread) interval if self.refresh_interval_timer is None: self.refresh_interval_thread() else: # If this isn't the first time connect is being called, we will update # our ticket results by refreshing our interval thread which calls get_tickets self.refresh_interval_thread(force_refresh=True) except Exception as e: rumps.alert(e) finally: self.title = GumpyTitles.GUMPY
def lowercase_command(self, _): successful, message = update_text(converter.lowercase) if successful: rumps.notification("stripped 📋", "Updated clipboard text", message) else: rumps.notification("stripped 📋", "Error, count not convert", message)
def clipboard_function(sender=None): logging.debug("function {0} was called".format(name)) original_clipboard_text = clipboardmanager.get_latest() logging.debug( "copied {0} from clipboard".format(original_clipboard_text)) new_clipboard_text = None try: new_clipboard_text = funcmanager.get_command(name)( original_clipboard_text) except Exception as exception: logging.debug('triggering notification') rumps.notification(title='Error in running clipfunc', subtitle=type(exception).__name__, message=str(exception)) logging.exception(exception) logging.debug("new clipboard {0}".format(new_clipboard_text)) # text sanitization if new_clipboard_text is None: logging.warning( "command {0} returned a None instead of string, clipboard is unchanged" .format(name)) return clipboardmanager.put(new_clipboard_text) logging.debug("function {0} finished".format(name))
def presentationMode(self, sender): if (sender.title == "on"): self.presentation.on.set_callback(None) self.presentation.off.set_callback(self.presentationMode) setPresentationMode(True) osascript.run(''' tell application "System Events" set listOfProcesses to (name of every process where (background only is false) and (name ≠ "finder")) tell me to set selectedProcesses to choose from list listOfProcesses with prompt "Close windows before presenting?" default items "None" OK button name {"Close Selcted"} cancel button name {"Cancel"} with multiple selections allowed end tell --The variable `selectedProcesses` will contain the list of selected items. repeat with processName in selectedProcesses do shell script "Killall " & quoted form of processName end repeat ''') rumps.notification(title="Presentation Mode: Enabled", subtitle=f"", message='', sound=False) else: self.presentation.off.set_callback(None) self.presentation.on.set_callback(self.presentationMode) setPresentationMode(False) rumps.notification(title="Presentation Mode: Disabled", subtitle=f"", message='', sound=False)
def prefs(self): daemon = xmlrpclib.ServerProxy("http://localhost:7080/") try: daemon.is_running() webbrowser.get('safari').open("lbry://settings") except: rumps.notification(title='LBRY', subtitle='', message="Couldn't connect to lbrynet daemon", sound=True)
def check_update(self, _): last_update_date = self.settings.get('date', '') if not last_update_date: last_update_date = datetime.datetime.today() else: last_update_date = parser.parse(last_update_date) if not self.settings['apps']: return page = 1 try: while page > 0: response = requests.get(SOURCE_URL.format(page=page), timeout=10) soup = bs4.BeautifulSoup(response.text, 'html.parser') apps = soup.find('ul', class_='post_list row').find_all('a', title=True) for app in apps: update_date = app.find('span', class_='item date') app_update_date = parser.parse(update_date.text) if app_update_date < last_update_date: page = 0 break app_href = app.attrs['href'] app_name = app_href[app_href.rfind('/') + 1:app_href.rfind('.')] if app_name not in self.settings['apps']: continue # app_data = json.dumps() rumps.notification(app_name, 'xclient.info', '{} updated on {}.'.format(app_name, update_date.text), data={'name': app_name, 'date': update_date.text, 'href': app_href}) page += 1 if page > 0 else 0 except Exception as e: rumps.alert('Check update failed! Exception: {}'.format(repr(e))) return
def error(message): stack = "HappyMac Execution Stack at Error Time:\n%s\n" % "".join(traceback.format_stack()[:-1]) exception = "HappyMac Exception:\n %s\n" % traceback.format_exc() error = "HappyMac Error:\n %s\n%s%s%s%s%s\n%s%sHappyMac Error:\n %s\n" % ( message, get_system_info(), get_home_dir_info(), get_preferences(), get_versions(), log.get_log(), stack, exception, message ) path = get_error_file_path() try: with open(path, "w") as output: output.write("HappyMac Error Report - %s\n\n" % datetime.datetime.utcnow()) os.system("system_profiler SPHardwareDataType >> %s" % path) with open(path, "a") as output: output.write(error) with open(path) as input: print(input.read()) except: pass log.log(error) rumps.notification("HappyMac", "Error: %s. For details see:" % message, path, sound=True)
def timerb(self, sender): # call respawner # respawner will return a list of tunnels it COULD NOT AND WILL NOT RESTART ANYMORE # as well as reaped tunnels not set to restart. # get all tunnel states, and adjust the check marks to correspond #print "TICK" message = "" s = self.manager.respawner() if len(s["restartfails"]) > 0: message = message + "The following tunnels failed to restart: " decorate=0 for rf in s["restartfails"]: if decorate != 0: message = message + ", " message = message + rf decorate = decorate + 1 self.menu["Tunnels"][rf].state = 0 message = message + "\n" if len(s["terminators"]) > 0: message = message + "The following items terminated: " decorate = 0 for tr in s["terminators"]: if decorate != 0: message = message + ", " message = message + tr self.menu["Tunnels"][tr].state = 0 if len(message) != 0: print message rumps.notification(title="SSH Tunnel Alert", subtitle="", message=message, data=None) return # popup return
def pom(self, sender): """print 'pom callback'""" if self.working and self.intervals_done == self.worklength: self.working = False self.resting = True self.intervals_done = 0 rumps.notification( "Pompy", "Work Cycle Done", "{} minutes have passed, beginning rest cycle".format( self.worklength ) ) elif self.resting and self.intervals_done == self.restlength: self.working = False self.resting = False self.intervals_done = 0 self.pomodoros_done += 1 self.title = "" rumps.notification( "Pompy", "Rest Cycle Done", "Congratulations! You've done {} pomodoros.".format( self.pomodoros_done ) ) elif self.working or self.resting: self.intervals_done += 1 if self.working: self.title = "{}".format(self.worklength - self.intervals_done) elif self.resting: self.title = "{}".format(self.restlength - self.intervals_done) """
def create(self, magnet, destination): sid = self.auth() print("sid", sid) data = { "api": "SYNO.DownloadStation.Task", "version": "1", "method": "create", "session": "DownloadStation", "_sid": sid, "uri": magnet, "destination": destination, } r = requests.post(self.url_ds, data=data) rj = json.loads(r.text) if r.status_code != 200 or not rj["success"]: print("Create failed with response data: {}".format(rj)) rumps.notification(title="Error", subtitle="Create failed...", message="") return False else: print("Create successful") rumps.notification( title="Success", subtitle="Added to " + destination, message="", ) self.logout()
def does_something(sender): my_data = {'poop': 88} rumps.notification(title='Hi', subtitle='There.', message='Friend!', sound=does_something.sound, data=my_data)
def on_tick(self, sender): time_left = sender.end - sender.count mins = time_left // 60 if time_left >= 0 else time_left // 60 + 1 secs = time_left % 60 if time_left >= 0 else (-1 * time_left) % 60 if mins == 0 and time_left < 0: rumps.notification( title="Timebox", subtitle="Time is up! Take a break :)", message="", ) if self.current_things_task_url is not None: # print("opening url", self.current_things_task_url) subprocess.call( shlex.split("open '" + self.current_things_task_url + "'") ) self.current_things_task_url = None if self.toggle_sit_stand_button.state == True: self.desk_handler.toggle() self.stop_timer(sender) self.stop_button.set_callback(None) self.sync_data() else: self.stop_button.set_callback(self.stop_timer) self.app.title = "{:2d}:{:02d} {}".format( mins, secs, getattr(self, "menu_title", "") ) sender.count += 1
def run(quit_callback=None): if license.get_license(): rumps.notification("HappyMac", "HappyMac is now running", "See the emoji icon in the status bar", sound=False) HappyMacStatusBarApp(quit_callback).run()
def _notify_failed_builds(self): log.info("processing notifications") # TODO: togglable notifiactions setting if not settings.notifications_enabled: log.info("notifications currently disabled") return if not self.last_errored_builds: return unseen_failed_builds = [ b for b in self.last_errored_builds if not notified_build_ids.search( tinydb.where("build_id") == b["id"]) ] if not unseen_failed_builds: log.info("no unseen failed builds to notify on") return log.info( f"{len(unseen_failed_builds)} unseen failed build(s), triggering notification" ) rumps.notification( title= f"{len(unseen_failed_builds)} failed {p.plural('build', len(unseen_failed_builds))} since last check", subtitle=", ".join( set([b["repoName"] for b in unseen_failed_builds])), message=None, sound=True, ) ids = [{"build_id": b["id"]} for b in unseen_failed_builds] notified_build_ids.insert_multiple(ids)
def run_checks(self, _=None): log.debug("Running checks") all_ok = True for check in self.checks: log.debug("Running check {}".format(check)) success, msg = check.run() check.last_result = (success, msg) if success: log.debug("Success: {}".format(msg)) check.snooze_until = None else: all_ok = False log.error("Fail: {}".format(msg)) if not check.snoozing: log.debug("Sending notification") rumps.notification("{} check failed".format(check.name), "", msg, data={"name": check.name}, actionButton="Snooze", otherButton="Dismiss") else: log.debug("Check is snoozing until {} - not sending notification".format(check.snooze_until)) try: if self.last_ok != all_ok: self.last_ok = all_ok if all_ok: app.title = emoji.emojize(random.choice(list(config.ok_titles)), use_aliases=True) else: app.title = emoji.emojize(random.choice(list(config.not_ok_titles)), use_aliases=True) app.update_menu() except NameError: log.error("No app")
def _get_invasions(self, sender): '''Notifies the user of new invasions. Communicates with the Toontown Rewritten API to get information about current invasions, then determines which invasions are new. If there are new invasions, the user will be notified via notification. Args: sender (rumps.MenuItem): Automatically sent when a menu item is invoked. ''' # Get the previous iteration's and the current invasion information previous = self._invasions current = self._tracker.get_invasions() # Determine what invasions changed since the last check difference = set(current.items()) - set(previous.items()) # Send a notification for each different invasion for invasion in difference: district, cog = invasion rumps.notification( title='A cog invasion has begun!', subtitle=None, message=f'{cog}s have invaded {district}!', ) # Store the current invasions for the next iteration self._invasions = current
def shorten(self, _): s = pst.Shortener() retrieved_url = clipboard.paste() is_valid = validators.url(retrieved_url) if is_valid: if chosenShortener.__eq__(""): rumps.notification("Unspecified Shortener Service", "Please choose shortener service to use.", "") if chosenShortener.__eq__("chilpit"): clipboard.copy(s.chilpit.short(retrieved_url)) elif chosenShortener.__eq__("clckru"): clipboard.copy(s.clckru.short(retrieved_url)) elif chosenShortener.__eq__("dagd"): clipboard.copy(s.dagd.short(retrieved_url)) elif chosenShortener.__eq__("isgd"): clipboard.copy(s.isgd.short(retrieved_url)) elif chosenShortener.__eq__("osdb"): clipboard.copy(s.osdb.short(retrieved_url)) elif chosenShortener.__eq__("owly"): clipboard.copy(s.owly.short(retrieved_url)) elif chosenShortener.__eq__("qpsru"): clipboard.copy(s.qpsru.short(retrieved_url)) elif chosenShortener.__eq__("tinyurl"): clipboard.copy(s.tinyurl.short(retrieved_url)) else: rumps.notification("Invalid URL", "Make sure to copy URL in correct form.", "") clipboard.copy("Invalid URL")
def from_lunch(self, _): resp = self.tiima.user_from_lunch() if resp.get("success") == True: rumps.notification("TiiMac", "Checked you back from lunch!", "") else: rumps.notification("TiiMac", "Couldn't check you back from lunch!", "") self.refresh()
def on_tick(self, sender): if self.is_in_mode == self.config["work_mode"]: self.stop_button.set_callback(self.stop_timer) self.time_left = sender.end - sender.count self.mins = self.time_left // 60 if self.time_left >= 0 else ( -1 * self.time_left) // 60 self.secs = self.time_left % 60 if self.time_left >= 0 else ( -1 * self.time_left) % 60 #count up one round and send message at every interval if (-1 * self.time_left % self.config["interval"]) == 0 and self.time_left <= 0: self.round += 1 rumps.notification(title=self.config["app_name"], subtitle=self.config["break_message"], message='') #display seconds if self.time_left >= 0: self.app.title = 'Tập trung 💪 | ▶️ {:2d}:{:02d} | Lượt 🍅: {}'.format( self.mins, self.secs, self.round) else: self.app.title = 'Tập trung 💪 | ▶️ -{:2d}:{:02d} | Lượt 🍅: {}'.format( self.mins, self.secs, self.round) elif self.is_in_mode == self.config["rest_mode"]: self.mins = sender.count // 60 self.secs = sender.count % 60 self.app.title = 'Giải lao 💤 | {:2d}:{:02d}'.format( self.mins, self.secs, self.round) sender.count += 1
def check_in(self, _): resp = self.tiima.user_enter() if resp.get("success") == True: rumps.notification("TiiMac", "Checked you in!", "") else: rumps.notification("TiiMac", "Couldn't check you in!", "") self.refresh()
def copy_key(self, sender): for key_id, username, passwd in decode(): if key_id == sender.title: pyperclip.copy(passwd) rumps.notification( 'Accest to {0}'.format(key_id), 'Your username is {0}'.format(username), 'Your password is copied into clipboard')
def refresh_bar(self): ''' Refreshing the information displayed in the apps status bar menu ''' if (psutil.sensors_battery().power_plugged == True and str(int(self.unplugAt)) == str(int(psutil.sensors_battery().percent))): rumps.notification("Your Mac is charged at a set threshold", "You can unplug your machine", "Save your battery life!") self.menu["Plugged in: "].title = "Plugged in: " + str(psutil.sensors_battery().power_plugged)
def hello(self, _): show_text = f"現在時刻は[{datetime.today()}]です" rumps.notification( "Helloタイトル", "Hello world", show_text, icon="app.png", )
def take_break(self, timer): now = datetime.datetime.now() if now - self.checkin >= self.delta: self.checkin = now rumps.notification("Break Timer", "Time for a break!", "Click to take your break.") self.app.icon = "alert-circle.png" self.delta = self.nag_delta
def run_bridge(self, _): """ Starts up the bridge """ self.controller = controller.BehringerController() self.controller.start() self.controller.find_mixer() rumps.notification("XAir OSC Bridge", "Connected!", "Connected to "+self.controller.mixer_name) self.service = midireceiver.MidiReceiver(self.controller, self.controller.mixer_name) self.service.start()
def stream_status_watcher(self, _): if self.started and not self.stream.active: self.onoff() rumps.notification('Menu Playthrough', 'Error: Menu Playthrough SoundStream has crashed.', 'The playthrough has stopped.', sound=False) self.run_show.title = 'Running' if self.started else 'Stopped' self.run_show.state = self.started self.run_toggle.title = ' ' + ('Stop' if self.started else 'Start')
def run(self): self.debug("Loading Keys") keys = self.pickle.loadall() self.create_menu(keys) rumps.notification(title="Keypaste", subtitle="App Running", message="", icon="keyboard.icns") self.app.run()
def mount(self, _): print(self.login) self.UID = rumps.Window(title="HPCC username", message="Please enter your MSU NETID:", dimensions=(250, 50)).run() UserID = str( self.UID.text ) # since rumps.Window returns its type from window class we need to convert it to string if (self.key_present(UserID)): # SSH does not connect through print("The SSH keys are present {}".format( self.key_present(UserID))) else: print("Need to generate ssh keys") self.alert = rumps.alert( title="SSH Keys", message= "To mount your HPCC drive using SSHFS, you need to generate SSH Key-Based " "authentication. Would you like to continue to create your SSH Keys. NOTE: " "By clicking continue, the program will generate two files onto your computer " "system, a public and a private key. Additionally, the public key will be copied " "to your HPCC system account to a file within the your home directory at ~/.ssh/authorized_keys." " This procedure will enable Password-less login when connecting to the HPCC. This way, you'll " "be able to automatically login each time immediately without needing to enter your password. ", ok="Continue", cancel="Cancel") if self.alert == 0: sys.exit(0) self.gen_key() self.push_key(UserID) sshfs_cmd = "/usr/local/bin/sshfs -o allow_other,defer_permissions,IdentityFile=~/.ssh/id_rsa" remote_host = "@hpcc.msu.edu:/mnt/home/" options = "-o cache=no -o nolocalcaches -o volname=hpcc -o StrictHostKeyChecking=no" # StrictHostKeyChecking ignores authentication for first time use os.mkdir(self.local_mount_point + self.path) var = sshfs_cmd + " " + UserID + remote_host + UserID + " " + self.local_mount_point + self.path + " " + options print(var) os.system(var) if ( self.drive_mounted() ): # os.system() returns the encoded process exit value. 0 means succecss no error self.menu["Mount HPCC"].set_callback(None) rumps.notification( title="HPCC drive Mounted", subtitle="Sucessfull", # !!!!Fix This message="Your drive is located at " + self.local_mount_point + self.path, sound=True)
def sync_done(self, local_path, remote_path, remote_host): rumps.notification( "GitSync", "Completed", "Sync of %s and %s on %s" % ( local_path, remote_path, remote_host, ) )
def time_done(self): self.title = DEFAULT_TITLE rumps.alert( title="Boxy", message="Hey! Times up!") rumps.notification( title="Boxy", subtitle="A message for you", message="Hey! Times up!", sound=True)
def kill_job(self, job: JobDescription): response = Windows.kill_job() if response.clicked: try: self.client.job_kill(job.id) del self.menu[job.id] self.set_active_mode() except Exception as e: rumps.notification('Failed to kill the job', '', str(e))
def submit_preset(self, preset: dict): response = Windows.job_description(preset['name']) if response.clicked: try: params = f'-d \'{response.text}\' ' + preset['job_params'] self.client.submit_raw(params) self.set_active_mode() except Exception as e: rumps.notification('Failed to create new job', '', str(e))
def sync_start(self, local_path, remote_path, remote_host): rumps.notification( "GitSync", "Starting", "Syncing %s and %s on %s" % ( local_path, remote_path, remote_host, ) )
def check_if_working(self, _): """ Every 30min, check if I've not forgotten to stop the time. """ if not self.task_started: return rumps.notification( title='Watson Time Tracker', message=f'Are you still working on {self.task_name}?', )
def check_in(self, callback=None, silent=False): if self.geek_hub is None: self.geek_hub = Robot(self.setting_config.get("session")) score = self.geek_hub.check_in() if isinstance(score, int): self.user_score_menu.title = f'积分:{score}' if not silent: rumps.notification( "签到", "签到成功!", f"当前积分{score}", icon=self.get_icon('notification')) else: rumps.alert("获取积分失败,请尝试重新获取", icon_path=self.get_icon('alert'))
def save_contents(latest): version = latest["version"] path = os.path.join(downloads_dir, '%s' % version) if os.path.exists(path): log.log("Download: version %s already installed" % version) else: with open(path, "wb") as file: pickle.dump(latest, file, 2) log.log("Download: extracted version %s to %s" % (version, path)) rumps.notification("HappyMac Update", "A new version was downloaded", "Running %s" % version, sound=False) log.log("Download: available versions: %s" % get_versions())
def show_updates(updates: List[StatusUpdate or NewJobUpdate]): for update in updates: if isinstance(update, StatusUpdate): reason = f' ({update.reason})' if update.reason else '' rumps.notification('Job status has changed', update.job_id, f'New status: {update.status}{reason}') if isinstance(update, NewJobUpdate): reason = f' ({update.reason})' if update.reason else '' rumps.notification('New job is created', update.job_id, f'Status: {update.status}{reason}')
def startcount(target): """start a counter for num mins""" global target_time global notify print 'target: %s' % target target_time = target notify = True rumps.notification(title="Countdown has begun.", subtitle="TimerBar", message="Ends at %s"%target.strftime('%X on %x'))
def checkTimerAlert(): global secondLeft, rt if(secondLeft <= 0): rt.stop() app.title="!!! Take a break !!!" rumps.notification(title='Take a break', subtitle='', message='Your hour is up, take a quick break!') secondLeft = breaktimeValue return m, s = divmod(secondLeft, 60) app.title = str(m).zfill(2) + 'm ' + str(s).zfill(2) + 's' secondLeft -= 1;
def start_new_file(self, _): today = datetime.date.today() path = today.strftime(os.envget("FREECODE_DIR") + "/%Y/%m/") if not os.path.exists(path): os.makedirs(path) filename = today.strftime('fc_%Y_%m_%d.py') full_path = os.path.join(path, filename) if os.path.isfile(full_path): rumps.alert("Today's file is already created") else: with open(full_path, 'w') as file: file.write(file_template % today.isoformat()) rumps.notification("Halotis", "started a new file", "good to go")
def disp_balance(self): daemon = xmlrpclib.ServerProxy("http://localhost:7080/") try: balance = daemon.get_balance() r = round(float(balance), 2) try: rumps.notification(title='LBRY', subtitle='', message=str("Your balance is %.2f LBC" % r), sound=False) except: rumps.alert(title='LBRY', message=str("Your balance is %.2f LBC" % r)) except: try: rumps.notification(title='LBRY', subtitle='', message="Couldn't connect to lbrynet daemon", sound=True) except: rumps.alert(title='LBRY', message="Couldn't connect to lbrynet daemon")
def checkName(audio, lock, v, names): #print("Called checkName") try: list = r.recognize(audio, True) for prediction in list: if(match.checkArray(prediction["text"], names, 0.3)): with lock: v.value += 1 if(v.value >= 1): rumps.notification("Pay attention!", "Someone said your name!", "") #if(v.value >= 2): # message = client.messages.create(body="Pay some f*****g attention to the people around you!", to="+18583822455", from_="+17606704339") break print(prediction["text"]) except LookupError: print("")
def alert_daemon_start(self): daemon = xmlrpclib.ServerProxy("http://localhost:7080/") try: start_msg = daemon.is_running() if isinstance(start_msg, str): rumps.notification(title='LBRY', subtitle='', message=str(start_msg), sound=True) update_info = daemon.check_for_new_version() update_msg = "" for p in update_info: if not p[0]: update_msg += p[1] + "\n" if update_msg: update_msg += "\n Try running the installer again to fix this" rumps.notification(title='LBRY', subtitle='', message=update_msg, sound=True) except: pass
def tick(sender): """ Called automatically every second """ global target_time global notify global app if target_time: timeleft = target_time - datetime.now() app.title = "(%02d:%02d:%02d)" % (timeleft.total_seconds()//3600,(timeleft.seconds % 3600)//60, timeleft.seconds%60) if (timeleft.total_seconds() < 1) and notify: app.title = "Done!" rumps.notification(title="Countdown Done!", subtitle="TimerBar", sound=True, message="The Timer has Completed!") notify = False target_time = None
def send_data(self): """ Data is sent to email_recipient using the gmail module. :return: None """ data_to_send = list(controller.retriever.data) # If the data retriever has worked properly and data has been retrieved, # we try to write the data into a file and send it. if data_to_send: try: # Try to open a new log self.log = Log() except (IOError, OSError): logger.debug("Can't open log") try: # Try to write the log self.write_data(data_to_send) except (IOError, OSError): logger.debug("Can't write data into file") # If there was data and it has been written into a file, then the # list should be re-initialized so no data is written twice. controller.retriever.data = [] try: # Try to send data. If there is no internet connection or the # connection to the server can't be established, then the # data is put back to the list controller.retriever.data, so it can # be re-sent when there is a connection. # TODO: Retry sending files instead of saving info to list # There should be a file list with the files that haven't been # sent. If the connections fails, the data is already written # into a file, and every time info is sent, the list of files # to be sent should be popped from this list. If the connection # fails, the file is appended back to the list. self.sender.send_email(subject=self.log.user, text="", attach=self.log.file_name) except smtplib.socket.gaierror: logger.debug("Connection to send data not established.") controller.retriever.data = list(data_to_send) print len(controller.retriever.data) rumps.notification("Warning!", "Please check internet connection", "Data has not been sent", sound=False)
def update_monitors_states(self): try: erroneous_monitors = self.get_erroneous_monitors() except urllib2.URLError: pass else: for monitor in erroneous_monitors: if not monitor in self.erroneous_monitors: rumps.notification('Serveur indisponible', '', '%s est injoignable depuis %s' % (monitor['name'], monitor['since'].strftime('%H:%M'))) for monitor in self.erroneous_monitors: if not monitor in erroneous_monitors: rumps.notification('Serveur disponible', '', '%s est de nouveau joignable' % monitor['name']) self.erroneous_monitors = erroneous_monitors self.set_icon() self.build_menu() threading.Timer(60*2, self.update_monitors_states).start()
def changeit(sender): checked = time.strftime("%d %b %Y %H:%M:%S", time.localtime()) if USE_ICON: str = '' else: str = 'Bikes: ' data = rideindego.get_bike_data() app.menu.clear() app.menu.update([ rumps.MenuItem('Check now',callback=changeit), rumps.MenuItem('Checked: ' + checked), rumps.MenuItem('Quit',callback=rumps.quit_application,key='q'), #rumps.MenuItem('Test',callback=test), rumps.separator, ]) for i in ['33rd & Market','Amtrak 30th Street Station','University City Station',None,'19th & Lombard','23rd & South','17th & Pine']: if i: state = True if prev_num_bikes.get(i,-1)>-1 else False bikes = rideindego.get_data(data,i,'bikesAvailable') if state: try: num_bikes = int(bikes) my_data = {'sender': sender} if prev_num_bikes[i] == 0 and num_bikes > 0: rumps.notification(title='Bike Update', subtitle=i, message='There are %d bikes available now' % num_bikes, sound=True, data=my_data) elif num_bikes > 0 and num_bikes<=3: rumps.notification(title='Bike Update', subtitle=i, message='There are only %d bikes available' % num_bikes, sound=True, data=my_data) prev_num_bikes[i] = num_bikes except Exception as e: print e pass item = rumps.MenuItem(i+": "+bikes +'/' + rideindego.get_data(data,i,'docksAvailable') + '',callback=set_alert) item.state = state app.menu.update(item) else: app.menu.update([rumps.separator]) pass pass str+= rideindego.get_data(data,'33rd & Market','bikesAvailable') +', ' + rideindego.get_data(data,'19th & Lombard','bikesAvailable') app.title = str
def check_channel_status(self, channel_name): channel_url = 'https://api.twitch.tv/kraken/streams/{channel_name}'.format(channel_name=channel_name) print 'check stream at ', channel_url response = self.session.get(channel_url, verify=False) if response.status_code == 200: stream_json = response.json() stream = stream_json.get('stream') # Check prev state icon and new stream state. If it changes to online that user should be notified if self.user_defaults.boolForKey_(consts.ALLOW_USER_NOTIFICATION) \ and self.menu['Channels'][channel_name].icon == consts.Images.offline \ and stream: rumps.notification( consts.WHALE_TITLE, 'Channel online!', '%s is online now' % self.menu['Channels'][channel_name].title ) print '%s is active? %s' % (channel_name, True if stream else False) self.menu['Channels'][channel_name].set_icon(consts.Images.online if stream else consts.Images.offline)
def auth_callback(self, access_token, error): """Callback function called after Twitch OAuth Authentication. :param access_token: access token :type access_token: str or None :param error: error :type error: str or None :return: None """ # Check for auth errors if error: rumps.notification('Whale', 'Error', 'Twitch.tv authentication failed') return self.user_defaults.setValue_forKey_(access_token, consts.TWITCH_ACCESS_TOKEN) self.user_defaults.synchronize() print 'Token successfullly updated' self.init_twitch_session() user_dict = self.load_user_info() self.load_user_followings(user_dict['name'])
def prefs(self, sender): # Foundation.NSWorkspace.sharedWorkspace().openFile_(url) rumps.notification(consts.WHALE_TITLE, '', 'Preferences are not implemented at the moment')
def rate_changed(sender): if notify: notification_text = "Был: " + str(last_rate) + " стал: " + str(rate) rumps.notification("Obmenka", "Изменение курса!", notification_text, sound=sound)
def get_input(): try: while True: line = sys.stdin.readline() if not line: break if line == '': continue print "info:Read %s" % line sys.stdout.flush() cfg = None try: cfg = json.loads(line) except: pass if cfg == None: print "info:Unable to parse line" sys.stdout.flush() continue if cfg.has_key("Action"): print "info:Running %s" % cfg["Action"] sys.stdout.flush() if cfg["Action"] == "setmenu": menu = cfg["Menu"] if lookup.has_key(menu["Key"]): lookup[menu["Key"]].title = menu["Text"] if menu.has_key("Enabled") and not menu["Enabled"]: lookup[menu["Key"]].set_callback(None) else: lookup[menu["Key"]].set_callback(item_clicked) app.menu.update([]) else: print "warn:Key not found %s" % cfg["Action"] sys.stdout.flush() elif cfg["Action"] == "setmenus": app.menu.clear() app.menu = parsemenus(cfg) print "info:Updated menus" sys.stdout.flush() elif cfg["Action"] == "seticon": try: raw = base64.b64decode(cfg["Image"]) data = NSData.dataWithBytes_length_(raw, len(raw)) img = NSImage.alloc().initWithData_(data) img.setScalesWhenResized_(True) img.setSize_((18, 18)) img.setTemplate_(True) app.icon = img print "info:Image updated" sys.stdout.flush() except: print "warn:Failed to set image" sys.stdout.flush() elif cfg["Action"] == "setappicon": try: raw = base64.b64decode(cfg["Image"]) data = NSData.dataWithBytes_length_(raw, len(raw)) img = NSImage.alloc().initWithData_(data) #img.setScalesWhenResized_(True) #img.setSize_((21, 21)) NSApplication.sharedApplication().setApplicationIconImage_(img) print "info:AppImage updated" sys.stdout.flush() except: print "warn:Failed to set image" sys.stdout.flush() elif cfg["Action"] == "shutdown": break elif cfg["Action"] == "foreground": transform_app_type(True) elif cfg["Action"] == "background": transform_app_type(False) elif cfg["Action"] == "notification": if rumps._NOTIFICATIONS: title = cfg["Title"] message = cfg["Message"] subtitle = '' playSound = True image = None if cfg.has_key("SubTitle"): subtitle = cfg["SubTitle"] if cfg.has_key("PlaySound"): playSound = cfg["PlaySound"] if cfg.has_key("Image"): try: raw = base64.b64decode(cfg["Image"]) data = NSData.dataWithBytes_length_(raw, len(raw)) image = NSImage.alloc().initWithData_(data) except: print "warn:Failed to decode image" sys.stdout.flush() rumps.notification(cfg["Title"], subtitle, cfg["Message"], sound=playSound, image=image) finally: try: traceback.print_exc() except: pass rumps.quit_application() print "info:Shutdown" sys.stdout.flush() print "info:Stdin close" sys.stdout.flush() sys.stdin.close()
def get_input(): try: while True: line = sys.stdin.readline() if not line: break if line == '': continue print "info:Read %s" % line sys.stdout.flush() cfg = None try: cfg = json.loads(line) except: pass if cfg == None: print "info:Unable to parse line" sys.stdout.flush() continue if cfg.has_key("Action"): print "info:Running %s" % cfg["Action"] sys.stdout.flush() if cfg["Action"] == "setmenu": menu = cfg["Menu"] if lookup.has_key(menu["Key"]): lookup[menu["Key"]].title = menu["Text"] if menu.has_key("Enabled") and not menu["Enabled"]: lookup[menu["Key"]].set_callback(None) else: lookup[menu["Key"]].set_callback(item_clicked) app.menu.update([]) else: print "warn:Key not found %s" % cfg["Action"] sys.stdout.flush() elif cfg["Action"] == "setmenus": app.menu.clear() app.menu = parsemenus(cfg) print "info:Updated menus" sys.stdout.flush() elif cfg["Action"] == "seticon": try: raw = base64.b64decode(cfg["Image"]) data = NSData.dataWithBytes_length_(raw, len(raw)) img = NSImage.alloc().initWithData_(data) img.setScalesWhenResized_(True) img.setSize_((21, 21)) app.icon = img print "info:Image updated" sys.stdout.flush() except: print "warn:Failed to set image" sys.stdout.flush() elif cfg["Action"] == "shutdown": break elif cfg["Action"] == "notification": if rumps_NOTIFICATIONS: rumps.notification(cfg["Title"], '', cfg["Message"]) finally: rumps.quit_application() print "info:Shutdown" sys.stdout.flush() print "info:Stdin close" sys.stdout.flush() sys.stdin.close()
def show_balloon(self, title, body): rumps.notification(tray_common.APP_NAME, title, body, sound=False)
def sayhi(self, _): rumps.notification("Awesome title", "amazing subtitle", "hi!!1")
def get_messages(self, commandline=False): # Set labels is_inbox_only = True labels = [] if 'labels' in self.settings and self.settings['labels'] != '': for l in self.settings['labels'].split(','): labels.append(l.strip()) if l != 'INBOX': is_inbox_only = False elif 'filter' not in self.settings\ or self.settings['filter'].strip() == '': labels.append('INBOX') if not is_inbox_only: # Get labelIds label_name_id = {x['name'].upper().replace('/', '-'): x['id'] for x in self.timeout_execute( self.get_service().users().labels() .list(userId='me'))['labels']} else: label_name_id = {'INBOX': 'INBOX', 'None': None} labels = [x for x in labels if x.replace('/', '-') in label_name_id] if len(labels) == 0: labels.append('None') # Get message ids query = 'label:unread ' + (self.settings['filter'] if 'filter' in self.settings else '') ids = {} is_new = False for l in labels: response = self.timeout_execute( self.get_service().users().messages().list( userId='me', labelIds=label_name_id[l.replace('/', '-')], q=query)) ids[l] = [] if 'messages' in response: ids[l].extend([x['id'] for x in response['messages']]) while 'nextPageToken' in response: page_token = response['nextPageToken'] response = self.timeout_execute( self.get_service().users().messages().list( userId='me', labelIds=label_name_id[l.replace('/', '-')], q=query, pageToken=page_token)) ids[l].extend([x['id'] for x in response['messages']]) if l not in self.messages: self.messages[l] = [] if ids[l] != self.messages[l]: is_new = True # Remove read messages' id self.messages[l] = ids[l] removed = [x for x in self.messages if x not in labels] if len(removed) > 0: is_new = True for l in removed: del self.messages[l] # No change if not is_new: # No new message return # Check total number of messages # Remove duplication in different labels all_ids = [] for l in labels: all_ids += ids[l] all_ids = list(set(all_ids)) self.message_contents = { k: v for k, v in self.message_contents.items() if k in all_ids} # Set menu's title um_menu = self.menu['Unread messages'] um_menu.title = 'Unread messages: %d' % len(all_ids) # Set menubar icon's title if len(all_ids) == 0: self.title = '' else: self.title = '%d' % len(all_ids) # Reset menu bar icon after title is put, # to adjust the width. self.icon = self.menu_bar_icon # Get message contents n_get = 0 for i in all_ids: if i in self.message_contents\ and 'Subject' in self.message_contents[i]: continue is_new = True if i not in self.message_contents\ else False self.message_contents[i] = {} if n_get >= self.mails_max_get: continue n_get += 1 message = self.timeout_execute( self.get_service().users().messages().get( userId='me', id=i)) for k in ['labelIds', 'snippet', 'threadId']: self.message_contents[i][k] = message[k] for x in message['payload']['headers']: if x['name'] == 'Subject': self.message_contents[i]['Subject'] = x['value'] elif x['name'] == 'Date': self.message_contents[i]['Date'] =\ x['value'].split(', ')[1].split(' +')[0] elif x['name'] == 'From': self.message_contents[i]['FromName'] =\ self.get_address_name(x['value']) self.message_contents[i]['From'] = x['value'] elif x['name'] in ['Subject', 'To', 'Cc', 'Bcc', 'In-Reply-To', 'References']: self.message_contents[i][x['name']] = x['value'] for k in ['To', 'Cc']: if k not in self.message_contents[i]: self.message_contents[i][k] = '' body = None if 'parts' in message['payload']: for p in message['payload']['parts']: if 'body' in p and 'data' in p['body']: body = p['body']['data'] break if body is None and 'body' in message['payload']\ and 'data' in message['payload']['body']: body = message['payload']['body']['data'] if body is not None: self.message_contents[i]['body']\ = base64.urlsafe_b64decode(body.encode('UTF-8')) if body is None: self.message_contents[i]['body'] = message['snippet'] # Popup notification if is_new and not self.is_first\ and self.menu['Mail notification'].state: rumps.notification( title='Mail from %s' % self.message_contents[i]['FromName'], subtitle=self.message_contents[i]['Subject'], message=self.message_contents[i]['snippet']) self.is_first = False # Get contents if um_menu._menu is not None: um_menu.clear() for l in labels: threadIds = [] if len(labels) > 1: # Set each labels' menu um_menu.add(rumps.MenuItem( l, callback=lambda x, y=l: self.open_gmail(y))) um_menu[l].title = '%s: %d' % (l, len(ids[l])) for i in sorted([i for i in self.messages[l] if 'Subject' in self.message_contents[i]], key=lambda x: dateutil.parser.parse( self.message_contents[x]['Date']) .isoformat(), reverse=True): v = self.message_contents[i] if v['threadId'] in threadIds: continue threadIds.append(v['threadId']) title = '%s %s | %s' % (v['Date'], v['FromName'], v['Subject']) title = title[0:80] if len(labels) > 1: m = um_menu[l] else: m = um_menu if len(m) < self.mails_max_show: m.add( rumps.MenuItem( l+str(i), callback=lambda x, y=l, z=i: self.show_mail(y, z))) m[l+str(i)].title = title m[l+str(i)].add(rumps.MenuItem( l+str(i)+'snippet', callback=lambda x, y=l, z=i: self.show_mail(y, z))) m[l+str(i)][l+str(i)+'snippet'].title = v['snippet'] if commandline or self.debug_mode: print '' print 'labels: %s' % (self.settings['labels'] if 'labels' in self.settings else '') print 'filter: %s' % (self.settings['filter'] if 'filter' in self.settings else '') print 'Total number of unread messages: %d\n' % len(all_ids) for l in labels: if len(labels) > 1: print '%d messages for %s' % (len(ids[l]), l) for i in um_menu[l].values(): print '%s\n' % i.title else: for i in um_menu.values(): print '%s\n' % i.title
def status(self, _): rumps.notification("Freelan", "Status Notification", "Nothing to say")
def _update_status(self, delay): time.sleep(delay) if self.menu_pause_button.state: logging.info("HipStatus is paused: status will not be updated") return now = datetime.datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S") try: hipchat_user = self.hipchat.get_status(self.preferences.email()) except Unauthorized: rumps.notification("Authentication error to HipChat",'', "It looks like something may be wrong with your API token. Click here to update, or use " "the 'Preferences...' menu option.", data={'update_token': ''}) return except UserNotFound: rumps.notification("Could not find the user in HipChat", self.preferences.email(), "Your saved email address could not be found in HipChat. Click here to update, or use " "the 'Preferences...' menu option.", data={'update_email': ''}) return except (RateLimited, ServerError, ServiceUnavailable): rumps.notification("There seems to be a problem with HipChat", '', "There was an error indicating an issue " "on HipChat's end. If the issue persists click here to open an IT Help ticket.", data={'open_ticket': ticket_url}) return if not hipchat_user['presence']: logging.info("The user is not online") return busy_hipstatus = True if hipchat_user['presence']['show'] != 'chat' else False try: office365_calendar = self.office365.calendar_status(now) except Unauthorized: rumps.notification("Authentication error to Office 365", '', "Something may be wrong with your Office 365 email address/password. Click here to try " "updating your password.", data={'update_o365': ''}) return except ServerError: rumps.notification("There seems to be a problem with Office 365", '', "There was an error indicating an " "issue on Office 365's end. If the issue persists click here to open an IT Help ticket.", data={'open_ticket': ticket_url}) return if office365_calendar['value']: busy_office365 = True if office365_calendar['value'][0]['ShowAs'] == 'Busy' else False else: busy_office365 = False if busy_hipstatus == busy_office365: logging.info("Status unchanged") return message = '' update_data = { 'name': hipchat_user['name'], 'email': hipchat_user['email'], 'mention_name': hipchat_user['mention_name'], 'title': hipchat_user['title'], 'timezone': self.preferences.timezone(), 'is_group_admin': hipchat_user['is_group_admin'], 'presence': { 'status': None, 'show': None, } } if busy_hipstatus and not busy_office365: logging.info("Setting HipChat status to 'Available'") update_data['presence']['status'] = '' update_data['presence']['show'] = None message = "You are now 'Available'" elif busy_office365 and not busy_hipstatus: logging.info("Setting HipChat status to 'Do not disturb'") update_data['presence']['status'] = self.preferences.default_message() update_data['presence']['show'] = 'dnd' message = "You are now set to 'Do not disturb'" self.hipchat.update_status(update_data) rumps.notification("Status Updated", message, "Your status in HipChat has been updated", sound=False)