def menu_albums(params):

    # get connection
    connection = get_connection()

    if connection == False:
        return

    listing = []

    menus = {
        'albums_newest': {
            'name': Addon().get_localized_string(30023),
            'thumb': None,
            'args': {
                "ltype": "newest"
            }
        },
        'albums_frequent': {
            'name': Addon().get_localized_string(30024),
            'thumb': None,
            'args': {
                "ltype": "frequent"
            }
        },
        'albums_recent': {
            'name': Addon().get_localized_string(30025),
            'thumb': None,
            'args': {
                "ltype": "recent"
            }
        },
        'albums_random': {
            'name': Addon().get_localized_string(30026),
            'thumb': None,
            'args': {
                "ltype": "random"
            }
        }
    }

    # Iterate through albums

    for menu_id in menus:

        menu = menus.get(menu_id)

        # image
        if 'thumb' in menu:
            thumb = menu.get('thumb')

        listing.append({
            'label':
            menu.get('name'),
            'thumb':
            menu.get('thumb'),  # Item thumbnail
            'fanart':
            menu.get('thumb'),  # Item thumbnail
            'url':
            plugin.get_url(action='list_albums',
                           page=1,
                           query_args=json.dumps(menu.get('args')),
                           menu_id=menu_id)
        })  # Item label

    add_directory_items(create_listing(listing, ))
def download_tracks(ids):

    #popup is fired before, in download_item
    download_folder = Addon().get_setting('download_folder')
    if not download_folder:
        return

    if not ids:
        return False

    #make list
    if not isinstance(ids, list) or isinstance(ids, tuple):
        ids = [ids]

    ids_count = len(ids)

    #check if empty
    if ids_count == 0:
        return False

    plugin.log('download_tracks IDs:')
    plugin.log(json.dumps(ids))

    # get connection
    connection = get_connection()

    if connection is False:
        return

    #progress...
    pc_step = 100 / ids_count
    pc_progress = 0
    ids_parsed = 0
    progressdialog = xbmcgui.DialogProgress()
    progressdialog.create("Downloading tracks...")  #Title

    for id in ids:

        if (progressdialog.iscanceled()):
            return False

        # debug
        plugin.log('Trying to download track #' + str(id))

        # get track infos
        response = connection.getSong(id)
        track = response.get('song')
        plugin.log('Track info :')
        plugin.log(track)

        # progress bar
        pc_progress = ids_parsed * pc_step
        progressdialog.update(pc_progress, 'Getting track informations...',
                              get_entry_track_label(track))

        track_path_relative = track.get("path", None).encode(
            'utf8', 'replace')  # 'Radiohead/Kid A/Idioteque.mp3'
        track_path = os.path.join(
            download_folder, track_path_relative
        )  # 'C:/users/.../Radiohead/Kid A/Idioteque.mp3'
        track_directory = os.path.dirname(
            os.path.abspath(track_path))  # 'C:/users/.../Radiohead/Kid A'

        #check if file exists
        if os.path.isfile(track_path):

            progressdialog.update(pc_progress,
                                  'Track has already been downloaded!')
            plugin.log("File '%s' already exists" % (id))

        else:

            progressdialog.update(pc_progress, "Downloading track...",
                                  track_path)

            try:
                #get remote file (file-object like)
                file_obj = connection.download(id)

                #create directory if it does not exists
                if not os.path.exists(track_directory):
                    os.makedirs(track_directory)

                #create blank file
                file = open(
                    track_path, 'a'
                )  #create a new file but don't erase the existing one if it exists

                #fill blank file
                shutil.copyfileobj(file_obj, file)
                file.close()

            except:
                popup("Error while downloading track #%s" % (id))
                plugin.log("Error while downloading track #%s" % (id))
                pass

        ids_parsed += 1

    progressdialog.update(100, "Done !", "Enjoy !")
    xbmc.sleep(1000)
    progressdialog.close()
Example #3
0
# coding: utf-8
# Created on: 24.03.2016
# Author: Roman Miroshnychenko aka Roman V.M. ([email protected])

import os
import re
import cPickle as pickle
from traceback import format_exc
from requests import post
from simpleplugin import Addon
from torrent_info import get_torrents, OrderedDict, check_proper

addon = Addon('plugin.video.rk.tv')
yatp_addon = Addon('plugin.video.yatp')

filters_file = os.path.join(addon.config_dir, 'filters.pcl')
json_rpc_url = 'http://127.0.0.1:{0}/json-rpc'.format(yatp_addon.server_port)


