Example #1
0
        def Queue(self):
            queue_type = __settings__.getSetting("queue_type")
            if queue_type == '0':
                    fields = "media.episode_number,media.name,media.description,media.media_type,media.series_name,media.available,media.available_time,media.free_available,media.free_available_time,media.duration,media.playhead,media.url,media.screenshot_image,image.fwide_url,image.fwidestar_url,series.landscape_image,image.full_url"
                    options = {'media_types':"anime|drama", 'fields':fields}
                    request = self.makeAPIRequest('queue', options)
                    if request['error'] is False:	
                            return self.list_media_items(request['data'], 'Queue', '1', 'queue', 'fanart')				

            elif queue_type == '1':
                    fields = "series.name,series.description,series.series_id,series.rating,series.media_count,series.url,series.publisher_name,series.year,series.portrait_image,image.large_url,series.landscape_image,image.full_url"
                    options = {'media_types':"anime|drama", 'fields':fields}
                    request = self.makeAPIRequest('queue', options)
                    if request['error'] is False:
                            for series in request['data']:
                                    series = series['series']
                                    year = 'None' if series['year'] is None else series['year'] #only available on some series
                                    description = '' if series['description'] is None else series['description'].encode('utf-8') #Adding sinopses
                                    
                                    thumb = '' if (series['portrait_image'] is None or series['portrait_image']['large_url'] is None or 'portrait_image' not in series or 'large_url' not in series['portrait_image']) else series['portrait_image']['full_url'] #Becuase not all series have a thumbnail. 
                                    art = '' if (series['landscape_image'] is None or series['landscape_image']['full_url'] is None or 'landscape_image' not in series or 'full_url' not in series['landscape_image']) else series['landscape_image']['full_url'] #Becuase not all series have art. 
                                    rating = '0' if (series['rating'] == '' or 'rating' not in series) else series['rating'] #Because Crunchyroll seems to like passing series without ratings
                                    if ('media_count' in series and 'series_id' in series and 'name' in series and series['media_count'] > 0): #Because Crunchyroll seems to like passing series without these things
                                            crunchy_main.UI().addItem({'Title':series['name'].encode("utf8"),'mode':'list_coll', 'series_id':series['series_id'], 'Thumb':thumb, 'Fanart_Image':art, 'plot':description, 'year':year}, True)
                            
                            crunchy_main.UI().endofdirectory('none')
Example #2
0
 def list_collections(self, series_id, series_name, count, thumb, fanart):
     fields = "collection.collection_id,collection.season,collection.name,collection.description,collection.complete,collection.media_count"
     options = {
         'series_id': series_id,
         'fields': fields,
         'sort': 'desc',
         'limit': count
     }
     request = self.makeAPIRequest('list_collections', options)
     if request['error'] is False:
         if len(request['data']) <= 1:
             for collection in request['data']:
                 complete = '1' if collection['complete'] else '0'
                 return self.list_media(collection['collection_id'],
                                        series_name, count, complete, '1',
                                        fanart)
         else:
             for collection in request['data']:
                 complete = '1' if collection['complete'] else '0'
                 crunchy_main.UI().addItem(
                     {
                         'Title': collection['name'].encode("utf8"),
                         'filterx': series_name,
                         'mode': 'list_media',
                         'count': str(count),
                         'id': collection['collection_id'],
                         'plot': collection['description'].encode("utf8"),
                         'complete': complete,
                         'season': str(collection['season']),
                         'series_id': series_id,
                         'Thumb': thumb,
                         'Fanart_Image': fanart
                     }, True)
     crunchy_main.UI().endofdirectory('none')
Example #3
0
    def list_categories(self, title, media_type, filterx):
        options = {'media_type': media_type.lower()}
        request = self.makeAPIRequest('categories', options)
        if request['error'] is False:
            if filterx == 'genre':
                if 'genre' in request['data']:
                    for genre in request['data']['genre']:
                        crunchy_main.UI().addItem(
                            {
                                'Title': genre['label'].encode("utf8"),
                                'mode': 'list_series',
                                'showtype': media_type,
                                'filterx': 'tag:' + genre['tag']
                            }, True)

            if filterx == 'season':
                if 'season' in request['data']:
                    for season in request['data']['season']:
                        crunchy_main.UI().addItem(
                            {
                                'Title': season['label'].encode("utf8"),
                                'mode': 'list_series',
                                'showtype': media_type,
                                'filterx': 'tag:' + season['tag']
                            }, True)
        crunchy_main.UI().endofdirectory('none')
