def add_directory_item(self, name, url, mode, context='', iconimage=''): # listitem listitem = xbmcgui.ListItem(name) listitem.setArt({'icon': iconimage}) # context menu contextMenu = [] if context == 'smartlist': # スマートリストを編集 contextMenu.append(( Common.STR(30904), 'RunPlugin(%s?%s)' % (sys.argv[0], urlencode({'mode': 'beginEditSmartList', 'name': name})))) # スマートリストを削除 contextMenu.append(( Common.STR(30905), 'RunPlugin(%s?%s)' % (sys.argv[0], urlencode({'mode': 'deleteSmartList', 'name': name})))) elif context != 'top': # トップに戻る contextMenu.append(( Common.STR(30936), 'Container.Update(%s,replace)' % (sys.argv[0]))) # アドオン設定 contextMenu.append((Common.STR(30937), 'RunPlugin(%s?mode=openSettings)' % sys.argv[0])) listitem.addContextMenuItems(contextMenu, replaceItems=True) # add directory item url = '%s?%s' % (sys.argv[0], urlencode({'mode': mode, 'url': url})) xbmcplugin.addDirectoryItem(int(sys.argv[1]), url, listitem, True)
def select_date(self): # すべての日付 name = '[COLOR lightgreen]%s[/COLOR]' % Common.STR(30912) if self.args.get('ch') is None: mode = 'selectChannel' elif self.args.get('g0') is None: mode = 'selectGenre' else: mode = 'search' self.add_directory_item(name, '%s&sdate=&edate=' % self.query, mode, iconimage=Common.CALENDAR) # 月,火,水,木,金,土,日 w = Common.STR(30920).split(',') for i in range(120): d = datetime.date.today() - datetime.timedelta(i) wd = d.weekday() # 月日 # date1 = '%s(%s)' % (d.strftime(Common.STR(30919)), w[wd]) date1 = '%s(%s)' % (Common.strftime(d, Common.STR(30919)), w[wd]) date2 = d.strftime('%Y-%m-%d') if Common.isholiday(date2) or wd == 6: name = '[COLOR red]%s[/COLOR]' % date1 elif wd == 5: name = '[COLOR blue]%s[/COLOR]' % date1 else: name = date1 query = '%s&sdate=%s 00:00:00&edate=%s 23:59:59' % (self.query, date2, date2) if self.args.get('ch') is None: mode = 'selectChannel' elif self.args.get('g0') is None: mode = 'selectGenre' else: mode = 'search' self.add_directory_item(name, query, mode, iconimage=Common.CALENDAR) # end of directory xbmcplugin.endOfDirectory(int(sys.argv[1]))
def run(argv): plugin = Common(addon=xbmcaddon.Addon(), addon_handle=int(argv[1])) credential = Credential(plugin) content = Content(plugin, credential) params = dict(urllib_parse_qsl(argv[2][1:])) if 'action' in params: plugin.log('params = {0}'.format(params)) if params.get('action') == 'listHome': content.listHome() elif params.get('action') == 'listSubnavi': content.listSubnavi(params.get('path'), params.get('hasitems'), params.get('items_to_add')) elif params.get('action') == 'showVideos': content.showVideos(params.get('path'), params.get('show_videos')) elif params.get('action') == 'playVoD': content.playVoD(params.get('path')) elif params.get('action') == 'login': content.login() elif params.get('action') == 'logout': content.logout() elif params.get('action') == 'clearCache': content.clearCache() else: content.rootDir()
def search(key): try: # 番号案内ページのURL url = 'https://www.telnavi.jp/phone/%s' % key # ページ読み込み res = urlopen(url) status = res.getcode() if status == 200: # タグ抽出 html = res.read() soup = BeautifulSoup(html, 'html.parser') title = soup.find('title').get_text() # 電話番号08012000021の情報は?|電話番号検索の電話帳ナビ # 電話番号0120102030は司法書士法人新宿事務所 if re.match(r'電話番号[0-9]+は', title): name = re.sub(r'電話番号[0-9]+は', '', title) else: name = None else: name = None res.close() Common.log('key=%s name=%s status=%s url=%s' % (key, name, status, url)) except Exception as e: name = None Common.log(e) return name
def get_contextmenu(self): gtvid = self.item['gtvid'] title = self.item['title'] menu = [] # 詳細情報 menu.append((Common.STR(30906), 'Action(Info)')) # スマートリストに追加 try: if self.item['genre'][0]: genre = self.item['genre'][0].split('/') else: genre = ['', ''] except Exception: genre = ['', ''] args = { 'mode': 'beginEditSmartList', 'name': title, 'ch': self.item['ch'], 'g0': genre[0], 'g1': genre[1] } menu.append((Common.STR(30903), 'RunPlugin(%s?%s)' % (sys.argv[0], urlencode(args)))) # お気に入りに追加 if self.item['favorite'] == '0': # add args = { 'mode': 'switchFavorites', 'name': title, 'url': urlencode({ 'gtvid': gtvid, 'rank': 1 }) } menu.append((Common.STR(30925), 'RunPlugin(%s?%s)' % (sys.argv[0], urlencode(args)))) else: # delete args = { 'mode': 'switchFavorites', 'name': title, 'url': urlencode({ 'gtvid': gtvid, 'rank': 0 }) } menu.append((Common.STR(30926), 'RunPlugin(%s?%s)' % (sys.argv[0], urlencode(args)))) # サウンロードに追加 menu += Downloader().contextmenu(self.item, Request().content_url(gtvid)) # トップに戻る menu.append((Common.STR(30936), 'Container.Update(%s,replace)' % (sys.argv[0]))) return menu
def __init__(self): # トークン初期化 self.data = Common.read_json(Common.TOKEN_FILE) or {} # settings.xmlを作成 self.update_settings() # 表示するメール数 self.listsize = Common.GET('listsize') if self.listsize == 'Unlimited': self.listsize = 0 else: self.listsize = int(self.listsize)
def onRegState(self, param): # ログ Common.log('\n'.join([ # https://www.pjsip.org/pjsip/docs/html/structpj_1_1OnRegStateParam.htm 'status: %s' % param.status, 'code: %s' % param.code, 'reason: %s' % param.reason, # 'rdata: %s' % param.rdata, 'rdata.info: %s' % param.rdata.info, 'rdata.wholeMsg: \n-----\n%s\n-----' % '\n'.join(param.rdata.wholeMsg.strip().split('\r\n')), 'rdata.srcAddress: %s' % param.rdata.srcAddress, 'rdata.pjRxData: %s' % param.rdata.pjRxData, 'expiration: %s' % param.expiration, ])) info = self.getInfo() Common.log('\n'.join([ # https://www.pjsip.org/pjsip/docs/html/structpj_1_1AccountInfo.htm 'id: %s' % info.id, 'isDefault: %s' % info, 'uri: %s' % info.uri, 'regIsConfigured: %s' % info.regIsConfigured, 'regIsActive: %s' % info.regIsActive, 'regExpiresSec: %s' % info.regExpiresSec, 'regStatus: %s' % info.regStatus, 'regStatusText: %s' % info.regStatusText, 'regLastErr: %s' % info.regLastErr, 'onlineStatus: %s' % info.onlineStatus, 'onlineStatusText: %s' % info.onlineStatusText, ])) # 通知 if param.code == 200: Common.notify('Registered as SIP client', time=3000) else: Common.notify('SIP registration failed (%d)' % param.code, time=3000, error=True)
def update_settings(self): # テンプレートを読み込む template = Common.read_file(Common.TEMPLATE_FILE) # 設定ファイルに書き出すトークンを設定 keys = list(self.data.keys()) if len(keys) == 0: namelist = 'n/a' else: namelist = ('|'.join(keys)) if len(keys) == 1: Common.SET('defaultname', keys[0]) # 設定ファイルを書き出す Common.write_file( Common.SETTINGS_FILE, template.format(tokenname=namelist, tokenname2=namelist))
def open(self, filename): # ファイル読み込み filepath = os.path.join(self.cache_path, filename) f = open(filepath, 'r') lines = f.readlines() f.close() # パース header = [] body = [] params = {'Subject': Common.STR(30901), 'body': False} for line in lines: line = line.rstrip() if params['body'] is True: body.append(line) elif line == '': params['body'] = True else: pair = line.split(': ', 1) if len(pair) == 2: params[pair[0]] = pair[1] if pair[0] != 'Subject' and pair[0] != 'Message-Id': header.append('[COLOR green]%s:[/COLOR] %s' % (pair[0], pair[1])) # テキストビューア viewer_id = 10147 # ウィンドウを開く xbmc.executebuiltin('ActivateWindow(%s)' % viewer_id) # ウィンドウの用意ができるまで1秒待つ xbmc.sleep(1000) # ウィンドウへ書き込む viewer = xbmcgui.Window(viewer_id) viewer.getControl(1).setLabel('[COLOR orange]%s[/COLOR]' % params['Subject']) viewer.getControl(5).setText('%s\n\n%s' % ('\n'.join(header), '\n'.join(body)))
def beginEdit(self, name, ch, g0, g1): if ch: # keyword Common.SET('keyword', name) # channel channel = Channel().search(ch) Common.SET('channel', channel['name']) # genre genre = Genre().search(g0, g1) Common.SET('g0', genre['name0']) Common.SET(genre['id'], genre['name1']) else: # スマートリストでtitleが一致するものをダイアログに設定 for item in filter(lambda x: x['title'] == name, self.getList()): for key, val in item.items(): Common.SET(key, val)
class Channel(): DEFAULT_NAME = '[COLOR lightgreen]%s[/COLOR]' % Common.STR(30913) # すべてのチャンネル def __init__(self): self.data = Common.read_json(Common.CHANNEL_FILE) def search(self, key): result = {'id': '', 'name': '', 'hash': ''} for key, val in filter(lambda x: key in {x[0], x[1]['ch_name'], x[1]['hash_tag']}, self.data['ch_list'].items()): result['id'] = key result['name'] = val['ch_name'] result['hash'] = val['hash_tag'] return result def getList(self): result = [{'id': '', 'name': self.DEFAULT_NAME}] for key, value in self.data['ch_list'].items(): result.append({'id': key, 'name': value['ch_name']}) return sorted(result, key=lambda item: item['id']) def getLabel(self): return '|'.join(map(lambda x: x['name'], self.getList())) def getDefault(self): return self.DEFAULT_NAME
def check(self, refresh=True): # 管理用ファイル criterion_file = os.path.join(self.cache_path, '.criterion') newmails_file = os.path.join(self.cache_path, '.newmails') # ロケールを変更 locale.setlocale(locale.LC_TIME, 'en_US.UTF-8') # 前回表示時の月日を読み込む if os.path.isfile(criterion_file): f = open(criterion_file, 'r') criterion = f.read() f.close() else: # 前回表示時の月日が不明の場合は30日前に設定 d = datetime.datetime.utcnow() - datetime.timedelta(days=30) criterion = d.strftime('SINCE %d-%b-%Y') # 設定した期間のメールを検索 newmails, senders = self.receive(criterion) if len(newmails) > 0: # 新着メールのファイルパスリストを書き出す f = open(newmails_file, 'a') f.write('\n'.join(newmails) + '\n') f.close() xbmc.sleep(1000) # Kodiをアクティベート if Common.GET('cec') == 'true': xbmc.executebuiltin('XBMC.CECActivateSource') # 新着があることを通知 Common.notify('New mail from %s' % senders[newmails[0]]) # アドオン操作で呼び出された場合の処理 if refresh: if os.path.isfile(newmails_file): # 新着メールのファイルパスリストを読み込む f = open(newmails_file, 'r') newmails = f.read().split('\n') f.close() # 新着メールのファイルパスリストを削除 os.remove(newmails_file) else: newmails = [] # リストを表示 self.list(newmails) # 次回表示時のために今回表示時の月日を書き出す d = datetime.datetime.utcnow() criterion = d.strftime('SINCE %d-%b-%Y') f = open(criterion_file, 'w') f.write(criterion) f.close()
def __init__(self): # 設定をコピー self.settings = {} for key in ('id', 'pw', 'auto', 'addr', 'http', 'https', 'session'): self.settings[key] = Common.GET('garapon_%s' % key) # サーバアドレス self.server = 'http://%s' % self.settings['addr'] if self.settings['http']: self.server = '%s:%s' % (self.server, self.settings['http'])
def update(self): size = 0 for file in self.files: try: size = size + os.path.getsize( os.path.join(Common.CACHE_PATH, file)) except Exception: pass if size > 1024 * 1024: Common.SET( 'cache', '%.1f MB / %d files' % (size / 1024 / 1024, len(self.files))) elif size > 1024: Common.SET('cache', '%.1f kB / %d files' % (size / 1024, len(self.files))) else: Common.SET('cache', '%d bytes / %d files' % (size, len(self.files)))
def top(self): # 放送中の番組 self.add_directory_item(Common.STR(30916), self.query, 16, context='top', iconimage=Common.RETRO_TV) # 検索:日付 self.add_directory_item(Common.STR(30933), '', 'selectDate', context='top', iconimage=Common.CALENDAR) # 検索:チャンネル self.add_directory_item(Common.STR(30934), '', 'selectChannel', context='top', iconimage=Common.RADIO_TOWER) # 検索:ジャンル self.add_directory_item(Common.STR(30935), '', 'selectGenre', context='top', iconimage=Common.CATEGORIZE) # お気に入り self.add_directory_item(Common.STR(30923), '%s&rank=all' % self.query, 'search', context='top', iconimage=Common.FAVORITE_FOLDER) # ダウンロード Downloader().top(Common.DOWNLOADS_FOLDER) # スマートリスト for i in SmartList().getList(): title = i['title'] query = i['query'] self.add_directory_item(title, query, 'search', context='smartlist', iconimage=Common.BROWSE_FOLDER) # end of directory xbmcplugin.endOfDirectory(int(sys.argv[1]))
def check_timer(self): interval = Common.GET('interval') status = False if interval == 'None': self.timer = 0 elif self.timer < int(interval): self.timer += 1 else: status = True self.timer = 0 return status
def favorites(self): # 検索 response_body = Request().favorites(self.query) if response_body: response_data = json.loads(response_body) if response_data['status'] == 1: xbmc.executebuiltin('Container.Refresh') else: Common.log('switch favorites failed (status=%s)' % response_data['status'], error=True) Common.notify('Operation failed') else: Common.log('empty response', error=True) Common.notify('Operation failed')
def lookup(uri): name = None key = parse(uri) # 0で始まって9桁以上ある場合は電話番号として先ず電話帳、次にキャッシュ、最後にウェブを検索 if re.compile('^0[0-9]{8,}').search(key): # 電話帳を検索 name = PhoneBook().lookup(key) if name is None: # キャッシュを検索 cache = PhoneBook(Common.CACHE_FILE) name = cache.lookup(key) if name is None: # ウェブを検索 name = search(key) if name: # キャッシュに追加 cache.update(key, name or 'n/a') elif name == 'n/a': name = None # 以下は # http://www.ttc.or.jp/jp/document_list/pdf/j/STD/JJ-90.22v1.1.pdf # による elif key == 'Anonymous': # ユーザ拒否のため通知不可 name = Common.STR(32908) elif key == 'Coin line/payphone': # 公衆電話発信のため通知不可 name = Common.STR(32909) elif key == 'Unavailable': # 通知可能な情報が存在しない name = Common.STR(32910) elif key == 'Interaction with other service': # サービス競合のため通知不可 name = Common.STR(32910) # 検索結果 name = name or key or uri # 履歴に追加 History().append(uri, key or 'n/a', name or 'n/a') return name, key
def show(self): for key, name in sorted(self.data.items()): # 電話帳エントリ - リストアイテム title = '%s [COLOR lightgreen]%s[/COLOR]' % (key, name) li = xbmcgui.ListItem(title) li.setArt({'icon': Common.CONTACTS, 'thumb': Common.CONTACTS}) # 履歴 - コンテクストメニュー menu = [] action = 'RunPlugin(%s?action=beginEditPhoneBookItem&key=%s&name=%s)' % ( sys.argv[0], quote_plus(key), quote_plus(name)) menu.append((Common.STR(32905), action)) action = 'RunPlugin(%s?action=removePhoneBookItem&key=%s&name=%s)' % ( sys.argv[0], quote_plus(key), quote_plus(name)) menu.append((Common.STR(32906), action)) action = 'RunPlugin(%s?action=settings)' % (sys.argv[0]) menu.append((Common.STR(32902), action)) li.addContextMenuItems(menu, replaceItems=True) # リストアイテムを追加 url = '' xbmcplugin.addDirectoryItem(int(sys.argv[1]), url, listitem=li) # リストアイテム追加完了 xbmcplugin.endOfDirectory(int(sys.argv[1]))
def show_tokens(self): for name in self.data.keys(): listitem = xbmcgui.ListItem(name) listitem.setArt({ 'iconImage': 'DefaultFolder.png', 'thumb': 'DefaultFolder.png' }) query = '%s?action=history&name=%s' % (sys.argv[0], quote(name)) # コンテクストメニュー menu = [] # トークン削除 menu.append((Common.STR(32905), 'RunPlugin(%s?action=deletetoken&name=%s)' % (sys.argv[0], quote(name)))) # アドオン設定 menu.append((Common.STR(32900), 'Addon.OpenSettings(%s)' % Common.ADDON_ID)) # 追加 listitem.addContextMenuItems(menu, replaceItems=True) xbmcplugin.addDirectoryItem(int(sys.argv[1]), query, listitem, True) # end of directory xbmcplugin.endOfDirectory(int(sys.argv[1]))
def receive(self, criterion): # メール取得 mails = self.service.receive(criterion, 'TEXT') # 新規メールのリスト newmails = [] senders = {} # メール毎の処理 for mail in mails: # データ変換 filename, timestamp = self.convert(mail) # ファイルパス filepath = os.path.join(self.cache_path, filename) if not os.path.isfile(filepath): content = '' # header for key in [ 'From', 'To', 'CC', 'Date', 'Subject', 'Message-Id' ]: if mail[key]: content += '%s: %s\r\n' % (key, mail[key].replace( '\r\n', '')) # separator content += '\r\n' # body content += mail['body'] # ファイル書き込み f = open(filepath, 'w') f.write(content) f.close() # タイムスタンプを変更 os.utime(filepath, (timestamp, timestamp)) # 新規メールのパスを格納 newmails.append(filepath) senders[filepath] = mail['From'].replace('\r\n', '') Common.log('%d/%d mails retrieved using criterion "%s"' % (len(newmails), len(mails), criterion)) return newmails, senders
def show_history(self, name): # ディレクトリ cache_dir = os.path.join(Common.CACHE_PATH, name) if not os.path.isdir(cache_dir): os.makedirs(cache_dir) # ファイルリスト count = 0 files = sorted(os.listdir(cache_dir), key=lambda message: os.stat( os.path.join(cache_dir, message)).st_mtime, reverse=True) for filename in files: path = os.path.join(cache_dir, filename) if os.path.isfile(path) and not filename.startswith('.'): if self.listsize == 0 or count < self.listsize: content = Common.read_file(path) # 日付文字列 d = datetime.datetime.fromtimestamp(os.stat(path).st_mtime) weekday = d.weekday() date1 = Common.strftime( d, Common.STR(32901) ) + '(%s)' % Common.STR(32902).split(',')[weekday] time1 = d.strftime('%H:%M:%S') if weekday == 6 or Common.isholiday( d.strftime('%Y-%m-%d')): template = '[COLOR red]%s %s[/COLOR]' elif weekday == 5: template = '[COLOR blue]%s %s[/COLOR]' else: template = '%s %s' fd = template % (date1, time1) # リストアイテム label = '%s %s' % (fd, content) listitem = xbmcgui.ListItem(label) listitem.setArt({ 'iconImage': 'DefaultFile.png', 'thumb': 'DefaultFile.png' }) values = {'action': 'message', 'name': name, 'path': path} query = '%s?%s' % (sys.argv[0], urlencode(values)) # コンテクストメニュー menu = [] # アドオン設定 menu.append((Common.STR(32900), 'Addon.OpenSettings(%s)' % Common.ADDON_ID)) # 追加 listitem.addContextMenuItems(menu, replaceItems=True) xbmcplugin.addDirectoryItem(int(sys.argv[1]), query, listitem, False) # カウントアップ count += 1 else: os.remove(path) # end of directory xbmcplugin.endOfDirectory(int(sys.argv[1]))
def show_message(self, name, path): # 表示内容 mtime = datetime.datetime.fromtimestamp( os.stat(path).st_mtime).strftime('%Y-%m-%d %H:%M:%S') content = '[COLOR green]From:[/COLOR] %s\n' % name content += '[COLOR green]Date:[/COLOR] %s\n\n' % mtime # ファイル読み込み content += Common.read_file(path) # テキストビューア viewer_id = 10147 # ウィンドウを開く xbmc.executebuiltin('ActivateWindow(%s)' % viewer_id) # ウィンドウの用意ができるまで1秒待つ xbmc.sleep(1000) # ウィンドウへ書き込む viewer = xbmcgui.Window(viewer_id) viewer.getControl(1).setLabel(mtime) viewer.getControl(5).setText(content)
def set_timer(self): # 現在時刻 now = time.time() if now > self.next_aired: xbmc.executebuiltin('Container.Refresh') Common.log('updateOnAir: xbmc.executebuiltin') else: # 遅延を設定 delay = self.next_aired - now + 30 if delay < 0: delay = 0 # idを設定 Common.write_file(Common.RESUME_FILE, '') id = os.path.getmtime(Common.RESUME_FILE) # スレッドを起動 threading.Timer(delay, self.check_onair, args=[id]).start() Common.log('updateOnAir: threading.Timer.start: %d %f' % (id, delay))
def __request(self, url, data=None): try: if data: if isinstance(data, bytes): pass elif isinstance(data, str): data = data.encode(encoding='utf-8', errors='ignore') else: raise TypeError response = urllib.request.urlopen( urllib.request.Request(url, data)) else: response = urllib.request.urlopen(url) except urllib.error.HTTPError as e: Common.log('HTTPError: %s' % str(e.code), error=True) Common.notify('Request failed') return except urllib.error.URLError as e: Common.log('URLError: %s' % str(e.reason), error=True) Common.notify('Request failed') return response_body = response.read() response.close() return response_body
def send_message(self, token, message): headers = {'Authorization': 'Bearer %s' % token} values = {'message': message} postdata = urlencode(values).encode() try: req = Request(Common.ENDPOINT, headers=headers, data=postdata) response = urlopen(req) status = response.getcode() # ステータスコードを確認 if status == 200: Common.notify('Message has been sent') return True else: Common.notify('HTTP Error (%d)' % status) return False except Exception as e: Common.notify('Unknown Error (%s)' % str(e)) return False
def convert(self, item): # extract filename & timestamp filename = re.match('^<?(.*?)>?$', item['Message-Id']).group(1) timestamp = email.utils.mktime_tz( email.utils.parsedate_tz(item['Date'])) # date - self.convert by strftime accrding to format string defined as 30902 parsed = email.utils.parsedate_tz(item['Date']) t = email.utils.mktime_tz(parsed) item['Date'] = time.strftime(Common.STR(30902), time.localtime(t)) # body - extract plain text from html using beautifulsoup decoded_body = item['body'] if re.compile(r'<html|<!doctype', re.IGNORECASE).match(decoded_body): decoded_body = re.compile(r'<style.*?</style>', re.DOTALL | re.MULTILINE | re.IGNORECASE).sub('', decoded_body) decoded_body = re.compile(r'<script.*?</script>', re.DOTALL | re.MULTILINE | re.IGNORECASE).sub('', decoded_body) soup = BeautifulSoup(decoded_body, 'html.parser') buf = [] for text in soup.stripped_strings: buf.append(text) item['body'] = ' '.join(buf) return filename, timestamp
# -*- coding: utf-8 -*- import sys import urlparse from resources.lib.common import Common from resources.lib.client import Client from resources.lib.parser import Parser handle_ = int(sys.argv[1]) url_ = sys.argv[0] plugin = Common( addon_handle=handle_, addon_url=url_ ) client = Client(plugin) parser = Parser(plugin) def router(paramstring): args = dict(urlparse.parse_qs(sys.argv[2][1:])) mode = args.get('mode', ['root'])[0] id_ = args.get('id', [''])[0] params = args.get('params', [''])[0] if mode == 'root': parser.channel(client.channels()) elif mode == 'sports': parser.sport(client.categories()) elif mode == 'all_sports': parser.all_sports(client.category_all()) elif mode == 'events':
# -*- coding: utf-8 -*- import sys import os import re from resources.lib.common import Common from resources.lib.phonebook import PhoneBook from resources.lib.history import History from resources.lib.defaultsearch import search # searchをインポート path = Common.GET('customsearch') if os.path.isfile(path): dirname = os.path.dirname(path) if os.path.samefile(path, os.path.join(dirname, 'customsearch.py')): sys.path.append(os.path.dirname(path)) from customsearch import search def parse(uri): key = None m = re.compile(r'(?:"(.*)"|(.*))\s*<(sip:(.*)@.*|.*)>').search(uri) if m: key = m.group(1) or m.group(2) or m.group(4) or m.group(3) return key def lookup(uri): name = None key = parse(uri)
from resources.lib.common import Common from resources.lib.history import History from resources.lib.phonebook import PhoneBook if __name__ == '__main__': # 引数 args = parse_qs(sys.argv[2][1:], keep_blank_values=True) for key in args.keys(): args[key] = args[key][0] action = args.get('action', 'showHistory') # アドオン設定 settings = {} for key in ('key', 'name'): settings[key] = Common.GET(key) Common.SET('key', '') Common.SET('name', '') Common.SET('mode', 'create') # actionに応じた処理 # 着信履歴 if action == 'showHistory': History().show() elif action == 'clearHistory': History().clear() xbmc.executebuiltin('Container.Refresh()') # 電話帳 elif action == 'showPhoneBook':
def delete(self, name, token): self.data.pop(name) Common.write_json(Common.TOKEN_FILE, self.data)