def download_torrent(torrent, save_path):
    """
    Download torrent via YATP
    """
    post(json_rpc_url,
         json={
             'method': 'add_torrent',
             'params': {
                 'torrent': torrent,
                 'save_path': save_path,
                 'paused': False
             }
 def test_addon_instance_creation(self):
     addon = Addon('test.addon')
     self.assertEqual(addon.id, 'test.addon')
     self.assertTrue(os.path.exists(os.path.join(cwd, 'config')))
def star_item(params):

    ids = params.get('ids')
    #can be single or lists of IDs
    unstar = params.get('unstar', False)
    unstar = (unstar) and (unstar != 'None') and (unstar != 'False'
                                                  )  #TO FIX better statement ?
    type = params.get('type')
    sids = albumIds = artistIds = None

    #validate type
    if type == 'track':
        sids = ids
    elif type == 'artist':
        artistIds = ids
    elif type == 'album':
        albumIds = ids

    #validate capability
    if not can_star(type, ids):
        return

    #validate IDs
    if (not sids and not artistIds and not albumIds):
        return

    # get connection
    connection = get_connection()

    if connection is False:
        return

    ###

    did_action = False

    try:
        if unstar:
            request = connection.unstar(sids, albumIds, artistIds)
        else:
            request = connection.star(sids, albumIds, artistIds)

        if request['status'] == 'ok':
            did_action = True

    except:
        pass

    ###

    if did_action:

        if unstar:
            message = Addon().get_localized_string(30091)
            plugin.log('Unstarred %s #%s' % (type, json.dumps(ids)))
        else:  #star
            message = Addon().get_localized_string(30092)
            plugin.log('Starred %s #%s' % (type, json.dumps(ids)))

        stars_cache_update(ids, unstar)

        popup(message)

        #TO FIX clear starred lists caches ?
        #TO FIX refresh current list after star set ?

    else:
        if unstar:
            plugin.log_error('Unable to unstar %s #%s' %
                             (type, json.dumps(ids)))
        else:
            plugin.log_error('Unable to star %s #%s' % (type, json.dumps(ids)))

    return did_action
Example #6
0
# coding: utf-8
# Module: json_requests
# Created on: 17.07.2015
# Author: Roman Miroshnychenko aka Roman V.M. ([email protected])
# Licence: GPL v.3: http://www.gnu.org/copyleft/gpl.html
"""
JSON-RPC requests to the Torrent Server
"""

from requests import post
from simpleplugin import Addon

addon = Addon('plugin.video.yatp')
json_rpc_url = 'http://127.0.0.1:{0}/json-rpc'.format(addon.server_port)


def _request(data):
    """
    Send JSON-RPC request

    :param data: JSON request as dict
    :return:
    """
    reply = post(json_rpc_url, json=data).json()
    try:
        return reply['result']
    except KeyError:
        raise RuntimeError('JSON-RPC returned error:\n{0}'.format(
            reply['error']))

Example #7
0
def menu_albums(params):

    # get connection
    connection = get_connection()

    if connection is False:
        return

    listing = []

    menus = {
        'albums_newest': {
            'name': Addon().get_localized_string(30023),
            'thumb': None,
            'args': {
                "ltype": "newest"
            }
        },
        'albums_frequent': {
            'name': Addon().get_localized_string(30024),
            'thumb': None,
            'args': {
                "ltype": "frequent"
            }
        },
        'albums_recent': {
            'name': Addon().get_localized_string(30025),
            'thumb': None,
            'args': {
                "ltype": "recent"
            }
        },
        'albums_random': {
            'name': Addon().get_localized_string(30026),
            'thumb': None,
            'args': {
                "ltype": "random"
            }
        }
    }

    # Iterate through categories

    for menu_id in menus:

        menu = menus.get(menu_id)

        # image
        if 'thumb' in menu:
            thumb = menu.get('thumb')

        listing.append({
            'label':
            menu.get('name'),
            'thumb':
            menu.get('thumb'),  # Item thumbnail
            'fanart':
            menu.get('thumb'),  # Item thumbnail
            'url':
            plugin.get_url(action='list_albums',
                           page=1,
                           query_args=json.dumps(menu.get('args')),
                           menu_id=menu_id)
        })  # Item label

    return plugin.create_listing(
        listing,
        #succeeded = True, #if False Kodi won’t open a new listing and stays on the current level.
        #update_listing = False, #if True, Kodi won’t open a sub-listing but refresh the current one.
        #cache_to_disk = True, #cache this view to disk.
        #sort_methods = None, #he list of integer constants representing virtual folder sort methods.
        #view_mode = None, #a numeric code for a skin view mode. View mode codes are different in different skins except for 50 (basic listing).
        #content = None #string - current plugin content, e.g. ‘movies’ or ‘episodes’.
    )
def list_tracks(params):

    menu_id = params.get('menu_id')
    listing = []

    #query
    query_args = {}
    try:
        query_args_json = params['query_args']
        query_args = json.loads(query_args_json)
    except:
        pass

    #size
    tracks_per_page = int(Addon().get_setting('tracks_per_page'))
    query_args["size"] = tracks_per_page

    #offset
    offset = int(params.get('page', 1)) - 1
    if offset > 0:
        query_args["offset"] = offset * tracks_per_page

    #debug
    query_args_json = json.dumps(query_args)
    plugin.log('list_tracks with args:' + query_args_json)

    # get connection
    connection = get_connection()

    if connection is False:
        return

    # Album
    if 'album_id' in params:
        generator = connection.walk_album(params['album_id'])

    # Playlist
    elif 'playlist_id' in params:
        generator = connection.walk_playlist(params['playlist_id'])
##########TO FIX
#        tracknumber = 0
#        for item in items:
#            tracknumber += 1
#            items[item]['tracknumber'] = tracknumber

# Top tracks
    elif menu_id == 'tracks_top':
        generator = connection.walk_tracks_top(query_args['artist'])

    # Starred
    elif menu_id == 'tracks_starred':
        generator = connection.walk_tracks_starred()

    # Random
    elif menu_id == 'tracks_random':
        generator = connection.walk_tracks_random(**query_args)

    #make a list out of the generator so we can iterate it several times
    items = list(generator)

    #check if there is only one artist for this album (and then hide it)
    artists = [item.get('artist', None) for item in items]
    if len(artists) <= 1:
        params['hide_artist'] = True

    #update stars
    if menu_id == 'tracks_starred':
        ids_list = [item.get('id') for item in items]
        stars_cache_update(ids_list)

    # Iterate through items
    key = 0
    for item in items:
        track = get_entry_track(item, params)
        listing.append(track)
        key += 1


######TO FIX    # Pagination if we've not reached the end of the list
# if type(items) != type(True): TO FIX
#link_next = navigate_next(params)
#listing.append(link_next)

    return plugin.create_listing(listing,
                                 cache_to_disk=False,
                                 sort_methods=get_sort_methods(
                                     'tracks', params),
                                 view_mode=Addon().get_setting('view_song'),
                                 content='songs')
Example #9
0
def download_media(params):

    from slugify import slugify

    #validate path
    download_folder = Addon().get_setting('download_folder')

    if not download_folder:
        common.popup(
            "Veuillez configurer un répertoire de téléchargement dans les paramètres du plugin"
        )
        common.plugin.log_error("download_media: No directory set")
        return False

    #get media details
    mid = int(params.get('media_id', None))
    media = api.get_media_details(mid)
    media_title = media.get('title')
    media_subtitle = media.get('subtitle')

    #media URL
    stream_node = media.get('url_streaming')

    if stream_node:
        media_url = stream_node.get('url', '').encode('utf-8').strip()

    if not media_url:
        common.plugin.log_error("unable to get a downloadable stream URL.")
        common.popup("Impossible de trouver un flux media téléchargeable")
        return False

    #filename
    remote_path = urlparse.urlparse(media_url).path  #full path
    remote_file = media_url.rsplit('/', 1)[-1]  #only what's after the last '/'
    remote_filename = os.path.splitext(remote_file)[0]
    remote_ext = os.path.splitext(remote_file)[1]

    if media_subtitle:
        file_title = "%s - %s" % (media_title, media_subtitle)
    else:
        file_title = media_title

    file_title = slugify(file_title)

    file_name = file_title + remote_ext
    file_path = xbmc.makeLegalFilename(os.path.join(download_folder,
                                                    file_name))
    file_path = urllib2.unquote(file_path)

    common.plugin.log("download_media #{0} - filename:{1} - from:{2}".format(
        mid, file_name, media_url))

    # Overwrite existing file?
    if os.path.isfile(file_path):

        do_override = common.ask(
            'Le fichier [B]%s[/B] existe déjà.  Écraser ?' % (file_name))

        if not do_override:
            return

    # Download
    size = 1024 * 1024
    start = time.clock()
    f = open(file_path, 'wb')
    u = urllib2.urlopen(media_url)
    bytes_so_far = 0
    error = False

    # Get file size
    try:
        total_size = u.info().getheader('Content-Length').strip()
        total_size = int(total_size)
    except AttributeError:
        total_size = 0  # a response doesn't always include the "Content-Length" header

    if total_size < 1:
        common.popup(
            "Erreur lors du téléchargement: Impossible de déterminer la taille du fichier."
        )
        return False

    # Progress dialog
    progressdialog = xbmcgui.DialogProgress()
    progressdialog.create("Téléchargement du média...")  #Title

    while True:

        # Aborded by user
        if progressdialog.iscanceled():
            error = True
            break

        try:

            buff = u.read(size)
            if not buff:
                break
            else:
                bytes_so_far += len(buff)
                f.write(buff)

                percent = min(100 * bytes_so_far / total_size, 100)
                speed_str = str(
                    int((bytes_so_far / 1024) /
                        (time.clock() - start))) + ' KB/s'
                percent_str = str(percent) + '%'
                progressdialog.update(percent, file_name, percent_str,
                                      speed_str)

        except Exception, e:
            error = True
            break
Example #10
0
def media_to_kodi_item(media):

    #common.plugin.log(json.dumps(media))

    context_actions = []  #context menu actions

    #MEDIA
    mid = media.get('id')
    media_type = media.get('type')
    is_livevideo = (media_type == 'livevideo')
    kodi_type = utils.get_kodi_media_type(media)
    has_drm = media.get('drm')

    #build label
    title = media.get('title', '').encode('utf-8').strip()
    subtitle = media.get('subtitle', '').encode('utf-8').strip()
    channel_node = media.get('channel')

    if channel_node:
        channel = channel_node.get('label', '').encode('utf-8').strip()
        title = "[B]{0}[/B] - {1}".format(channel, title)

    if subtitle:
        title = "{0} - [I]{1}[/I]".format(title, subtitle)

    #Add 'DRM' prefix
    if has_drm and Addon().get_setting('drm_title_prefix'):
        title = "[COLOR red]DRM[/COLOR] " + title

    #live video
    if is_livevideo:
        if utils.media_is_streaming(media):
            title += ' [COLOR yellow]direct[/COLOR]'
        else:
            stream_start = utils.get_stream_start_date_formatted(
                media.get('start_date', None))
            title += ' [COLOR red]' + stream_start + '[/COLOR]'

    #MEDIA INFOS
    #http://romanvm.github.io/script.module.simpleplugin/_actions/vf.html
    #http://kodi.wiki/view/InfoLabels#ListItem

    infos = {}
    info_details = {
        #'date':         utils.datetime_W3C_to_kodi(media.get('date_publish_from')), #file date
        'count': media.get(
            'id'
        ),  #can be used to store an id for later, or for sorting purposes
        'duration': utils.get_kodi_media_duration(media),
    }

    if kodi_type == 'video':

        video_infos = {
            'aired':
            utils.datetime_W3C_to_kodi(media.get('date_publish_from')),
            'genre': media.get('category', {}).get('label',
                                                   '').encode('utf-8'),
            'plot': media.get('description',
                              '').encode('utf-8'),  #Long Description
            'plotoutline': media.get('description',
                                     '').encode('utf-8'),  #Short Description
        }

        #parse args
        info_details = utils.parse_dict_args(info_details, video_infos)

        infos = {'video': info_details}

    elif kodi_type == 'music':
        music_infos = {
            'genre': media.get('category', {}).get('label').encode('utf-8'),
        }

        #parse args
        info_details = utils.parse_dict_args(info_details, music_infos)

        infos = {'music': info_details}

    #download context menu
    if not is_livevideo and not has_drm:
        download_action = (
            'Télécharger', 'XBMC.RunPlugin(%s)' %
            common.plugin.get_url(action='download_media', media_id=mid))
        context_actions.append(download_action)

    li = {
        'label':
        title,
        'label2':
        subtitle,
        'thumb':
        media.get('images',
                  {}).get('cover', {}).get('1x1',
                                           {}).get('370x370',
                                                   '').encode('utf-8').strip(),
        'fanart':
        media.get('images',
                  {}).get('illustration',
                          {}).get('16x9', {}).get('1920x1080',
                                                  '').encode('utf-8').strip(),
        'url':
        common.plugin.get_url(action='play_media',
                              media_id=mid,
                              livevideo=is_livevideo),
        'info':
        infos,
        'is_playable':
        True,
        'context_menu':
        context_actions
    }

    return li
def root(params):

    # get connection
    connection = get_connection()

    if connection == False:
        return

    listing = []

    menus = {
        'folders': {
            'name': Addon().get_localized_string(30038),
            'callback': 'browse_folders',
            'thumb': None
        },
        'library': {
            'name': Addon().get_localized_string(30019),
            'callback': 'browse_library',
            'thumb': None
        },
        'albums': {
            'name': Addon().get_localized_string(30020),
            'callback': 'menu_albums',
            'thumb': None
        },
        'tracks': {
            'name': Addon().get_localized_string(30021),
            'callback': 'menu_tracks',
            'thumb': None
        },
        'playlists': {
            'name': Addon().get_localized_string(30022),
            'callback': 'list_playlists',
            'thumb': None
        },
        'search': {
            'name': Addon().get_localized_string(30039),
            'callback': 'search',
            'thumb': None
        },
    }

    # Iterate through categories

    for mid in menus:

        # image
        if 'thumb' in menus[mid]:
            thumb = menus[mid]['thumb']

        listing.append({
            'label':
            menus[mid]['name'],
            'thumb':
            thumb,  # Item thumbnail
            'fanart':
            thumb,  # Item thumbnail
            'url':
            plugin.get_url(action=menus[mid]['callback'], menu_id=mid)
        })  # Item label

    add_directory_items(create_listing(
        listing,
        sort_methods=None,
    ))
def list_tracks(params):

    menu_id = params.get('menu_id')
    listing = []

    #query
    query_args = {}
    try:
        query_args_json = params['query_args']
        query_args = json.loads(query_args_json)
    except:
        pass

    #size
    tracks_per_page = int(Addon().get_setting('tracks_per_page'))
    query_args["size"] = tracks_per_page

    #offset
    offset = int(params.get('page', 1)) - 1
    if offset > 0:
        query_args["offset"] = offset * tracks_per_page

    #debug
    query_args_json = json.dumps(query_args)
    plugin.log('list_tracks with args:' + query_args_json)

    # get connection
    connection = get_connection()

    if connection == False:
        return

    # Album
    if 'album_id' in params:
        generator = walk_album(params['album_id'])

    # Playlist
    elif 'playlist_id' in params:
        generator = walk_playlist(params['playlist_id'])

        #TO FIX
        #tracknumber = 0
        #for item in items:
        #    tracknumber += 1
        #    items[item]['tracknumber'] = tracknumber

    # Starred
    elif menu_id == 'tracks_starred':
        generator = walk_tracks_starred()

    # Random
    elif menu_id == 'tracks_random':
        generator = walk_tracks_random(**query_args)
    # Filters
    #else:
    #TO WORK

    #make a list out of the generator so we can iterate it several times
    items = list(generator)

    #check if there==only one artist for this album (and then hide it)
    artists = [item.get('artist', None) for item in items]
    if len(artists) <= 1:
        params['hide_artist'] = True

    #update stars
    if menu_id == 'tracks_starred':
        ids_list = [item.get('id') for item in items]
        #stars_local_update(ids_list)
        cache_refresh(True)

    # Iterate through items
    key = 0
    for item in items:
        track = get_entry_track(item, params)
        listing.append(track)
        key += 1

    # Root menu
    #link_root = navigate_root()
    #listing.append(link_root)

    # Pagination if we've not reached the end of the lsit
    # if type(items) != type(True): TO FIX
    #link_next = navigate_next(params)
    #listing.append(link_next)

    add_directory_items(
        create_listing(
            listing,
            sort_methods=get_sort_methods('tracks', params),
            content=
            'songs'  #string - current plugin content, e.g. ‘movies’ or ‘episodes’.
        ))
def list_albums(params):
    """
    List albums from the library (ID3 tags)
    """

    listing = []

    # get connection
    connection = get_connection()

    if connection == False:
        return

    #query
    query_args = {}
    try:
        query_args_json = params['query_args']
        query_args = json.loads(query_args_json)
    except:
        pass

    #size
    albums_per_page = int(Addon().get_setting('albums_per_page'))
    query_args["size"] = albums_per_page

    #offset
    offset = int(params.get('page', 1)) - 1
    if offset > 0:
        query_args["offset"] = offset * albums_per_page

    #debug
    query_args_json = json.dumps(query_args)
    plugin.log('list_albums with args:' + query_args_json)

    #Get items
    if 'artist_id' in params:
        generator = walk_artist(params.get('artist_id'))
    else:
        generator = walk_albums(**query_args)

    #make a list out of the generator so we can iterate it several times
    items = list(generator)

    #check if there==only one artist for this album (and then hide it)
    artists = [item.get('artist', None) for item in items]
    if len(artists) <= 1:
        params['hide_artist'] = True

    # Iterate through items
    for item in items:
        album = get_entry_album(item, params)
        listing.append(album)

    # Root menu
    link_root = navigate_root()
    listing.append(link_root)

    if not 'artist_id' in params:
        # Pagination if we've not reached the end of the lsit
        # if type(items) != type(True): TO FIX
        link_next = navigate_next(params)
        listing.append(link_next)

    add_directory_items(
        create_listing(
            listing,
            cache_to_disk=True,  #cache this view to disk.
            sort_methods=get_sort_methods('albums', params),
            content=
            'albums'  #string - current plugin content, e.g. ‘movies’ or ‘episodes’.
        ))
def list_directory(params):
    connection = get_connection()

    if connection is False:
        return

    listing = []

    # Get items
    id = params.get('id')
    items = connection.walk_directory_nonrecursive(id)
    dircount = 0
    songcount = 0

    # Iterate through items
    for item in items:
        genre_setting = item.get('genre') if (
            Addon().get_setting('view_genre')) else None

        # Is a directory
        if (item.get('isDir') == True):
            dircount += 1
            entry = {
                'label':
                item.get('title'),
                'url':
                plugin.get_url(action='list_directory',
                               id=item.get('id'),
                               menu_id=params.get('menu_id')),
                'thumb':
                connection.getCoverArtUrl(item.get('coverArt')),
                'icon':
                'DefaultMusicAlbums.png',
                'info': {
                    'music': {
                        'mediatype': 'album',
                        'year': item.get('year'),
                        'artist': item.get('artist'),
                        'rating': item.get('starred'),
                        'genre': genre_setting
                    }
                }
            }
            listing.append(entry)

        # Songs or a combination of both
        else:
            songcount += 1
            entry = get_entry_track(item, params)
            listing.append(entry)

        # Set view, sort and content
        if (dircount == 0):
            view_mode_setting = Addon().get_setting('view_song')
            sort_mode = get_sort_methods('tracks', params)
            content_mode = 'songs'
        if (songcount == 0):
            view_mode_setting = Addon().get_setting('view_album')
            sort_mode = get_sort_methods('albums', params)
            content_mode = 'albums'

        else:
            view_mode_setting = Addon().get_setting('view_song')
            sort_mode = get_sort_methods('tracks', params)
            content_mode = 'songs'

    # Only show in artist directory, maybe check results first?
    if (songcount == 0) and params.get('menu_id') == 'folders':
        topsongs = {
            'label':
            item.get('artist') + '\'s top songs',
            'url':
            plugin.get_url(
                action='list_tracks',
                query_args=json.dumps({
                    'artist':
                    item.get('artist'),
                    'count':
                    Addon().get_setting('tracks_per_page'),
                }),
                menu_id='tracks_top',
            ),
            'thumb':
            'DefaultMusicTop100.png',
            'info': {
                'music': {
                    'mediatype': 'album',
                    'artist': item.get('artist'),
                }
            }
        }
        listing.append(topsongs)
        """
     artist_radio = {
                'label':    item.get('artist') + ' radio',
                'url':      plugin.get_url(
                            action=     'list_tracks',
                            id=         item.get('id'),
                            menu_id=    'artist_radio'
                            ),
                'thumb':    'DefaultMusicCompilations.png',  
                'info': {
                    'music': {            
                              'mediatype': 'album',
                              'artist':    item.get('artist'),     
                              }           
                    }
                }
     listing.append(artist_radio)
     """
    return plugin.create_listing(
        listing,
        cache_to_disk=True,
        sort_methods=sort_mode,
        view_mode=view_mode_setting,
        content=content_mode,
    )
Example #15
0
def root(params):

    # get connection
    connection = get_connection()

    if connection is False:
        return

    listing = []

    menus = {
        'folders': {
            'name': Addon().get_localized_string(30038),
            'callback': 'browse_folders',
            'thumb': None
        },
        'library': {
            'name': Addon().get_localized_string(30019),
            'callback': 'browse_library',
            'thumb': None
        },
        'albums': {
            'name': Addon().get_localized_string(30020),
            'callback': 'menu_albums',
            'thumb': None
        },
        'tracks': {
            'name': Addon().get_localized_string(30021),
            'callback': 'menu_tracks',
            'thumb': None
        },
        'playlists': {
            'name': Addon().get_localized_string(30022),
            'callback': 'list_playlists',
            'thumb': None
        },
        'search': {
            'name': Addon().get_localized_string(30039),
            'callback': 'search',
            'thumb': None
        },
    }

    # Iterate through categories

    for mid in menus:

        # image
        if 'thumb' in menus[mid]:
            thumb = menus[mid]['thumb']

        listing.append({
            'label':
            menus[mid]['name'],
            'thumb':
            thumb,  # Item thumbnail
            'fanart':
            thumb,  # Item thumbnail
            'url':
            plugin.get_url(action=menus[mid]['callback'], menu_id=mid)
        })  # Item label

    return plugin.create_listing(
        listing,
        #succeeded = True, #if False Kodi won’t open a new listing and stays on the current level.
        #update_listing = False, #if True, Kodi won’t open a sub-listing but refresh the current one.
        #cache_to_disk = True, #cache this view to disk.
        sort_methods=
        None,  #he list of integer constants representing virtual folder sort methods.
        #view_mode = None, #a numeric code for a skin view mode. View mode codes are different in different skins except for 50 (basic listing).
        #content = None #string - current plugin content, e.g. ‘movies’ or ‘episodes’.
    )
def list_albums(params):

    #List albums from the library (ID3 tags)
    listing = []

    connection = get_connection()

    if connection is False:
        return

    #query
    query_args = {}
    try:
        query_args_json = params['query_args']
        query_args = json.loads(query_args_json)
    except:
        pass

    #Size, defined in settings
    albums_per_page = int(Addon().get_setting('albums_per_page'))
    query_args["size"] = albums_per_page

    #offset
    offset = int(params.get('page', 1)) - 1
    if offset > 0:
        query_args["offset"] = offset * albums_per_page

    #debug
    query_args_json = json.dumps(query_args)
    plugin.log('list_albums with args:' + query_args_json)

    #Get items
    if 'artist_id' in params:
        generator = connection.walk_artist(params.get('artist_id'))
    else:
        generator = connection.walk_albums(**query_args)

    #make a list out of the generator so we can iterate it several times
    items = list(generator)

    #coverart first in random album list if setting is true
    if Addon().get_setting('coverart_first') and params.get(
            'menu_id') == 'albums_random':
        items = coverart_first(items)

    #check if there is only one artist for this album (and then hide it)
    artists = [item.get('artist', None) for item in items]
    if len(artists) <= 1:
        params['hide_artist'] = True

    # Iterate through items
    for item in items:
        album = get_entry_album(item, params)
        listing.append(album)

    if not 'artist_id' in params:
        ####TO FIX Pagination if we've not reached the end of the lsit
        ########### if type(items) != type(True): TO FIX
        link_next = navigate_next(params)
        listing.append(link_next)

    return plugin.create_listing(listing,
                                 cache_to_disk=True,
                                 sort_methods=get_sort_methods(
                                     'albums', params),
                                 view_mode=Addon().get_setting('view_album'),
                                 content='albums')
Example #17
0
            xbmcaddon.Addon("plugin.audio.subsonic").getAddonInfo("path"),
            "lib")))

