123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- #!/usr/bin/env python3
- # -*- encoding: utf-8 -*-
- # Author: MoeClub.org
- import tornado.web
- import tornado.ioloop
- import tornado.options
- import tornado.httpserver
- import json
- import os
- import time
- import base64
- MasterKey = ["MoeClub"]
- SubPath = "Player"
- RootPath = os.path.dirname(os.path.abspath(__file__))
- DataPath = os.path.join(RootPath, "data")
- class Utils:
- treelist = []
- treetime = 0
- @staticmethod
- def load(file, mode="r"):
- if "b" in mode:
- fd = open(file, mode)
- else:
- fd = open(file, mode, encoding="utf-8")
- data = fd.read()
- fd.close()
- return data
- @classmethod
- def b64(cls, file):
- data = cls.load(file=file)
- b64data = base64.b64encode(data.encode("utf-8"))
- return b64data.decode("utf-8")
- @classmethod
- def list(cls, dirname, second=15):
- if not os.path.exists(dirname):
- return ""
- if int(time.time()) - second >= cls.treetime:
- cls.treelist = []
- cls.tree(dirname=dirname, FileType="m3u8")
- cls.treetime = int(time.time())
- return "\n".join(cls.treelist)
- @classmethod
- def tree(cls, dirname, padding=" ", Print=False, FileType=None):
- PRINTITEM = padding[:-1] + '+-' + os.path.basename(os.path.abspath(dirname)) + '/'
- cls.treelist.append(PRINTITEM)
- if Print:
- print(PRINTITEM)
- padding = padding + ' '
- files = os.listdir(dirname)
- count = 0
- for file in files:
- count += 1
- path = dirname + os.sep + file
- if os.path.isdir(path):
- if count == len(files):
- cls.tree(path, padding + ' ', Print, FileType)
- else:
- cls.tree(path, padding + '|', Print, FileType)
- else:
- if FileType is None or str(path).lower().endswith("." + str(FileType).lower()):
- PRINTITEM = padding + '+-' + file
- cls.treelist.append(PRINTITEM)
- if Print:
- print(PRINTITEM)
- class MainHandler(tornado.web.RequestHandler):
- StringList = [chr(item) for item in range(65, 90 + 1)] + [chr(item) for item in range(48, 57 + 1)] + [chr(item) for item in range(97, 122 + 1)] + ["-", "_", ".", "@"]
- StaticFile = {}
- def check_argument(self, key):
- value = None
- if key in self.request.arguments:
- value = self.get_argument(key)
- return value
- def real_address(self):
- if 'X-Real-IP' in self.request.headers:
- self.request.remote_ip = self.request.headers['X-Real-IP']
- return self.request.remote_ip
- def WriteString(self, obj):
- if isinstance(obj, (str, int)):
- return obj
- elif isinstance(obj, (dict, list)):
- return json.dumps(obj, ensure_ascii=False)
- else:
- return obj
- def get(self, Item=None):
- try:
- self.real_address()
- assert Item and str(Item).strip()
- if Item == "list":
- data = Utils.list(DataPath)
- self.set_header("Content-Type", "text/plain; charset=utf-8")
- self.write(self.WriteString(data))
- self.finish()
- return
- if str(Item).strip().lstrip("/").startswith("static/"):
- StaticPath = os.path.join(RootPath, Item)
- if os.path.exists(StaticPath):
- if str(StaticPath).endswith(".js"):
- self.set_header("Content-Type", "application/javascript; charset=utf-8")
- elif str(StaticPath).endswith(".css"):
- self.set_header("Content-Type", "text/css")
- else:
- self.set_header("Content-Type", "application/octet-stream")
- if StaticPath not in self.StaticFile:
- self.StaticFile[StaticPath] = Utils.load(StaticPath, "rb")
- self.finish(self.StaticFile[StaticPath])
- self.flush()
- else:
- self.set_status(404)
- self.finish()
- return
- if str(Item).strip().lower().endswith(".vtt"):
- ItemPath = os.path.join(DataPath, Item)
- if os.path.exists(ItemPath):
- self.set_header("Content-Type", "application/octet-stream")
- if ItemPath not in self.StaticFile:
- self.StaticFile[ItemPath] = Utils.load(ItemPath, "rb")
- self.finish(self.StaticFile[ItemPath])
- self.flush()
- else:
- self.set_status(404)
- self.finish()
- return
- if str(Item).strip().lower().endswith(".m3u8"):
- ItemPath = os.path.join(DataPath, Item)
- else:
- ItemPath = os.path.join(DataPath, Item + ".m3u8")
- if os.path.exists(ItemPath):
- self.render("Player.html", PageTitle=str(Item).rstrip(".m3u8"), SubPath=str("/%s" % SubPath), PageData=Utils.b64(ItemPath))
- else:
- self.set_status(404)
- self.write("Not Found")
- except:
- self.set_status(400)
- self.write("Null")
- def post(self, Item=None):
- try:
- assert Item and str(Item).strip()
- assert str(Item) in MasterKey
- filesDict = self.request.files["file"]
- for FileItem in filesDict:
- if "filename" in FileItem and FileItem["filename"]:
- ItemName = FileItem["filename"]
- else:
- ItemName = "UN" + str(int(time.time())) + ".m3u8"
- FileSave = os.path.join(DataPath, ItemName)
- fd = open(FileSave, "wb")
- fd.write(FileItem["body"])
- fd.close()
- self.set_status(200)
- self.write("ok")
- except:
- self.set_status(400)
- self.write("fail")
- class Web:
- @staticmethod
- def main():
- tornado.options.define("host", default='127.0.0.1', help="Host", type=str)
- tornado.options.define("port", default=5866, help="Port", type=int)
- tornado.options.parse_command_line()
- application = tornado.web.Application([(r"/%s/(?P<Item>.+)" % SubPath, MainHandler)], static_path=os.path.join(RootPath, "static"))
- http_server = tornado.httpserver.HTTPServer(application)
- http_server.listen(tornado.options.options.port)
- tornado.ioloop.IOLoop.instance().start()
- if __name__ == "__main__":
- Web.main()
|