Kodi Community Forum

Full Version: Trakt.tv v3
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
(2016-05-03, 19:16)FriedLocust Wrote: [ -> ]Sorry for delay.

http://xbmclogs.com/pjmkuw95k

Are you able to test from github? If so can you try https://github.com/Razzeee/script.trakt/...en-refresh
And let me know how/if it's working?
Is there any way to stop the addon from scobbling if I'm already checked in on the trakt website?

Checking in is how I share to social media (I don't want to post every single thing I watch so I set check-ins to share rather than scrobbles so that I can choose what to share). The problem is I end up with 2 watch counts because kodi scrobbles after I've checked in.
(2016-05-06, 11:14)TheStretchedElf Wrote: [ -> ]Is there any way to stop the addon from scobbling if I'm already checked in on the trakt website?

Checking in is how I share to social media (I don't want to post every single thing I watch so I set check-ins to share rather than scrobbles so that I can choose what to share). The problem is I end up with 2 watch counts because kodi scrobbles after I've checked in.

No, there is not.
(2016-05-06, 13:25)Razze Wrote: [ -> ]
(2016-05-06, 11:14)TheStretchedElf Wrote: [ -> ]Is there any way to stop the addon from scobbling if I'm already checked in on the trakt website?

Checking in is how I share to social media (I don't want to post every single thing I watch so I set check-ins to share rather than scrobbles so that I can choose what to share). The problem is I end up with 2 watch counts because kodi scrobbles after I've checked in.

No, there is not.
Would it not be possible to have a context menu option of "play without scrobble" that would temporarily switch off scobbling?
(2016-05-06, 16:16)TheStretchedElf Wrote: [ -> ]
(2016-05-06, 13:25)Razze Wrote: [ -> ]
(2016-05-06, 11:14)TheStretchedElf Wrote: [ -> ]Is there any way to stop the addon from scobbling if I'm already checked in on the trakt website?

Checking in is how I share to social media (I don't want to post every single thing I watch so I set check-ins to share rather than scrobbles so that I can choose what to share). The problem is I end up with 2 watch counts because kodi scrobbles after I've checked in.

No, there is not.
Would it not be possible to have a context menu option of "play without scrobble" that would temporarily switch off scobbling?

Everything is possible, if you put enough work into it.
And want to pollute a clean interface with edge case options just for one person
(2016-05-06, 10:51)Razze Wrote: [ -> ]
(2016-05-03, 19:16)FriedLocust Wrote: [ -> ]Sorry for delay.

http://xbmclogs.com/pjmkuw95k

Are you able to test from github? If so can you try https://github.com/Razzeee/script.trakt/...en-refresh
And let me know how/if it's working?
Uh, never tried it this way. I am only only a user. Wink
The zip in https://github.com/Razzeee/script.trakt/zipball/master has the fix-tokenm refresh in it?

Or copy

PHP Code:
secret=self.__client_secret
         
)
 
+        
# Bind event
+        Trakt.on('oauth.token_refreshed'self.on_token_refreshed)
+
+        
Trakt.configuration.defaults.oauth(
+            
refresh=True
+        )
+
         if 
getSetting('authorization') and not force:
             
self.authorization loads(getSetting('authorization'))
         else:
@@ -
118,+125,13 @@ def on_poll(selfcallback):
         
# Continue polling
         
callback(True)
 
+    
def on_token_refreshed(selfresponse):
+        
# OAuth token refreshed, save token for future calls
+        self.authorization response
+        setSetting('authorization'dumps(self.authorization))
+
+        
logger.debug('Token refreshed')
+
     
def updateUser(self):
         
user self.getUser()
         if 
user and 'user' in user


into traktapi.py and overwrite it on my kodi-box?
(2016-05-07, 18:05)FriedLocust Wrote: [ -> ]
(2016-05-06, 10:51)Razze Wrote: [ -> ]
(2016-05-03, 19:16)FriedLocust Wrote: [ -> ]Sorry for delay.

http://xbmclogs.com/pjmkuw95k

Are you able to test from github? If so can you try https://github.com/Razzeee/script.trakt/...en-refresh
And let me know how/if it's working?
Uh, never tried it this way. I am only only a user. Wink
The zip in https://github.com/Razzeee/script.trakt/zipball/master has the fix-tokenm refresh in it?

Or copy

PHP Code:
secret=self.__client_secret
         
)
 
+        
# Bind event
+        Trakt.on('oauth.token_refreshed'self.on_token_refreshed)
+
+        
Trakt.configuration.defaults.oauth(
+            
refresh=True
+        )
+
         if 
getSetting('authorization') and not force:
             
self.authorization loads(getSetting('authorization'))
         else:
@@ -
118,+125,13 @@ def on_poll(selfcallback):
         
# Continue polling
         
callback(True)
 
+    
def on_token_refreshed(selfresponse):
+        
# OAuth token refreshed, save token for future calls
+        self.authorization response
+        setSetting('authorization'dumps(self.authorization))
+
+        
logger.debug('Token refreshed')
+
     
def updateUser(self):
         
user self.getUser()
         if 
user and 'user' in user


into traktapi.py and overwrite it on my kodi-box?

both ways should work, whatever is easier for you.
Hi, I'm getting this exception when manually syncing (executing trakt itself):
Code:
19:17:15 T:2854421568   ERROR: Exception in thread trakt-sync:
       Traceback (most recent call last):
         File "/home/alex/OpenELEC.tv/build.OpenELEC-Amlogic.M8.arm-6.0.3/Python-2.7.3/.install_pkg/usr/lib/python2.7/threading.py", line 551, in __bootstrap_inner
         File "/storage/.kodi/addons/script.trakt/service.py", line 334, in run
            sync.sync()
         File "/storage/.kodi/addons/script.trakt/sync.py", line 56, in sync
            syncMovies.SyncMovies(self, progress)
         File "/storage/.kodi/addons/script.trakt/syncMovies.py", line 19, in __init__
             kodiMovies = self.__kodiLoadMovies()
         File "/storage/.kodi/addons/script.trakt/syncMovies.py", line 63, in __kodiLoadMovies
             if data['limits']['total'] == 0:
         TypeError: 'NoneType' object has no attribute '__getitem__'

Full Log: http://xbmclogs.com/plnap7kxb
I'm a little lost what could cause this, any help is apreciated.
Is there a reason why trakt isn't syncing Big Bang theory? I have enabled the notifcations and everytime i get a notification but it doesn't scroblle? All other shows works fine. I can't post log atm.
(2016-05-09, 00:13)Razze Wrote: [ -> ][quote='FriedLocust' pid='2330292' dateline='1462637144']
[quote='Razze' pid='2329290' dateline='1462524686']

Are you able to test from github? If so can you try https://github.com/Razzeee/script.trakt/...en-refresh
And let me know how/if it's working?

Sorry again for delay, been busy.

I tried the zip from https://github.com/Razzeee/script.trakt/zipball/master, got notification for updating trakt plugin. But all files in plugin folder have april 30 as date. Traktapi.py too. Your commit is from may 6th should it not have this date?

Did not work. No pop up no notification from trakt for successfully transmitting with the dev zip.

Tried
Code:
# -*- coding: utf-8 -*-
#
import xbmcaddon
import logging
import deviceAuthDialog
import time

from trakt import Trakt
from trakt.objects import Movie, Show
from utilities import findMovieMatchInList, findShowMatchInList, findEpisodeMatchInList, findSeasonMatchInList, createError
from kodiUtilities import getSetting, setSetting, notification, getString, checkAndConfigureProxy, getSettingAsInt
from sys import version_info


if version_info >= (2, 7):
    from json import loads, dumps
else:
    from simplejson import loads, dumps

# read settings
__addon__ = xbmcaddon.Addon('script.trakt')
__addonversion__ = __addon__.getAddonInfo('version')

logger = logging.getLogger(__name__)


class traktAPI(object):
    __client_id = "d4161a7a106424551add171e5470112e4afdaf2438e6ef2fe0548edc75924868"
    __client_secret = "b5fcd7cb5d9bb963784d11bbf8535bc0d25d46225016191eb48e50792d2155c0"

    def __init__(self, force=False):
        logger.debug("Initializing.")

        proxyURL = checkAndConfigureProxy()
        if proxyURL:
            Trakt.http.proxies = {
                'http': proxyURL,
                'https': proxyURL
            }

        Trakt.configuration.defaults.app(
            id=999
        )

        # Configure
        Trakt.configuration.defaults.client(
            id=self.__client_id,
            secret=self.__client_secret
        )

        # Bind event
        Trakt.on('oauth.token_refreshed', self.on_token_refreshed)

        Trakt.configuration.defaults.oauth(
            refresh=True
        )

        if getSetting('authorization') and not force:
            self.authorization = loads(getSetting('authorization'))
        else:
            last_reminder = getSettingAsInt('last_reminder')
            now = int(time.time())
            if last_reminder >= 0 and last_reminder < now - (24 * 60 * 60) or force:
                self.login()

    def login(self):
        # Request new device code
        with Trakt.configuration.http(retry=True, timeout=90):
            code = Trakt['oauth/device'].code()

            # Construct device authentication poller
            poller = Trakt['oauth/device'].poll(**code)\
                .on('aborted', self.on_aborted)\
                .on('authenticated', self.on_authenticated)\
                .on('expired', self.on_expired)\
                .on('poll', self.on_poll)

            # Start polling for authentication token
            poller.start(daemon=False)

            logger.debug('Enter the code "%s" at %s to authenticate your account' % (
                code.get('user_code'),
                code.get('verification_url')
            ))

            self.authDialog = deviceAuthDialog.DeviceAuthDialog('script-trakt-DeviceAuthDialog.xml', __addon__.getAddonInfo('path'),
                                                                code=code.get('user_code'), url=code.get('verification_url'))
            self.authDialog.doModal()

            del self.authDialog

    def on_aborted(self):
        """Triggered when device authentication was aborted (either with `DeviceOAuthPoller.stop()`
           or via the "poll" event)"""

        logger.debug('Authentication aborted')
        self.authDialog.close()

    def on_authenticated(self, token):
        """Triggered when device authentication has been completed
        :param token: Authentication token details
        :type token: dict
        """
        self.authorization = token
        setSetting('authorization', dumps(self.authorization))
        logger.debug('Authentication complete: %r' % token)
        self.authDialog.close()
        notification(getString(32157), getString(32152), 3000)
        self.updateUser()

    def on_expired(self):
        """Triggered when the device authentication code has expired"""

        logger.debug('Authentication expired')
        self.authDialog.close()

    def on_poll(self, callback):
        """Triggered before each poll
        :param callback: Call with `True` to continue polling, or `False` to abort polling
        :type callback: func
        """

        # Continue polling
        callback(True)

    def on_token_refreshed(self, response):
        # OAuth token refreshed, save token for future calls
        self.authorization = response
        setSetting('authorization', dumps(self.authorization))

        logger.debug('Token refreshed')

    def updateUser(self):
        user = self.getUser()
        if user and 'user' in user:
            setSetting('user', user['user']['username'])
        else:
            setSetting('user', '')

    def scrobbleEpisode(self, show, episode, percent, status):
        result = None

        with Trakt.configuration.oauth.from_response(self.authorization):
            if status == 'start':
                with Trakt.configuration.http(retry=True):
                    result = Trakt['scrobble'].start(
                        show=show,
                        episode=episode,
                        progress=percent)
            elif status == 'pause':
                with Trakt.configuration.http(retry=True):
                    result = Trakt['scrobble'].pause(
                        show=show,
                        episode=episode,
                        progress=percent)
            elif status == 'stop':
                # don't retry on stop, this will cause multiple scrobbles
                result = Trakt['scrobble'].stop(
                    show=show,
                    episode=episode,
                    progress=percent)
            else:
                logger.debug("scrobble() Bad scrobble status")
        return result

    def scrobbleMovie(self, movie, percent, status):
        result = None

        with Trakt.configuration.oauth.from_response(self.authorization):
            if status == 'start':
                with Trakt.configuration.http(retry=True):
                    result = Trakt['scrobble'].start(
                        movie=movie,
                        progress=percent)
            elif status == 'pause':
                with Trakt.configuration.http(retry=True):
                    result = Trakt['scrobble'].pause(
                        movie=movie,
                        progress=percent)
            elif status == 'stop':
                # don't retry on stop, this will cause multiple scrobbles
                result = Trakt['scrobble'].stop(
                    movie=movie,
                    progress=percent)
            else:
                logger.debug("scrobble() Bad scrobble status")
        return result

    def getShowsCollected(self, shows):
        with Trakt.configuration.oauth.from_response(self.authorization):
            with Trakt.configuration.http(retry=True, timeout=90):
                Trakt['sync/collection'].shows(shows, exceptions=True)
        return shows

    def getMoviesCollected(self, movies):
        with Trakt.configuration.oauth.from_response(self.authorization):
            with Trakt.configuration.http(retry=True, timeout=90):
                Trakt['sync/collection'].movies(movies, exceptions=True)
        return movies

    def getShowsWatched(self, shows):
        with Trakt.configuration.oauth.from_response(self.authorization):
            with Trakt.configuration.http(retry=True, timeout=90):
                Trakt['sync/watched'].shows(shows, exceptions=True)
        return shows

    def getMoviesWatched(self, movies):
        with Trakt.configuration.oauth.from_response(self.authorization):
            with Trakt.configuration.http(retry=True, timeout=90):
                Trakt['sync/watched'].movies(movies, exceptions=True)
        return movies

    def getShowsRated(self, shows):
        with Trakt.configuration.oauth.from_response(self.authorization):
            with Trakt.configuration.http(retry=True, timeout=90):
                Trakt['sync/ratings'].shows(shows, exceptions=True)
        return shows

    def getEpisodesRated(self, shows):
        with Trakt.configuration.oauth.from_response(self.authorization):
            with Trakt.configuration.http(retry=True, timeout=90):
                Trakt['sync/ratings'].episodes(shows, exceptions=True)
        return shows

    def getMoviesRated(self, movies):
        with Trakt.configuration.oauth.from_response(self.authorization):
            with Trakt.configuration.http(retry=True, timeout=90):
                Trakt['sync/ratings'].movies(movies, exceptions=True)
        return movies

    def addToCollection(self, mediaObject):
        with Trakt.configuration.oauth.from_response(self.authorization):
            with Trakt.configuration.http(retry=True):
                result = Trakt['sync/collection'].add(mediaObject)
        return result

    def removeFromCollection(self, mediaObject):
        with Trakt.configuration.oauth.from_response(self.authorization):
            with Trakt.configuration.http(retry=True):
                result = Trakt['sync/collection'].remove(mediaObject)
        return result

    def addToHistory(self, mediaObject):
        with Trakt.configuration.oauth.from_response(self.authorization):
            # don't try this call it may cause multiple watches
            result = Trakt['sync/history'].add(mediaObject)
        return result

    def addToWatchlist(self, mediaObject):
        with Trakt.configuration.oauth.from_response(self.authorization):
            with Trakt.configuration.http(retry=True):
                result = Trakt['sync/watchlist'].add(mediaObject)
        return result

    def getShowRatingForUser(self, showId, idType='tvdb'):
        ratings = {}
        with Trakt.configuration.oauth.from_response(self.authorization):
            with Trakt.configuration.http(retry=True):
                Trakt['sync/ratings'].shows(ratings)
        return findShowMatchInList(showId, ratings, idType)

    def getSeasonRatingForUser(self, showId, season, idType='tvdb'):
        ratings = {}
        with Trakt.configuration.oauth.from_response(self.authorization):
            with Trakt.configuration.http(retry=True):
                Trakt['sync/ratings'].seasons(ratings)
        return findSeasonMatchInList(showId, season, ratings, idType)

    def getEpisodeRatingForUser(self, showId, season, episode, idType='tvdb'):
        ratings = {}
        with Trakt.configuration.oauth.from_response(self.authorization):
            with Trakt.configuration.http(retry=True):
                Trakt['sync/ratings'].episodes(ratings)
        return findEpisodeMatchInList(showId, season, episode, ratings, idType)

    def getMovieRatingForUser(self, movieId, idType='imdb'):
        ratings = {}
        with Trakt.configuration.oauth.from_response(self.authorization):
            with Trakt.configuration.http(retry=True):
                Trakt['sync/ratings'].movies(ratings)
        return findMovieMatchInList(movieId, ratings, idType)

    # Send a rating to Trakt as mediaObject so we can add the rating
    def addRating(self, mediaObject):
        with Trakt.configuration.oauth.from_response(self.authorization):
            with Trakt.configuration.http(retry=True):
                result = Trakt['sync/ratings'].add(mediaObject)
        return result

    # Send a rating to Trakt as mediaObject so we can remove the rating
    def removeRating(self, mediaObject):
        with Trakt.configuration.oauth.from_response(self.authorization):
            with Trakt.configuration.http(retry=True):
                result = Trakt['sync/ratings'].remove(mediaObject)
        return result

    def getMoviePlaybackProgress(self):
        progressMovies = []

        # Fetch playback
        with Trakt.configuration.oauth.from_response(self.authorization):
            with Trakt.configuration.http(retry=True):
                playback = Trakt['sync/playback'].movies(exceptions=True)

                for _, item in playback.items():
                    if type(item) is Movie:
                        progressMovies.append(item)

        return progressMovies

    def getEpisodePlaybackProgress(self):
        progressEpisodes = []

        # Fetch playback
        with Trakt.configuration.oauth.from_response(self.authorization):
            with Trakt.configuration.http(retry=True):
                playback = Trakt['sync/playback'].episodes(exceptions=True)

                for _, item in playback.items():
                    if type(item) is Show:
                        progressEpisodes.append(item)

        return progressEpisodes

    def getMovieSummary(self, movieId):
        with Trakt.configuration.http(retry=True):
            return Trakt['movies'].get(movieId)

    def getShowSummary(self, showId):
        with Trakt.configuration.http(retry=True):
            return Trakt['shows'].get(showId)

    def getEpisodeSummary(self, showId, season, episode):
        with Trakt.configuration.http(retry=True):
            return Trakt['shows'].episode(showId, season, episode)

    def getIdLookup(self, id, id_type):
        with Trakt.configuration.http(retry=True):
            result = Trakt['search'].lookup(id, id_type)
            if result and not isinstance(result, list):
                result = [result]
            return result

    def getUser(self):
        with Trakt.configuration.oauth.from_response(self.authorization):
            with Trakt.configuration.http(retry=True):
                result = Trakt['users/settings'].get()
return result

copied it with notepad++ to traktapi.py replaced old traktapi.py in C:\Users\XBMC\AppData\Roaming\Kodi\addons\script.trakt with your version. Trakt popped up with errors on startup.
One strange thing. On github it says there are 350 lines, in notepad++ there are only 348 lines after copying the code.
Ich mach was falsch Razze. Wink

PS: I am a moron, I downloaded the wrong branch. I have to learn the proper use of github. Changed the branch to fix token refresh. I will try this zip and report back.

PPS: Adding the zip via kodi did not not work. So I manually copied all the files to the trakt script folder. Now everything works. I'm happy. Big Grin Kodi crashed after trakt.api submitted the data, but I am not sure if this was trakt related. Will monitor this, thx Razze. Wink
Hello

Some days ago the rating popup don't appear after view a movie or a series.

Someone can help me?
never mind...
(2016-05-12, 16:33)Zpower Wrote: [ -> ]Hello

Some days ago the rating popup don't appear after view a movie or a series.

Someone can help me?
Yeah, see one post over yours. Wink Had the same problems.

Try this zip. https://github.com/Razzeee/script.trakt/...efresh.zip I had to overwrite the files in C:\Users\"your profilename"\AppData\Roaming\Kodi\addons\script.trakt with the files from the zip to get it to work. But now everything works as expected.
Same problem here...it doesn't work anymore..i tried the whatever...on 3 devices...no pop up, no ..scrobbling..it worked until sunday afternoon..i didn't change anything...so...i have no idea why it stopped working everywhere...

Ok...i tried to delete "script.trakt" user folder...it asked me to connect again with barcode...and now it seems it's working again...