import libsonic_extra  #TO FIX - we should get rid of this and use only libsonic

from simpleplugin import Plugin
from simpleplugin import Addon

# Create plugin instance
plugin = Plugin()

# initialize_gettext
#_ = plugin.initialize_gettext()

connection = None
cachetime = int(Addon().get_setting('cachetime'))


def popup(text, time=5000, image=None):
    title = plugin.addon.getAddonInfo('name')
    icon = plugin.addon.getAddonInfo('icon')
    xbmc.executebuiltin('Notification(%s, %s, %d, %s)' %
                        (title, text, time, icon))


def get_connection():
    global connection

    if connection is None:

        connected = False
def get_search_results(params):
    # get connection
    connection = get_connection()

    if connection is False:
        return

    query_args = json.loads(params['query_args'])
    maxitems = int(
        Addon().get_setting('tracks_per_page' if query_args['type'] ==
                            "track" else 'albums_per_page'))

    # Get items
    # This uses the same maximum amount for all types, but since we only use the one we're interested in that's ok.
    items = connection.search2(query=query_args['query'],
                               artistCount=maxitems,
                               artistOffset=maxitems * params['page'],
                               albumCount=maxitems,
                               albumOffset=maxitems * params['page'],
                               songCount=maxitems,
                               songOffset=maxitems * params['page'],
                               musicFolderId=None)

    itemfunc = {
        "get_entry_artist": get_entry_artist,
        "get_entry_album": get_entry_album,
        "get_entry_track": get_entry_track,
    }
    listing = []
    # Maybe we should refactor "track" functions to "song" some day to stay in line with subsonic API lingo
    type = "song" if query_args['type'] == "track" else query_args['type']
    # Iterate through items
    if type in items['searchResult2']:
        for item in items.get('searchResult2').get(type):
            entry = itemfunc['get_entry_{0}'.format(query_args['type'])](
                item, params)
            listing.append(entry)

        prev = navigate_prev(params)
        if prev:
            listing.append(prev)
            maxitems += 1
        # TODO: check that there are actually more results available
        if len(listing) == maxitems:
            listing.append(navigate_next(params))
    else:
        d = xbmcgui.Dialog().ok(
            Addon().get_localized_string(30062),  # Search
            Addon().get_localized_string(30088)  # No items found
        )
        return

    if query_args['type'] == "track":
        content = 'songs'
        view_mode_setting = Addon().get_setting('view_song')
    elif query_args['type'] == "album":
        content = 'albums'
        view_mode_setting = Addon().get_setting('view_album')
    else:
        content = 'artists'
        view_mode_setting = Addon().get_setting('view_artist')

    return plugin.create_listing(
        listing,
        update_listing=not params.get('firstEntry', False),
        view_mode=view_mode_setting,
        content=content,
    )
