1
0

Player.py 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. #!/usr/bin/env python3
  2. # -*- encoding: utf-8 -*-
  3. # Author: MoeClub.org
  4. import tornado.web
  5. import tornado.ioloop
  6. import tornado.options
  7. import tornado.httpserver
  8. import json
  9. import os
  10. import time
  11. import base64
  12. MasterKey = ["MoeClub"]
  13. SubPath = "Player"
  14. RootPath = os.path.dirname(os.path.abspath(__file__))
  15. DataPath = os.path.join(RootPath, "data")
  16. class Utils:
  17. treelist = []
  18. treetime = 0
  19. @staticmethod
  20. def load(file, mode="r"):
  21. if "b" in mode:
  22. fd = open(file, mode)
  23. else:
  24. fd = open(file, mode, encoding="utf-8")
  25. data = fd.read()
  26. fd.close()
  27. return data
  28. @classmethod
  29. def b64(cls, file):
  30. data = cls.load(file=file)
  31. b64data = base64.b64encode(data.encode("utf-8"))
  32. return b64data.decode("utf-8")
  33. @classmethod
  34. def list(cls, dirname, second=15):
  35. if not os.path.exists(dirname):
  36. return ""
  37. if int(time.time()) - second >= cls.treetime:
  38. cls.treelist = []
  39. cls.tree(dirname=dirname, FileType="m3u8")
  40. cls.treetime = int(time.time())
  41. return "\n".join(cls.treelist)
  42. @classmethod
  43. def tree(cls, dirname, padding=" ", Print=False, FileType=None):
  44. PRINTITEM = padding[:-1] + '+-' + os.path.basename(os.path.abspath(dirname)) + '/'
  45. cls.treelist.append(PRINTITEM)
  46. if Print:
  47. print(PRINTITEM)
  48. padding = padding + ' '
  49. files = os.listdir(dirname)
  50. count = 0
  51. for file in files:
  52. count += 1
  53. path = dirname + os.sep + file
  54. if os.path.isdir(path):
  55. if count == len(files):
  56. cls.tree(path, padding + ' ', Print, FileType)
  57. else:
  58. cls.tree(path, padding + '|', Print, FileType)
  59. else:
  60. if FileType is None or str(path).lower().endswith("." + str(FileType).lower()):
  61. PRINTITEM = padding + '+-' + file
  62. cls.treelist.append(PRINTITEM)
  63. if Print:
  64. print(PRINTITEM)
  65. class MainHandler(tornado.web.RequestHandler):
  66. 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)] + ["-", "_", ".", "@"]
  67. StaticFile = {}
  68. def check_argument(self, key):
  69. value = None
  70. if key in self.request.arguments:
  71. value = self.get_argument(key)
  72. return value
  73. def real_address(self):
  74. if 'X-Real-IP' in self.request.headers:
  75. self.request.remote_ip = self.request.headers['X-Real-IP']
  76. return self.request.remote_ip
  77. def WriteString(self, obj):
  78. if isinstance(obj, (str, int)):
  79. return obj
  80. elif isinstance(obj, (dict, list)):
  81. return json.dumps(obj, ensure_ascii=False)
  82. else:
  83. return obj
  84. def get(self, Item=None):
  85. try:
  86. self.real_address()
  87. assert Item and str(Item).strip()
  88. if Item == "list":
  89. data = Utils.list(DataPath)
  90. self.set_header("Content-Type", "text/plain; charset=utf-8")
  91. self.write(self.WriteString(data))
  92. self.finish()
  93. return
  94. if str(Item).strip().lstrip("/").startswith("static/"):
  95. StaticPath = os.path.join(RootPath, Item)
  96. if os.path.exists(StaticPath):
  97. if str(StaticPath).endswith(".js"):
  98. self.set_header("Content-Type", "application/javascript; charset=utf-8")
  99. elif str(StaticPath).endswith(".css"):
  100. self.set_header("Content-Type", "text/css")
  101. else:
  102. self.set_header("Content-Type", "application/octet-stream")
  103. if StaticPath not in self.StaticFile:
  104. self.StaticFile[StaticPath] = Utils.load(StaticPath, "rb")
  105. self.finish(self.StaticFile[StaticPath])
  106. self.flush()
  107. else:
  108. self.set_status(404)
  109. self.finish()
  110. return
  111. if str(Item).strip().lower().endswith(".vtt"):
  112. ItemPath = os.path.join(DataPath, Item)
  113. if os.path.exists(ItemPath):
  114. self.set_header("Content-Type", "application/octet-stream")
  115. if ItemPath not in self.StaticFile:
  116. self.StaticFile[ItemPath] = Utils.load(ItemPath, "rb")
  117. self.finish(self.StaticFile[ItemPath])
  118. self.flush()
  119. else:
  120. self.set_status(404)
  121. self.finish()
  122. return
  123. if str(Item).strip().lower().endswith(".m3u8"):
  124. ItemPath = os.path.join(DataPath, Item)
  125. else:
  126. ItemPath = os.path.join(DataPath, Item + ".m3u8")
  127. if os.path.exists(ItemPath):
  128. self.render("Player.html", PageTitle=str(Item).rstrip(".m3u8"), SubPath=str("/%s" % SubPath), PageData=Utils.b64(ItemPath))
  129. else:
  130. self.set_status(404)
  131. self.write("Not Found")
  132. except:
  133. self.set_status(400)
  134. self.write("Null")
  135. def post(self, Item=None):
  136. try:
  137. assert Item and str(Item).strip()
  138. assert str(Item) in MasterKey
  139. filesDict = self.request.files["file"]
  140. for FileItem in filesDict:
  141. if "filename" in FileItem and FileItem["filename"]:
  142. ItemName = FileItem["filename"]
  143. else:
  144. ItemName = "UN" + str(int(time.time())) + ".m3u8"
  145. FileSave = os.path.join(DataPath, ItemName)
  146. fd = open(FileSave, "wb")
  147. fd.write(FileItem["body"])
  148. fd.close()
  149. self.set_status(200)
  150. self.write("ok")
  151. except:
  152. self.set_status(400)
  153. self.write("fail")
  154. class Web:
  155. @staticmethod
  156. def main():
  157. tornado.options.define("host", default='127.0.0.1', help="Host", type=str)
  158. tornado.options.define("port", default=5866, help="Port", type=int)
  159. tornado.options.parse_command_line()
  160. application = tornado.web.Application([(r"/%s/(?P<Item>.+)" % SubPath, MainHandler)], static_path=os.path.join(RootPath, "static"))
  161. http_server = tornado.httpserver.HTTPServer(application)
  162. http_server.listen(tornado.options.options.port)
  163. tornado.ioloop.IOLoop.instance().start()
  164. if __name__ == "__main__":
  165. Web.main()