def _thread_tracker(self): log("in tracker thread") total_time = self.getTotalTime() total_time_min = int(get_setting("min-length")) perc_mark = int(get_setting("scr-pct")) self._is_detected = True timeout = 1000 # if total_time set and is lower than total_time_min then we do not start the loop at all and stop the thread, if total_time <= 0 or total_time > total_time_min: while self._playback_lock.isSet() and not xbmc.abortRequested: try: # The max() assures that the total time is over two minutes # preventing it from scrobbling while buffering and solving #31 if min(99, 100 * self.getTime() / max(120, total_time)) >= perc_mark: success = self._api.mark_as_watched(self._item) if not success: if timeout == 1000: log("Failed to scrobble") notify(get_str(32080)) timeout = 30000 elif (self.getTime() / total_time) > 0.95: log("Stopped scrobbling") notify(get_str(32081)) break else: log("Retrying") elif success and bool(get_setting("bubble")): self._show_bubble(self._item) break except: pass xbmc.sleep(timeout) log('track stop')
def check_connection(self, cnt=0): if cnt < 3: try: self.get_usersettings() self.internet = True except Exception: time.sleep(5) self.check_connection(cnt=cnt + 1) else: self.internet = False interface.notify(getstr(32027))
def _show_bubble(self, item): log("in bubble") if "title" in item: txt = '' title = item["title"] if "episode" in item: txt = "- S{:02}E{:02}".format(item["season"], item["episode"]) elif "year" in item: title = "".join([title, " (", str(item["year"]), ")"]) log("Show Bubble") notify(get_str(32028).format(txt), title=title)
def _http(self, url, headers={}, body=None, is_json=True): try: con = httplib.HTTPSConnection("api.simkl.com") con.request("GET", url, headers=headers, body=body) r = con.getresponse().read().decode("utf-8") if r.find('user_token_failed') != -1: self.isLoggedIn = False set_setting('token', '') notify(get_str(32031)) return False return json.loads(r) if is_json else r except Exception: return None
def __init__(self): self.userSettings = {} self.isLoggedIn = False self.loginInProgress = False self.headers = { "Content-Type": "application-json", "simkl-api-key": APIKEY } # set_setting('token', '') token = get_setting('token') if token: self.headers["authorization"] = "Bearer " + token r = self.get_user_settings() if r: notify( get_str(32025).format(self.userSettings["user"]["name"])) return elif r is None: notify(get_str(32027)) return self.login()
def login(self): if self.loginInProgress: return self.loginInProgress = True if not self.isLoggedIn: rdic = self._http("/oauth/pin?client_id=" + APIKEY + "&redirect=" + REDIRECT_URI, headers=self.headers) if isinstance(rdic, dict) and "error" not in rdic.keys(): pin = rdic["user_code"] url = rdic["verification_url"] login = LoginDialog("simkl-LoginDialog.xml", __addon__.getAddonInfo("path"), pin=pin, url=url, pin_check=self.pin_check, pin_success=self.pin_success) login.doModal() del login else: notify(get_str(32025).format(self.userSettings["user"]["name"])) self.loginInProgress = False
def pin_success(self): notify(get_str(32030).format(self.userSettings["user"]["name"]))
def watched(self, item, duration, date=time.strftime('%Y-%m-%d %H:%M:%S'), cnt=0): #OR IDMB, member: only works with movies filename = item["file"].replace("\\", "/") if self.is_user_logged() and not self.is_locked(filename): try: con = httplib.HTTPSConnection("api.simkl.com") mediadict = { "movie": "movies", "episode": "shows", "show": "shows" } if item["imdbnumber"] != "": if item["type"] == "movie": toappend = { "ids": { "imdb": item["imdbnumber"] }, "watched_at": date } elif item["type"] == "episode": toappend = { "ids": { "tvdb": item["imdbnumber"] }, "watched_at": date, "seasons": [{ "number": item["season"], "episodes": [{ "number": item["episode"] }] }] } media = mediadict[item["type"]] else: xbmc.log("Simkl: Filename - {0}".format(filename)) values = json.dumps({"file": filename}) xbmc.log("Simkl: Query: {0}".format(values)) con.request("GET", "/search/file/", body=values, headers=headers) r1 = con.getresponse().read() #.decode("utf-8") xbmc.log("Simkl: Response: {0}".format(r1)) r = json.loads(str(r1)) self.lastwatched = r if r == []: xbmc.log("Simkl: Couldn't scrobble: Null Response") return 0 media = mediadict[r["type"]] toappend = {"ids": r[r["type"]]["ids"], "watched_at": date} tosend = {} tosend[media] = [] tosend[media].append(toappend) tosend = json.dumps(tosend) xbmc.log("Simkl: values {0}".format(tosend)) con.request("GET", "/sync/history/", body=tosend, headers=headers) r = con.getresponse().read().decode("utf-8") xbmc.log("Simkl: {0}".format(r)) success = max(json.loads(r)["added"].values()) if success: self.scrobbled_dict self.lock(filename, duration) return success #except httplib.BadStatusLine: # xbmc.log("Simkl: {0}".format("ERROR: httplib.BadStatusLine")) except: xbmc.log("Simkl: ERROR: SSLError, retrying?") interface.notify(getstr(32029).format(cnt + 1)) time.sleep(5) if cnt <= 3: self.watched(item, duration, date, cnt=cnt + 1) else: interface.notify(getstr(32027)) else: xbmc.log( "Simkl: Can't scrobble. User not logged in or file locked") return 0
def onPlayBackStopped(self): ''' Gets the info needed to pass to the api ''' self.api.check_connection() try: item = json.loads( xbmc.executeJSONRPC( json.dumps({ "jsonrpc": "2.0", "method": "Player.GetItem", "params": { "properties": [ "showtitle", "title", "season", "episode", "file", "tvshowid", "imdbnumber", "genre" ], "playerid": 1 }, "id": "VideoGetItem" })))["result"]["item"] if item["tvshowid"] != -1: item["imdbnumber"] = json.loads( xbmc.executeJSONRPC( json.dumps({ "jsonrpc": "2.0", "method": "VideoLibrary.GetTVShowDetails", "params": { "tvshowid": item["tvshowid"], "properties": ["imdbnumber"] }, "id": 1 })))["result"]["tvshowdetails"]["imdbnumber"] xbmc.log("Simkl: Full: {0}".format(item)) percentage = min(99, 100 * self.getTime() / self.getTotalTime()) pctconfig = int(self.addon.getSetting("scr-pct")) if percentage > pctconfig: bubble = __addon__.getSetting("bubble") xbmc.log("Simkl: Bubble == {0}".format(bubble)) xbmc.log("Percentage: {0}, pctconfig {1}".format( percentage, pctconfig)) r = self.api.watched(item, self.getTotalTime()) if bubble == "true" and r: if item["label"] == os.path.basename(item["file"]): #if True: #For testing purposes xbmc.log("Simkl: Label and file are the same") lstw = self.api.lastwatched if lstw["type"] == "episode": item["showtitle"] = lstw["show"]["title"] item["season"] = lstw["episode"]["season"] item["episode"] = lstw["episode"]["episode"] elif lstw["type"] == "movie": item["title"] = "".join([ lstw["movie"]["title"], " (", str(lstw["movie"]["year"]), ")" ]) media = lstw["type"] txt = item["label"] title = "" if item["type"] == "movie": txt = item["title"] elif item["type"] == "episode": txt = item["showtitle"] title = "- S{:02}E{:02}".format( item["season"], item["episode"]) xbmc.log("Simkl: " + "; ".join([item["type"], txt, title])) interface.notify(getstr(32028).format(title), title=txt) r = 0 except RuntimeError: pass except ZeroDivisionError: self.onPlayBackStopped()