Example #19
0
def list_albums(params):

    listing = []

    # get connection
    connection = get_connection()

    if connection is False:
        return

    #query
    query_args = {}
    try:
        query_args_json = params['query_args']
        query_args = json.loads(query_args_json)
    except:
        pass

    #size
    albums_per_page = int(Addon().get_setting('albums_per_page'))
    query_args["size"] = albums_per_page

    #offset
    offset = int(params.get('page', 1)) - 1
    if offset > 0:
        query_args["offset"] = offset * albums_per_page

    #debug
    query_args_json = json.dumps(query_args)
    plugin.log('list_albums with args:' + query_args_json)

    #Get items
    if 'artist_id' in params:
        generator = connection.walk_artist(params.get('artist_id'))
    else:
        generator = connection.walk_albums(**query_args)

    #make a list out of the generator so we can iterate it several times
    items = list(generator)

    #check if there is only one artist for this album (and then hide it)
    artists = [item.get('artist', None) for item in items]
    if len(artists) <= 1:
        params['hide_artist'] = True

    # Iterate through items
    for item in items:
        album = get_entry_album(item, params)
        listing.append(album)

    # Root menu
    link_root = navigate_root()
    listing.append(link_root)

    if not 'artist_id' in params:
        # Pagination if we've not reached the end of the lsit
        # if type(items) != type(True): TO FIX
        link_next = navigate_next(params)
        listing.append(link_next)

    return plugin.create_listing(
        listing,
        #succeeded = True, #if False Kodi won’t open a new listing and stays on the current level.
        #update_listing = False, #if True, Kodi won’t open a sub-listing but refresh the current one.
        cache_to_disk=True,  #cache this view to disk.
        sort_methods=get_sort_methods('albums', params),
        #view_mode = None, #a numeric code for a skin view mode. View mode codes are different in different skins except for 50 (basic listing).
        content=
        'albums'  #string - current plugin content, e.g. ‘movies’ or ‘episodes’.
    )
