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 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 initializeSession(): # リセット Common.SET('garapon_session', '') # データ取得 response_body = Request().auth() if response_body: response_data = json.loads(response_body) if response_data['status'] == 1: if response_data['login'] == 1: gtvsession = response_data['gtvsession'] Common.SET('garapon_session', gtvsession) Common.notify('Session initialized successfully') return True else: Common.log('auth failed', response_body, error=True) Common.notify('Session initialization failed') return False else: Common.log('auth failed', response_body, error=True) Common.notify('Session initialization failed') return False else: Common.log('empty response', error=True) Common.notify('Session initialization failed') return False
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 search(self, onair=False, retry=True): # 検索 response_body = Request().search(self.query) if response_body: response_data = json.loads(response_body) if response_data['status'] == 1: # 検索結果の番組 programs = response_data['program'] if onair: # 放送中の番組はチャンネル順 for item in sorted(programs, key=lambda item: item['ch']): if item.get('ts') == 1: self.add_item(item, onair) # 放送中の番組の更新を設定 UpdateOnAir(programs).set_timer() else: # 放送済みの番組は時間降順 for item in sorted(programs, key=lambda item: item['startdate'], reverse=True): if item.get('ts') == 1: self.add_item(item, onair) # 検索結果の続きがある場合は次のページへのリンクを表示 hit = int(response_data['hit']) page = int(self.args.get('p')) if hit > page * Common.ITEMS: self.args['p'] = page + 1 query = urlencode(self.args) # 次のページへ self.add_directory_item('[COLOR lightgreen]%s[/COLOR]' % (Common.STR(30922)), query, 'search', iconimage=Common.RIGHT) # end of directory xbmcplugin.endOfDirectory(int(sys.argv[1])) elif retry is True: # セッションを初期化してリトライする if initializeSession(): if checkSettings(): self.search(onair, retry=False) else: Common.log('invalid settings', error=True) Common.notify('Search failed') else: Common.log('session initialization failed', error=True) Common.notify('Search failed') else: # リトライも失敗 Common.log('retry failed', error=True) Common.notify('Search failed') else: Common.log('empty response', error=True) Common.notify('Search failed')
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 initializeChannel(): # リセット Common.SET('garapon_ch', '') # チャンネル情報を取得 response_body = Request().channel() if response_body: response_data = json.loads(response_body) if response_data['status'] == 1: # チャンネル情報をファイルに書き出す Common.write_json(Common.CHANNEL_FILE, response_data) # チャンネル数を設定 Common.SET('garapon_ch', '%d channels' % len(response_data['ch_list'].keys())) # 設定画面のテンプレートを読み込む template = Common.read_file(Common.TEMPLATE_FILE) # テンプレートに書き出すジャンル情報 genre = Genre().getLabel() # チャンネル情報とあわせてテンプレートに適用 source = template.format( channel=Channel().getLabel(), g0=genre['g0'], g00=genre['g00'], g01=genre['g01'], g02=genre['g02'], g03=genre['g03'], g04=genre['g04'], g05=genre['g05'], g06=genre['g06'], g07=genre['g07'], g08=genre['g08'], g09=genre['g09'], g10=genre['g10'], g11=genre['g11'] ) # 設定画面をファイルに書き出す Common.write_file(Common.SETTINGS_FILE, source) # 完了 Common.notify('Channel initialized successfully') return True else: Common.log('channel failed', response_body, error=True) Common.notify('Channel initialization failed') return False else: Common.log('empty response', error=True) Common.notify('Channel initialization failed') return False
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 initializeNetwork(): # リセット Common.SET('garapon_addr', '') Common.SET('garapon_http', '') Common.SET('garapon_https', '') # データ取得 response_body = Request().getgtvaddress() if response_body: params = {} for i in response_body.split('\n'): try: (key, value) = i.split(';', 1) if key == '0': params['message'] = value elif key == '1': params['message'] = value else: params[key] = value except Exception: pass if params['message'] == 'success': Common.SET('garapon_addr', params['ipaddr']) if params['ipaddr'] == params['gipaddr']: Common.SET('garapon_http', params['port']) Common.SET('garapon_https', params['port2']) else: Common.SET('garapon_http', '') Common.SET('garapon_https', '') Common.notify('Network initialized successfully') return True else: Common.log('getgtvaddress failed', response_body, error=True) Common.notify('Network initialization failed') return False else: Common.log('empty response', error=True) Common.notify('Network initialization failed') return False
def onIncomingCall(self, param): # ログ Common.log('\n'.join([ # https://www.pjsip.org/pjsip/docs/html/structpj_1_1OnIncomingCallParam.htm 'callId: %s' % param.callId, # '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, ])) call = pj.Call(self, param.callId) info = call.getInfo() Common.log('\n'.join([ # https://www.pjsip.org/pjsip/docs/html/structpj_1_1CallInfo.htm 'id: %s' % info.id, 'role: %s' % info.role, 'accId: %s' % info.accId, 'localUri: %s' % info.localUri, 'localContact: %s' % info.localContact, 'remoteUri: %s' % info.remoteUri, 'remoteContact: %s' % info.remoteContact, 'callIdString: %s' % info.callIdString, # 'setting: %s' % info.setting, 'setting.flag: %s' % info.setting.flag, 'setting.reqKeyframeMethod: %s' % info.setting.reqKeyframeMethod, 'setting.audioCount: %s' % info.setting.audioCount, 'setting.videoCount: %s' % info.setting.videoCount, 'state: %s' % info.state, 'stateText: %s' % info.stateText, 'lastStatusCode: %s' % info.lastStatusCode, 'media: %s' % info.media, 'provMedia: %s' % info.provMedia, 'connectDuration: %d.%03d' % (info.connectDuration.sec, info.connectDuration.msec), 'totalDuration: %d.%03d' % (info.totalDuration.sec, info.totalDuration.msec), 'remOfferer: %s' % info.remOfferer, 'remAudioCount: %s' % info.remAudioCount, 'remVideoCount: %s' % info.remVideoCount, ])) # Kodiをアクティベート if Common.GET('cec') == 'true': xbmc.executebuiltin('CECActivateSource') # 発信者番号から番号検索 name, key = lookup(info.remoteUri) local = parse(info.localUri) # 通知 duration = Common.GET('duration') Common.notify(name, time=int(duration) * 1000) # メールによる通知 if Common.GET('mailaddon') and Common.GET('mailnotify') == 'true': template = Common.GET('mailtemplate') or Common.STR(32913) address = Common.GET('mailaddress') message = template.format(name=name, key=key, local=local) xbmc.executebuiltin('RunPlugin("plugin://%s?%s")' % (Common.GET('mailaddon'), urlencode({ 'action': 'send', 'subject': message, 'message': message, 'to': address }))) # LINE notifyによる通知 if Common.GET('lineaddon') and Common.GET('linenotify') == 'true': template = Common.GET('linetemplate') or Common.STR(32913) token = Common.GET('linetoken') message = template.format(name=name, key=key, local=local) xbmc.executebuiltin('RunPlugin("plugin://%s?%s")' % (Common.GET('lineaddon'), urlencode({ 'action': 'send', 'name': token, 'message': message })))
# pjsua2.pyのパス設定を取得 srcfile = Common.GET('pjsua2') # 設定をチェック if not os.path.isfile(srcfile) or os.path.basename(srcfile) != 'pjsua2.py': Common.ADDON.openSettings() sys.exit() try: # pjsua2.pyをコピー shutil.copy(srcfile, Common.PY_FILE) # _pjsua2.soをコピー srcfile = glob.glob(os.path.join(os.path.dirname(srcfile), '_pjsua2*.so'))[0] shutil.copy(srcfile, Common.SO_FILE) # インポート実行 from resources.pjsua2 import pjsua2 as pj except Exception as e: Common.notify('Importing pjsua2 failed', time=3000, error=True) Common.log(e) sys.exit() # 電子メールクライアントの有無を確認 try: mailaddon = 'script.handler.email' xbmcaddon.Addon(mailaddon) Common.SET('mailaddon', mailaddon) except Exception: Common.SET('mailaddon', '') # LINE Notifyハンドラの有無を確認 try: lineaddon = 'script.handler.line.notify' xbmcaddon.Addon(lineaddon)
def send(self, subject, message, to, cc=[], bcc=[]): # メール送信 self.service.send(subject, message, to, cc, bcc) # 通知 Common.notify('Message has been sent to %s' % ', '.join(to))