aocame

Untitled

May 31st, 2018
132
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.13 KB | None | 0 0
  1. import sys
  2. sys.path.insert(0, "/var/www/apps/virtualenv1/lib/python2.7/site-packages")
  3. from flask import Flask, request, render_template
  4. from flask_restful import Resource, Api
  5. from flask_httpauth import HTTPBasicAuth
  6. from bs4 import BeautifulSoup
  7. import logging.handlers
  8. import os
  9. import requests
  10. import base64
  11. import glob
  12. import binascii
  13. import time
  14. from datetime import datetime
  15. import urllib
  16.  
  17. ###########################################
  18. # Local app settings
  19. try:
  20. import settings as cfg
  21. except: pass
  22.  
  23. try:
  24. user_database = cfg.user_database
  25. except:
  26. user_database = "users.xml"
  27. try:
  28. log_location = cfg.log_location
  29. except:
  30. log_location = "beta"
  31. try:
  32. app_debug = cfg.app_debug
  33. except:
  34. app_debug = False
  35. try:
  36. data_location = cfg.data_location
  37. except:
  38. data_location = "data"
  39.  
  40.  
  41.  
  42. app_version = "0.4.3-beta"
  43.  
  44. app = Flask(__name__)
  45. api = Api(app)
  46.  
  47. auth = HTTPBasicAuth()
  48. users = {
  49. "x5tr34m": "eGu4gr8B"
  50. }
  51.  
  52. @auth.get_password
  53. def get_pw(username):
  54. if username in users:
  55. return users.get(username)
  56. return None
  57.  
  58. def get_logdata(fname):
  59. data = []
  60. with open(fname) as f:
  61. for i, l in enumerate(f):
  62. info = l.strip()[len("2017-09-15 15:15:02 INFO: "):].split("[*]")
  63. user_data = {}
  64. user_data["time"] = l.strip()[:len("2017-09-15 15:15:02")]
  65. for i in info:
  66. key = i[:i.find("=")]
  67. value = i[i.find("=")+1:]
  68. user_data[key] = value
  69. data.append(user_data)
  70. return data
  71.  
  72. def getRemainingDays(subcription_date):
  73. try:
  74. subscription_date = datetime.strptime(subcription_date, '%Y-%m-%d').date()
  75. except TypeError:
  76. subscription_date = datetime(*(time.strptime(subcription_date, '%Y-%m-%d')[0:6])).date()
  77. days_remaining = (subscription_date - datetime.now().date()).days
  78. return days_remaining
  79.  
  80. @app.route('/user_stats')
  81. @auth.login_required
  82. def user_stats():
  83. requested_log_file = "" if not "log_file" in request.args else urllib.unquote_plus(request.args["log_file"])
  84.  
  85. if requested_log_file != "":
  86. user_data = get_logdata(os.path.join(log_location, "user_logs", requested_log_file))
  87. user_name, host_id = os.path.basename(requested_log_file)[:-len(".log")].split("#")
  88. return render_template('logfile.html', result=user_data, username=user_name)
  89.  
  90. users_data = {}
  91. user_database = getUserDatabase()
  92. for user_log_file in glob.glob(os.path.join(log_location, "user_logs", "*.log")):
  93. try:
  94. user_name, host_id = os.path.basename(user_log_file)[:-len(".log")].split("#")
  95. if not user_name in user_database:
  96. os.remove(user_log_file)
  97. continue
  98.  
  99. host_id = base64.b64decode(binascii.a2b_hex(host_id))
  100. cdate, hostname = host_id.split("$")
  101. cdate = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(int(cdate)))
  102. user_data = get_logdata(user_log_file)
  103. actions = len(user_data)
  104.  
  105. if not user_name in users_data:
  106. users_data[user_name] = {}
  107.  
  108. if not host_id in users_data[user_name]:
  109. users_data[user_name][host_id] = {}
  110.  
  111. users_data[user_name][host_id]["logfile"] = urllib.quote_plus(os.path.basename(user_log_file))
  112. users_data[user_name][host_id]["hostname"] = hostname
  113. users_data[user_name][host_id]["creation_date"] = cdate
  114. users_data[user_name][host_id]["actions"] = actions
  115. users_data[user_name][host_id]["expiration"] = user_database[user_name]["subscription"]
  116. users_data[user_name][host_id]["remaining_days"] = getRemainingDays(user_database[user_name]["subscription"])
  117.  
  118. for key, value in user_data[-1].iteritems():
  119. users_data[user_name][host_id][key] = value
  120. except: pass
  121. return render_template('users.html', result=users_data)
  122.  
  123. ## Server logs
  124. if not os.path.exists(os.path.join(log_location, "server_logs")):
  125. os.makedirs(os.path.join(log_location, "server_logs"))
  126.  
  127. server_log = logging.getLogger('werkzeug')
  128. server_log.setLevel(logging.INFO)
  129. fh = logging.handlers.TimedRotatingFileHandler(filename=os.path.join(log_location, "server_logs", "beta.log"), backupCount=182, when='midnight')
  130. fh.setLevel(logging.INFO)
  131. formatter = logging.Formatter(fmt='%(asctime)s v{0} %(levelname)s: %(message)s'.format(app_version), datefmt='%Y-%m-%d %H:%M:%S')
  132. fh.setFormatter(formatter)
  133. server_log.addHandler(fh)
  134.  
  135. def output_data(data, content, guide_data):
  136. output = {}
  137. output["content"] = content
  138. output["guide_data"] = guide_data
  139. output["subscription"] = data["subscription"]
  140. return output
  141.  
  142. def open_logfile(log_file):
  143. logging.getLogger().setLevel(logging.INFO)
  144. fh = logging.FileHandler(filename=log_file)
  145. fh.setLevel(logging.INFO)
  146. formatter = logging.Formatter(fmt='%(asctime)s %(levelname)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S')
  147. fh.setFormatter(formatter)
  148. logging.getLogger().addHandler(fh)
  149. return logging.getLogger(), fh
  150.  
  151. def close_logfile(log, fh):
  152. log.removeHandler(fh)
  153.  
  154. def getGuideData(req_filename):
  155. guide_data = ""
  156. guide_file_path = os.path.join(data_location, "guide_data", req_filename + ".json")
  157. if os.path.exists(guide_file_path):
  158. with open(guide_file_path,"r") as f:
  159. guide_data = f.read()
  160. return guide_data
  161.  
  162. def getXmlData(uri):
  163. data = ""
  164. uri = uri.encode('utf-8', 'ignore')
  165. try:
  166. if uri.lower().startswith("http"):
  167. data = requests.get(uri).content
  168. else:
  169. xml_file_path = os.path.join(data_location, uri)
  170. if os.path.exists(xml_file_path):
  171. with open(xml_file_path , 'r') as f:
  172. data = f.read()
  173. except: pass
  174.  
  175. return data
  176.  
  177. def getUserDatabase():
  178. if user_database.lower().startswith("http"):
  179. page = requests.get(user_database)
  180. soup = BeautifulSoup(page.content, "html.parser")
  181. else:
  182. soup = BeautifulSoup(open(user_database,"r").read(), "html.parser")
  183.  
  184. user_data = {}
  185. for user in soup("user"):
  186. user_attributes = {}
  187. for att in user.attrs:
  188. if not att.lower() == "username":
  189. user_attributes[att] = user[att]
  190. user_data[user["username"]] = user_attributes
  191. return user_data
  192.  
  193. class Validator(Resource):
  194. def __init__(self):
  195. super(Resource, self).__init__()
  196.  
  197. def get(self):
  198. server_log.info(request)
  199.  
  200. # Grab arguments
  201. remote_user = "" if not "username" in request.args else request.args["username"]
  202. remote_password = "" if not "password" in request.args else request.args["password"]
  203. remote_uuid = "None" if not "uuid" in request.args else request.args["uuid"]
  204. remote_url = "None" if not "url" in request.args else request.args["url"]
  205. addon_version = "None" if not "addon_version" in request.args else request.args["addon_version"]
  206. kodi_version = "None" if not "kodi_version" in request.args else request.args["kodi_version"]
  207. os_name = "None" if not "os" in request.args else request.args["os"]
  208.  
  209. if remote_user and remote_password:
  210. user_database = getUserDatabase()
  211. if remote_user in user_database:
  212. user_data = user_database[remote_user]
  213. if user_data["password"] == remote_password:
  214. days_remaining = getRemainingDays(user_data["subscription"])
  215. if days_remaining < 0:
  216. return user_data["subscription"], 402
  217.  
  218. if not os.path.exists(os.path.join(log_location, "user_logs")):
  219. os.makedirs(os.path.join(log_location, "user_logs"))
  220.  
  221. user_log_path = os.path.join(log_location, "user_logs", "{0}#{1}.log".format(remote_user, remote_uuid))
  222. user_log, fh = open_logfile(user_log_path)
  223. user_log.info('ip={1}{0}addon_version={2}{0}url={3}{0}os={4}{0}kodi_version={5}'.format("[*]", request.environ["REMOTE_ADDR"], addon_version, remote_url.encode('utf-8', 'ignore'), os_name, kodi_version))
  224. close_logfile(user_log, fh)
  225.  
  226. content = ""
  227. guide_data = ""
  228. requested_xml = ""
  229. if remote_url.lower() == "home":
  230. requested_xml = user_data["home"]
  231. elif remote_url.lower().endswith(".xml"):
  232. requested_xml = remote_url
  233.  
  234. if requested_xml:
  235. content = base64.b64encode(getXmlData(requested_xml))
  236. guide_data = getGuideData(requested_xml.rsplit('/', 1)[-1])
  237.  
  238. return output_data(user_data, content, guide_data), 202
  239.  
  240. # Invalid user
  241. server_log.warning("Connection REFUSED")
  242. return "invalid user", 401
  243.  
  244. api.add_resource(Validator, '/validator')
  245.  
  246. if __name__ == '__main__':
  247. # Production
  248. app.run(debug=app_debug, port=52481, host='0.0.0.0')
Add Comment
Please, Sign In to add comment