def root(params):

    # get connection
    connection = get_connection()

    if connection is False:
        return

    listing = []

    if Addon().get_setting('merge_folders') == True:
        mediafolders = Addon().get_localized_string(30060)
        thumbnail = 'DefaultMusicArtists.png'
    else:
        mediafolders = Addon().get_localized_string(30059)
        thumbnail = None

    menus = {
        'folders': {
            'name': mediafolders,
            'callback': 'browse_folders',
            'thumb': thumbnail,
            'fanart': None,
        },
        'playlists': {
            'name': Addon().get_localized_string(30061),
            'callback': 'list_playlists',
            'thumb': 'DefaultMusicPlaylists.png',
            'fanart': None,
        },
        'search': {
            'name': Addon().get_localized_string(30062),
            'callback': 'search',
            'thumb': 'DefaultAddonsSearch.png',
            'fanart': None,
        },
    }
    # Iterate through categories
    for mid in menus:

        if 'thumb' in menus[mid]:
            thumb = menus[mid]['thumb']

        listing.append({
            'label':
            menus[mid]['name'],
            'thumb':
            thumb,
            'fanart':
            None,
            'url':
            plugin.get_url(action=menus[mid]['callback'], menu_id=mid)
        })

    menus = {
        'albums_newest': {
            'name': Addon().get_localized_string(30070),
            'thumb': 'DefaultMusicRecentlyAdded.png',
            'args': {
                "ltype": "newest"
            },
            'fanart': None,
        },
        'albums_frequent': {
            'name': Addon().get_localized_string(30071),
            'thumb': 'DefaultMusicTop100Albums.png',
            'args': {
                "ltype": "frequent"
            },
            'fanart': None,
        },
        'albums_recent': {
            'name': Addon().get_localized_string(30072),
            'thumb': 'DefaultMusicRecentlyPlayed.png',
            'args': {
                "ltype": "recent"
            },
            'fanart': None,
        },
        'albums_random': {
            'name': Addon().get_localized_string(30073),
            'thumb': 'DefaultMusicAlbums.png',
            'args': {
                "ltype": "random"
            },
            'fanart': None,
        }
    }
    # Iterate through albums
    for menu_id in menus:

        menu = menus.get(menu_id)

        if 'thumb' in menu:
            thumb = menu.get('thumb')

        listing.append({
            'label':
            menu.get('name'),
            'thumb':
            menu.get('thumb'),
            'url':
            plugin.get_url(action='list_albums',
                           page=1,
                           query_args=json.dumps(menu.get('args')),
                           menu_id=menu_id)
        })

    menus = {
        'tracks_starred': {
            'name': Addon().get_localized_string(30080),
            'thumb': 'DefaultMusicTop100Songs.png',
            'fanart': None,
        },
        'tracks_random': {
            'name': Addon().get_localized_string(30081),
            'thumb': 'DefaultMusicSongs.png',
            'fanart': None,
        }
    }
    # Iterate through tracks
    for menu_id in menus:

        menu = menus.get(menu_id)

        if 'thumb' in menu:
            thumb = menu.get('thumb')

        listing.append({
            'label':
            menu.get('name'),
            'thumb':
            menu.get('thumb'),
            'url':
            plugin.get_url(action='list_tracks', menu_id=menu_id)
        })

    return plugin.create_listing(
        listing,
        cache_to_disk=True,
        sort_methods=None,
        view_mode=None,
        content='mixed',
    )
