first commit
This commit is contained in:
65
ExceptionHandler.py
Normal file
65
ExceptionHandler.py
Normal file
@ -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)
|
149
Gateway.py
Normal file
149
Gateway.py
Normal file
@ -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('')
|
66
Route.py
Normal file
66
Route.py
Normal file
@ -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`的占位符 `<parameter_name>` 声明路径参数,服务名称固定使用 `<service_name>` 占位符
|
||||||
|
: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 将 <service_name> 替换为路由配置中的后端服务
|
||||||
|
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)
|
BIN
__pycache__/ExceptionHandler.cpython-310.pyc
Normal file
BIN
__pycache__/ExceptionHandler.cpython-310.pyc
Normal file
Binary file not shown.
BIN
__pycache__/Gateway.cpython-310.pyc
Normal file
BIN
__pycache__/Gateway.cpython-310.pyc
Normal file
Binary file not shown.
BIN
__pycache__/Route.cpython-310.pyc
Normal file
BIN
__pycache__/Route.cpython-310.pyc
Normal file
Binary file not shown.
BIN
__pycache__/app.cpython-310.pyc
Normal file
BIN
__pycache__/app.cpython-310.pyc
Normal file
Binary file not shown.
BIN
__pycache__/hello.cpython-310.pyc
Normal file
BIN
__pycache__/hello.cpython-310.pyc
Normal file
Binary file not shown.
BIN
__pycache__/test.cpython-310.pyc
Normal file
BIN
__pycache__/test.cpython-310.pyc
Normal file
Binary file not shown.
BIN
__pycache__/test2.cpython-310.pyc
Normal file
BIN
__pycache__/test2.cpython-310.pyc
Normal file
Binary file not shown.
BIN
__pycache__/utils.cpython-310.pyc
Normal file
BIN
__pycache__/utils.cpython-310.pyc
Normal file
Binary file not shown.
66
app.py
Normal file
66
app.py
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
from flask import Flask, request
|
||||||
|
from Gateway import *
|
||||||
|
from Route import *
|
||||||
|
from ExceptionHandler import *
|
||||||
|
|
||||||
|
class GatewayServer():
|
||||||
|
def __init__(self):
|
||||||
|
self.app = Flask('gateway')
|
||||||
|
self.url_map = {
|
||||||
|
'test': 'http://127.0.0.1:7777',
|
||||||
|
'music_server': 'http://192.168.124.12:4533'
|
||||||
|
}
|
||||||
|
self.url_supplier = lambda x: self.url_map[x]
|
||||||
|
|
||||||
|
route_2 = {
|
||||||
|
"name": "add-sound",
|
||||||
|
"service_name": "music_server",
|
||||||
|
"methods": ["POST"],
|
||||||
|
"path": "/music/api/playlist/<playlist_id>/tracks",
|
||||||
|
"upstream_path": "/api/playlist/<playlist_id>/tracks",
|
||||||
|
"pipelines": {
|
||||||
|
"outbound": [{ "name": "plugin.MusicHandler.MusicHandler" }]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
route_3 = {
|
||||||
|
"name": "del-sound",
|
||||||
|
"service_name": "music_server",
|
||||||
|
"methods": ["DELETE"],
|
||||||
|
"path": "/music/api/playlist/<playlist_id>/tracks",
|
||||||
|
"upstream_path": "/api/playlist/<playlist_id>/tracks",
|
||||||
|
"pipelines": {
|
||||||
|
"outbound": [{ "name": "plugin.MusicHandler.MusicHandler" }]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
route_4 = {
|
||||||
|
"name": "del-playlist",
|
||||||
|
"service_name": "music_server",
|
||||||
|
"methods": ["DELETE"],
|
||||||
|
"path": "/music/api/playlist/<playlist_id>",
|
||||||
|
"upstream_path": "/api/playlist/<playlist_id>",
|
||||||
|
"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)
|
15
plugin/MusicHandler.py
Normal file
15
plugin/MusicHandler.py
Normal file
@ -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]
|
0
plugin/NavidromePlaylistSync/__init__.py
Normal file
0
plugin/NavidromePlaylistSync/__init__.py
Normal file
Binary file not shown.
BIN
plugin/NavidromePlaylistSync/__pycache__/app.cpython-310.pyc
Normal file
BIN
plugin/NavidromePlaylistSync/__pycache__/app.cpython-310.pyc
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
plugin/NavidromePlaylistSync/__pycache__/sync.cpython-310.pyc
Normal file
BIN
plugin/NavidromePlaylistSync/__pycache__/sync.cpython-310.pyc
Normal file
Binary file not shown.
0
plugin/NavidromePlaylistSync/api/__init__.py
Normal file
0
plugin/NavidromePlaylistSync/api/__init__.py
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
25
plugin/NavidromePlaylistSync/api/playlist.py
Normal file
25
plugin/NavidromePlaylistSync/api/playlist.py
Normal file
@ -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
|
7
plugin/NavidromePlaylistSync/api/token.py
Normal file
7
plugin/NavidromePlaylistSync/api/token.py
Normal file
@ -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')
|
33
plugin/NavidromePlaylistSync/app.py
Normal file
33
plugin/NavidromePlaylistSync/app.py
Normal file
@ -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()
|
10
plugin/NavidromePlaylistSync/resetDir.py
Normal file
10
plugin/NavidromePlaylistSync/resetDir.py
Normal file
@ -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)
|
||||||
|
|
6
plugin/NavidromePlaylistSync/saveFile.py
Normal file
6
plugin/NavidromePlaylistSync/saveFile.py
Normal file
@ -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)
|
28
plugin/NavidromePlaylistSync/sync.py
Normal file
28
plugin/NavidromePlaylistSync/sync.py
Normal file
@ -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!!')
|
13
plugin/NavidromePlaylistSync/temp/ClariS.m3u
Normal file
13
plugin/NavidromePlaylistSync/temp/ClariS.m3u
Normal file
@ -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
|
31
plugin/NavidromePlaylistSync/temp/HIMEHINA.m3u
Normal file
31
plugin/NavidromePlaylistSync/temp/HIMEHINA.m3u
Normal file
@ -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
|
17
plugin/NavidromePlaylistSync/temp/JOJO.m3u
Normal file
17
plugin/NavidromePlaylistSync/temp/JOJO.m3u
Normal file
@ -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
|
17
plugin/NavidromePlaylistSync/temp/YOSOBI.m3u
Normal file
17
plugin/NavidromePlaylistSync/temp/YOSOBI.m3u
Normal file
@ -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
|
7
plugin/NavidromePlaylistSync/temp/ナユタン星人.m3u
Normal file
7
plugin/NavidromePlaylistSync/temp/ナユタン星人.m3u
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#EXTM3U
|
||||||
|
#EXTINF:191,ナユタン星人 - ダンスロボットダンス
|
||||||
|
/music/ナユタン星人/ナユタン星からの物体Y/04 ダンスロボットダンス.flac
|
||||||
|
#EXTINF:203,ナユタン星人 - 太陽系デスコ
|
||||||
|
/music/ナユタン星人/ナユタン星からの物体Y/07 太陽系デスコ.flac
|
||||||
|
#EXTINF:211,ナユタン星人 - ディスコミュ星人
|
||||||
|
/music/ナユタン星人/ナユタン星からの物体Y/08 ディスコミュ星人.flac
|
69
plugin/NavidromePlaylistSync/temp/公主殿下.m3u
Normal file
69
plugin/NavidromePlaylistSync/temp/公主殿下.m3u
Normal file
@ -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
|
7
plugin/NavidromePlaylistSync/temp/后摇.m3u
Normal file
7
plugin/NavidromePlaylistSync/temp/后摇.m3u
Normal file
@ -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
|
13
plugin/NavidromePlaylistSync/temp/哥特风.m3u
Normal file
13
plugin/NavidromePlaylistSync/temp/哥特风.m3u
Normal file
@ -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
|
21
plugin/NavidromePlaylistSync/temp/恋与恋语.m3u
Normal file
21
plugin/NavidromePlaylistSync/temp/恋与恋语.m3u
Normal file
@ -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
|
5
plugin/NavidromePlaylistSync/temp/校园乐队.m3u
Normal file
5
plugin/NavidromePlaylistSync/temp/校园乐队.m3u
Normal file
@ -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
|
41
plugin/NavidromePlaylistSync/temp/樱兰高校K-ON部.m3u
Normal file
41
plugin/NavidromePlaylistSync/temp/樱兰高校K-ON部.m3u
Normal file
@ -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
|
45
plugin/NavidromePlaylistSync/temp/治愈.m3u
Normal file
45
plugin/NavidromePlaylistSync/temp/治愈.m3u
Normal file
@ -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
|
3
plugin/NavidromePlaylistSync/temp/测试.m3u
Normal file
3
plugin/NavidromePlaylistSync/temp/测试.m3u
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
#EXTM3U
|
||||||
|
#EXTINF:317,浮森かや子 - お隣はだあれ
|
||||||
|
/music/浮森かや子/お隣はだあれ.mp3
|
1
plugin/NavidromePlaylistSync/temp/测试2.m3u
Normal file
1
plugin/NavidromePlaylistSync/temp/测试2.m3u
Normal file
@ -0,0 +1 @@
|
|||||||
|
#EXTM3U
|
27
plugin/NavidromePlaylistSync/temp/蓝之华.m3u
Normal file
27
plugin/NavidromePlaylistSync/temp/蓝之华.m3u
Normal file
@ -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
|
0
plugin/__init__.py
Normal file
0
plugin/__init__.py
Normal file
BIN
plugin/__pycache__/MusicHandler.cpython-310.pyc
Normal file
BIN
plugin/__pycache__/MusicHandler.cpython-310.pyc
Normal file
Binary file not shown.
BIN
plugin/__pycache__/__init__.cpython-310.pyc
Normal file
BIN
plugin/__pycache__/__init__.cpython-310.pyc
Normal file
Binary file not shown.
BIN
plugin/__pycache__/app.cpython-310.pyc
Normal file
BIN
plugin/__pycache__/app.cpython-310.pyc
Normal file
Binary file not shown.
24
test2.py
Normal file
24
test2.py
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
from flask import Flask
|
||||||
|
|
||||||
|
app = Flask(__name__)
|
||||||
|
|
||||||
|
@app.route("/api/tracks")
|
||||||
|
def hello_tracks():
|
||||||
|
return "<p>Hello, tracks!</p>"
|
||||||
|
|
||||||
|
@app.route("/api/playlist/<playlist_id>/tracks")
|
||||||
|
def hello_playlist():
|
||||||
|
return "<p>Hello, playlist!</p>"
|
||||||
|
|
||||||
|
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
|
||||||
|
)
|
28
utils.py
Normal file
28
utils.py
Normal file
@ -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("/<service_name>/resource/<resource_id>/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))
|
||||||
|
|
Reference in New Issue
Block a user