def main(wf): request = get_request(wf.args[0]) if request is None: notify("Timer not created", "Invalid request %s" % wf.args[0]) return set_timer(request)
def logout(): data = {'action': 'logout'} try: res = post(LOGIN_URL, data=data, timeout=1) notify(title=str(res.status_code), text=res.text) except URLError as e: notify(title=str(e.errno), text=str(e.reason))
def search_metal_archives(queue, text, field='name'): results = [] r = web.get('https://www.metal-archives.com/search/ajax-band-search/', { 'field': field, 'query': text }) r.raise_for_status() data = r.json() if 'error' in data: error = data['error'] if len(error) > 0: notify('Band search error!', error) return if not 'aaData' in data: return # Each result is on the following form: # ["<a href=\"https://www.metal-archives.com/bands/BAND/NUMBER\">BAND</a> <!-- LOAD TIME -->" , # "GENRE", # "COUNTRY"] for res in data['aaData']: if len(res) < 3: continue (link, genre, country) = res (band, url) = parse_link(link) if not band or not url: continue results.append(Result(band, url, genre, country)) queue.put(results)
def main(wf): query_api = FULLINFO_API.format(date="20190908") fullinfo = GetFullInfo(query_api) #work wf.add_item(u"今天是%s" % (GetWork(fullinfo)), "") #time ts = GetTs(TS_API) wf.add_item(u'北京时间', ts, arg=ts, valid=True) notify(u"当前时间", ts) #nongli wf.add_item(u'农历', GetNongli(fullinfo), arg=GetNongli(fullinfo), valid=True) #week wf.add_item(u'星期', GetWeek(fullinfo), arg=GetWeek(fullinfo), valid=True) #suit wf.add_item(u'宜', fullinfo["suit"], arg=fullinfo["suit"], valid=True) #avoid wf.add_item(u'忌', fullinfo["avoid"], arg=fullinfo["avoid"], valid=True) wf.send_feedback()
def main(wf): import argparse from workflow.notify import notify parser = argparse.ArgumentParser() parser.add_argument('profile', nargs='?', default=None) args = parser.parse_args(wf.args) #################################################################### # Get saved profiles or use Default #################################################################### profiles = wf.settings.setdefault("profiles", []) wf.logger.debug("profiles=%s", ', '.join(profiles)) profile = args.profile if not profile: # we have no data to show, so show a warning and stop notify('No profile specified') return 1 #################################################################### # Save the added profiles #################################################################### profiles.append(profile) wf.settings['profiles'] = profiles notify('Profile will be searched', profile) run_in_background( BACKGROUND_JOB_KEY, ['/usr/bin/python', wf.workflowfile(UPDATE_INDEX_COMMAND)]) return 0 # 0 means script exited cleanly
def cli(query, set_variable_name, set_variable_value): if set_variable_name and set_variable_value: # Set the value to workflow setting wf.settings[set_variable_name] = set_variable_value title = VARIABLES[set_variable_name][0] notify("{} successfully".format(title)) elif set_variable_name: # Show only one item when the user selects title, default_value = VARIABLES[set_variable_name] current_value = wf.settings.get(set_variable_name, default_value) item = wf.add_item(title=title, valid=True, subtitle="Current value: {}".format(current_value)) item.setvar("SET_VARIABLE_NAME", set_variable_name) item.setvar("SET_VARIABLE_VALUE", query) wf.send_feedback() else: # Show all possible variables if query: variables = wf.filter(query, VARIABLES.items(), key=lambda item: item[1][0]) else: variables = VARIABLES.items() for variable_name, (title, default_value) in variables: current_value = wf.settings.get(variable_name, default_value) item = wf.add_item( title=title, valid=True, subtitle="Current value: {}".format(current_value), ) item.setvar("SET_VARIABLE_NAME", variable_name) item.setvar("VARIABLE_CURRENT_VALUE", current_value) wf.send_feedback()
def logout(): data = { 'action': 'logout' } try: res = post(LOGIN_URL, data=data, timeout=1) notify(title=str(res.status_code), text=res.text) except URLError as e: notify(title=str(e.errno), text=str(e.reason))
def main(wf): args = wf.args log.debug(args) if args[0] == u'--account': username = wf.save_password(u'username', args[1]) password = wf.save_password(u'password', args[2]) return 0 elif args[0] == u'--logout': logout() return 0 try: username = wf.get_password(u'username') password = wf.get_password(u'password') except PasswordNotFound: notify(title=u'Account Missing', text=u'set your account by "thu account [username] [password]" Firstly.') return -1 if args[0] == u'--login': login(username, password) elif args[0] == u'--info': info(username, password) elif args[0] == u'--learn': learn(username, password) elif args[0] == u'--academic': academic(username, password) elif args[0] == u'--mail': mails(username, password) elif args[0] == u'--clear': wf.delete_password(u'username') wf.delete_password(u'password')
def remove_task(gid): name = get_task_name(gid) status = server.tellStatus(secret, gid, ['status'])['status'] if status in ['active', 'waiting', 'paused']: server.remove(secret, gid) server.removeDownloadResult(secret, gid) notify('Download removed:', name)
def cli(task_id, complete, track): if track and complete: raise ValueError("Only one of track and complete can be true.") sync_client = create_todoist_sync_client(wf.settings[TODOIST_API_TOKEN]) todoist_state = get_todoist_state(wf, sync_client) item = next(item for item in todoist_state["items"] if item["id"] == task_id) if track: # TODO # Get project name and try to map it to Toggl project todoist_project_name = next( (p["name"] for p in todoist_state["projects"] if p["id"] == item["project_id"]), None, ) toggl_client = create_toggl_client(wf.settings[TOGGL_API_TOKEN]) toggl_project_map = get_toggl_project_map(wf, toggl_client) # If project with the same name exists, set pid to this project ID toggl_project_id = toggl_project_map.get(todoist_project_name) # Start a new time entry toggl_client.start_time_entry(item["content"], toggl_project_id) # Update notify message to show tracking project notify( u"Start tracking", "{} ({})".format( item["content"], todoist_project_name if toggl_project_id else "No Project", ), ) if complete: item.complete() sync_client.commit() notify(u"Complete task", item[u"content"])
def main(wf): import os # Argument parsing configuration parser = argparse.ArgumentParser() parser.add_argument('--setlang', dest='lang', nargs='?', default=0) parser.add_argument('query', nargs='?', default=None) args = parser.parse_args(wf.args) if args.lang == '1': global lang lang = 1 # Set global lang # Call different functions filtering by argument if 'showmanga:' in args.query: # Search and show list of results mid = args.query.split('showmanga:')[1] # Parse the unique manga id search_by_mid(wf, mid) elif 'downloadmanga:' in args.query: # Perform a massive download of selected manga mid = args.query.split('downloadmanga:')[1] # TODO check if there is at least 1 element notify.notify("Background download started!", "Multithreading download started. You will be notified when completed.", sound='Submarine') wf.add_item("Download started", "At the end you will be notified in the notification center.", valid=False, arg="", autocomplete="") # Autocomplete will restore the clear command # Run massive download in background (~ subprocess.call) run_in_background('download', ['/usr/bin/python', wf.workflowfile('mangaedenAPI.py'), 'dmanga:' + mid]) wf.send_feedback() elif 'dmanga:' in args.query: # TODO better error handling while background download is running mid = args.query.split('dmanga:')[1] download_manga(mid) else: # Search on mangaeden json list query = args.query.lower() search_by_query(wf, query)
def auth(self, token): with open(TOKEN_FILE, 'w') as f: f.write(json.dumps({ 'access_token': token, 'expire_at': int(time.time()) + 24 * 30 * 60 * 60, })) notify(u'授权成功', u'您已成功授权,有效期为30天')
def main(wf): args = wf.args log.debug(args) if args[0] == u'--account': username = wf.save_password(u'username', args[1]) password = wf.save_password(u'password', args[2]) return 0 elif args[0] == u'--logout': logout() return 0 try: username = wf.get_password(u'username') password = wf.get_password(u'password') except PasswordNotFound: notify( title=u'Account Missing', text= u'set your account by "thu --account [username] [password]" Firstly.' ) return -1 if args[0] == u'--login': login(username, password) elif args[0] == u'--info': info(username, password) elif args[0] == u'--learn': learn(username, password) elif args[0] == u'--academic': academic(username, password) elif args[0] == u'--clear': wf.delete_password(u'username') wf.delete_password(u'password')
def main(wf): import ast # 得到查询字符串 user_dict = ast.literal_eval(wf.args[0]) # 拼接卡片字段 front = user_dict['pinyin'] jieshi = '<br/>'.join(user_dict['jieshi']) back = user_dict['word'] + '<br>' + jieshi # 添加卡片信息 note = { "deckName": u"汉语字词及成语", "modelName": "Basic", "fields": { "Front": front, "Back": back }, "options": { "allowDuplicate": False }, "tags": [ "百度词典" ] } # 添加到Anki try: invoke('addNote', note=note) notify(title=u'已成功添加卡片信息', text=user_dict['word']) # 捕捉异常信息 except Exception, e: notify(title=u'添加卡片失败!', text=str(e))
def cli(stop): toggl_client = create_toggl_client(wf.settings[TOGGL_API_TOKEN]) if stop: log.debug(u"Stop the current entry {}".format(stop)) toggl_client.end_time_entry(stop) notify(u"Stop the current entry") else: log.debug("View the current entry") current_entry = toggl_client.get_current_time_entry() log.debug(u"Current entry: {}".format(current_entry)) if current_entry: item = wf.add_item( title=u"Current entry: {}".format( current_entry["description"]), subtitle=u"Press CMD + Enter to stop this entry", valid=False, ) item.add_modifier( "cmd", subtitle="Stop this entry", valid=True, arg="--stop {}".format(current_entry["id"]), ) else: wf.add_item("There is no running entry") wf.send_feedback()
def get_url(gid): urls = server.getFiles(secret, gid)[0]['uris'] if urls: url = urls[0]['uri'] notify('URL has been copied to clipboard:', url) print(url, end='') else: notify('No URL found')
def auth(self, token): with open(TOKEN_FILE, 'w') as f: f.write( json.dumps({ 'access_token': token, 'expire_at': int(time.time()) + 24 * 30 * 60 * 60, })) notify(u'授权成功', u'您已成功授权,有效期为30天')
def change_temperature(self, wf): temperature = wf.args[2] req = aircon.ChangeTemperatureRequest(create_config(), temperature) dic = RemoClient.call(req) temperature = dic['temp'] mode = dic['mode'] text = u'{0}度({1})になったよ'.format(temperature, mode) notify.notify(text, u'エアコンの温度を変更')
def insert_work(task_id, then, now): now = now user = get_user() hours, minutes = hours_and_minutes(then, now) duration = 'PT' + str(hours) + 'H' + str(minutes) + 'M' data = ''' <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> <s:Body> <InsertWork xmlns="http://www.timelog.com/api/tlp/v1_6"> <work xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> <WorkUnit> <GUID>{guid}</GUID> <AllocationGUID>{aguid}</AllocationGUID> <TaskID>{task_id}</TaskID> <EmployeeInitials>{initials}</EmployeeInitials> <Duration>{duration}</Duration> <StartDateTime>{then}</StartDateTime> <EndDateTime>{now}</EndDateTime> <Description>{description}</Description> <TimeStamp i:nil="true" /> <IsEditable>false</IsEditable> <AdditionalText i:nil="true" /> <Details i:nil="true" /> </WorkUnit> </work> <source>50</source> <token xmlns:d4p1="http://www.timelog.com/api/tlp/v1_3" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> <d4p1:Initials>{initials}</d4p1:Initials> <d4p1:Expires>{expires}</d4p1:Expires> <d4p1:Hash>{hash}</d4p1:Hash> </token> </InsertWork> </s:Body> </s:Envelope>'''.format(guid=uuid.uuid4(), aguid='00000000-0000-0000-0000-000000000000', task_id=task_id, initials=user.token.initials, duration=duration, then=then.isoformat(), now=now.isoformat(), description='', expires=user.token.expires, hash=user.token.hash) headers = {'Content-Type': 'text/xml', 'SOAPAction': 'InsertWorkRequest'} response = web.post( "https://app1.timelog.com/arnsbomedia/WebServices/ProjectManagement/V1_6/ProjectManagementServiceSecure.svc", data=data, headers=headers) if response.status_code == 200: notify( u'Done! ʕっ•ᴥ•ʔっ', 'Registed ' + str(hours) + ' hours & ' + str(minutes) + ' minutes', 'Pop') else: notify('Ohhh no', 'TimeLog responded with ' + str(response.status_code), 'Basso')
def save_token(url): # todo parse_result = urlparse(url) data = dict(map(lambda x: x.split('='), parse_result.fragment.split('&'))) token = data['access_token'] wf.save_password(TOKEN_KEY, token) expire = int(data['expires_in']) + time.time() wf.store_data(TOKEN_EXPIRES_IN, expire) notify('授权成功', '授权码已保存到Keychain')
def save_new_access_token(self, access_token): """ Function to save the access_token. Requires a wf object to save permanently. """ self.access_token = access_token if self.wf is not None: self.wf.save_password('access_token', access_token) from workflow.notify import notify notify('Salesforce', 'New access token.')
def set_suffix(query): """Set new value to the suffix environment variable.""" try: util.set_config('suffix', query, exportable=True) notify.notify('Alfred PDF Tools', 'Suffix set to "{}".'.format(query)) except SuffixNotSetError: notify.notify('Alfred PDF Tools', 'An error occurred while setting the suffix.')
def get_documents(wf, api_key, logger): auth_headers = {'Authorization': 'Bearer {0}'.format(api_key)} user_response = web.get(user_api, headers=auth_headers) if user_response.status_code != 200: wf.delete_password('quip_api_key') notify.notify('Quip API key incorrect, please re-set') else: user_response = user_response.json() folders = user_response['group_folder_ids'] + [ user_response['private_folder_id'] ] documents = set() while folders: logger.info('{0} folders left'.format(len(folders))) folder_ids = ','.join(folders) folder_responses = web.get(folders_api, { 'ids': folder_ids }, headers=auth_headers).json() folders = [] for folder_info in folder_responses.values(): children = folder_info['children'] documents.update({ child['thread_id'] for child in children if child.get('thread_id') }) folders.extend(child['folder_id'] for child in children if child.get('folder_id')) logger.info('Fetching {0} documents'.format(len(documents))) document_ids = ','.join(documents) document_data = web.get(threads_api, { 'ids': document_ids }, headers=auth_headers).json() results = [] for thread in document_data.values(): parser = Parser() result = { 'title': thread['thread']['title'], 'link': thread['thread']['link'], 'type': thread['thread']['type'], 'id': thread['thread']['id'] } parser.feed(thread.get('html', '')) result['text'] = wf.decode(' '.join(parser.text)) results.append(result) return results
def main(wf): """ TODO: apply for token definition exceed one line avoid command mode called directly notes not work """ # The Workflow instance will be passed to the function # you call from `Workflow.run`. Not so useful, as # the `wf` object created in `if __name__ ...` below is global. # # Your imports go here if you want to catch import errors (not a bad idea) # Get args from Workflow, already in normalized Unicode if len(wf.args): logger.info("called " + DELIMITER.join(wf.args) + " length " + str(len(wf.args))) q = wf.args[0] else: q = "test " # Do stuff here ... mode_q = True try: args = q.strip().split(DELIMITER) if len(args) == 1: # query mode if not q.endswith(' '): wf.add_item(u"Ending with space to query...") else: query(args[0]) else: # command mode mode_q = False cmd = args[0] if cmd.lower() == "add" and len(args) == 2: add(args[1]) elif cmd.lower() == "notify" and len(args) == 2: notify(cmd, args[1]) # elif cmd.lower() == "note" and len(args) >= 3: # note(args[1], args[2:]) else: logger.warn("illegal command: " + str(cmd)) except RuntimeError as e: if mode_q: wf.add_item(u"ERROR", str(e.message)) else: notify("ERROR" + str(e.message)) # Add an item to Alfred feedback # Send output to Alfred. You can only call this once. # Well, you *can* call it multiple times, but Alfred won't be listening # any more... wf.send_feedback()
def test_invalid_notifications(infopl, alfred4): """Invalid notifications""" with pytest.raises(ValueError): notify.notify() # Is not installed yet assert os.path.exists(APP_PATH) is False assert notify.notify('Test Title', 'Test Message') is True # A notification should appear now, but there's no way of # checking whether it worked assert os.path.exists(APP_PATH) is True
def show_temperature_and_humidity(self, wf): req = device.ListRequest(create_config()) dic = RemoClient.call(req) newest_events = dic[0]['newest_events'] temp = newest_events['te']['val'] humo = newest_events['hu']['val'] text = u"室温: %0.2f度\\n湿度: %0.2f%" % (temp, humo) notify.notify(u'室温と湿度', text) wf.add_item(title=text, icon='icon.png', arg=text, valid=True) wf.send_feedback()
def conn(looker_host, my_token, my_secret): from lookerapi import LookerApi my_host = 'https://%s.looker.com:19999/api/3.0/' % (looker_host) looker = LookerApi(host=my_host, token=my_token, secret=my_secret) if looker is None: notify('Alfred - Looker', 'Connection to Looker failed!') exit() return looker
def main(workflow): path = workflow.args[0].strip() config = Config(path) if config.validate(): # Behavior: overwrite existing data workflow.store_data("configuration", config) notify(title="Success!", text="Cheat sheets updated to {}".format(config.getPath())) else: notify(title="Error:(", text="The path doesn't exist") return 0
def do_set_default(args): """Set site as default.""" from workflow.util import run_trigger, set_config from workflow.notify import notify s = site_from_env() log.debug('[default] site=%r', s) set_config('site_id', s.id, exportable=True) set_config('site_name', s.name, exportable=True) run_trigger('search') notify(u'Updated Settings', u'Default site changed to “{s.name}”'.format(s=s))
def set_timer(request): name = request[0] duration = int(request[1]) unit = request[2] seconds = get_seconds(duration, unit) time.sleep(seconds) notify("%s" % name, "set %s%s ago" % (duration, unit), "Purr")
def config(wf, args): if len(args) != 2: notify("Can't config", "type: ml config <username> <password>") return 1 wf.logger.debug(args) username = args.pop(0) password = args.pop(0) wf.save_password(USERNAME_KEY, username) wf.save_password(PASSWORD_KEY, password) notify("Set success", "Username:%s Password: %s" % (username, password)) return 0
def add(self, wid): if not self.access_token: notify( u'您必须填写授权码才能添加单词进词库', u'请访问github主页了解详情', ) return self.post('learning', { 'access_token': self.access_token, }, { 'id': wid, })
def main(workflow): try: auth_token = workflow.get_password('ghpr-auth-token') username = workflow.cached_data('username', max_age=0) if username is None: username = get_username(auth_token) workflow.cache_data('username', username) workflow.cache_data('pull_requests', get_pull_requests(username, auth_token)) workflow.send_feedback() except PasswordNotFound: notify('Github PRs', 'Please set the API key first.') return 1
def main(wf): """Run workflow.""" args = docopt(__doc__) query = wf.args[1].encode('utf-8') abs_path = os.environ['abs_path'] pdfs = abs_path.split('\t') suffix = os.environ['suffix'] if args.get('--optimize'): optimize(query, pdfs) elif args.get('--progress'): get_progress() elif args.get('--encrypt'): encrypt(query, pdfs) elif args.get('--decrypt'): decrypt(query, pdfs) elif args.get('--mrg'): merge(query, pdfs, False) elif args.get('--mrg-trash'): merge(query, pdfs, True) elif args.get('--split-count'): split_count(query, abs_path, suffix) elif args.get('--split-size'): split_size(query, abs_path, suffix) elif args.get('--slice-multi'): slice_(query, abs_path, False, suffix) elif args.get('--slice-single'): slice_(query, abs_path, True, suffix) elif args.get('--crop'): crop(pdfs) elif args.get('--scale'): scale(query, pdfs) elif args.get('--suffix'): set_suffix(query) if wf.update_available: notify.notify('Alfred PDF Tools', 'A newer version of the workflow is available.', 'Glass') wf.start_update()
def connect(name, passwd): params = dict(opr='pwdLogin', userName=name, pwd=passwd) r = web.post(loginurl, params) r.raise_for_status() log.debug(r.status_code) # encoding 的值为 None # 不得不BS一下硬件公司的软件程序员的编码水平 # 没有 encoding ,JSON用单引号 log.debug(r.encoding) # 是哪个傻X在JSON里面使用单引号! jsonstr = unicode(r.content, 'utf8').replace("'", '"') result = json.loads(jsonstr) notify.notify(result['msg'], u'user: %s' % result['userName'])
def parseFiles(): log.info("Parsing Downloaded Files") log.info('Creating DataFileBuilder') # Open the output file csv = open('emoji.tab', 'w') msg = u'Converting emoji data' parse_html_file(csv, 'full-emoji-list.html', msg) msg = u'Converting skin-tone data' parse_html_file(csv, 'full-emoji-modifiers.html', msg) emoji_count = wf.stored_data('emoji_count') notify(title=u'Emoji Taco', text=u'Is ready for use. {} emoji processed'.format(emoji_count), sound=None)
def login(username, password): md5pwd = hexlify(md5(password.encode('latin-1')).digest()) data = { 'action': 'login', 'username': username, 'password': u'{MD5_HEX}' + md5pwd, 'ac_id': 1 } try: res = post(LOGIN_URL, data=data, timeout=1) notify(title=str(res.status_code), text=res.text) except URLError as e: notify(title=str(e.errno), text=str(e.reason))
def do_notify(self): """Show a notification.""" wf = self.wf args = self.args msg = args.get('<message>') if wf.settings.get('suppress_notifications'): log.debug('Notifications turned off') return if msg.strip() == '': log.debug('Empty notification') return from workflow.notify import notify notify('Password Generator', msg)
def test_notifyapp_called(infopl, alfred4): """Notify.app is called""" c = WorkflowMock() notify.install_notifier() with c: assert notify.notify('Test Title', 'Test Message') is False assert c.cmd[0] == APPLET_PATH
def authorize(wf): wf.logger.info('Running Authorization') g = GoogleInterface(wf) # credentials = g.get_credentials() import httplib2 if g.credentials: use_ssl = get_value_from_settings_with_default_boolean(wf, 'use_ssl', True) http = g.HTTP_INSTANCE #, ca_certs="/usr/local/etc/openssl/cert.pem")) notify(u'Google Authorization', 'Success!!')
def test_notifyapp_called(self): """Notify.app is called""" c = WorkflowMock() with InfoPlist(): notify.install_notifier() with c: self.assertFalse(notify.notify('Test Title', 'Test Message')) self.assertEqual(c.cmd[0], APPLET_PATH)
def main(wf): ''' main to check args and call ''' tr = Transmission(wf) if wf.args[0] == '--register' and len(wf.args) > 1: registerTransmission(wf, tr) elif wf.args[0] == '--reset': tr.resetConfig() elif wf.args[0] == '--copy' and len(wf.args) > 1: print(wf.args[1], end='') notify(title='Link copied in your clipboard') elif wf.args[0] == '--open' and len(wf.args) > 1: if tr.connection(): tr.addTorrent(wf.args[1]) else: nyaa(wf)
def get_notified(): threading.Timer(1.0, get_notified).start() for gid in watch_list: try: task = server.tellStatus(secret, gid, ['status', 'errorMessage']) status = task['status'] except (xmlrpclib.Fault, socket.error): pass else: if status == 'active': return elif status == 'complete': notify('Download completed: ', get_task_name(gid)) elif status == 'error': notify('Error occurred while downloading "' + get_task_name(gid) + '":', task['errorMessage']) with lock: watch_list.remove(gid)
def sync(cls, background=False): from wunderlist.api import root start = time.time() instance = None root_data = root.root() log.info('Retrieved Root revision in %s', time.time() - start) try: instance = cls.get() except Root.DoesNotExist: pass if not background and (not instance or instance.revision != root_data['revision']): notify('Please wait...', 'The workflow is making sure your tasks are up-to-date') return cls._perform_updates([instance], [root_data])
def test_invalid_notifications(self): """Invalid notifications""" with InfoPlist(): self.assertRaises(ValueError, notify.notify) # Is not installed yet self.assertFalse(os.path.exists(APP_PATH)) self.assertTrue(notify.notify('Test Title', 'Test Message')) # A notification should appear now, but there's no way of # checking whether it worked self.assertTrue(os.path.exists(APP_PATH))
def scale(query, pdfs): """Scale PDF files to a given page size.""" try: for pdf in pdfs: reader = PdfFileReader(pdf, strict=False) if reader.isEncrypted: raise FileEncryptedError writer = PdfFileWriter() w, h = [float(i) * 72 for i in query.split('x')] for i in xrange(reader.numPages): inp_page = reader.getPage(i) inp_page_w = float(inp_page.mediaBox[2]) inp_page_h = float(inp_page.mediaBox[3]) scale_w = w / inp_page_w scale_h = h / inp_page_h scale = min(scale_w, scale_h) out_page = PageObject.createBlankPage(None, w, h) out_page.mergeScaledTranslatedPage(inp_page, scale, 0, 0) writer.addPage(out_page) noextpath = os.path.splitext(pdf)[0] out_file = '{} (scaled).pdf'.format(noextpath) with open(out_file, 'wb') as f: writer.write(f) except FileEncryptedError: notify.notify('Alfred PDF Tools', 'Scale action cannot handle an encrypted PDF file.') except PdfReadError: notify.notify('Alfred PDF Tools', 'Cannot scale a malformed PDF file.')
def decrypt(query, pdfs): """Decrypt PDF files.""" try: for pdf in pdfs: reader = PdfFileReader(pdf, strict=False) if reader.isEncrypted: reader.decrypt(query) writer = PdfFileWriter() for i in xrange(reader.numPages): writer.addPage(reader.getPage(i)) noextpath = os.path.splitext(pdf)[0] out_file = "{} (decrypted).pdf".format(noextpath) with open(out_file, 'wb') as f: writer.write(f) notify.notify('Alfred PDF Tools', 'Decryption successfully completed.') else: notify.notify('Alfred PDF Tools', 'The PDF file is not encrypted.') except PdfReadError: notify.notify('Alfred PDF Tools', 'The entered password is not valid.')
def run(wf, argv): """Run ``searchio add`` sub-command.""" args = docopt(usage(wf), argv) ctx = Context(wf) d = parse_args(wf, args) s = engines.Search.from_dict(d) if not util.valid_url(d['search_url']): raise ValueError('Invalid search URL: {!r}'.format(d['search_url'])) if d['suggest_url'] and not util.valid_url(d['suggest_url']): raise ValueError('Invalid suggest URL: {!r}'.format(d['suggest_url'])) p = ctx.search(s.uid) with open(p, 'wb') as fp: json.dump(s.dict, fp, sort_keys=True, indent=2) # m.save(**d) log.debug('Adding new search to info.plist ...') notify('Added New Search', d['title'])
def encrypt(query, pdfs): """Encrypt PDF files.""" for pdf in pdfs: reader = PdfFileReader(pdf, strict=False) if not reader.isEncrypted: writer = PdfFileWriter() for i in xrange(reader.numPages): writer.addPage(reader.getPage(i)) writer.encrypt(query) noextpath = os.path.splitext(pdf)[0] out_file = "{} (encrypted).pdf".format(noextpath) with open(out_file, 'wb') as f: writer.write(f) notify.notify('Alfred PDF Tools', 'Encryption successfully completed.') else: notify.notify('Alfred PDF Tools', 'The PDF file is already encrypted.')
def merge(query, pdfs, should_trash): """Merge PDF files.""" try: paths = [os.path.split(path)[0] for path in pdfs] if len(pdfs) < 2: raise SelectionError if not paths[1:] == paths[:-1]: raise MultiplePathsError merger = PdfFileMerger(strict=False) for pdf in pdfs: reader = PdfFileReader(pdf) if reader.isEncrypted: raise FileEncryptedError merger.append(reader) if should_trash: for pdf in pdfs: send2trash(pdf) merger.write(paths[0] + '/' + query + '.pdf') except SelectionError: notify.notify('Alfred PDF Tools', 'You must select at least two PDF files to merge.') except MultiplePathsError: notify.notify('Alfred PDF Tools', 'Cannot merge PDF files from multiple paths.') except FileEncryptedError: notify.notify('Alfred PDF Tools', 'Merge action cannot handle an encrypted PDF file.') except PdfReadError: notify.notify('Alfred PDF Tools', 'Cannot merge a malformed PDF file.')
def switch_task(gid): name = get_task_name(gid) status = server.tellStatus(secret, gid, ['status'])['status'] if status in ['active', 'waiting']: server.pause(secret, gid) notify('Download paused:', name) elif status == 'paused': server.unpause(secret, gid) notify('Download resumed:', name) elif status == 'complete': pass else: urls = server.getFiles(secret, gid)[0]['uris'] if urls: url = urls[0]['uri'] server.addUri(secret, [url]) server.removeDownloadResult(secret, gid) notify('Download resumed:', name) else: notify('Cannot resume download:', name)
def download_manga(mid): """Download whole manga """ i = 0 import os.path try: data = get_json_info(mid) for chapter in data['chapters']: i += 1 download_chapter(data['alias'], chapter[0], chapter[3]) if i == 0: # No chapters in this manga! notify.notify("Download Failed!", "This manga has no chapters!", sound="Bass") else: folder_path = os.path.expanduser("~") + "/" + str(data['alias']) + "/" notify.notify("Download completed!", "Look at " + folder_path + " folder!", sound='Glass') except Exception: notify.notify("Download Failed!", "You can restart it!\nYour progress will not be lost!" + folder_path + " folder!")
def main(wf): qs = wf.args[0] if len(wf.args) else None if qs == 'wifi': networkset = ['networksetup', '-setairportpower', 'en0'] networkget = ['networksetup', '-getairportpower', 'en0'] status = subprocess.check_output(networkget).strip() log.debug(status) if status.endswith('Off'): networkset.append('on') subprocess.call(networkset) notify.notify(u'打开Wi-Fi', u'已开启') elif status.endswith('On'): networkset.append('off') subprocess.call(networkset) notify.notify(u'关闭Wi-Fi', u'已关闭') else: status = subprocess.check_output( ['networksetup', '-getinfo', 'Wi-Fi']) log.debug(status) notify.notify(u'Wi-Fi信息', status)
def optimize(query, pdfs): """Optimize PDF files.""" try: if query: if not query.lstrip('+-').isdigit(): raise NotIntegerError if query: if int(query) < 0: raise NegativeValueError for pdf in pdfs: command = "echo -y | ./k2pdfopt '{}' -as -mode copy -dpi {} -o '%s (optimized).pdf' -x".format(pdf, query) proc = Popen(command, shell=True, stdout=PIPE) while proc.poll() is None: line = proc.stdout.readline() if "Reading" in line: pg_cnt = line.split() wf.cache_data('page_count', pg_cnt[1]) if "SOURCE PAGE" in line: pg_no = line.split() wf.cache_data('page_number', pg_no[2]) notify.notify('Alfred PDF Tools', 'Optimization successfully completed.') except NotIntegerError: notify.notify('Alfred PDF Tools', 'The argument is not an integer.') except NegativeValueError: notify.notify('Alfred PDF Tools', 'Negative integer is not a valid argument.')