Example #21
0
def list_tracks(params):

    menu_id = params.get('menu_id')
    listing = []

    #query
    query_args = {}
    try:
        query_args_json = params['query_args']
        query_args = json.loads(query_args_json)
    except:
        pass

    #size
    tracks_per_page = int(Addon().get_setting('tracks_per_page'))
    query_args["size"] = tracks_per_page

    #offset
    offset = int(params.get('page', 1)) - 1
    if offset > 0:
        query_args["offset"] = offset * tracks_per_page

    #debug
    query_args_json = json.dumps(query_args)
    plugin.log('list_tracks with args:' + query_args_json)

    # get connection
    connection = get_connection()

    if connection is False:
        return

    # Album
    if 'album_id' in params:
        generator = connection.walk_album(params['album_id'])

    # Playlist
    elif 'playlist_id' in params:
        generator = connection.walk_playlist(params['playlist_id'])

        #TO FIX
        #tracknumber = 0
        #for item in items:
        #    tracknumber += 1
        #    items[item]['tracknumber'] = tracknumber

    # Starred
    # Starred
    elif menu_id == 'tracks_starred':
        generator = connection.walk_tracks_starred()

    # Random
    elif menu_id == 'tracks_random':
        generator = connection.walk_tracks_random(**query_args)
    # Filters
    #else:
    #TO WORK

    #make a list out of the generator so we can iterate it several times
    items = list(generator)

    #check if there is only one artist for this album (and then hide it)
    artists = [item.get('artist', None) for item in items]
    if len(artists) <= 1:
        params['hide_artist'] = True

    #update stars
    if menu_id == 'tracks_starred':
        ids_list = [item.get('id') for item in items]
        stars_cache_update(ids_list)

    # Iterate through items
    key = 0
    for item in items:
        track = get_entry_track(item, params)
        listing.append(track)
        key += 1

    # Root menu
    #link_root = navigate_root()
    #listing.append(link_root)

    # Pagination if we've not reached the end of the lsit
    # if type(items) != type(True): TO FIX
    #link_next = navigate_next(params)
    #listing.append(link_next)

    return plugin.create_listing(
        listing,
        #succeeded = True, #if False Kodi won’t open a new listing and stays on the current level.
        #update_listing = False, #if True, Kodi won’t open a sub-listing but refresh the current one.
        #cache_to_disk = True, #cache this view to disk.
        sort_methods=get_sort_methods('tracks', params),
        #view_mode = None, #a numeric code for a skin view mode. View mode codes are different in different skins except for 50 (basic listing).
        content=
        'songs'  #string - current plugin content, e.g. ‘movies’ or ‘episodes’.
    )
 def test_gettext_initialized(self):
     addon = Addon()
     _ = addon.initialize_gettext()
     self.assertEqual(_('Hello World!'), u'Привет, мир!')
     self.assertEqual(_('I love you.'), u'Я тебя люблю.')
     self.assertRaises(SimplePluginError, _, 'Foo Bar')