Example #4
0
 def list_media_items(self, request, series_name, season, mode, fanart):
         for media in request:
                 #The following are items to help display Recently Watched and Queue items correctly
                 season = media['collection']['season'] if mode == "history" else season 
                 series_name = media['series']['name'] if mode == "history" else series_name
                 series_name = media['most_likely_media']['series_name'] if mode == "queue" else series_name
                 fanart = media['series']['landscape_image']['fwide_url'] if (mode == "history" or mode == "queue") else fanart  #On history/queue, the fanart is get directly from the json.
                 media = media['media'] if mode == "history" else media  #History media is one level deeper in the json string than normal media items. 
                 if mode == "queue" and 'most_likely_media' not in media: #Some queue items don't have most_likely_media so we have to skip them.
                         continue 
                 media = media['most_likely_media'] if mode == "queue" else media  #Queue media is one level deeper in the json string than normal media items.
                 
                 #Dates, times, and such
                 current_datetime = datetime.datetime.now(dateutil.tz.tzutc()) 
                 available_datetime = dateutil.parser.parse(media['available_time']).astimezone(dateutil.tz.tzlocal())
                 available_date = available_datetime.date() 
                 available_delta = available_datetime - current_datetime
                 available_in = str(available_delta.days)+" days." if available_delta.days > 0 else str(available_delta.seconds/60/60)+" hours."
                 
                 #Fix Crunchyroll inconsistencies & add details for upcoming or unreleased episodes
                 media['episode_number'] = '0' if media['episode_number'] == '' else media['episode_number'] #PV episodes have no episode number so we set it to 0. 
                 media['episode_number'] = re.sub('\D', '', media['episode_number'])	#Because CR puts letters into some rare episode numbers.
                 if media['episode_number'] == '0':
                         name = "NO NAME" if media['name'] == '' else media['name']
                 else:
                         name = "Episode "+str(media['episode_number']) if media['name'] == '' else "Episode "+media['episode_number']+" - "+media['name'] #CR doesn't seem to include episode names for all media so we have to make one up.
                 name = series_name + " " + name if (mode == "history" or mode == "queue") else name
                 name = "* " + name if media['free_available'] is False else name
                 soon = "Coming Soon - " + series_name + " Episode "+str(media['episode_number']) if mode == "queue" else "Coming Soon - Episode "+str(media['episode_number'])
                 name = soon if media['available'] is False else name #Set the name for upcoming episode
                 #season = '1' if season == '0' else season #There is a bug which prevents Season 0 from displaying correctly in PMC. This is to help fix that. Will break if a series has both season 0 and 1. 
                 thumb = "http://static.ak.crunchyroll.com/i/no_image_beta_full.jpg" if media['screenshot_image'] is None else media['screenshot_image']['fwide_url'] if media['free_available'] is True else media['screenshot_image']['fwidestar_url']#because not all shows have thumbnails.
                 thumb = "http://static.ak.crunchyroll.com/i/coming_soon_beta_fwide.jpg" if media['available'] is False else thumb #Sets the thumbnail to coming soon if the episode isn't available yet.
                 description = '' if media['description'] is None else media['description'].encode('utf-8') #Adding sinopses
                 description = "This episode will be available in "+str(available_in) if media['available'] is False else description #Set the description for upcoming episodes.
                 duration = "0" if media['available'] is False else str(media['duration'])
                 playhead = "0" if media['available'] is False else str(media['playhead']) #current playback point
                 year = 'None' if media['available_time'] is None else media['available_time'][:10] #Adding published date instead
                 url = media['url']
                 media_id = url.split('-')[-1]
                 crunchy_main.UI().addItem({'Title':name.encode("utf8"),'mode':'videoplay', 'id':media_id.encode("utf8"), 'Thumb':thumb.encode("utf8"), 'url':url.encode("utf8"), 'Fanart_Image':fanart, 'plot':description, 'year':year, 'playhead':playhead, 'duration':duration}, False)
         crunchy_main.UI().endofdirectory('none')
