diff --git a/logic.py b/logic.py index ac4dee0..a2d26cb 100644 --- a/logic.py +++ b/logic.py @@ -46,6 +46,10 @@ class Logic(object): 'dedupe_on_remote' : 'False', 'dedupe_on_cloud' : 'False', + # 20230331 새로 추가 + 'alt_download' : 'False', + 'alt_download_time' : '4', + 'alt_upload' : '', # cache 'cache_save_type_list' : '', 'cache_receive_info_send_telegram' : 'False' @@ -259,4 +263,4 @@ def migration(): except Exception as e: logger.error('Exception:%s', e) - logger.error(traceback.format_exc()) \ No newline at end of file + logger.error(traceback.format_exc()) diff --git a/logic_base.py b/logic_base.py index 882cb47..c397db9 100644 --- a/logic_base.py +++ b/logic_base.py @@ -12,7 +12,7 @@ from framework import db, scheduler, path_app_root from framework.job import Job from framework.util import Util -from framework.common.rss import RssUtil +from .rss_nyaa import RssUtil # 패키지 from .plugin import logger, package_name diff --git a/logic_cache.py b/logic_cache.py index f2ba19c..3e4a48a 100644 --- a/logic_cache.py +++ b/logic_cache.py @@ -16,7 +16,7 @@ from framework import db, scheduler, path_app_root, SystemModelSetting from framework.job import Job from framework.util import Util -from framework.common.rss import RssUtil +from .rss_nyaa import RssUtil from tool_base import ToolBaseNotify # 패키지 diff --git a/logic_rss.py b/logic_rss.py index bdc715c..abf343d 100644 --- a/logic_rss.py +++ b/logic_rss.py @@ -18,14 +18,13 @@ # sjva 공용 from framework import db, scheduler, path_app_root, SystemModelSetting, celery, app, Util from framework.job import Job -from framework.common.rss import RssUtil import framework.common.celery as celery_task # 패키지 from .plugin import logger, package_name from .model import ModelSetting, ModelOffcloud2Account, ModelOffcloud2Job, ModelOffcloud2Item, ModelOffcloud2Cache from .offcloud_api import Offcloud - +from .rss_nyaa import RssUtil ######################################################### @@ -177,7 +176,8 @@ def scheduler_function2(): LogicRss.scheduler_function_remove_history() if ModelSetting.get_bool('remove_cloud_history_on_web'): LogicRss.scheduler_function_remove_cloud_history('cloud') - + if ModelSetting.get_bool('alt_download'): + LogicRss.scheduler_function_alt_download('remote') # status # 0 : 초기 값 # 1 : 마그넷. 캐쉬. 오버 @@ -257,7 +257,38 @@ def scheduler_function_remove_cloud_history(target): logger.error(e) logger.error(traceback.format_exc()) - + @staticmethod + def scheduler_function_alt_download(target): + try: + from downloader.logic import Logic + from downloader.logic_normal import LogicNormal + LogicNormal.program_init() + get_default_value = Logic.get_default_value() + apikey = ModelSetting.get('apikey') + history_status = Offcloud.get_history(apikey, target) + history_status = history_status['history_status'] + if len(history_status) != 0: + for remote_item in history_status: + remote_magnet = str(remote_item.get('originalLink')).strip() + try: + if (remote_item.get('status') != 'uploading') and int(remote_item.get('downloadingTime')) > (ModelSetting.get_int('alt_download_time')*3600*1000) and remote_item.get('downloadingSpeed') == None : + Logic.add_download2(remote_magnet, get_default_value[0], get_default_value[1]) + item = remote_item.get('requestId') + result = Offcloud.remove(apikey, target, item) + logger.debug('다운로드 중지됨 - removed : %s === %s', result, item) + elif (remote_item.get('status') == 'uploading') and ModelSetting.get_int('alt_upload_time') > 0 and int(remote_item.get('downloadingTime')) > (int(remote_item.get('fileSize') / (2 * 1024 * 2024)) * 1000) : + if ModelSetting.get_bool('alt_upload'): + Logic.add_download2(remote_magnet, get_default_value[0], get_default_value[1]) + item = remote_item.get('requestId') + result = Offcloud.remove(apikey, target, item) + logger.debug('업로드 중지됨 - removed : %s === %s', result, item) + + except: + continue + except Exception as e: + logger.error(e) + logger.error(traceback.format_exc()) + @staticmethod def scheduler_function_remove_duplicated_job(target): diff --git a/plugin.py b/plugin.py index d9af048..cee3b69 100644 --- a/plugin.py +++ b/plugin.py @@ -255,7 +255,7 @@ def api(sub): item['link'] = t.link item['created_time'] = t.created_time data.append(item) - from framework.common.rss import RssUtil + from .rss_nyaa import RssUtil xml = RssUtil.make_rss(package_name, data) return Response(xml, mimetype='application/xml') elif sub == 'cache': @@ -267,7 +267,7 @@ def api(sub): item['link'] = t.magnet item['created_time'] = t.created_time data.append(item) - from framework.common.rss import RssUtil + from .rss_nyaa import RssUtil xml = RssUtil.make_rss(package_name, data) return Response(xml, mimetype='application/xml') elif sub == 'hash': diff --git a/rss_nyaa.py b/rss_nyaa.py new file mode 100644 index 0000000..79f5145 --- /dev/null +++ b/rss_nyaa.py @@ -0,0 +1,155 @@ +# -*- coding: utf-8 -*- +######################################################### +# python +import os +import traceback +import logging +import urllib +import xml.etree.ElementTree as ET +# third-party +import requests +# sjva 공용 +from framework import logger, py_urllib2 + +# 패키지 +from .plugin import logger, package_name +# 로그 + +######################################################### +class RssUtil(object): + @staticmethod + def get_rss(url): + try: + logger.debug('get_rss : %s', url) + """ + req = py_urllib2.Request(url) + req.add_header('user-agent', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36') + resp = py_urllib2.urlopen(req) + + tree = ET.ElementTree(file=resp) + """ + text = requests.get(url, headers={'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.92 Safari/537.36'}).text + + #logger.warning(text) + + try: + root = ET.fromstring(text) + except ET.ParseError as e: + print(f"XML 파싱 에러: {e}") + else: + namespaces = {'nyaa': 'https://nyaa.si/xmlns/nyaa'} # 'nyaa' 네임스페이스 정의 + #logger.warning(tree) + #root = tree.getroot() + item_list = root.findall('.//channel/item') + logger.debug('xml item count:%s', len(item_list)) + ret = [] + for item in item_list: + try: + info_hash_element = item.find('nyaa:infoHash', namespaces=namespaces) + if info_hash_element is not None and info_hash_element.text: + link = "magnet:?xt=urn:btih:" + info_hash_element.text + else: + link = item.find('link').text.strip() + if link.startswith('magnet'): + try: + link = link[0:60] + except: + logger.error(e) + logger.error(traceback.format_exc()) + link = item.find('link').text.strip() + rss = Feed(item.find('title').text.strip(), link) + ret.append(rss) + except Exception as exception: + #logger.debug(item.find('title').text) + #logger.debug(item.find('link').text) + logger.debug(exception) + logger.debug(traceback.format_exc()) + return ret + except Exception as exception: + logger.debug(exception) + logger.debug(traceback.format_exc()) + logger.debug('url:%s', url) + return None + + """ + @staticmethod + def make_rss(title, rss_list, torrent_mode, ddns, is_bot=False): + xml = '\n' + xml += '\t\n' + xml += '\t\t' + '%s\n' % title + xml += '\t\t\n' + xml += '\t\t\n' + for bbs in rss_list: + for download in bbs.files: + try: + item_str = '\t\t\n' + if download.filename.lower().endswith('.smi') or download.filename.lower().endswith('.srt') or download.filename.lower().endswith('.ass') or download.filename.lower().endswith('.ssa') or download.filename.lower().endswith('.sub'): + tmp = '\t\t\t[자막]%s\n' % TorrentSite.replace_xml(bbs.title) + else: + tmp = '\t\t\t%s\n' % TorrentSite.replace_xml(bbs.title) + + item_str += tmp + if torrent_mode == 'magnet' and download.is_torrent: + item_str += '\t\t\t%s\n' % download.magnet + else: + if is_bot: + item_str += '\t\t\t%s/rss/download_bot/%s\n' % (ddns, download.id) + else: + item_str += '\t\t\t%s/rss/download/%s\n' % (ddns, download.id) + item_str += '\t\t\t%s\n' % TorrentSite.replace_xml(download.filename) + date_str = bbs.created_time.strftime("%a, %d %b %Y %H:%M:%S") + ' +0900' + item_str += '\t\t\t%s\n' % date_str + item_str += '\t\t\n' + xml += item_str + except Exception as exception: + logger.debug('Exception:%s', exception) + logger.debug(traceback.format_exc()) + xml += '\t\n' + xml += '' + return xml + """ + + @staticmethod + def replace_xml(xml): + tmp = [['&', '&'], ['<', '<'], ['>', '>'], ['‘', '''], ['"', '"']] + for t in tmp: + xml = xml.replace(t[0], t[1]) + return xml + + + @staticmethod + def make_rss(package_name, rss_list): + #from system.model import ModelSetting as SystemModelSetting + #ddns = SystemModelSetting.get('ddns') + xml = '\n' + xml += '\t\n' + xml += '\t\t' + '%s\n' % package_name + xml += '\t\t\n' + xml += '\t\t\n' + for bbs in rss_list: + try: + item_str = '\t\t\n' + tmp = '\t\t\t%s\n' % RssUtil.replace_xml(bbs['title']) + item_str += tmp + #item_str += '\t\t\t%s\n' % bbs['link'] + item_str += '\t\t\t%s\n' % RssUtil.replace_xml(bbs['link']) + date_str = bbs['created_time'].strftime("%a, %d %b %Y %H:%M:%S") + ' +0900' + item_str += '\t\t\t%s\n' % date_str + item_str += '\t\t\n' + xml += item_str + except Exception as exception: + logger.debug('Exception:%s', exception) + logger.debug(traceback.format_exc()) + xml += '\t\n' + xml += '' + return xml + + + + + +class Feed(object): + def __init__(self, title, link): + self.title = title + self.link = link + diff --git a/templates/offcloud2_rss_setting.html b/templates/offcloud2_rss_setting.html index 6ceae00..e3097e9 100644 --- a/templates/offcloud2_rss_setting.html +++ b/templates/offcloud2_rss_setting.html @@ -20,6 +20,9 @@ {{ macros.setting_checkbox('remove_cloud_history_on_web', '완료시 웹에서 Cloud 작업 삭제', value=arg['remove_cloud_history_on_web'], desc=None) }} {{ macros.setting_checkbox('dedupe_on_remote', 'Remote 중복 작업 제거', value=arg['dedupe_on_remote'], desc=None) }} {{ macros.setting_checkbox('dedupe_on_cloud', 'Cloud 중복 작업 제거', value=arg['dedupe_on_cloud'], desc=None) }} + {{ macros.setting_checkbox('alt_download', '중지된 목록 다운로드 클라이언트로', value=arg['alt_download'], desc='지정한 시간이 넘고 다운로드 속도가 없으면 다운로드 클라이언트로 마그넷 넘깁니다') }} + {{ macros.setting_input_int('alt_download_time', '다운로드 중지 판정시간', value=arg['alt_download_time'], desc=['hours', '']) }} + {{ macros.setting_checkbox('alt_upload', '업로드 중지된 것도 넘김', value=arg['alt_upload'], desc='업로드 시간이 넘은 것 처리. off: 그냥 삭제, on: 넘김') }} {{ macros.setting_button([['global_setting_save_btn', '설정 저장']]) }} {{ macros.m_tab_content_end() }}