def navigate_root():
    return {
        'label': Addon().get_localized_string(30030),
        'url': plugin.get_url(action='root')
    }
Example #24
0
# Author: Roman V.M.
# Created on: 12.05.2015
# License: GPL v.3 https://www.gnu.org/copyleft/gpl.html
"""
Buffering torrent
"""

import os
from urllib import quote
import xbmc
import xbmcgui
import json_requests as jsonrq
from simpleplugin import Addon


addon = Addon()
_ = addon.initialize_gettext()
media_url = 'http://127.0.0.1:{0}/stream/'.format(addon.server_port)
MEDIAFILES = ('.avi', '.mkv', '.mp4', '.ts', '.m2ts', '.mov', '.m4v', '.wmv')


def get_videofiles(files):
    """
    Get a sorted list of videofiles from all files in a torrent

    :param files:
    :return: the sorted list of 3-item tuples (file_index, file_name, file_size)
    """
    videofiles = []
    for file_index, file_ in enumerate(files):
        if os.path.splitext(file_[0].lower())[1] in MEDIAFILES:
def context_action_download(type, id):

    label = Addon().get_localized_string(30095)

    return (label, 'XBMC.RunPlugin(%s)' %
            plugin.get_url(action='download_item', type=type, id=id))
 def test_gettext_not_initialized(self):
     addon = Addon()
     self.assertRaises(SimplePluginError, addon.gettext, 'Hello World!')