Example #5
0
        def list_series(self, title, media_type, filterx, offset): 
            fields = "series.name,series.description,series.series_id,series.rating,series.media_count,series.url,series.publisher_name,series.year,series.portrait_image,image.large_url,series.landscape_image,image.full_url"
            options = {'media_type':media_type.lower(), 'filter':filterx, 'fields':fields, 'limit':'64', 'offset':int(offset)}
            request = self.makeAPIRequest('list_series', options)
            if request['error'] is False:
                    counter = 0
                    for series in request['data']:
                            counter = counter + 1
                            year = 'None' if series['year'] is None else series['year'] #only available on some series
                            description = '' if series['description'] is None else series['description'].encode('utf-8') #Adding sinopses
                            thumb = '' if (series['portrait_image'] is None or series['portrait_image']['large_url'] is None or 'portrait_image' not in series or 'large_url' not in series['portrait_image']) else series['portrait_image']['full_url'] #Becuase not all series have a thumbnail. 
                            art = '' if (series['landscape_image'] is None or series['landscape_image']['full_url'] is None or 'landscape_image' not in series or 'full_url' not in series['landscape_image']) else series['landscape_image']['full_url'] #Becuase not all series have art. 
                            rating = '0' if (series['rating'] == '' or 'rating' not in series) else series['rating'] #Because Crunchyroll seems to like passing series without ratings
                            if ('media_count' in series and 'series_id' in series and 'name' in series and series['media_count'] > 0): #Because Crunchyroll seems to like passing series without these things
                                crunchy_main.UI().addItem({'Title':series['name'].encode("utf8"),'mode':'list_coll', 'series_id':series['series_id'], 'count':str(series['media_count']), 'Thumb':thumb, 'Fanart_Image':art, 'plot':description, 'year':year}, True) 
                    if counter >= 64:
                            offset = (int(offset) + counter)
                            crunchy_main.UI().addItem({'Title':'...load more','mode':'list_series','showtype':media_type,'filterx':filterx, 'offset':str(offset)})

            crunchy_main.UI().endofdirectory('none')
