def DeleteTask(self, task_id): delete_url = self.cfg.GetDSDownloadUrl( ) + '/webapi/DownloadStation/task.cgi' params = { 'api': 'SYNO.DownloadStation.Task', 'version': '3', 'method': 'delete', 'id': task_id } try: res = requests.get(delete_url, params=params, cookies=self.auth_cookie, verify=self.cfg.IsUseCert()) except requests.ConnectionError: log.error('DeleteTask|synology rest api request Connection Error') return False except: log.error('DeleteTask|synology requests fail') return False if res.status_code != 200: log.warn("Delete Task Request fail") return False json_data = json.loads(res.content.decode('utf-8')) if self.ChkAPIResponse(json_data, "Download station Delete Task") == False: return False return True
def CreateTaskForFile(self, file_path): create_url = self.cfg.GetDSDownloadUrl() + '/webapi/DownloadStation/task.cgi' params2 = {'api' : 'SYNO.DownloadStation.Task', 'version' : '3', 'method' : 'create' } files = {'file' : open(file_path, 'rb')} try: res = requests.post(create_url, data=params2, files=files, cookies=self.auth_cookie, verify=self.cfg.IsUseCert()) except requests.ConnectionError: log.error('CreateTaskForFile|synology rest api request Connection Error') return False except: log.error('CreateTaskForFile|synology requests fail') return False if res.status_code != 200: # print('request fail') log.warn("Create Task For File Request fail") return False json_data = json.loads(res.content.decode('utf-8')) if self.ChkTaskResponse(json_data, "Download station Create Task for file") == False: return False # Remove Torrent File files['file'].close() os.remove(file_path) log.info('Torrent File removed, file:%s', file_path) return True
def GetTaskList(self): #url = 'https://downloadstation_dsm_url:9999/webapi/DownloadStation/task.cgi?api=SYNO.DownloadStation.Task&version=1&method=list' if self.auth_cookie == None: return False params = { 'api': 'SYNO.DownloadStation.Task', 'version': '3', 'method': 'list' } url = self.cfg.GetDSDownloadUrl() + '/webapi/DownloadStation/task.cgi' try: res = requests.get(url, params=params, cookies=self.auth_cookie, verify=self.cfg.IsUseCert()) except requests.ConnectionError: log.error('GetTaskList|synology rest api request Connection Error') return False except: log.error('GetTaskList|synology requests fail') return False if res.status_code != 200: log.warn("Get Task List Request fail") return False #print(res.content) json_data = json.loads(res.content.decode('utf-8')) if self.ChkTaskResponse( json_data, "GetTaskList Download station api fail") == False: self.auth_cookie = None return False exists_task_list = [] for item in json_data['data']['tasks']: # log.info('GetTaskList : %s, %s, %s, %s, %s' % (item['id'], item['title'], CommonUtil.hbytes(item['size']), item['username'], item['status']) ) # size 가 0 보다 큰 값인 경우에만 Torrent 정보가 정상적으로 확인 된다. exists_task_list.append(item['id']) tor_size = int(item['size']) if tor_size > 0: self.theTaskMgr.InsertOrUpdateTask(item['id'], item['title'], item['size'], item['username'], item['status']) self.theTaskMgr.CheckRemoveTest(exists_task_list) if self.cfg.IsTaskAutoDel() == True: self.TaskAutoDelete(json_data) return True
def GetStatistic(self): # param = {'api' : 'SYNO.DownloadStation.Statistic', 'version' : '1', 'method' : 'getinfo'} # url = 'https://downloadstation_dsm_url:9999/webapi/DownloadStation/statistic.cgi' if self.auth_cookie == None: return False log.info('try get statistic') params = { 'api': 'SYNO.DownloadStation.Statistic', 'version': '1', 'method': 'getinfo' } url = self.cfg.GetDSDownloadUrl( ) + '/webapi/DownloadStation/statistic.cgi' try: res = requests.get(url, params=params, cookies=self.auth_cookie, verify=self.cfg.IsUseCert()) except requests.ConnectionError: log.error( 'GetStatistic|synology rest api request Connection Error') return False except: log.error('GetStatistic|synology requests fail') return False log.info('GetStatistic|complete get statistic') if res.status_code != 200: log.warn("GetStatistic|Get statistic Request fail") return False json_data = json.loads(res.content.decode('utf-8')) if self.ChkAPIResponse(json_data, "Download station api fail") == False: self.auth_cookie = None log.info('GetStatistic|ChkAPIResponse fail') return False # Data sample : {"data":{"speed_download":3496632,"speed_upload":0},"success":true} item = json_data.get('data') if item != None: download_speed = item['speed_download'] upload_speed = item['speed_upload'] self.SendStatistic(download_speed, upload_speed) else: log.info('GetStatistic|not found data, %s', res.content) return True
def CreateTaskForUrl(self, url): create_url = self.cfg.GetDSDownloadUrl() + '/webapi/DownloadStation/task.cgi' params = {'api' : 'SYNO.DownloadStation.Task', 'version' : '3', 'method' : 'create' , 'uri' : url} try: res = requests.get(create_url, params=params, cookies=self.auth_cookie, verify=self.cfg.IsUseCert()) except requests.ConnectionError: log.error('CreateTaskForUrl|synology rest api request Connection Error') return False except: log.error('CreateTaskForUrl|synology requests fail') return False if res.status_code != 200: log.warn("Create Task For Url Request fail") return False json_data = json.loads(res.content.decode('utf-8')) if self.ChkTaskResponse(json_data, "Download station Create Task for url") == False: return False return True
def StartDsmLogin(self): retry_cnt = self.cfg.GetDsmRetryLoginCnt() bot = self.BotUpdater.bot # 재시도 횟수 까지 로그인을 시도하며, 횟수 초과시 프로그램 종료 while self.try_login_cnt < retry_cnt: # 로그인 Flow # 1. dsm_id 값이 있는지 확인 # 2. dsm_pw 값이 있는지 확인 # 3. DS API Login 시도 # 4. 결과 코드 조회 # 4-1 반환된 rest api 의 content 값을 보고 판단. # step 1 # dsm_id 가 비어 있는 경우 if not self.cfg.GetDsmId(): log.info('DSM ID is empty') self.StartInputLoginId() return False # step 2 if not self.cfg.GetDsmPW(): log.info('DSM PW is empty') self.StartInputPW() return False # step 3 id = self.cfg.GetDsmId() pw = self.cfg.GetDsmPW() otp_code = self.otp_code res, content = self.ds.DsmLogin(id, pw, otp_code) # step 4 if res == False: log.info('DSM Login fail, API request fail') # 3초 대기 후 재시도 time.sleep(3) continue log.info('DSM Login check content json data') # step 4-1 # rest api 의 내용 중 http status code 가 200이 아닌 경우 예외처리 # status code 가 200 이면 수신 된 json 데이터를 가지고 예외 처리 if content.status_code != 200: log.warn("DSM Login Request fail") # msg = '로그인 요청 실패\n, 응답 코드 : %d' % (res.status_code) msg = self.lang.GetBotHandlerLang('dsm_login_api_fail') % ( res.status_code) bot.sendMessage(self.cfg.GetDsmPwId(), msg) time.sleep(3) continue # content 에서 json 데이터 파싱 json_data = json.loads(content.content.decode('utf-8')) # json_data 가 None 이라면 DS API 이상, 재시도 if json_data == None: log.info('DS API Response content is none') #bot.sendMessage(self.cfg.GetDsmPwId(), 'DS API 응답 데이터가 비어있습니다') bot.sendMessage( self.cfg.GetDsmPwId(), self.lang.GetBotHandlerLang('dsm_api_res_empty')) time.sleep(3) continue if json_data['success'] == False: log.info('DS API Response false') errcode = json_data['error']['code'] # 105 세션 만료 # 400 id 또는 암호 오류 # 401 계정 비활성화 # 402 2단계 인증 실패 if errcode == 105: log.info('105 error, session expired') #bot.sendMessage(self.cfg.GetDsmPwId(), "DSM Login 실패\n세션이 만료되었습니다.") bot.sendMessage( self.cfg.GetDsmPwId(), self.lang.GetBotHandlerLang('dsm_session_expire')) return False elif errcode == 400: log.info('400 error, id or pw invalid') #bot.sendMessage(self.cfg.GetDsmPwId(), "DSM Login 실패\nID 또는 비밀번호가 다릅니다.") bot.sendMessage( self.cfg.GetDsmPwId(), self.lang.GetBotHandlerLang('dsm_invalid_id_pw')) self.StartInputPW() return False elif errcode == 401: log.info('401 error, account disabled') #bot.sendMessage(self.cfg.GetDsmPwId(), "DSM Login 실패\n비활성화 된 계정입니다.") bot.sendMessage( self.cfg.GetDsmPwId(), self.lang.GetBotHandlerLang('dsm_account_disable')) return False elif errcode == 402: log.info( '402 error, permission denied, try otp auth login') self.StartInputOTP() return False if json_data['success'] == True: log.info('DSM Login success') self.ds.auth_cookie = content.cookies self.try_login_cnt = 0 # bot.sendMessage(self.cfg.GetDsmPwId(), 'DS Login 성공\nSynobot을 시작합니다.') bot.sendMessage(self.cfg.GetDsmPwId(), self.lang.GetBotHandlerLang('dsm_login_succ')) return True log.info('retry login... %d/%d', self.try_login_cnt, retry_cnt) self.try_login_cnt += 1 #bot.sendMessage(self.cfg.GetDsmPwId(), "DSM Login에 실패 하였습니다.\n프로그램이 종료됩니다") bot.sendMessage(self.cfg.GetDsmPwId(), self.lang.GetBotHandlerLang('dsm_login_fail_exit')) log.info('DSM Login Fail!!') sys.exit() return False
def GetTaskDetail(self): #url = 'https://downloadstation_dsm_url:9999/webapi/DownloadStation/task.cgi?api=SYNO.DownloadStation.Task&version=1&method=list&additional=detail,file,transfer' if self.auth_cookie == None: return False log.info('try task list detail') params = { 'api': 'SYNO.DownloadStation.Task', 'version': '3', 'method': 'list', 'additional': 'detail,file,transfer' } url = self.cfg.GetDSDownloadUrl() + '/webapi/DownloadStation/task.cgi' try: res = requests.get(url, params=params, cookies=self.auth_cookie, verify=self.cfg.IsUseCert()) except requests.ConnectionError: log.error('GetTaskList|synology rest api request Connection Error') return False except: log.error('GetTaskList|synology requests fail') return False log.info('complete task list detail') if res.status_code != 200: log.warn("Get Task List Request fail") return False json_data = json.loads(res.content.decode('utf-8')) if self.ChkAPIResponse(json_data, "Download station api fail") == False: self.auth_cookie = None log.info('ChkAPIResponse fail') return False # Json 분석 후 다운로드 리스트 보내기 # 보낼 데이터, Task ID, 파일이름, 파일 크기, 다운로드 된 크기, 진행 상태, 업스피드, 다운스피드, 상태 log.info("Task : %s", json_data['data']['tasks']) for item in json_data['data']['tasks']: # size 가 0 보다 큰 값인 경우에만 Torrent 정보가 정상적으로 확인 된다. tor_size = int(item['size']) # item 정보 # id : Task ID # size : 파일 전체 크기 # status : 진행 상태 # title : 토렌트 제목 # item['additional']['transfer'] # size_downloaded : 다운로드 된 크기 # size_uploaded : 업로드 된 크기 # speed_download : 다운로드 속도(단위/s) # speed_upload : 업로드 속도 (단위/s) tor_id = item['id'] tor_status = item['status'] tor_title = item['title'] tor_size_download = 0 tor_size_upload = 0 tor_speed_down = 0 tor_speed_up = 0 if tor_size <= 0: self.SendTaskList(tor_id, tor_size, tor_status, tor_title, tor_size_download, tor_size_upload, tor_speed_down, tor_speed_up) return True # additional 아이템이 없다면 0 정보 전송 if 'additional' in item == False: self.SendTaskList(tor_id, tor_size, tor_status, tor_title, tor_size_download, tor_size_upload, tor_speed_down, tor_speed_up) return True # transfer 아이템이 없다면 0 정보 전송 if 'transfer' in item['additional'] == False: self.SendTaskList(tor_id, tor_size, tor_status, tor_title, tor_size_download, tor_size_upload, tor_speed_down, tor_speed_up) return True transfer_item = item['additional']['transfer'] tor_size_download = transfer_item['size_downloaded'] tor_size_upload = transfer_item['size_uploaded'] tor_speed_down = transfer_item['speed_download'] tor_speed_up = transfer_item['speed_upload'] self.SendTaskList(tor_id, tor_size, tor_status, tor_title, tor_size_download, tor_size_upload, tor_speed_down, tor_speed_up) log.info('success Task List') return True