consts.py 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611
  1. # -*- coding: utf-8 -*-
  2. ##define DEBUG
  3. ##define DEBUG_SERVER
  4. import framework
  5. import xbmc
  6. import cookielib
  7. import os
  8. import xbmcgui
  9. import urllib2
  10. import platform, sys
  11. import random
  12. import time
  13. import traceback
  14. #ifdef DEBUG_SERVER
  15. import socket
  16. #endif
  17. from utils import *
  18. #ifdef DEBUG
  19. DEBUG = True
  20. #else
  21. DEBUG = False
  22. #endif
  23. BASEPATH = "vnext.to"
  24. APPTITLE = "Cryflix"
  25. DELETE_PASSWORD = False
  26. CJ = cookielib.LWPCookieJar()
  27. MASTERLOCK = False, None
  28. #ifdef DEBUG_SERVER
  29. sock = None
  30. #endif
  31. def output(message, to_log_file=True):
  32. """
  33. @param message:
  34. """
  35. #ifdef DEBUG_SERVER
  36. global sock
  37. try:
  38. if not sock:
  39. sock = socket.create_connection(("192.168.1.116", 12345), timeout=1)
  40. if sock:
  41. sock.send("%s\n" % message)
  42. except Exception as e:
  43. xbmc.log("[DEBUG] Error: %s" % traceback.format_exc())
  44. finally:
  45. if sock:
  46. sock.close()
  47. sock = None
  48. #endif
  49. #ifdef DEBUG
  50. if to_log_file:
  51. xbmc.log(message)
  52. #else
  53. pass
  54. #endif
  55. __output = output
  56. def pre_dispatch_func(plugin):
  57. """
  58. @param plugin:
  59. @return:
  60. """
  61. return check_settings()
  62. # Init
  63. PLUGIN = framework.Plugin(None, log_func=output, pre_dispatch=pre_dispatch_func)
  64. COOKIE_PATH = os.path.realpath(os.path.join(PLUGIN.storage_path, ".heuldoch"))
  65. PLUGIN_PATH = os.path.realpath(PLUGIN.info("path"))
  66. RESOURCE_PATH = os.path.realpath(os.path.join(PLUGIN.info("path"), "resources"))
  67. # Settings
  68. USE_SIMPLEJSON = PLUGIN.get_setting("usesimplejson") == "true"
  69. try:
  70. import ujson as json
  71. except ImportError:
  72. if USE_SIMPLEJSON:
  73. try:
  74. import simplejson as json
  75. except ImportError:
  76. import json
  77. else:
  78. try:
  79. import json
  80. except ImportError:
  81. import simplejson as json
  82. PORTAL_USERNAME = ""
  83. PORTAL_PASSWORD = ""
  84. PORTAL_USERID = 0
  85. PORTAL_SESSION = ""
  86. API_URL = ""
  87. PORTAL_URL = ""
  88. IMAGEPATH = "http://image.tmdb.org/t/p/"
  89. IMAGESIZE_COVER = "w185"
  90. IMAGESIZE_SCENE = "w500"
  91. IMAGESIZE_POSTER = "w1280"
  92. win = xbmcgui.Window(xbmcgui.getCurrentWindowId())
  93. if win.getWidth() >= 1600:
  94. IMAGESIZE_COVER = "w342"
  95. IMAGESIZE_SCENE = "w780"
  96. # IMAGESIZE_POSTER = "original"
  97. PLUGIN_NAME = "kodi"
  98. PLUGIN_VERSION = PLUGIN.info("version")
  99. PLUGIN_TOKEN = "74f0f17b644c5c1cb2ea4fbf18093131"
  100. PLUGIN_HASH = md5_string("%s%s%s" % (PLUGIN_NAME, PLUGIN_VERSION, PLUGIN_TOKEN))
  101. DEVICE_IDENTIFER = ""
  102. WATCHLIST_ID = 1
  103. WATCHEDLIST_ID = 1
  104. SHOW_NEWCOMER = True
  105. WATCHLIST_TOGETHER = True
  106. USE_TAGLINE = True
  107. ASK_BEFORE_PLAY = True
  108. HIDE_UHD = True
  109. HIDE_HD = True
  110. HIDE_SERIES = True
  111. HIDE_3D = True
  112. SWITCH_TAGLINE = True
  113. HIDE_SETTINGS = True
  114. HIDE_LOGOUT = True
  115. ASK_FOR_NEXT_EPISODE = True
  116. VIEW_TYPES = ""
  117. COLOR_LINE = "red"
  118. COLOR_UHD = "yellow"
  119. SOCKET_TIMEOUT = 10
  120. USER_AGENT = ""
  121. MOVIES_PER_PAGE = 50
  122. YOUTUBE_SEARCH_URL = "https://www.googleapis.com/youtube/v3/search?key=AIzaSyDA0A-a085kg2wB7b-0F2XLOLCpypZYYgg&part=snippet&order=relevance&q=%s&regionCode=de&type=video&relevanceLanguage=de&maxResults=50&safeSearch=none"
  123. API_HEADERS = [
  124. ("Authorization", "Bearer %s" % PLUGIN_TOKEN),
  125. ("User-Agent", USER_AGENT)
  126. ]
  127. def get_storage(name):
  128. return PLUGIN.get_storage(name)
  129. def load_session():
  130. internal_storage = get_storage("session")
  131. if not ("user_id" in internal_storage):
  132. return None, None
  133. return internal_storage["user_id"], internal_storage["session_hash"]
  134. def clear_session():
  135. global PORTAL_USERID, PORTAL_SESSION
  136. internal_storage = PLUGIN.get_storage("session")
  137. if not ("user_id" in internal_storage):
  138. return None, None
  139. output("[SESSION] Clearing!!!!!")
  140. del internal_storage["user_id"]
  141. del internal_storage["session_hash"]
  142. internal_storage.sync()
  143. PORTAL_USERID = 0
  144. PORTAL_SESSION = None
  145. def read_settings():
  146. global PORTAL_USERNAME, PORTAL_PASSWORD, PORTAL_USERID, PORTAL_SESSION
  147. global API_URL, PORTAL_URL
  148. global DEVICE_IDENTIFER
  149. global SHOW_NEWCOMER, WATCHLIST_TOGETHER, USE_TAGLINE, ASK_BEFORE_PLAY
  150. global HIDE_UHD, HIDE_HD, HIDE_SERIES, HIDE_3D
  151. global SWITCH_TAGLINE, HIDE_SETTINGS, HIDE_LOGOUT, ASK_FOR_NEXT_EPISODE, VIEW_TYPES
  152. global MOVIES_PER_PAGE, COLOR_LINE, COLOR_UHD, SOCKET_TIMEOUT
  153. global USER_AGENT, WATCHLIST_ID, WATCHEDLIST_ID, SOCKET_TIMEOUT, MOVIES_PER_PAGE, API_HEADERS
  154. PLUGIN.set_goto_top(PLUGIN.get_setting("gototop") == "true")
  155. DELAY = PLUGIN.get_setting("directorydelay")
  156. if not DELAY.isdigit():
  157. DELAY = "0"
  158. PLUGIN.set_delay(int(DELAY))
  159. PORTAL_USERNAME = PLUGIN.get_setting("username")
  160. PORTAL_PASSWORD = PLUGIN.get_setting("password")
  161. PORTAL_USERID, PORTAL_SESSION = load_session()
  162. API_URL = ""
  163. PORTAL_URL = PLUGIN.get_setting("url")
  164. if not PORTAL_URL or not len(PORTAL_URL):
  165. PORTAL_URL = "vnext.to"
  166. API_URL = "http://api.%s" % PORTAL_URL
  167. if not ("://" in PORTAL_URL):
  168. PORTAL_URL = "http://%s" % PORTAL_URL
  169. DEVICE_IDENTIFER = PLUGIN.get_setting("deviceidentifier")
  170. if not DEVICE_IDENTIFER:
  171. DEVICE_IDENTIFER = "Unknown"
  172. WATCHLIST_ID = PLUGIN.get_setting("watchlistid")
  173. WATCHEDLIST_ID = PLUGIN.get_setting("watchedlistid")
  174. if not WATCHLIST_ID.isdigit():
  175. WATCHLIST_ID = "0"
  176. if not WATCHEDLIST_ID.isdigit():
  177. WATCHEDLIST_ID = "0"
  178. SHOW_NEWCOMER = PLUGIN.get_setting("shownewcomer") == "true"
  179. WATCHLIST_TOGETHER = PLUGIN.get_setting("watchlisttogether") == "true"
  180. USE_TAGLINE = PLUGIN.get_setting("usetagline") == "true"
  181. ASK_BEFORE_PLAY = PLUGIN.get_setting("askbeforeplay") == "true"
  182. HIDE_UHD = PLUGIN.get_setting("hideuhd") == "true"
  183. HIDE_HD = PLUGIN.get_setting("hidehd") == "true"
  184. HIDE_SERIES = PLUGIN.get_setting("hideseries") == "true"
  185. HIDE_3D = PLUGIN.get_setting("hide3d") == "true"
  186. SWITCH_TAGLINE = PLUGIN.get_setting("switchtagline") == "true"
  187. HIDE_SETTINGS = PLUGIN.get_setting("hidesettings") == "true"
  188. HIDE_LOGOUT = PLUGIN.get_setting("hidelogout") == "true"
  189. ASK_FOR_NEXT_EPISODE = PLUGIN.get_setting("askfornextepisode") == "true"
  190. VIEW_TYPES = PLUGIN.get_setting("viewtypes")
  191. if VIEW_TYPES == "1":
  192. VIEW_TYPES = "1,2"
  193. elif VIEW_TYPES == "2":
  194. VIEW_TYPES = "1,3"
  195. elif VIEW_TYPES == "3":
  196. VIEW_TYPES = "2,3"
  197. elif VIEW_TYPES == "4":
  198. VIEW_TYPES = "1"
  199. elif VIEW_TYPES == "5":
  200. VIEW_TYPES = "2"
  201. elif VIEW_TYPES == "6":
  202. VIEW_TYPES = "3"
  203. MOVIES_PER_PAGE = PLUGIN.get_setting("moviesperpage")
  204. COLOR_LINE = PLUGIN.get_setting("colorline").replace("#", "")
  205. COLOR_UHD = PLUGIN.get_setting("coloruhd").replace("#", "")
  206. SOCKET_TIMEOUT = PLUGIN.get_setting("sockettimeout")
  207. if not SOCKET_TIMEOUT.isdigit():
  208. SOCKET_TIMEOUT = "10"
  209. USER_AGENT = "%s %s/%s_%s" % (DEVICE_IDENTIFER, PLUGIN_NAME, PLUGIN_HASH, PLUGIN_VERSION)
  210. WATCHLIST_ID = int(WATCHLIST_ID) + 1
  211. WATCHEDLIST_ID = int(WATCHEDLIST_ID) + 1
  212. SOCKET_TIMEOUT = max(5, int(SOCKET_TIMEOUT))
  213. MOVIES_PER_PAGE = max(min(int(MOVIES_PER_PAGE), 150), 1)
  214. API_HEADERS = [
  215. ("Authorization", "Bearer %s" % PLUGIN_TOKEN),
  216. ("User-Agent", USER_AGENT)
  217. ]
  218. output("[SETTINGS] Loaded")
  219. read_settings()
  220. def ping():
  221. internal_storage = get_storage("internal")
  222. pinged = False
  223. if "ping" in internal_storage:
  224. try:
  225. pinged = (time.time() - int(internal_storage["ping"])) < (10.0 * 60)
  226. except:
  227. pinged = False
  228. if pinged:
  229. return True
  230. data = __api__.__get__("get/ping")
  231. if not data:
  232. return False
  233. if data["data"] == "pong":
  234. pinged = True
  235. internal_storage["ping"] = time.time()
  236. internal_storage.sync()
  237. if DEBUG:
  238. PLUGIN.notify("Erneut gepingt...")
  239. return pinged
  240. def save_session(user_id, session_hash):
  241. internal_storage = get_storage("session")
  242. internal_storage["user_id"] = user_id
  243. internal_storage["session_hash"] = session_hash
  244. internal_storage.sync()
  245. internal_storage = get_storage("internal")
  246. internal_storage["ping"] = time.time()
  247. internal_storage.sync()
  248. return True
  249. def save_watchtime(episode_id, time=0, seen=False):
  250. episode_id = str(episode_id)
  251. if seen:
  252. internal_storage = get_storage("watched")
  253. internal_storage[episode_id] = 1
  254. internal_storage.sync()
  255. time = 0
  256. try:
  257. __api__.__get__("set/watchedlist", __data__={
  258. "id": episode_id,
  259. "type": "episode"
  260. })
  261. except:
  262. pass
  263. if time < 3 * 60:
  264. time = 0
  265. internal_storage = get_storage("watchtime")
  266. internal_storage[episode_id] = time
  267. internal_storage.sync()
  268. def read_watchtime(episode_id):
  269. episode_id = str(episode_id)
  270. internal_storage = get_storage("watchtime")
  271. if internal_storage is None or not (episode_id in internal_storage):
  272. return 0
  273. return internal_storage[episode_id]
  274. def total_clear_storage():
  275. played_list_indexed = PLUGIN.get_storage("playedlistindexed")
  276. played_list_indexed.clear()
  277. played_list = PLUGIN.get_storage("playedlist")
  278. played_list.clear()
  279. played_lime = PLUGIN.get_storage("playedtime")
  280. played_lime.clear()
  281. def check_settings():
  282. global DEVICE_IDENTIFER, MOVIES_PER_PAGE, COLOR_UHD, COLOR_LINE, PORTAL_PASSWORD, PORTAL_USERNAME
  283. if "parse_episode" in sys.argv[0]:
  284. return True
  285. refresh = False
  286. if len(DEVICE_IDENTIFER) < 2 or (len(DEVICE_IDENTIFER) == 16 and is_hex(DEVICE_IDENTIFER)):
  287. # DEVICE_IDENTIFER = md5_string(str(randint(0, 99999)) + "" + str(int(time.time())))[:16]
  288. try:
  289. DEVICE_IDENTIFER = platform.system() + " " + platform.node() + " #" + str(random.randint(0, 99999))
  290. except:
  291. DEVICE_IDENTIFER = "Maybe iOS " + sys.platform + " #" + str(random.randint(0, 99999))
  292. PLUGIN.set_setting("deviceidentifier", DEVICE_IDENTIFER)
  293. internal_storage = get_storage("internal")
  294. # Version
  295. if "version" in internal_storage and internal_storage["version"] != PLUGIN.info("version"):
  296. if os.path.isfile(COOKIE_PATH):
  297. try:
  298. os.remove(COOKIE_PATH)
  299. except:
  300. pass
  301. PLUGIN.notify("Es wurde eine neue Version installiert.")
  302. clear_session()
  303. if DELETE_PASSWORD:
  304. PLUGIN.set_setting("password", "")
  305. PLUGIN.dialog(u"Eine neue Version wurde installiert\nAus Sicherheitsgründen musst du dein Passwort neu eingeben.", "Information")
  306. internal_storage["version"] = PLUGIN.info("version")
  307. internal_storage.sync()
  308. PORTAL_USERNAME = PLUGIN.get_setting("username")
  309. PORTAL_PASSWORD = PLUGIN.get_setting("password")
  310. if not PORTAL_USERNAME or not PORTAL_PASSWORD:
  311. return True
  312. if not COLOR_LINE:
  313. COLOR_LINE = "red"
  314. elif is_hex(COLOR_LINE) and len(COLOR_LINE) == 6:
  315. COLOR_LINE = "FF" + COLOR_LINE
  316. if not COLOR_UHD:
  317. COLOR_UHD = "yellow"
  318. elif is_hex(COLOR_UHD) and len(COLOR_UHD) == 6:
  319. COLOR_UHD = "FF" + COLOR_UHD
  320. PLUGIN.set_setting("moviesperpage", str(MOVIES_PER_PAGE))
  321. PLUGIN.set_setting("colorline", COLOR_LINE)
  322. PLUGIN.set_setting("coloruhd", COLOR_UHD)
  323. PLUGIN.set_setting("sockettimeout", str(SOCKET_TIMEOUT))
  324. # Check Password
  325. if PORTAL_PASSWORD and PORTAL_PASSWORD[0] != chr(2):
  326. PORTAL_PASSWORD = chr(2) + md5_string(PORTAL_PASSWORD)
  327. PLUGIN.set_setting("password", PORTAL_PASSWORD)
  328. PORTAL_PASSWORD = PORTAL_PASSWORD[1:]
  329. # Settings Hash
  330. settings_hash_last = None
  331. settings_hash_now = None
  332. try:
  333. settings_hash_now = md5_file(PLUGIN.addondata_path + "settings.xml")
  334. if "hash" in internal_storage and internal_storage["hash"]:
  335. settings_hash_last = internal_storage["hash"]
  336. if not settings_hash_last or settings_hash_last != settings_hash_now:
  337. refresh = True
  338. try:
  339. os.remove(COOKIE_PATH)
  340. except:
  341. pass
  342. except:
  343. pass
  344. internal_storage["hash"] = settings_hash_now
  345. internal_storage["version"] = PLUGIN.info("version")
  346. internal_storage.sync()
  347. return True
  348. # --------------------------------------------------------
  349. xbmc.log("------------------------------------------------------------------------------------------")
  350. xbmc.log("Portal: %s" % PORTAL_URL)
  351. output("API: %s" % API_URL)
  352. output("Hash: %s" % PLUGIN_HASH)
  353. output("Cookie: %s" % COOKIE_PATH)
  354. output("UserAgent: %s" % USER_AGENT)
  355. output("Call: %s" % sys.argv[0])
  356. xbmc.log("------------------------------------------------------------------------------------------")
  357. # Functions
  358. @PLUGIN.route("/empty/", name="empty", update=False, cache=True)
  359. def empty():
  360. return PLUGIN.set_resolved_url(None)
  361. EMPTY_PATH = PLUGIN.url_for(endpoint="empty")
  362. YOUTUBE_LIB_SEARCHED = False
  363. HAS_YOUTUBE_LIB = False
  364. def parse_youtube(trailer_id):
  365. global YOUTUBE_LIB_SEARCHED, HAS_YOUTUBE_LIB
  366. if not YOUTUBE_LIB_SEARCHED:
  367. YOUTUBE_LIB_SEARCHED = True
  368. sys.path.append(os.path.realpath(os.path.join(PLUGIN_PATH, "..", "plugin.video.youtube", "resources")))
  369. try:
  370. import lib.youtube_resolver
  371. HAS_YOUTUBE_LIB = True
  372. except:
  373. HAS_YOUTUBE_LIB = False
  374. if HAS_YOUTUBE_LIB:
  375. output("YouTube library found")
  376. else:
  377. output("YouTube library not found!")
  378. if not HAS_YOUTUBE_LIB:
  379. return False
  380. output("Search for %s" % trailer_id)
  381. return lib.youtube_resolver.resolve(trailer_id)
  382. def master_lock_access(age):
  383. return True
  384. def get_view(view_type="list"):
  385. """
  386. @param view_type:
  387. @return:
  388. """
  389. if not view_type:
  390. return VIEW_IDS["skin.confluence"][0]
  391. val = PLUGIN.get_setting("view" + view_type)
  392. try:
  393. val = int(val)
  394. except:
  395. val = 0
  396. skin = xbmc.getSkinDir()
  397. if val == 3: # Manuell
  398. return PLUGIN.get_setting("view" + view_type + "_man")
  399. elif skin in VIEW_IDS: # Auswahl
  400. try:
  401. return VIEW_IDS[skin][val]
  402. except:
  403. return VIEW_IDS["skin.confluence"][0]
  404. else:
  405. output("[%s] View IDs for Skin not found: %s" % (APPTITLE, skin))
  406. return VIEW_IDS["skin.confluence"][0]
  407. import urllib
  408. import collections
  409. OPENER = None
  410. class __ApiRequest__(object):
  411. def __init__(self, __url, __data__=None, __headers={}, __origin_req_host=None, __unverifiable=False):
  412. global OPENER
  413. self._request = None
  414. if OPENER is None:
  415. OPENER = urllib2.build_opener(urllib2.HTTPCookieProcessor(CJ))
  416. OPENER.addheaders = API_HEADERS
  417. original_url = __url
  418. __url = "%s/%s" % (API_URL, __url)
  419. if not __headers:
  420. __headers = {}
  421. tmp = collections.OrderedDict()
  422. tmp.update(__data__)
  423. __data__ = tmp
  424. if isinstance(__data__, dict):
  425. if original_url != "auth":
  426. __data__["x"] = "%sFE%s" % (PORTAL_USERID, PORTAL_SESSION)
  427. __data__["z"] = int(time.time())
  428. __data__["hash"] = md5_string("DEADBEEF%s?%s" % (original_url, urllib.urlencode(__data__)))
  429. __data__ = urllib.urlencode(__data__)
  430. if isinstance(__data__, str):
  431. __url = "%s?%s" % (__url, __data__)
  432. __data__ = None
  433. output("[API] Request: %s" % str(__url))
  434. self._request = urllib2.Request(__url, __data__, __headers, __origin_req_host, __unverifiable)
  435. def __execute__(self):
  436. try:
  437. return OPENER.open(self._request.get_full_url(), self._request.data).read()
  438. except Exception as e:
  439. raise e
  440. output(repr(e))
  441. return None