Example #6
0
        def loadShelf(self):
                try:
                        self.base_path = xbmc.translatePath(__settings__.getAddonInfo('profile')).decode('utf-8')
                        self.base_cache_path = os.path.join(self.base_path, "cache")
                        if not os.path.exists(self.base_cache_path):
                                os.makedirs(self.base_cache_path)
                        shelf_path = os.path.join(self.base_path, "cruchyXBMC")
                        #Load Persistan Vars
                        userData = shelve.open(shelf_path,writeback=True)
                        local_string = __settings__.getLocalizedString
                        notice_msg = local_string(30200).encode("utf8")
                        setup_msg = local_string(30203).encode("utf8")
                        acc_type_error = local_string(30312).encode("utf8")
                        change_language = __settings__.getSetting("change_language")
                        if change_language == "0":
                                userData.setdefault('API_LOCALE',"enUS")
                        elif change_language == "1":
                                userData['API_LOCALE']  = "enUS"
                        elif change_language == "2":
                                userData['API_LOCALE']  = "enGB"
                        elif change_language == "3":
                                userData['API_LOCALE']  = "jaJP"
                        elif change_language == "4":
                                userData['API_LOCALE']  = "frFR"
                        elif change_language == "5":
                                userData['API_LOCALE']  = "deDE"
                        elif change_language == "6":
                                userData['API_LOCALE']  = "ptBR"
                        elif change_language == "7":
                                userData['API_LOCALE']  = "ptPT"
                        elif change_language == "8":
                                userData['API_LOCALE']  = "esLA"
                        elif change_language == "9":
                                userData['API_LOCALE']  = "esES"
                        userData['username'] = __settings__.getSetting("crunchy_username")
                        userData['password'] = __settings__.getSetting("crunchy_password")
                        if not userData.has_key('device_id'):
                                char_set = string.ascii_letters + string.digits
                                device_id = ''.join(random.sample(char_set,32))
                                userData["device_id"] = device_id
                                xbmc.log("Crunchyroll;xbmc ----> New device_id created. New device_id is: "+ str(device_id))
                        userData['API_URL'] = "https://api.crunchyroll.com"
                        userData['API_HEADERS'] = [('User-Agent',"Mozilla/5.0 (PLAYSTATION 3; 4.46)"), ('Host',"api.crunchyroll.com"), ('Accept-Encoding',"gzip, deflate"), ('Accept',"*/*"), ('Content-Type',"application/x-www-form-urlencoded")]
                        userData['API_VERSION'] = "1.0.1"
                        userData['API_ACCESS_TOKEN'] = "S7zg3vKx6tRZ0Sf"
                        userData['API_DEVICE_TYPE'] = "com.crunchyroll.ps3"
                        userData.setdefault('premium_type', 'UNKNOWN')
                        current_datetime = datetime.datetime.now(dateutil.tz.tzutc())
                        userData.setdefault('lastreported', (current_datetime - dateutil.relativedelta.relativedelta( hours = +24 )))
                        self.userData = userData
                except:
                        xbmc.log( "Unexpected error:", sys.exc_info())
                        userData['session_id'] = ''
                        userData['auth_expires'] = current_datetime - dateutil.relativedelta.relativedelta( hours = +24 )
                        userData['lastreported'] = current_datetime - dateutil.relativedelta.relativedelta( hours = +24 )
                        userData['premium_type'] = 'UNKNOWN'
                        userData['auth_token'] = ''
                        userData['session_expires'] = current_datetime - dateutil.relativedelta.relativedelta( hours = +24 )
                        self.userData = userData
                        userData.close()
                        xbmc.log( "Crunchyroll -> Unable to Load shelve")
                        return False

                #Check to see if a session_id doesn't exist or if the current auth token is invalid and if so start a new session and log it in.                   
                if (not userData.has_key('session_id')) or (not userData.has_key('auth_expires')) or current_datetime > userData['auth_expires']:
                        #Start new session
                        xbmc.log( "Crunchyroll;xbmc ----> Starting new session")
                        opener = urllib2.build_opener()
                        opener.addheaders = userData['API_HEADERS']
                        options = urllib.urlencode({'device_id':userData["device_id"], 'device_type':userData['API_DEVICE_TYPE'], 'access_token':userData['API_ACCESS_TOKEN'], 'version':userData['API_VERSION'], 'locale': userData['API_LOCALE']})
                        urllib2.install_opener(opener)
                        url = userData['API_URL']+"/start_session.0.json"
                        req = opener.open(url, options)
                        json_data = req.read()
                        if req.headers.get('content-encoding', None) == 'gzip':
				json_data = gzip.GzipFile(fileobj=StringIO.StringIO(json_data)).read().decode('utf-8','ignore')
			req.close()
                        request = json.loads(json_data)  
                        if request['error'] is False:
                                userData['session_id'] = request['data']['session_id'] 
                                userData['session_expires'] = (current_datetime + dateutil.relativedelta.relativedelta( hours = +4 ))
                                userData['test_session'] = current_datetime 
                                xbmc.log( "Crunchyroll.bundle ----> New session created! Session ID is: "+ str(userData['session_id']))
                        elif request['error'] is True:
                                xbmc.log( "Crunchyroll.bundle ----> Error starting new session. Error message is: "+ str(request['message']))
                                return False
                        #Login the session we just started.
                        if not userData['username'] or not userData['password']:
                                xbmc.log("Crunchyroll.bundle ----> No Username or Password set")
                                self.userData = userData
                                userData.close()
                                ex = 'XBMC.Notification("'+notice_msg+':","'+setup_msg+'.", 3000)'
                                xbmc.executebuiltin(ex)
                                xbmc.log( "crunchyroll-takeout -> NO CRUNCHYROLL ACCOUNT FOUND!")
                                return False
                        else: 
                                xbmc.log("Crunchyroll.bundle ----> Logging in the new session we just created.")
                                opener = urllib2.build_opener()
                                opener.addheaders = userData['API_HEADERS']
                                options = urllib.urlencode({'session_id':userData['session_id'], 'password':userData['password'], 'account':userData['username'], 'version':userData['API_VERSION'], 'locale': userData['API_LOCALE']})
                                url = userData['API_URL']+"/login.0.json"
                                req = opener.open(url, options)
                                json_data = req.read()
                                if req.headers.get('content-encoding', None) == 'gzip':
                                        json_data = gzip.GzipFile(fileobj=StringIO.StringIO(json_data)).read().decode('utf-8','ignore')
                                req.close()
                                request = json.loads(json_data) 
                                if request['error'] is False:
                                        userData['auth_token'] = request['data']['auth'] 
                                        userData['auth_expires'] = dateutil.parser.parse(request['data']['expires'])
                                        userData['premium_type'] = 'free' if request['data']['user']['premium'] == '' else request['data']['user']['premium']
                                        xbmc.log("Crunchyroll.bundle ----> Login successful.")
                                elif request['error'] is True:
                                        xbmc.log("Crunchyroll.bundle ----> Error logging in new session. Error message was: "+ str(request['message']))
                                        self.userData = userData
                                        userData.close()
                                        return False
                        #Call for Usage Reporting
                        if current_datetime > userData['lastreported']:
                                userData['lastreported'] = (current_datetime + dateutil.relativedelta.relativedelta( hours = +24 ))
                                self.userData = userData
                                self.usage_reporting() 
                        #Verify user is premium
                        if userData['premium_type'] in 'anime|drama|manga':
                                xbmc.log("Crunchyroll.bundle ----> User is a premium "+str(userData['premium_type'])+" member.")
                                self.userData = userData
                                userData.close()
                                return True
                        else:
                                xbmc.log("Crunchyroll.bundle ----> User is not premium. ")
                                xbmc.executebuiltin('Notification('+notice_msg+','+acc_type_error+',5000)')
                                self.userData = userData = None
                                userData.close()
                                crunchy_main.UI().addItem({'Title':acc_type_error, 'mode':'Fail'})
                                crunchy_main.UI().endofdirectory('none')
                                return False

                #Check to see if a valid session and auth token exist and if so reinitialize a new session using the auth token. 
                elif userData.has_key("session_id") and userData.has_key("auth_expires") and current_datetime < userData['auth_expires'] and current_datetime > userData['session_expires']:

                        #Re-start new session
                        xbmc.log( "Crunchyroll.bundle ----> Valid auth token was detected. Restarting session.")
                        opener = urllib2.build_opener()
                        options = urllib.urlencode({'device_id':userData["device_id"], 'device_type':userData['API_DEVICE_TYPE'], 'access_token':userData['API_ACCESS_TOKEN'], 'version':userData['API_VERSION'], 'locale': userData['API_LOCALE'], 'auth':userData['auth_token']})
                        urllib2.install_opener(opener)
                        url = userData['API_URL']+"/start_session.0.json"
                        req = opener.open(url, options)
                        json_data = req.read()
                        if req.headers.get('content-encoding', None) == 'gzip':
				json_data = gzip.GzipFile(fileobj=StringIO.StringIO(json_data)).read().decode('utf-8','ignore')
			req.close()
                        request = json.loads(json_data)  
                        try:
                                if request['error'] is False:
                                        userData['session_id'] = request['data']['session_id'] 
                                        userData['auth_expires'] = dateutil.parser.parse(request['data']['expires']) 
                                        userData['premium_type'] = 'free' if request['data']['user']['premium'] == '' else request['data']['user']['premium']
                                        userData['auth_token'] = request['data']['auth'] 
                                        userData['session_expires'] = (current_datetime + dateutil.relativedelta.relativedelta( hours = +4 )) #4 hours is a guess. Might be +/- 4.
                                        userData['test_session'] = current_datetime 
                                        xbmc.log("Crunchyroll.bundle ----> Session restart successful. New session_id is: "+ str(userData['session_id']))
                                        #Call for Usage Reporting
                                        if current_datetime > userData['lastreported']:
                                                userData['lastreported'] = (current_datetime + dateutil.relativedelta.relativedelta( hours = +24 ))
                                                self.userData = userData
                                                self.usage_reporting() 
                                                
                                        #Verify user is premium
                                        if userData['premium_type'] in 'anime|drama|manga':
                                                xbmc.log("Crunchyroll.bundle ----> User is a premium "+str(userData['premium_type'])+" member.")
                                                self.userData = userData
                                                userData.close()
                                                return True
                                        else:
                                                xbmc.log("Crunchyroll.bundle ----> User is not premium.")
                                                xbmc.executebuiltin('Notification('+notice_msg+','+acc_type_error+',5000)')
                                                self.userData = userData = None
                                                userData.close()
                                                crunchy_main.UI().addItem({'Title':acc_type_error, 'mode':'Fail'})
                                                crunchy_main.UI().endofdirectory('none')
                                                return False

                                elif request['error'] is True:
                                        #Remove userData so we start a new session next time around. 
                                        del userData['session_id']
                                        del userData['auth_expires']
                                        del userData['premium_type']
                                        del userData['auth_token']
                                        del userData['session_expires']
                                        xbmc.log("Crunchyroll.bundle ----> Error restarting session. Error message was: "+ str(request['message']))
                                        self.userData = userData
                                        userData.Save()
                                        return False
                        except:
                                userData['session_id'] = ''
                                userData['auth_expires'] = current_datetime - dateutil.relativedelta.relativedelta( hours = +24 )
                                userData['premium_type'] = 'unknown'
                                userData['auth_token'] = ''
                                userData['session_expires'] = current_datetime - dateutil.relativedelta.relativedelta( hours = +24 )
                                xbmc.log("Crunchyroll.bundle ----> Error restarting session. Error message was: "+ str(request['message']))
                                self.userData = userData
                                userData.Save()
                                return False
                        

                #If we got to this point that means a session exists and it's still valid, we don't need to do anything.
                elif userData.has_key("session_id") and current_datetime < userData['session_expires']:
                    #This secion below is Stupid Slow
                        #return True
                        if userData['test_session'] is None or current_datetime > userData['test_session']:
                                userData['test_session'] = (current_datetime + dateutil.relativedelta.relativedelta( minutes = +10 )) #test once every 10 min 
                                #Test to make sure the session still works. (Sometimes sessions just stop working.) 
                                fields = "media.episode_number,media.name,media.description,media.media_type,media.series_name,media.available,media.available_time,media.free_available,media.free_available_time,media.duration,media.url,media.screenshot_image,image.fwide_url,image.fwidestar_url,series.landscape_image,image.full_url"
                                options = {'media_types':"anime|drama", 'fields':fields}
                                request = self.makeAPIRequest('queue', options)
                                if request['error'] is False:	
                                        xbmc.log("Crunchyroll.bundle ----> A valid session was detected. Using existing session_id of: "+ str(userData['session_id']))
                                        #Call for Usage Reporting
                                        if current_datetime > userData['lastreported']:
                                                userData['lastreported'] = (current_datetime + dateutil.relativedelta.relativedelta( hours = +24 ))
                                                self.userData = userData
                                                self.usage_reporting() 
                                        #Verify user is premium
                                        if userData['premium_type'] in 'anime|drama|manga':
                                                xbmc.log("Crunchyroll.bundle ----> User is a premium "+str(userData['premium_type'])+" member.")
                                                self.userData = userData
                                                userData.close()
                                                return True
                                        else:
                                                xbmc.log("Crunchyroll.bundle ----> User is not premium.")
                                                xbmc.executebuiltin('Notification('+notice_msg+','+acc_type_error+',5000)')
                                                self.userData = userData = None
                                                userData.close()
                                                crunchy_main.UI().addItem({'Title':acc_type_error, 'mode':'Fail'})
                                                crunchy_main.UI().endofdirectory('none')
                                                return False					
                                elif request['error'] is True:
                                        xbmc.log("Crunchyroll.bundle ----> Something in the login process went wrong.")
                                        del userData['session_id']
                                        del userData['auth_expires']
                                        del userData['premium_type']
                                        del userData['auth_token']
                                        del userData['session_expires']
                                        self.userData = userData
                                        userData.close()	
                                        return False

                 
                
                #This is here as a catch all in case something gets messed up along the way. Remove userData variables so we start a new session next time around. 
                else:
                        del userData['session_id']
                        del userData['auth_expires']
                        del userData['premium_type']
                        del userData['auth_token']
                        del userData['session_expires']
                        xbmc.log("Crunchyroll.bundle ----> Something in the login process went wrong.")
                        self.userData = userData
                        userData.close()	
                        return False