From a2f1b6d4fd7fcfca818229ddf57f3638e657549c Mon Sep 17 00:00:00 2001 From: mol Date: Sat, 4 Feb 2023 00:14:50 +0800 Subject: [PATCH] first commit --- ExceptionHandler.py | 65 ++++++++ Gateway.py | 149 ++++++++++++++++++ README.md | 0 Route.py | 66 ++++++++ __pycache__/ExceptionHandler.cpython-310.pyc | Bin 0 -> 2948 bytes __pycache__/Gateway.cpython-310.pyc | Bin 0 -> 4642 bytes __pycache__/Route.cpython-310.pyc | Bin 0 -> 2783 bytes __pycache__/app.cpython-310.pyc | Bin 0 -> 1390 bytes __pycache__/hello.cpython-310.pyc | Bin 0 -> 646 bytes __pycache__/test.cpython-310.pyc | Bin 0 -> 2967 bytes __pycache__/test2.cpython-310.pyc | Bin 0 -> 466 bytes __pycache__/utils.cpython-310.pyc | Bin 0 -> 1047 bytes app.py | 66 ++++++++ plugin/MusicHandler.py | 15 ++ plugin/NavidromePlaylistSync/__init__.py | 0 .../__pycache__/__init__.cpython-310.pyc | Bin 0 -> 159 bytes .../__pycache__/app.cpython-310.pyc | Bin 0 -> 975 bytes .../__pycache__/resetDir.cpython-310.pyc | Bin 0 -> 376 bytes .../__pycache__/saveFile.cpython-310.pyc | Bin 0 -> 433 bytes .../__pycache__/sync.cpython-310.pyc | Bin 0 -> 1001 bytes plugin/NavidromePlaylistSync/api/__init__.py | 0 .../api/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 135 bytes .../api/__pycache__/playlist.cpython-310.pyc | Bin 0 -> 981 bytes .../api/__pycache__/token.cpython-310.pyc | Bin 0 -> 436 bytes plugin/NavidromePlaylistSync/api/playlist.py | 25 +++ plugin/NavidromePlaylistSync/api/token.py | 7 + plugin/NavidromePlaylistSync/app.py | 33 ++++ plugin/NavidromePlaylistSync/resetDir.py | 10 ++ plugin/NavidromePlaylistSync/saveFile.py | 6 + plugin/NavidromePlaylistSync/sync.py | 28 ++++ plugin/NavidromePlaylistSync/temp/ClariS.m3u | 13 ++ .../NavidromePlaylistSync/temp/HIMEHINA.m3u | 31 ++++ plugin/NavidromePlaylistSync/temp/JOJO.m3u | 17 ++ plugin/NavidromePlaylistSync/temp/YOSOBI.m3u | 17 ++ .../temp/ナユタン星人.m3u | 7 + .../NavidromePlaylistSync/temp/公主殿下.m3u | 69 ++++++++ plugin/NavidromePlaylistSync/temp/后摇.m3u | 7 + plugin/NavidromePlaylistSync/temp/哥特风.m3u | 13 ++ .../NavidromePlaylistSync/temp/恋与恋语.m3u | 21 +++ .../NavidromePlaylistSync/temp/校园乐队.m3u | 5 + .../temp/樱兰高校K-ON部.m3u | 41 +++++ plugin/NavidromePlaylistSync/temp/治愈.m3u | 45 ++++++ plugin/NavidromePlaylistSync/temp/测试.m3u | 3 + plugin/NavidromePlaylistSync/temp/测试2.m3u | 1 + plugin/NavidromePlaylistSync/temp/蓝之华.m3u | 27 ++++ plugin/__init__.py | 0 .../__pycache__/MusicHandler.cpython-310.pyc | Bin 0 -> 841 bytes plugin/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 137 bytes plugin/__pycache__/app.cpython-310.pyc | Bin 0 -> 727 bytes test2.py | 24 +++ utils.py | 28 ++++ 51 files changed, 839 insertions(+) create mode 100644 ExceptionHandler.py create mode 100644 Gateway.py create mode 100644 README.md create mode 100644 Route.py create mode 100644 __pycache__/ExceptionHandler.cpython-310.pyc create mode 100644 __pycache__/Gateway.cpython-310.pyc create mode 100644 __pycache__/Route.cpython-310.pyc create mode 100644 __pycache__/app.cpython-310.pyc create mode 100644 __pycache__/hello.cpython-310.pyc create mode 100644 __pycache__/test.cpython-310.pyc create mode 100644 __pycache__/test2.cpython-310.pyc create mode 100644 __pycache__/utils.cpython-310.pyc create mode 100644 app.py create mode 100644 plugin/MusicHandler.py create mode 100644 plugin/NavidromePlaylistSync/__init__.py create mode 100644 plugin/NavidromePlaylistSync/__pycache__/__init__.cpython-310.pyc create mode 100644 plugin/NavidromePlaylistSync/__pycache__/app.cpython-310.pyc create mode 100644 plugin/NavidromePlaylistSync/__pycache__/resetDir.cpython-310.pyc create mode 100644 plugin/NavidromePlaylistSync/__pycache__/saveFile.cpython-310.pyc create mode 100644 plugin/NavidromePlaylistSync/__pycache__/sync.cpython-310.pyc create mode 100644 plugin/NavidromePlaylistSync/api/__init__.py create mode 100644 plugin/NavidromePlaylistSync/api/__pycache__/__init__.cpython-310.pyc create mode 100644 plugin/NavidromePlaylistSync/api/__pycache__/playlist.cpython-310.pyc create mode 100644 plugin/NavidromePlaylistSync/api/__pycache__/token.cpython-310.pyc create mode 100644 plugin/NavidromePlaylistSync/api/playlist.py create mode 100644 plugin/NavidromePlaylistSync/api/token.py create mode 100644 plugin/NavidromePlaylistSync/app.py create mode 100644 plugin/NavidromePlaylistSync/resetDir.py create mode 100644 plugin/NavidromePlaylistSync/saveFile.py create mode 100644 plugin/NavidromePlaylistSync/sync.py create mode 100644 plugin/NavidromePlaylistSync/temp/ClariS.m3u create mode 100644 plugin/NavidromePlaylistSync/temp/HIMEHINA.m3u create mode 100644 plugin/NavidromePlaylistSync/temp/JOJO.m3u create mode 100644 plugin/NavidromePlaylistSync/temp/YOSOBI.m3u create mode 100644 plugin/NavidromePlaylistSync/temp/ナユタン星人.m3u create mode 100644 plugin/NavidromePlaylistSync/temp/公主殿下.m3u create mode 100644 plugin/NavidromePlaylistSync/temp/后摇.m3u create mode 100644 plugin/NavidromePlaylistSync/temp/哥特风.m3u create mode 100644 plugin/NavidromePlaylistSync/temp/恋与恋语.m3u create mode 100644 plugin/NavidromePlaylistSync/temp/校园乐队.m3u create mode 100644 plugin/NavidromePlaylistSync/temp/樱兰高校K-ON部.m3u create mode 100644 plugin/NavidromePlaylistSync/temp/治愈.m3u create mode 100644 plugin/NavidromePlaylistSync/temp/测试.m3u create mode 100644 plugin/NavidromePlaylistSync/temp/测试2.m3u create mode 100644 plugin/NavidromePlaylistSync/temp/蓝之华.m3u create mode 100644 plugin/__init__.py create mode 100644 plugin/__pycache__/MusicHandler.cpython-310.pyc create mode 100644 plugin/__pycache__/__init__.cpython-310.pyc create mode 100644 plugin/__pycache__/app.cpython-310.pyc create mode 100644 test2.py create mode 100644 utils.py diff --git a/ExceptionHandler.py b/ExceptionHandler.py new file mode 100644 index 0000000..73897b2 --- /dev/null +++ b/ExceptionHandler.py @@ -0,0 +1,65 @@ +import logging as logger + +class ExceptionHandler(object): + """异常处理器,可以自行实现错误的捕获、熔断、服务降级等""" + + def __init__(self, decorator=None): + if not decorator: + return + # 使用自定义装饰器覆盖 + self.decorator = decorator + + def handle(self, e, *args, **kwargs): + """异常处理 + :param e: + :param args: request args + :param kwargs: request kwargs + :return: tuple(content, status, headers) + :rtype: tuple + """ + raise NotImplementedError + + def decorator(self, func): + + + def wrapper(*args, **kwargs): + try: + return func(*args, **kwargs) + except Exception as e: + logger.debug("Exception handle") + return self.handle(e, *args, **kwargs) + + return wrapper + + +class InboundHandler(object): + """输入处理管道,可自定义一系列拦截器处理请求信息,如验证、鉴权、数据解码、参数包装等""" + #__metaclass__ = 'ABCMeta' + + def handle(self, request, *args, **kwargs): + """ + :param dict request: 请求信息 (初始:url, parameters, data, method),可根据需要添加 + :return: (request, args, kwargs) + """ + raise NotImplementedError + + def __call__(self, request, *args, **kwargs): + return self.handle(request, *args, **kwargs) + + +class OutboundHandler(object): + """输出处理管道,可自定义一系列拦截器处理返回信息,如返回码处理、数据编码等""" + # __metaclass__ = 'ABCMeta' + + def handle(self, response, headers, status, content, *args, **kwargs): + """ + :param requests.Response response: origin http response + :param dict headers: the response headers which will be responded + :param int status: the status code which will be responded + :param str content: the content which will be responded + :return: tuple(headers, status, content) + """ + raise NotImplementedError + + def __call__(self, response, headers, status, content, *args, **kwargs): + return self.handle(response, headers, status, content, *args, **kwargs) \ No newline at end of file diff --git a/Gateway.py b/Gateway.py new file mode 100644 index 0000000..79a2527 --- /dev/null +++ b/Gateway.py @@ -0,0 +1,149 @@ +import requests +import utils +import json +import logging as logger +#import InvalidParameterException + +from flask import make_response +from flask import request +from ExceptionHandler import * + + +class NoopExceptionHandler(ExceptionHandler): + + DEFAULT_CONTENT = { + "error_code": "InternalServerError", + "error_message": "", + "error_message_chs": "服务器内部错误" + } + + def handle(self, e, *args, **kwargs): + logger.exception("Unknown exception occurred: %s", e) + content = dict(self.DEFAULT_CONTENT) + content['error_message'] = e.message + return json.dumps(content), 500 + + +class GenericGateway(object): + + def __init__(self, app, routes, url_supplier, exception_handler=None): + """ + + :param app: flask app + :type app: flask.Flask + :param routes: 路由列表 + :type routes: list of Route + :param url_supplier: 服务名称解析函数,通过service name获取service url: url_supplier(service_name) -> service_url + :type url_supplier: function + :param exception_handler: exception handle decorator + :type exception_handler: ExceptionHandler + """ + if not callable(url_supplier): + raise ValueError("service url supplier (url_supplier) must be callable") + + self.app = app + self.routes = routes + self.url_supplier = url_supplier + self.exception_handler = exception_handler or NoopExceptionHandler() + self.proxy_list = [] + + def get_url(self, service_name): + try: + return self.url_supplier(service_name) + except Exception as e: + logger.warning("Failed to get the url of service: %s", service_name, exc_info=True) + raise RuntimeError("Failed to get the url of service {}: {}".format(service_name, e)) + + def create_request_proxy(self, route): + + logger.info("Register route: %s", route.path) + + def proxy_request(*args, **kwargs): + + upstream_path = route.upstream_path + for p_name in route.upstream_params: + v = get_params_from_context(p_name, kwargs) + upstream_path = utils.replace_placeholder(upstream_path, p_name, v) + + endpoint = self.get_url(route.service_name) + + final_url = "{}{}".format(endpoint, upstream_path) + upstream_req_info = dict( + url=final_url, + method=request.method, + params=request.args, + data=request.data, + files=request.files, + headers=request.headers, + ) + if request.form: + upstream_req_info['data'] = request.form + + for pipe_handler in route.inbound_pipes(): + upstream_req_info, args, kwargs = pipe_handler(upstream_req_info, *args, **kwargs) + + content_type = upstream_req_info['headers'].get('Content-Type') + if content_type and 'boundary' in content_type: + # requests prepare body时,会使重新生成 boundary,headers中旧的 boundary 会导致上游服务无法识别 + upstream_req_info['headers'] = {k: v for k, v in upstream_req_info['headers'].items()} + upstream_req_info['headers'].pop('Content-Type', None) + upstream_req_info['headers'].pop('content-type', None) + resp = requests.request(**upstream_req_info) + status = resp.status_code + content = None + headers = resp.headers + + for pipe_handler in route.outbound_pipes(): + resp, headers, status, content = pipe_handler(resp, headers, status, content, *args, **kwargs) + + content = make_response(content or resp.content) + for h_name, h_value in (headers or {}).items(): + content.headers[h_name] = h_value + + return content, status + + # 修改函数名称:Flask route注册使用func name必须唯一 + proxy_request.__name__ = route.name + return proxy_request + + def _register_route(self, route): + """ + :param Route route: + """ + proxy = self.create_request_proxy(route) + self.proxy_list.append( + self.app.route(route.path, methods=route.methods)(proxy) + ) + + def register_routes(self): + for route in self.routes: + self._register_route(route) + + +def get_params_from_context(param_name, kwargs): + """按顺序尝试从url参数、headers、args、form、json中获取参数值 + """ + payload = {} + + if kwargs and kwargs.get(param_name): + payload = kwargs + elif request.headers.get(param_name): + payload = request.headers + elif request.args and request.args.get(param_name): + payload = request.args + elif request.form and request.form.get(param_name): + payload = request.form + elif request.data: + body = json.loads(request.data) + if body and body.get(param_name): + payload = body + + try: + return payload[param_name] + except KeyError as e: + # raise InvalidParameterException( + # message="Missing the required params: {}".format(e), + # message_chs="缺少必要的参数 {}".format(e) + # ) + + print('') \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/Route.py b/Route.py new file mode 100644 index 0000000..7347d0d --- /dev/null +++ b/Route.py @@ -0,0 +1,66 @@ +from utils import * + +class Route(object): + """ + 路由实体类,对应一项路由配置 + TODO replace_placeholder 函数,替换字符串中的占位符 + TODO extract_placeholders 函数,获取字符串中的点位符 + TODO get_pipe 函数,通过handler name获取对应的PipeHandler类 + """ + + SERVICE_NAME_PLACEHOLDER = 'service_name' + + def __init__(self, name, service_name, methods, path, upstream_path, pipelines=None): + """ + :param str name: (string) 路由名称 + :param str service_name: (string) 内部微服务名称(如 `resolver` `data_manager` 等) + :param list methods: (array) 支持的请求方法列表, 如 `['GET', 'PUT']` + :param str path: (string) 匹配的路径,使用`flask`的占位符 `` 声明路径参数,服务名称固定使用 `` 占位符 + :param str upstream_path: (string) 转发到上游服务的路径,与`path`使用同样风格的参数占位符 + :param dict pipelines: (object) 数据处理管道 + """ + + if not isinstance(methods, (list, set, tuple)): + raise ValueError("methods must be an iterable list") + pipelines = pipelines or {} + + self.name = name + self.service_name = service_name + self.methods = list(set(methods)) + # 使用 replace_placeholder 将 替换为路由配置中的后端服务 + self.path = replace_placeholder(path, self.SERVICE_NAME_PLACEHOLDER, service_name) + self.upstream_path = replace_placeholder(upstream_path, self.SERVICE_NAME_PLACEHOLDER, service_name) + self.pipelines = { + "inbound": map(self.init_pipe_handler, pipelines.get('inbound') or []), + "outbound": map(self.init_pipe_handler, pipelines.get('outbound') or []), + } + + # 导出上游服务资源所需的参数(占位符) + self.upstream_params = extract_placeholders(self.upstream_path) + + + def init_pipe_handler(self, pipe_conf): + try: + name = pipe_conf['name'] + properties = pipe_conf.get('properties', {}) + klass = get_pipe(name) + return klass(**properties) + except Exception as e: + raise ValueError("illegal pipe config {}: {}".format(pipe_conf, e)) + + + def inbound_pipes(self): + return self.pipelines.get("inbound") or [] + + + def outbound_pipes(self): + return self.pipelines.get("outbound") or [] + + + def load(routes): + """ + + :param list of dict routes: 路由配置列表 + :rtype: list of Route + """ + return map(lambda kv: Route(**kv), routes) \ No newline at end of file diff --git a/__pycache__/ExceptionHandler.cpython-310.pyc b/__pycache__/ExceptionHandler.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..87cb1f0a71f0ce1103be828382e8c8c88d6101ab GIT binary patch literal 2948 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 literal 0 HcmV?d00001 diff --git a/__pycache__/hello.cpython-310.pyc b/__pycache__/hello.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..faae4216c040ec47e6d888e457ff6d170f6762a2 GIT binary patch literal 646 zcmYjPy-OoO6rb7I~Jh~*W-Rjve!ltIKs)W$2$DhSKo&S;{W-F0>rKS-e_#c`)t z9*75CbBB%LDiH<$1OI?&HH%jER=(LyAP?S~dGmh1_r(OGqeTRAdi>xDjL@TYhQ$PD z9yIy{h9QPMw2BrHGZ^V0MmTPhn!(Jk$jZF{0$Et$X;G@1m%Q4KQ$EX<4! zsu4zjZK~W7_q@Q>(1GaU1oR7NGyz6J18s~^3%86G+0aBI{sn;|O{E$-!f8_0a3vLd zJLZwB(&z4V^8e`R{!en)rBl7{zkC0FzTTb1!Yk7h&m|X8nKDN@W!mJj9x&_m?znf_ zO)hSdldG5WgXh18$@OjT$HkzK;4&6|l}`1`l&K>&Aj#H_KCM2iMkWMXb-kjQa8Kpyj?X-<7Zhnz z$QSW`Dc#^q7FvO71>5$WCbw->wC!fVVo%>ow!IxYUKSA}z)tH98T}=MUcA;UKPut$ wWyKHQrd-3W6S=xAof|`Pmx3U^jJbCRfXBCjXC&hgUpl0J3())8UO$Q literal 0 HcmV?d00001 diff --git a/__pycache__/test.cpython-310.pyc b/__pycache__/test.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..803ecfaa4acd5498cdce8a5ce6896a7e3590b3cb GIT binary patch literal 2967 zcmcImOOF#r5T5RN`mtW`1Ck{n;Sr)3i8V_^BB7OqL^gX#HVDjRgftr5z1}fn&(J-y zu-5nlQaHddHxAw-|0I|EfxdF$FQ6z%Roh++M4(7vELV5cRM)Gkzn)}ap=`kOWaW>} zizUN&fz1440dp1p@&*uQFcKU7WF$V(JoPDzG$wu1HwnHoW2-$G?Y6OPFpJrb3}$oE za~_($%gNX~G(eNwG#buJuxsozh_d=g=Pr!od|32Z zB|35sIP0;|qdjoI+%93>Q_4!1(?bGTlwnN;q*b=SYR~KuVT&NCv!yO&%WOrQ6Vi@b`f$}!vuz!bzE$9zJqL;EUJUdt3b;+|^>H21zbi!D+U^3Bvn2riRc zbhxsv|8lcE44Yx6ljMU;HaDlURx^j90*^zhIn5XN>8#b<#G*$X9t^@hZ#8Eoo13#) z5V2Ns;;=b9)7;f z=kJ<%f>M(bi%>$T^NN-!apvYT`EhT!^iBi6ai9<#up6(TgRg-UaG=KI&=`?|i~)QO z$%q!l*krVzJ?oGn^1)#wpelHhf)3OG_pr+|RS6~ZLAG@-4`Wr4 zS(xQA=p>9cOkD@%OtmejbvoDnI(1LmgCcK$b%}*8lQLN*!`1nmW=b7AAF~J7+wj+E z{RQU^!4HyxBnlEhLOpY2W)_TgVFGm+d1{WV!Wz38vOzEKmy)XGOMi_GkvxQeEo=@_=7d?@was3??d+8-pc