Example #27
0
def download_media(params):
    
    from slugify import slugify
    
    title=  params.get('title');
    url=    params.get('url');
    
    #validate path
    download_folder = Addon().get_setting('download_folder')
    
    if not download_folder:
        common.popup("Veuillez configurer un répertoire de téléchargement dans les paramètres du plugin")
        common.plugin.log_error("download_media: No directory set")
        return False

    if not url:
        common.popup("Impossible de télécharger ce média")
        plugin.log_error("download_media: Missing URL")
        return False

    #filename
    remote_path = urlparse.urlparse(url).path #full path
    remote_file = url.rsplit('/', 1)[-1] #only what's after the last '/'
    remote_filename = os.path.splitext(remote_file)[0]
    remote_ext = os.path.splitext(remote_file)[1]
    
    file_name = slugify(title) + remote_ext
    file_path = xbmc.makeLegalFilename(os.path.join(download_folder, file_name))
    file_path = urllib2.unquote(file_path)

    common.plugin.log('download_media - filename: %s from %s' % (file_name,url))
    
    # Overwrite existing file?
    if os.path.isfile(file_path):
        
        do_override = common.ask('Le fichier [B]%s[/B] existe déjà.  Écraser ?' % (file_name)) 

        if not do_override:
            return

    # Download
    size = 1024 * 1024
    start = time.clock()
    f = open(file_path, 'wb')
    u = urllib2.urlopen(url)
    bytes_so_far = 0
    error = False

    # Get file size
    try:
        total_size = u.info().getheader('Content-Length').strip()
        total_size = int(total_size)
    except AttributeError:
        total_size = 0 # a response doesn't always include the "Content-Length" header
        
    if total_size < 1:
        common.popup("Erreur lors du téléchargement: Impossible de déterminer la taille du fichier.")
        return False
    
    # Progress dialog
    progressdialog = xbmcgui.DialogProgress()
    progressdialog.create("Téléchargement du média...") #Title

    while True:
        
        # Aborded by user
        if (progressdialog.iscanceled()):
            error = True
            break
        
        try:
            
            buff = u.read(size)
            if not buff:
                break
            else:
                bytes_so_far += len(buff)
                f.write(buff)

                percent = min(100 * bytes_so_far / total_size, 100)
                speed_str = str(int((bytes_so_far / 1024) / (time.clock() - start))) + ' KB/s'
                percent_str = str(percent) + '%'
                progressdialog.update(percent, file_name,percent_str,speed_str)
                    
        except Exception, e:
            error = True
            break