+)QzZg2JD z*&ZJ&JZR4k)K|Cb3fv9iQ)meB1rX^X$@QuBb=OW2)3-y`j|R$Rd^gPFY*@$cI)d5@ z5o=h!J5^Q|;;QdX(bTUT;YGxJN4MqO>9{Wt`r&G@dNLWjL`GRG%);U2x39Z55b162 zGbmOj08aE9*cq<>Hv^610?&zG`Z?@IouA?2RaL>WTnvK!FwVL79N*Tq`GAY4GySg6 z$6J>VL9rXjjEi6bXyOd!;&zfj2B%(piK|xyPva176;1b&n87V1mQm446F~pdFcs%f zwFEb59E74P#W(ogW_drA%1rZ2IgG~~Je`6UjmiW!tN5u92!1bzeep|E4xmGa?RF>M zLCQ%(5%#6_ANMn^Z;rd zvP@y50J;<)7=F&5o>Qi)W{uQH9boD>&D2CAOV!nYw6+^TY7sBsm3 z*}C!D_zH&eTg&btC4SA~bp5)%sc% zV34oC2@W3gpl1^kzkwfM;!TP06+HQ-1znBP%=wK9n8=%3CRiW7@-lG`>11vrLYXX6k4GTz8vBw$Qe0@Uew;P znlrWA4;(kZI=@&Y@Fwhe*y1jjK01ca04!N013VxS_wgRaNRmyXkEhYVkY?ZLlRYvp z`zF8}**$1Ge|dEF`G9tlur?q2LbUxZqo*G}oxXZ=cJS`>{n7W2hd++?m!gy{_`NV@ zT;bZep2R7sG8btaNmcQ@sGBBSdY&@Gwon$}Wif-`8I!)09E!~zK&vao8!u1nWNovE z%EhrV;N&ghR{{TLwbfWnd9uj@xteavjig5}(@aLOsHNM=27E7t;VkG7`cB4)jVth& zn2$sH7ioHIeKR>}x>%xP+(##xZM^ffLSebCOF0vCma-R;`vJhme!w=8IAmPRRO?N_ z_*N9Kd~ml8wMoVUR&QQLUKF}@k*#$jS+6?3L4jPxB^6B0K&3-xXX$Qr7^`}RR);XE zgS@qo`rPl*jK>X_>v_h6)CtuD76qKijQ1Kej^I_YPKW0GQ{@nK(|fwS=q)YI&9@dF zFFtB5drNaGE3M_Wveu(s=*O{xl>yi}{e`&(B&o^&F`>y71Wd)^li&hP?B&w2R%lN2 z6a@%U69S}@_Kw-y9k`C6EY9-5Re3$(U0;HbKsE-SfbP!t&_5M|DQ)?2 z#{Qjj;sRv&&TaufKIjzY(-1qBBAoFugvtt%ZW@88uS1sWCI6SaZU|e;k>^y{%|fWI SmXa6+V4/tracks", + "upstream_path": "/api/playlist//tracks", + "pipelines": { + "outbound": [{ "name": "plugin.MusicHandler.MusicHandler" }] + } + } + + route_3 = { + "name": "del-sound", + "service_name": "music_server", + "methods": ["DELETE"], + "path": "/music/api/playlist//tracks", + "upstream_path": "/api/playlist//tracks", + "pipelines": { + "outbound": [{ "name": "plugin.MusicHandler.MusicHandler" }] + } + } + + route_4 = { + "name": "del-playlist", + "service_name": "music_server", + "methods": ["DELETE"], + "path": "/music/api/playlist/", + "upstream_path": "/api/playlist/", + "pipelines": { + "outbound": [{ "name": "plugin.MusicHandler.MusicHandler" }] + } + } + + route_5 = { + "name": "add-playlist", + "service_name": "music_server", + "methods": ["POST"], + "path": "/music/api/playlist", + "upstream_path": "/api/playlist", + "pipelines": { + "outbound": [{ "name": "plugin.MusicHandler.MusicHandler" }] + } + } + + self.routes = Route.load([route_2, route_3, route_4, route_5]) + + gateway = GenericGateway(self.app, self.routes, url_supplier=self.url_supplier) + gateway.register_routes() + +gateway_server = GatewayServer() +app = gateway_server.app +app.run(port=5000, debug=True) \ No newline at end of file diff --git a/plugin/MusicHandler.py b/plugin/MusicHandler.py new file mode 100644 index 0000000..e2662d9 --- /dev/null +++ b/plugin/MusicHandler.py @@ -0,0 +1,15 @@ +from ExceptionHandler import * +import plugin.NavidromePlaylistSync.app as navidromePlaylistSync + +class MusicHandler(OutboundHandler): + def handle(self, response, headers, status, content, *args, **kwargs): + """ + :param dict request: 请求信息 (初始:url, parameters, data, method),可根据需要添加 + :return: (request, args, kwargs) + """ + # raise NotImplementedError + print("222") + print(status) + if status == 200: + navidromePlaylistSync.start() + return [response, headers, status, content] \ No newline at end of file diff --git a/plugin/NavidromePlaylistSync/__init__.py b/plugin/NavidromePlaylistSync/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/plugin/NavidromePlaylistSync/__pycache__/__init__.cpython-310.pyc b/plugin/NavidromePlaylistSync/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e37f39bf9e3fdbe4d1064e8854a4cc34917ea6fd GIT binary patch literal 159 zcmd1j<>g`kf`2{dl0o!i5P=LBfgA@QE@lA|DGb33nv8xc8Hzx{2;!HMt5r-vQGQlx za!E`Q_$ literal 0 HcmV?d00001 diff --git a/plugin/NavidromePlaylistSync/__pycache__/app.cpython-310.pyc b/plugin/NavidromePlaylistSync/__pycache__/app.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bfae2852d21a3a8935fb09a60b396c99f19cafd5 GIT binary patch literal 975 zcmah{O>fgM820NpiQBbf;!A=PlNeGs^splW1Y%5@K+~k{6ctrgZMv*!5*%-+QgSN) zf$MtY!cXA`_{xdDzyWxjwo?yibM$`2kDm8=ZRg!?o8a2}`eV535%SX&>x*LX3a#8n zCy9iVoGcTTuE2oUKXHx>oIkc&iM;pxz2tJT89M|*=- zen)4>8C=rFdxp(H!kpH`_!XG}5EINu4JNE$1~na#+NL(_4(O}Fx9AcHZ}$CZa2S~WMD6?b?< zy^{pzLW{yf%Z!>7mL}4&OiYwzg)pa$;T>-H!wR&#WYPyV?8WvAc{g|GTxH;=Pb>IbldN7JLaXhQ2R&}vvQgZ zt(Q6isnQie)QY)Nc;r<1rfJYEmh7*!7Snih4Spa?3yEf^Si6g{ObR1nA0Y?w8_{?0 z-|rW1pY;o!pQ)kg7gKYZXOFJR^n8?L{X=n)NS#mAO2#pY>*Ex?Vru=;2yH@SDj%b} z51a;+Q--k(ZP-NHq8$imhjQou`@=xrYqU&6k{w22{G@2w^#0qXCyJ!E7&N*Ow>pV< z=UV91DQ{m7!zpiIYA$;((Tj=j6}ZS5T4m=+ZfxPdh;&iP#-{w2-cev!CR<@klo^z{J9$ofdoAG2tGh_^bvdp z-(asj`3i#IZ1B*5`M&vfW@mP%m`nm7dp~?7pTq|zj*XGHCO0zz0RmHqKrrFGL4*Py zAmrbafmMQz{*4n4$ZyEaf}nyuHqc><4KCqv*0Kt=Z0|MDu#UA}uXy8isL!Z&;39h9UdGjv<=aB#cBsrorP2Qg!jnRYAc4}ypYqQ@fiAeO=!Hxak&ZkA2jWo3J+cOO86 z?$L+v34DVb_2esf(aDxVXP7VZ&1Alik?r<60z3Zt3_jrewq(@^kaGyN1Hci-5gH&) zxbut#nBzY3=nr&IFR(Y4Mj>$_E+Et$fJP%cCp9{nRxnwSDbbBZy(A@i1=TlFf%1&J zY)qZfnXi?&!WiAayA*upV95ID5GgN*y7gNKTk~koP%Yy0iFV_ou_5`r*EB>bLsO<7 z4IRlaF-;z335$hseg7ehgzp+foW5f=8;S9;BcqHeieiiWhANm>4#gX4x6&!tTzpGo^OZ8Wa2& z9_Z1};@Qg_ym;~}s0qH=QY5^|ym|B9y!U%=<_({oE+e4t7vF*{1EHUKbDaomp2HL? zz$l_PLY`hpgk$0ntYsrIV$(BY%d=o_QtLDFY>IbK-Tnn$s8z?x-iSh$$U0GXUh}|@ zwwd7FEMP4zH+eUqYGIqjT(X<`KnIwR1Hu%{4VdBwFp4RmhKBrN4v|CybcTmm;v;fy z6x@{72vd7RhD73Xdq75bXyncSpF7kUVT|6PWWhwz?Kd$Rni%C}S)%S)VcCV^hUP~z zvBql;_t3z2f!?nUtue-c3@nIk=d%#8OiKf65e)zhBMCAsFG4;V<76E$ruxw(My0S$ zO{^1~llA{N6v6dXT6wJ_Wh&Mhjnq$;J7Jjlhv9M%b@$hrE6vpg^-q-%^T@02p1yj# zbG+GnctW2Xi??;to9VHAu(vy0$i$DCSGiO~{4h+e%&9L#k7v}IrlIinBi0T&EI3xC zWO16$yy=QCXxvXDzaND{=F>sM{AB6C4 zca+0Z8S+FZJ1Ck>xw?cc2=A39`3qHI9|Be!^jwY60=&$H2wzb)2g~n!FW2@G|1_i- zkJ*EX;{(x8f<4Wa)4npbV8Q9)Ul2mD9`;|?S-@pXNEKJ{Ja#{k3)iTEWfn#i-z_xe zpKQKJIMe;?RmZRL2wqkHkm6#zxry>BSy5D3lwY_Pxn5(pA(nEV#+-H|_6+OPbWtv< I0Ca`?1JErCKmY&$ literal 0 HcmV?d00001 diff --git a/plugin/NavidromePlaylistSync/api/__init__.py b/plugin/NavidromePlaylistSync/api/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/plugin/NavidromePlaylistSync/api/__pycache__/__init__.cpython-310.pyc b/plugin/NavidromePlaylistSync/api/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ca8fbc2f8c7a73a9ec8c20721491a28e81c3cc54 GIT binary patch literal 135 zcmd1j<>g`k0*}+DlR@-j5P=LBfgA@QE@lA|DGb33nv8xc8Hzx{2;!HPt5r;1Vp(QN zQGRZ!Zb43BWlm;siEeRaUUE!gL1s*Rd}dx|NqoFsLFFwDo80`A(wtN~kQv2HK!Sw< E09$+=g8%>k literal 0 HcmV?d00001 diff --git a/plugin/NavidromePlaylistSync/api/__pycache__/playlist.cpython-310.pyc b/plugin/NavidromePlaylistSync/api/__pycache__/playlist.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c2640a01db19a52f90f571b2dce536ffbb87ed2f GIT binary patch literal 981 zcmb7@&2G~`5Xbk!iA~eARjD{5ger_k+#ZmsiUOtL074O{x2RIJcvp#A$7^QS&_wBt zD^CEG;Miy34SeOqE95|#b()gGiIsNNJL?_K{QhIzY%UNS%NO6{JDiXoZZkg^Zl2;a zchN{9X-c|8GRZ%ZE|s3F;mTxP`nYmQ_emK1#5YMNrf#_$9CaWi{OtwT}`x=swu!+tl{xc;&!R^tTzO}j8 zj-o+flDOSZ5)i$l9jC?H?X8Wi%}C@)l&4~tCdNKFRGHj)xUqhyK`PkU-QQb3G#czq zBJsfreA+mtrQcTq&rQh70Mxre8EZ=3Q?~SujLt%@tXX}mGN@rGB?o0nAI(cVJ14M+ z&dL4f+XtC=pGeRH)tV*HGQ%uBz?2SVo_0Pg8yNZZWs0Z)F;0>N=3OlDfO-^`a2q=z zX5$*p2k5PEQioIWFNm-L>N&u&cE-mj5Q0UZM+}krozb!=WTK;!)*x5C0#b0F4Ov;= zjboKta37nr{s(O|@*@i(J~rU83pvzr0Uu52$2zkrv!T~r$VEDQg;KnbaKpXe2!gA( z!ZtNccWFiH4_T^(bY$F(26`(pj0Lp*>y}riu!_EGWL&tbMr-5d4;gHcDyDBDv;*3Q+K9pkcnE~S73EC?2Z-+RpA`Tzg` literal 0 HcmV?d00001 diff --git a/plugin/NavidromePlaylistSync/api/__pycache__/token.cpython-310.pyc b/plugin/NavidromePlaylistSync/api/__pycache__/token.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fe693268a09758c2c68ef7ce8a6667441765094c GIT binary patch literal 436 zcmYjNK}rKL6iqTy8;cbLFW^e1&{kKLA|i?#!6H~ULpRe&Xw%M2#{7(RO1pFG4P3NK z&*BZTb>$V@Xi^aR;J^G&{(B)$*6TH7aq#;Yf7|oR4cj1gxU>a_mKb6@@FWi8PvE<}VPdypbhd;1yY;C0US_$9C4vui6W} zR3`KN_~`K^v}-R6Jx?Vo5`Ka01a6n2J@N;cH)^c_ literal 0 HcmV?d00001 diff --git a/plugin/NavidromePlaylistSync/api/playlist.py b/plugin/NavidromePlaylistSync/api/playlist.py new file mode 100644 index 0000000..db6dd82 --- /dev/null +++ b/plugin/NavidromePlaylistSync/api/playlist.py @@ -0,0 +1,25 @@ +import requests + +def getPlaylist(token): + headers = { + 'x-nd-authorization': f'Bearer {token}' + } + res = requests.get('https://music.hiiragi.club:8081/api/playlist?_end=50&_order=ASC&_sort=id&_start=0', headers = headers) + resJson = res.json() + return resJson + +def downloadPlayList(palyListId, token): + headers = { + 'Accept': 'audio/x-mpegurl', + 'x-nd-authorization': f'Bearer {token}' + } + res = requests.get(f'https://music.hiiragi.club:8081/api/playlist/{palyListId}/tracks', headers = headers) + return res.content + +def delPlaylist(playlistId, token): + headers = { + 'x-nd-authorization': f'Bearer {token}' + } + res = requests.delete(f'https://music.hiiragi.club:8081/api/playlist/{playlistId}', headers = headers) + resJson = res.json() + return resJson \ No newline at end of file diff --git a/plugin/NavidromePlaylistSync/api/token.py b/plugin/NavidromePlaylistSync/api/token.py new file mode 100644 index 0000000..deab28a --- /dev/null +++ b/plugin/NavidromePlaylistSync/api/token.py @@ -0,0 +1,7 @@ +import requests + +def getToken(): + body = { 'username': 'mol', 'password': 'c!UxnePTkwBMb7' } + res = requests.post('https://music.hiiragi.club:8081/auth/login', json = body) + resJson = res.json() + return resJson.get('token') \ No newline at end of file diff --git a/plugin/NavidromePlaylistSync/app.py b/plugin/NavidromePlaylistSync/app.py new file mode 100644 index 0000000..d42c50f --- /dev/null +++ b/plugin/NavidromePlaylistSync/app.py @@ -0,0 +1,33 @@ +from plugin.NavidromePlaylistSync.api.token import * +from plugin.NavidromePlaylistSync.api.playlist import * +from plugin.NavidromePlaylistSync.saveFile import * +from plugin.NavidromePlaylistSync.sync import * +from plugin.NavidromePlaylistSync.resetDir import * + +def start(): + tempPath = os.path.join(os.path.dirname(__file__), 'temp') + + reset(tempPath) + + token = getToken() + + playlistArray = getPlaylist(token) + delPlaylistIds = [] + + for i in playlistArray: + id = i.get('id') + name = i.get('name') + if i.get('path') == '': + delPlaylistIds.append(id) + + data = downloadPlayList(i.get('id') , token) + saveFile(name, data) + + sync() + + if len(delPlaylistIds) > 0: + for delId in delPlaylistIds: + delPlaylist(delId, token) + +if __name__ == 'main': + start() diff --git a/plugin/NavidromePlaylistSync/resetDir.py b/plugin/NavidromePlaylistSync/resetDir.py new file mode 100644 index 0000000..b2a2837 --- /dev/null +++ b/plugin/NavidromePlaylistSync/resetDir.py @@ -0,0 +1,10 @@ +import os + +def reset(path): + delList = os.listdir(path) + + for f in delList: + filePath = os.path.join(path, f) + if os.path.isfile(filePath): + os.remove(filePath) + \ No newline at end of file diff --git a/plugin/NavidromePlaylistSync/saveFile.py b/plugin/NavidromePlaylistSync/saveFile.py new file mode 100644 index 0000000..50d171e --- /dev/null +++ b/plugin/NavidromePlaylistSync/saveFile.py @@ -0,0 +1,6 @@ +import os + +def saveFile(name, data): + tempPath = os.path.join(os.path.dirname(__file__), 'temp') + with open(os.path.join(tempPath, f'{name}.m3u'), 'wb') as code: + code.write(data) \ No newline at end of file diff --git a/plugin/NavidromePlaylistSync/sync.py b/plugin/NavidromePlaylistSync/sync.py new file mode 100644 index 0000000..8431e88 --- /dev/null +++ b/plugin/NavidromePlaylistSync/sync.py @@ -0,0 +1,28 @@ +import os +from webdav3.client import Client +from webdav3.exceptions import LocalResourceNotFound, RemoteResourceNotFound + +def sync(): + options = { + 'webdav_hostname': 'https://pan.hiiragi.club:8081/dav', + 'webdav_login': 'mol', + 'webdav_password': 'YvG4SkF82qd7ks', + 'disable_check': True, + } + + client = Client(options) + tempPath = os.path.join(os.path.dirname(__file__), 'temp') + playlists = os.listdir(tempPath) + + try: + client.clean('Music/#playlist') + except RemoteResourceNotFound as exception: + print('clean failed!') + + for fileName in playlists: + path = os.path.join(tempPath, fileName) + try: + client.upload('Music/#playlist/' + fileName, path) + print(fileName + ' upload success!!') + except LocalResourceNotFound as exception: + print(fileName + ' upload failed!!') \ No newline at end of file diff --git a/plugin/NavidromePlaylistSync/temp/ClariS.m3u b/plugin/NavidromePlaylistSync/temp/ClariS.m3u new file mode 100644 index 0000000..5718829 --- /dev/null +++ b/plugin/NavidromePlaylistSync/temp/ClariS.m3u @@ -0,0 +1,13 @@ +#EXTM3U +#EXTINF:264,ClariS - border +/music/ClariS/ClariS 〜SINGLE BEST 1st〜/11 border.mp3 +#EXTINF:260,ClariS - irony +/music/ClariS/irony/1-01 irony.mp3 +#EXTINF:304,ClariS - Don't cry +/music/ClariS/nexus/02 Don't cry.mp3 +#EXTINF:256,ClariS - STEP +/music/ClariS/STEP/01 STEP.mp3 +#EXTINF:282,ClariS - 桜咲く +/music/ClariS/STEP/03 桜咲く.mp3 +#EXTINF:272,ClariS - コネクト +/music/ClariS/コネクト/01 コネクト.mp3 diff --git a/plugin/NavidromePlaylistSync/temp/HIMEHINA.m3u b/plugin/NavidromePlaylistSync/temp/HIMEHINA.m3u new file mode 100644 index 0000000..fa8074a --- /dev/null +++ b/plugin/NavidromePlaylistSync/temp/HIMEHINA.m3u @@ -0,0 +1,31 @@ +#EXTM3U +#EXTINF:226,HIMEHINA - 相思相愛リフレクション +/music/HIMEHINA/希織歌/05 相思相愛リフレクション.flac +#EXTINF:275,HIMEHINA - 流れ行く命 +/music/HIMEHINA/流れ行く命/01 流れ行く命.flac +#EXTINF:90,HIMEHINA - 約束の血 +/music/HIMEHINA/藍の華/01 約束の血.flac +#EXTINF:227,HIMEHINA - 藍の華 +/music/HIMEHINA/藍の華/03 藍の華.flac +#EXTINF:223,HIMEHINA - ヒトガタRock +/music/HIMEHINA/藍の華/04 ヒトガタRock.flac +#EXTINF:262,HIMEHINA - ヒバリ(Laugh-In) +/music/HIMEHINA/藍の華/05 ヒバリ(Laugh-In).flac +#EXTINF:251,HIMEHINA - ライライラビットテイル +/music/HIMEHINA/藍の華/06 ライライラビットテイル.flac +#EXTINF:262,HIMEHINA - 琥珀の身体(Message-In) +/music/HIMEHINA/藍の華/08 琥珀の身体(Message-In).flac +#EXTINF:219,HIMEHINA - 溺れるほど愛した花 +/music/HIMEHINA/藍の華/10 溺れるほど愛した花.flac +#EXTINF:301,HIMEHINA - 夢景色 +/music/HIMEHINA/藍の華/11 夢景色.flac +#EXTINF:286,HIMEHINA - うたかたよいかないで(Message-In) +/music/HIMEHINA/藍の華/12 うたかたよいかないで(Message-In).flac +#EXTINF:265,HIMEHINA - ララ +/music/HIMEHINA/藍の華/14 ララ.flac +#EXTINF:237,HIMEHINA - アダムとマダム +/music/HIMEHINA/藍の華/16 アダムとマダム.flac +#EXTINF:225,HIMEHINA - ヒトガタ +/music/HIMEHINA/藍の華/17 ヒトガタ.flac +#EXTINF:390,HIMEHINA - My Dear +/music/HIMEHINA/藍の華/19 My Dear.flac diff --git a/plugin/NavidromePlaylistSync/temp/JOJO.m3u b/plugin/NavidromePlaylistSync/temp/JOJO.m3u new file mode 100644 index 0000000..1094c07 --- /dev/null +++ b/plugin/NavidromePlaylistSync/temp/JOJO.m3u @@ -0,0 +1,17 @@ +#EXTM3U +#EXTINF:337,SOUL’d OUT - VOODOO KINGDOM +/music/SOUL’d OUT/ATTITUDE/04 SOUL’d OUT - VOODOO KINGDOM.mp3 +#EXTINF:262,Coda - BLOODY STREAM +/music/Coda/BLOODY STREAM/01 BLOODY STREAM.mp3 +#EXTINF:340,Pat Metheny Group - Last Train Home +/music/Pat Metheny Group/Essential Collection_ Last Train Home/01 Last Train Home.mp3 +#EXTINF:243,青木カレン・ハセガワダイスケ - Great Days +/music/青木カレン・ハセガワダイスケ/Great Days/01 Great Days.mp3 +#EXTINF:265,富永TOMMY弘明 - ジョジョ 〜その血の運命〜 +/music/富永TOMMY弘明/ジョジョ 〜その血の運命〜/01 ジョジョ 〜その血の運命〜.mp3 +#EXTINF:264,JO☆STARS~TOMMY, Coda, JIN~ - ジョジョその血の記憶~end of THE WORLD~ +/music/Various Artists/ジョジョの奇妙な冒険 Theme Song Best 「Generation」/06 JO☆STARS~TOMMY, Coda, JIN~ - ジョジョその血の記憶~end of THE WORLD~.mp3 +#EXTINF:175,菅野祐悟 - 高潔なる教皇 +/music/菅野祐悟/ジョジョの奇妙な冒険 スターダストクルセイダース O.S.T [Departure]/09 高潔なる教皇.mp3 +#EXTINF:308,菅野祐悟 - スターダストクルセイダース +/music/菅野祐悟/ジョジョの奇妙な冒険 スターダストクルセイダース O.S.T [Departure]/23 スターダストクルセイダース.mp3 diff --git a/plugin/NavidromePlaylistSync/temp/YOSOBI.m3u b/plugin/NavidromePlaylistSync/temp/YOSOBI.m3u new file mode 100644 index 0000000..efc8f3e --- /dev/null +++ b/plugin/NavidromePlaylistSync/temp/YOSOBI.m3u @@ -0,0 +1,17 @@ +#EXTM3U +#EXTINF:271,YOASOBI - アンコール +/music/YOASOBI/THE BOOK/02 アンコール.flac +#EXTINF:199,YOASOBI - ハルジオン +/music/YOASOBI/THE BOOK/03 ハルジオン.flac +#EXTINF:241,YOASOBI - あの夢をなぞって +/music/YOASOBI/THE BOOK/04 あの夢をなぞって.flac +#EXTINF:257,YOASOBI - たぶん +/music/YOASOBI/THE BOOK/05 たぶん.flac +#EXTINF:248,YOASOBI - 群青 +/music/YOASOBI/THE BOOK/06 群青.flac +#EXTINF:244,YOASOBI - ハルカ +/music/YOASOBI/THE BOOK/07 ハルカ.flac +#EXTINF:259,YOASOBI - 夜に駆ける +/music/YOASOBI/THE BOOK/08 夜に駆ける.flac +#EXTINF:205,YOASOBI - 怪物 +/music/YOASOBI/THE BOOK 2/06 YOASOBI - 怪物.flac diff --git a/plugin/NavidromePlaylistSync/temp/ナユタン星人.m3u b/plugin/NavidromePlaylistSync/temp/ナユタン星人.m3u new file mode 100644 index 0000000..4284a2b --- /dev/null +++ b/plugin/NavidromePlaylistSync/temp/ナユタン星人.m3u @@ -0,0 +1,7 @@ +#EXTM3U +#EXTINF:191,ナユタン星人 - ダンスロボットダンス +/music/ナユタン星人/ナユタン星からの物体Y/04 ダンスロボットダンス.flac +#EXTINF:203,ナユタン星人 - 太陽系デスコ +/music/ナユタン星人/ナユタン星からの物体Y/07 太陽系デスコ.flac +#EXTINF:211,ナユタン星人 - ディスコミュ星人 +/music/ナユタン星人/ナユタン星からの物体Y/08 ディスコミュ星人.flac diff --git a/plugin/NavidromePlaylistSync/temp/公主殿下.m3u b/plugin/NavidromePlaylistSync/temp/公主殿下.m3u new file mode 100644 index 0000000..540a4bc --- /dev/null +++ b/plugin/NavidromePlaylistSync/temp/公主殿下.m3u @@ -0,0 +1,69 @@ +#EXTM3U +#EXTINF:222,40mP - 恋愛裁判 +/music/40mP/41m/02 40mP - 恋愛裁判.mp3 +#EXTINF:216,DECO*27 feat. 初音ミク - おじゃま虫 +/music/DECO_27/Conti New/1-02 おじゃま虫.flac +#EXTINF:216,DECO*27 feat. 初音ミク - 妄想税 +/music/DECO_27/Conti New/1-10 妄想税.mp3 +#EXTINF:306,蝶々P feat. 初音ミク - そういうこと。 +/music/蝶々P feat. 初音ミク/Fictional World/11 蝶々P feat. 初音ミク - そういうこと。.mp3 +#EXTINF:244,トーマ feat. 初音ミク - オレンジ +/music/Various Artists/HATSUNE MIKU 10th Anniversary Album 「Re_Start」/2-11 トーマ feat. 初音ミク - オレンジ.flac +#EXTINF:149,初音ミク - Ievan Polkka +/music/初音ミク/Hatsune Miku 1st Song Album/11 Ievan Polkka.mp3 +#EXTINF:265,ぼーかりおどP/初音ミク - 1/6 -out of the gravity- +/music/ぼーかりおどP_初音ミク/1_6 -out of the gravity-.mp3 +#EXTINF:323,doriko feat. 初音ミク - 文学者の恋文 +/music/doriko feat.初音ミク/Nostalgia/04 doriko feat. 初音ミク - 文学者の恋文.mp3 +#EXTINF:257,livetune feat. 初音ミク - Tell Your World +/music/livetune feat. 初音ミク/Tell Your World/01 Tell Your World.mp3 +#EXTINF:277,はりーP feat. 初音ミク - ぼくらのレットイットビー +/music/Various Artists/V♥25 -cantabile-/02 はりーP feat. 初音ミク - ぼくらのレットイットビー.mp3 +#EXTINF:210,ryo (supercell) feat. 初音ミク - こっち向いて Baby +/music/ryo (supercell) feat. 初音ミク _ kz (livetune) feat. 初音ミク/こっち向いて Baby _ Yellow/1-01 ryo (supercell) feat. 初音ミク - こっち向いて Baby.flac +#EXTINF:268,鏡音リン - 炉心融解 +/music/初音ミク/ミクの日感謝祭 39's Giving Day Project DIVA presents 初音ミク・ソロコンサート~こんばんは、初音ミクです。~/2-09 鏡音リン - 炉心融解.mp3 +#EXTINF:184,初音ミク & 鏡音リン - Promise +/music/初音ミク/ミクの日感謝祭 39's Giving Day Project DIVA presents 初音ミク・ソロコンサート~こんばんは、初音ミクです。~/2-12 初音ミク & 鏡音リン - Promise.mp3 +#EXTINF:192,初音ミク - 愛言葉 [Live] +/music/初音ミク/ミクの日感謝祭 39's Giving Day Project DIVA presents 初音ミク・ソロコンサート~こんばんは、初音ミクです。~/2-17 初音ミク - 愛言葉 [Live].mp3 +#EXTINF:259,ryo feat. 初音ミク - メルト +/music/ryo, supercell feat. 初音ミク/メルト/01 ryo feat. 初音ミク - メルト.flac +#EXTINF:277,doriko feat.初音ミク - ロミオとシンデレラ +/music/doriko feat.初音ミク/ロミオとシンデレラ/09 ロミオとシンデレラ.mp3 +#EXTINF:182,KazuP(源屋) feat. 初音ミク - Innocence +/music/Various Artists/初音ミク -Project DIVA- 2nd NONSTOP MIX COLLECTION/1-25 KazuP(源屋) feat. 初音ミク - Innocence.flac +#EXTINF:235,オワタP feat. 鏡音レン - パラジクロロベンゼン +/music/Various Artists/初音ミク -Project DIVA- extend Complete Collection/2-11 オワタP feat. 鏡音レン - パラジクロロベンゼン.mp3 +#EXTINF:202,wowaka feat. 初音ミク - 裏表ラバーズ +/music/Various Artists/初音ミク -Project DIVA- extend Complete Collection/2-12 wowaka feat. 初音ミク - 裏表ラバーズ.mp3 +#EXTINF:293,さつき が てんこもり - ネトゲ廃人シュプレヒコール +/music/初音ミク/初音ミク 5thバースデー ベスト ~impacts~/13 さつき が てんこもり - ネトゲ廃人シュプレヒコール.mp3 +#EXTINF:215,初音ミク - 深海少女 +/music/初音ミク/初音ミク 5thバースデー ベスト ~memories~/1-10 深海少女.mp3 +#EXTINF:219,黒うさP feat. 初音ミク - 千本桜 +/music/Various Artists/初音ミク Project DIVA MEGA39's 10th アニバーサリーコレクション/4-05 黒うさP feat. 初音ミク - 千本桜.mp3 +#EXTINF:238,supercell feat. 初音ミク - 恋は戦争 +/music/初音ミク/初音ミク ベスト~impacts~/11 supercell feat. 初音ミク - 恋は戦争.mp3 +#EXTINF:241,minato feat. 初音ミク - Magnet +/music/初音ミク/初音ミク ベスト~impacts~/13 minato feat. 初音ミク - Magnet.mp3 +#EXTINF:211,azuma feat. 初音ミク - あなたの歌姫 Complete Ver. +/music/初音ミク/初音ミク ベスト~memories~/08 azuma feat. 初音ミク - あなたの歌姫 Complete Ver..mp3 +#EXTINF:214,初音ミク - Weekender Girl +/music/Various Artists/初音ミク-Project DIVA- Ƒ Complete Collection/1-04 初音ミク - Weekender Girl.mp3 +#EXTINF:227,emon feat. 初音ミク・鏡音レン・鏡音リン - shake it! +/music/Various Artists/初音ミク「マジカルミライ 2014」OFFICIAL ALBUM/1-05 emon feat. 初音ミク・鏡音レン・鏡音リン - shake it!.mp3 +#EXTINF:235,八王子P feat. 初音ミク - Sweet Devil +/music/Various Artists/初音ミク「マジカルミライ 2014」OFFICIAL ALBUM/1-07 八王子P feat. 初音ミク - Sweet Devil.wav +#EXTINF:311,じーざす(ワンダフル☆オポチュニティ!) feat. 鏡音リン・鏡音レン - リモコン +/music/Various Artists/初音ミク「マジカルミライ 2015」OFFICIAL ALBUM/1-02 じーざす(ワンダフル☆オポチュニティ!) feat. 鏡音リン・鏡音レン - リモコン.mp3 +#EXTINF:186,ナユタン星人 feat. 初音ミク - エイリアンエイリアン +/music/Various Artists/初音ミク「マジカルミライ 2017」OFFICIAL ALBUM/03 ナユタン星人 feat. 初音ミク - エイリアンエイリアン.flac +#EXTINF:237,Giga feat. 鏡音リン・レン - 劣等上等 +/music/Various Artists/初音ミク「マジカルミライ 2018」OFFICIAL ALBUM/02 Giga feat. 鏡音リン・レン - 劣等上等.flac +#EXTINF:250,すこっぷ feat. 初音ミク Append (Soft) - アイロニ +/music/すこっぷ/境界センチメンタル/04 すこっぷ feat. 初音ミク Append (Soft) - アイロニ.mp3 +#EXTINF:250,40mP feat. 初音ミク - からくりピエロ +/music/40mP/小さな自分と大きな世界/07 40mP feat. 初音ミク - からくりピエロ.mp3 +#EXTINF:326,doriko feat.初音ミク - letter song +/music/doriko feat.初音ミク/花束 〜the best of doriko feat.初音ミク〜/13 letter song.flac diff --git a/plugin/NavidromePlaylistSync/temp/后摇.m3u b/plugin/NavidromePlaylistSync/temp/后摇.m3u new file mode 100644 index 0000000..33185e3 --- /dev/null +++ b/plugin/NavidromePlaylistSync/temp/后摇.m3u @@ -0,0 +1,7 @@ +#EXTM3U +#EXTINF:294,Metavari - Kings Die Like Other Men +/music/Metavari/Be One of Us and Hear No Noise/01 Kings Die Like Other Men.mp3 +#EXTINF:304,Lights & Motion - Victory Rose +/music/Lights & Motion/Reanimation/06 Victory Rose.mp3 +#EXTINF:487,Whale Fall - You Go Up, I Go Down +/music/Whale Fall/Whale Fall/10 You Go Up, I Go Down.mp3 diff --git a/plugin/NavidromePlaylistSync/temp/哥特风.m3u b/plugin/NavidromePlaylistSync/temp/哥特风.m3u new file mode 100644 index 0000000..3b8ca12 --- /dev/null +++ b/plugin/NavidromePlaylistSync/temp/哥特风.m3u @@ -0,0 +1,13 @@ +#EXTM3U +#EXTINF:317,浮森かや子 - お隣はだあれ +/music/浮森かや子/お隣はだあれ.mp3 +#EXTINF:275,ウサギキノコ - Secret +/music/ウサギキノコ/eclipse 改/13 Secret.flac +#EXTINF:352,梶浦由記 - my long forgotten cloistered sleep (unreleased work of Xenosaga) +/music/梶浦由記/Fiction II/04 my long forgotten cloistered sleep (unreleased work of Xenosaga).flac +#EXTINF:313,Stack - カゲロウ +/music/暁Records/NO SIGNAL/03 Stack - カゲロウ.flac +#EXTINF:209,kanon×kanon - ザ ドールハウス! +/music/kanon×kanon/カレンデュラ レクイエム/02 ザ ドールハウス!.flac +#EXTINF:256,WhiteFlame - 流れ星 +/music/WhiteFlame/月と星の虚構空間/1-01 流れ星.mp3 diff --git a/plugin/NavidromePlaylistSync/temp/恋与恋语.m3u b/plugin/NavidromePlaylistSync/temp/恋与恋语.m3u new file mode 100644 index 0000000..5bfa3f8 --- /dev/null +++ b/plugin/NavidromePlaylistSync/temp/恋与恋语.m3u @@ -0,0 +1,21 @@ +#EXTM3U +#EXTINF:235,TOKOTOKO feat. ゆいこんぬ - ハートビート・フロムユー +/music/TOKOTOKO/ハートビート・フロムユー/06 TOKOTOKO feat. ゆいこんぬ - ハートビート・フロムユー.mp3 +#EXTINF:222,40mP - 恋愛裁判 +/music/40mP/41m/02 40mP - 恋愛裁判.mp3 +#EXTINF:226,HIMEHINA - 相思相愛リフレクション +/music/HIMEHINA/希織歌/05 相思相愛リフレクション.flac +#EXTINF:254,千石撫子 (花澤香菜) - 恋愛サーキュレーション +/music/千石撫子 (花澤香菜)/恋愛サーキュレーション/01 恋愛サーキュレーション.flac +#EXTINF:277,スズム feat. GUMI - 世界寿命と最後の一日 (Album ver.) +/music/スズム/ケビョウニンゲン/06 スズム feat. GUMI - 世界寿命と最後の一日 (Album ver.).mp3 +#EXTINF:244,ギガP feat. れをる - No title +/music/ギガP/No title−/06 ギガP feat. れをる - No title.mp3 +#EXTINF:239,DECO*27 feat. GUMI - 弱虫モンブラン +/music/DECO_27/DECO_27 VOCALOID COLLECTION 2008~2012/12 DECO_27 feat. GUMI - 弱虫モンブラン.flac +#EXTINF:340,かぴ - 世界は恋に落ちている –acoustic version– +/music/HoneyWorks/ハニワ曲歌ってみた5/12 かぴ - 世界は恋に落ちている –acoustic version–.mp3 +#EXTINF:250,鹿乃 - アイロニ +/music/鹿乃/曖昧ばんび~な/11 アイロニ.flac +#EXTINF:335,ヲタみん - Letter Song +/music/未分类/ヲタみん - Letter Song.mp3 diff --git a/plugin/NavidromePlaylistSync/temp/校园乐队.m3u b/plugin/NavidromePlaylistSync/temp/校园乐队.m3u new file mode 100644 index 0000000..ba66e20 --- /dev/null +++ b/plugin/NavidromePlaylistSync/temp/校园乐队.m3u @@ -0,0 +1,5 @@ +#EXTM3U +#EXTINF:279,涼宮ハルヒ(CV.平野綾) - God knows... +/music/涼宮ハルヒ(CV.平野綾)、朝比奈みくる(CV.後藤邑子)/涼宮ハルヒの詰合/01 涼宮ハルヒ(CV.平野綾) - God knows....mp3 +#EXTINF:255,涼宮ハルヒ(CV.平野綾) - Lost my music +/music/涼宮ハルヒ(CV.平野綾)、朝比奈みくる(CV.後藤邑子)/涼宮ハルヒの詰合/02 涼宮ハルヒ(CV.平野綾) - Lost my music.mp3 diff --git a/plugin/NavidromePlaylistSync/temp/樱兰高校K-ON部.m3u b/plugin/NavidromePlaylistSync/temp/樱兰高校K-ON部.m3u new file mode 100644 index 0000000..5d97df2 --- /dev/null +++ b/plugin/NavidromePlaylistSync/temp/樱兰高校K-ON部.m3u @@ -0,0 +1,41 @@ +#EXTM3U +#EXTINF:250,Sakurakou K-ON Bu - Cagayake!GIRLS +/music/Sakurakou K-ON Bu/Cagayake!GIRLS/01 Cagayake!GIRLS.mp3 +#EXTINF:228,Sakurakou K-ON Bu - Happy!? Sorry!! +/music/Sakurakou K-ON Bu/Cagayake!GIRLS/02 Happy!_ Sorry!!.mp3 +#EXTINF:264,Sakurakou K-ON Bu - Don’t say “lazy” +/music/Sakurakou K-ON Bu/Don’t say “lazy”/01 Don’t say “lazy”.m4a +#EXTINF:266,Sakurakou K-ON Bu - Sweet Bitter Beauty Song +/music/Sakurakou K-ON Bu/Don’t say “lazy”/02 Sweet Bitter Beauty Song.m4a +#EXTINF:251,Ho-Kago Tea Time - GO! GO! MANIAC +/music/Ho-Kago Tea Time/GO! GO! MANIAC/01 GO! GO! MANIAC.mp3 +#EXTINF:269,Ho-Kago Tea Time - Genius…!? +/music/Ho-Kago Tea Time/GO! GO! MANIAC/02 Genius…!_.mp3 +#EXTINF:260,Death Devil - 光 +/music/未分类/日文流行/Death Devil - 光.flac +#EXTINF:227,放課後ティータイム - Listen!! +/music/放課後ティータイム/Listen!!/01 Listen!!.m4a +#EXTINF:252,放課後ティータイム - Our MAGIC +/music/放課後ティータイム/Listen!!/02 Our MAGIC.m4a +#EXTINF:257,Ho-Kago Tea Time - NO, Thank You! +/music/Ho-Kago Tea Time/NO, Thank You!/01 NO, Thank You!.m4a +#EXTINF:214,Ho-Kago Tea Time - Girls in Wonderland +/music/Ho-Kago Tea Time/NO, Thank You!/02 Girls in Wonderland.m4a +#EXTINF:232,放課後ティータイム - Unmei♪wa♪Endless! +/music/放課後ティータイム/Unmei♪wa♪Endless!/01 Unmei♪wa♪Endless!.mp3 +#EXTINF:250,放課後ティータイム - いちばんいっぱい +/music/放課後ティータイム/Unmei♪wa♪Endless!/02 いちばんいっぱい.mp3 +#EXTINF:242,放課後ティータイム - Utauyo!!MIRACLE +/music/放課後ティータイム/Utauyo!!MIRACLE/01 Utauyo!!MIRACLE.mp3 +#EXTINF:220,放課後ティータイム - キラキラDays +/music/放課後ティータイム/Utauyo!!MIRACLE/02 キラキラDays.mp3 +#EXTINF:239,桜高軽音部 - ふわふわ時間 +/music/桜高軽音部/ふわふわ時間/01 ふわふわ時間.mp3 +#EXTINF:204,桜高軽音部 - 翼をください +/music/桜高軽音部/ふわふわ時間/02 翼をください.mp3 +#EXTINF:196,放課後ティータイム - カレーのちライス +/music/放課後ティータイム/放課後ティータイム/1-01 カレーのちライス.mp3 +#EXTINF:264,放課後ティータイム - わたしの恋はホッチキス +/music/放課後ティータイム/放課後ティータイム/1-02 わたしの恋はホッチキス.mp3 +#EXTINF:238,放課後ティータイム - ふでペン 〜ボールペン〜 +/music/放課後ティータイム/放課後ティータイム/1-03 ふでペン 〜ボールペン〜.mp3 diff --git a/plugin/NavidromePlaylistSync/temp/治愈.m3u b/plugin/NavidromePlaylistSync/temp/治愈.m3u new file mode 100644 index 0000000..392adea --- /dev/null +++ b/plugin/NavidromePlaylistSync/temp/治愈.m3u @@ -0,0 +1,45 @@ +#EXTM3U +#EXTINF:369,Lia - 鳥の詩 +/music/Various Artists/AIR Original SoundTrack/1-03 Lia - 鳥の詩.mp3 +#EXTINF:275,ウサギキノコ - Secret +/music/ウサギキノコ/eclipse 改/13 Secret.flac +#EXTINF:197,Yuri Chika - 涙の物語 +/music/Yuri Chika/Good Luck To You/09 涙の物語.mp3 +#EXTINF:260,ClariS - irony +/music/ClariS/irony/1-01 irony.mp3 +#EXTINF:299,茶太 - 小さな手のひら +/music/Various Artists/KSL Live World 2008 ~Way to the Little Busters! EX~/1-13 茶太 - 小さな手のひら.flac +#EXTINF:335,ヲタみん - Letter Song +/music/未分类/ヲタみん - Letter Song.mp3 +#EXTINF:221,チト(CV:水瀬いのり)、ユーリ(CV:久保ユリカ) - More One Night +/music/チト(CV_水瀬いのり)、ユーリ(CV_久保ユリカ)/More One Night/01 More One Night.flac +#EXTINF:276,Lia - My Soul, Your Beats! +/music/Lia _ 多田葵/My Soul, Your Beats! _ Brave Song/1-01 Lia - My Soul, Your Beats!.mp3 +#EXTINF:325,多田葵 - Brave Song +/music/Lia _ 多田葵/My Soul, Your Beats! _ Brave Song/1-02 多田葵 - Brave Song.flac +#EXTINF:353,本間芽衣子(茅野愛衣) / 安城鳴子(戸松遥) / 鶴見知利子(早見沙織) - secret base 〜君がくれたもの〜 (10 years after Ver.) +/music/本間芽衣子(茅野愛衣) _ 安城鳴子(戸松遥) _ 鶴見知利子(早見沙織)/secret base 〜君がくれたもの〜/01 secret base 〜君がくれたもの〜 (10 years after Ver.).mp3 +#EXTINF:360,karuta - 一番の宝物 (original version) +/music/ANANT-GARDE EYES/TVアニメ「Angel Beats!」オリジナルサウンドトラック/2-19 karuta - 一番の宝物 (original version).flac +#EXTINF:268,千反田える(佐藤聡美)&伊原摩耶花(茅野愛衣) - まどろみの約束 +/music/千反田える(佐藤聡美)&伊原摩耶花(茅野愛衣)/まどろみの約束/01 まどろみの約束.mp3 +#EXTINF:253,RAM WIRE - 僕らの手には何もないけど、 +/music/RAM WIRE/むすぶ/13 僕らの手には何もないけど、.mp3 +#EXTINF:340,かぴ - 世界は恋に落ちている –acoustic version– +/music/HoneyWorks/ハニワ曲歌ってみた5/12 かぴ - 世界は恋に落ちている –acoustic version–.mp3 +#EXTINF:235,TOKOTOKO feat. ゆいこんぬ - ハートビート・フロムユー +/music/TOKOTOKO/ハートビート・フロムユー/06 TOKOTOKO feat. ゆいこんぬ - ハートビート・フロムユー.mp3 +#EXTINF:335,じん - アヤノの幸福理論 +/music/じん/メカクシティレコーズ/10 アヤノの幸福理論.mp3 +#EXTINF:273,茶太 - だんご大家族 +/music/eufonius _ 茶太/メグメル _ だんご大家族/02 茶太 - だんご大家族.flac +#EXTINF:239,髏々宮カルタ(花澤香菜) - sweets parade +/music/髏々宮カルタ(花澤香菜) & 青鬼院蜻蛉(杉田智和)/妖狐×僕SS ENDING SONG vol.3/01 髏々宮カルタ(花澤香菜) - sweets parade.mp3 +#EXTINF:254,千石撫子 (花澤香菜) - 恋愛サーキュレーション +/music/千石撫子 (花澤香菜)/恋愛サーキュレーション/01 恋愛サーキュレーション.flac +#EXTINF:250,鹿乃 - アイロニ +/music/鹿乃/曖昧ばんび~な/11 アイロニ.flac +#EXTINF:173,ゆめこ - 雨き声残響 +/music/未分类/动漫歌曲/ゆめこ - 雨き声残響.mp3 +#EXTINF:249,つじあやの - 風になる +/music/野見祐二/猫の恩返し サウンドトラック/25 つじあやの - 風になる.mp3 diff --git a/plugin/NavidromePlaylistSync/temp/测试.m3u b/plugin/NavidromePlaylistSync/temp/测试.m3u new file mode 100644 index 0000000..b8c4beb --- /dev/null +++ b/plugin/NavidromePlaylistSync/temp/测试.m3u @@ -0,0 +1,3 @@ +#EXTM3U +#EXTINF:317,浮森かや子 - お隣はだあれ +/music/浮森かや子/お隣はだあれ.mp3 diff --git a/plugin/NavidromePlaylistSync/temp/测试2.m3u b/plugin/NavidromePlaylistSync/temp/测试2.m3u new file mode 100644 index 0000000..fcd7187 --- /dev/null +++ b/plugin/NavidromePlaylistSync/temp/测试2.m3u @@ -0,0 +1 @@ +#EXTM3U diff --git a/plugin/NavidromePlaylistSync/temp/蓝之华.m3u b/plugin/NavidromePlaylistSync/temp/蓝之华.m3u new file mode 100644 index 0000000..a4b0f84 --- /dev/null +++ b/plugin/NavidromePlaylistSync/temp/蓝之华.m3u @@ -0,0 +1,27 @@ +#EXTM3U +#EXTINF:90,HIMEHINA - 約束の血 +/music/HIMEHINA/藍の華/01 約束の血.flac +#EXTINF:227,HIMEHINA - 藍の華 +/music/HIMEHINA/藍の華/03 藍の華.flac +#EXTINF:223,HIMEHINA - ヒトガタRock +/music/HIMEHINA/藍の華/04 ヒトガタRock.flac +#EXTINF:262,HIMEHINA - ヒバリ(Laugh-In) +/music/HIMEHINA/藍の華/05 ヒバリ(Laugh-In).flac +#EXTINF:251,HIMEHINA - ライライラビットテイル +/music/HIMEHINA/藍の華/06 ライライラビットテイル.flac +#EXTINF:262,HIMEHINA - 琥珀の身体(Message-In) +/music/HIMEHINA/藍の華/08 琥珀の身体(Message-In).flac +#EXTINF:219,HIMEHINA - 溺れるほど愛した花 +/music/HIMEHINA/藍の華/10 溺れるほど愛した花.flac +#EXTINF:301,HIMEHINA - 夢景色 +/music/HIMEHINA/藍の華/11 夢景色.flac +#EXTINF:286,HIMEHINA - うたかたよいかないで(Message-In) +/music/HIMEHINA/藍の華/12 うたかたよいかないで(Message-In).flac +#EXTINF:265,HIMEHINA - ララ +/music/HIMEHINA/藍の華/14 ララ.flac +#EXTINF:237,HIMEHINA - アダムとマダム +/music/HIMEHINA/藍の華/16 アダムとマダム.flac +#EXTINF:225,HIMEHINA - ヒトガタ +/music/HIMEHINA/藍の華/17 ヒトガタ.flac +#EXTINF:390,HIMEHINA - My Dear +/music/HIMEHINA/藍の華/19 My Dear.flac diff --git a/plugin/__init__.py b/plugin/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/plugin/__pycache__/MusicHandler.cpython-310.pyc b/plugin/__pycache__/MusicHandler.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..72f2f98c01d680c5ae74fe2f800bd62226b0bf8b GIT binary patch literal 841 zcmZuv&1(}u6rb7MBuhwb(e^5P@X(bIB*!S?rRc>}sHY{cj5}kpx?i1{RUe+1_ZgnnwL zEEYJ|;D{CgMHENqw$?_3W5Ylg#inOrbRAKXT6>6Etg>r*RcdS@w{i?`kc$<**bTH< z7AQ7Pyb1HCeBb>wz4FlMMVD{zdukZV_or$wP zefEC(@x{sE+nh&Dr-)~ganW=rk)-LwOb$}&o*cfMzMjm+UuUmAAHREY^kHXq@NN2h z{I?KiGUrLhSznZCI)wKj$^C~~yNfW-Y`5F4sVW%{6RFk`@*t!jZQD) z={*+6UN(d_66c>A<^3?}m1p0|hN?O!_Mo>QYyi7zV;eW{<8%K-&ZD}pJ=^ya5;Nad zb>ELunn&7h`2KcIqWKM9fkXwN5-jU)CV*bB&|sqmF1|qDD;tjjmdP+p7XO9kWCh_? z_q2hvNS1kPr(P)&?zrwpEpO)XPMRllk+UdPqNGR0H7{jfnRjv(gD0v0Had$}jX$&P B@45g0 literal 0 HcmV?d00001 diff --git a/plugin/__pycache__/__init__.cpython-310.pyc b/plugin/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..73d447caeaeb15ebf921cef434f7b8df63d0c4a9 GIT binary patch literal 137 zcmd1j<>g`k0?FQU$sqbMh(HF6K#l_t7qb9~6oz01O-8?!3`HPe1o2D9)hec-C_gJT zxg@5bvLquvPXW%&DNWDJi;0iV%*!l^kJl@xyv1RYo1apelWGStrI-mwurL4scyS&s literal 0 HcmV?d00001 diff --git a/plugin/__pycache__/app.cpython-310.pyc b/plugin/__pycache__/app.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f248e026cfcb959ec44736b9ad7d47600a0a6c76 GIT binary patch literal 727 zcmYjP&1(}u6rb7M#AQi}V7+;mgJ2_}ha7`QFGW2Vg?d^7%eXV9TlcH8v(-ohYkLqs z@FEDJkX{ro22VvS=wIL;Fjq}zPrZBc&1NI};JukQ`+L9lwMnz-Adtsze)&H!Lcg_B z6$_j-(Ci`@h8Paf9eo-hcJVdDOlIvPW^rTBbWLV#pjPb!kf?-=bkZUl^jC};*CWKq6aWl^X|2mCX$c3*X7NUzWL2rR(7r;m;Xb)o~@s=?*4-iHp zJTgY+Krorbk%^ zW7i$*;78}G!(W|adXU@pyqHGZ^OWOxQNr?2-y5E{ozrmsMJxeLQANcx^_$+A-d(1R zjT*Rk0oJqY4}G4>Ac@O$3tf*|x)I+^@|Z0ib$o?WH!3u-vaifbxeC8-*#@%lvhfeo C=*Ud~ literal 0 HcmV?d00001 diff --git a/test2.py b/test2.py new file mode 100644 index 0000000..4690cf3 --- /dev/null +++ b/test2.py @@ -0,0 +1,24 @@ +from flask import Flask + +app = Flask(__name__) + +@app.route("/api/tracks") +def hello_tracks(): + return "

Hello, tracks!

" + +@app.route("/api/playlist//tracks") +def hello_playlist(): + return "

Hello, playlist!

" + +app.run( + host = '127.0.0.1', + port = 7777, + debug = True +) + +if __name__== '__main__': + app.run( + host = '127.0.0.1', + port = 7777, + debug = True + ) \ No newline at end of file diff --git a/utils.py b/utils.py new file mode 100644 index 0000000..a6612df --- /dev/null +++ b/utils.py @@ -0,0 +1,28 @@ +import re +import sys + +_URL_PLACEHOLDER_PATTERN = re.compile('<(.*?)>') + + +def get_pipe(name): + """通过 mod.ClassName 导入自定义的PipeHandler""" + module_name, obj_name = name.rsplit('.', 1) + __import__(module_name) + module = sys.modules[module_name] + obj = getattr(module, obj_name) + return obj + + +def extract_placeholders(url): + """ + >>> res = extract_placeholders("//resource//submit/") + >>> assert set(res) == {"service_name", "resource_id"} + :param url: request url name + :return: list of placeholder name + """ + return _URL_PLACEHOLDER_PATTERN.findall(url) + + +def replace_placeholder(url, placeholder_name, value): + return url.replace('<{}>'.format(placeholder_name), str(value)) +