Exemple #1
0
    def hasAccess(self):
        # Plex: always return True for now
        return True
        # hasAccess is verified in service.py
        log = self.logMsg
        window = utils.window

        url = "{server}/emby/Users?format=json"
        result = self.doUtils.downloadUrl(url)

        if result == False:
            # Access is restricted, set in downloadutils.py via exception
            log("Access is restricted.", 1)
            self.HasAccess = False

        elif window('emby_online') != "true":
            # Server connection failed
            pass

        elif window('emby_serverStatus') == "restricted":
            log("Access is granted.", 1)
            self.HasAccess = True
            window('emby_serverStatus', clear=True)
            xbmcgui.Dialog().notification(self.addonName,
                                          utils.language(33007))
Exemple #2
0
    def hasAccess(self):
        # Plex: always return True for now
        return True
        # hasAccess is verified in service.py
        log = self.logMsg
        window = utils.window

        url = "{server}/emby/Users?format=json"
        result = self.doUtils.downloadUrl(url)

        if result == False:
            # Access is restricted, set in downloadutils.py via exception
            log("Access is restricted.", 1)
            self.HasAccess = False

        elif window('emby_online') != "true":
            # Server connection failed
            pass

        elif window('emby_serverStatus') == "restricted":
            log("Access is granted.", 1)
            self.HasAccess = True
            window('emby_serverStatus', clear=True)
            xbmcgui.Dialog().notification(self.addonName,
                                          utils.language(33007))
Exemple #3
0
    def singleNode(self, indexnumber, tagname, mediatype, itemtype):

        window = utils.window

        tagname = tagname.encode('utf-8')
        cleantagname = utils.normalize_nodes(tagname)
        nodepath = xbmc.translatePath(
            "special://profile/library/video/").decode('utf-8')
        nodeXML = "%splex_%s.xml" % (nodepath, cleantagname)
        path = "library://video/plex_%s.xml" % cleantagname
        windowpath = "ActivateWindow(Video,%s,return)" % path

        # Create the video node directory
        if not xbmcvfs.exists(nodepath):
            # We need to copy over the default items
            shutil.copytree(
                src=xbmc.translatePath(
                    "special://xbmc/system/library/video").decode('utf-8'),
                dst=xbmc.translatePath(
                    "special://profile/library/video").decode('utf-8'))
            xbmcvfs.exists(path)

        labels = {
            'Favorite movies': 30180,
            'Favorite tvshows': 30181,
            'channels': 30173
        }
        label = utils.language(labels[tagname])
        embynode = "Emby.nodes.%s" % indexnumber
        window('%s.title' % embynode, value=label)
        window('%s.path' % embynode, value=windowpath)
        window('%s.content' % embynode, value=path)
        window('%s.type' % embynode, value=itemtype)

        if xbmcvfs.exists(nodeXML):
            # Don't recreate xml if already exists
            return

        if itemtype == "channels":
            root = self.commonRoot(order=1,
                                   label=label,
                                   tagname=tagname,
                                   roottype=2)
            etree.SubElement(
                root, 'path'
            ).text = "plugin://plugin.video.plexkodiconnect/?id=0&mode=channels"
        else:
            root = self.commonRoot(order=1, label=label, tagname=tagname)
            etree.SubElement(root, 'order', {
                'direction': "ascending"
            }).text = "sorttitle"

        etree.SubElement(root, 'content').text = mediatype

        try:
            utils.indent(root)
        except:
            pass
        etree.ElementTree(root).write(nodeXML)
    def singleNode(self, indexnumber, tagname, mediatype, itemtype):

        window = utils.window

        tagname = utils.tryEncode(tagname)
        cleantagname = utils.normalize_nodes(tagname)
        nodepath = utils.tryDecode(xbmc.translatePath(
            "special://profile/library/video/"))
        nodeXML = "%splex_%s.xml" % (nodepath, cleantagname)
        path = "library://video/plex_%s.xml" % cleantagname
        windowpath = "ActivateWindow(Video,%s,return)" % path

        # Create the video node directory
        if not xbmcvfs.exists(nodepath):
            # We need to copy over the default items
            shutil.copytree(
                src=utils.tryDecode(xbmc.translatePath(
                    "special://xbmc/system/library/video")),
                dst=utils.tryDecode(xbmc.translatePath(
                    "special://profile/library/video")))
            xbmcvfs.exists(path)

        labels = {

            'Favorite movies': 30180,
            'Favorite tvshows': 30181,
            'channels': 30173
        }
        label = utils.language(labels[tagname])
        embynode = "Emby.nodes.%s" % indexnumber
        window('%s.title' % embynode, value=label)
        window('%s.path' % embynode, value=windowpath)
        window('%s.content' % embynode, value=path)
        window('%s.type' % embynode, value=itemtype)

        if xbmcvfs.exists(nodeXML):
            # Don't recreate xml if already exists
            return

        if itemtype == "channels":
            root = self.commonRoot(order=1, label=label, tagname=tagname, roottype=2)
            etree.SubElement(root, 'path').text = "plugin://plugin.video.plexkodiconnect/?id=0&mode=channels"
        else:
            root = self.commonRoot(order=1, label=label, tagname=tagname)
            etree.SubElement(root, 'order', {'direction': "ascending"}).text = "sorttitle"

        etree.SubElement(root, 'content').text = mediatype

        try:
            utils.indent(root)
        except: pass
        etree.ElementTree(root).write(nodeXML)
    def hasAccess(self):
        # hasAccess is verified in service.py
        window = utils.window

        result = self.doUtils.downloadUrl("{server}/emby/Users?format=json")

        if result == False:
            # Access is restricted, set in downloadutils.py via exception
            self.logMsg("Access is restricted.", 1)
            self.HasAccess = False

        elif window('emby_online') != "true":
            # Server connection failed
            pass

        elif window('emby_serverStatus') == "restricted":
            self.logMsg("Access is granted.", 1)
            self.HasAccess = True
            window('emby_serverStatus', clear=True)
            xbmcgui.Dialog().notification("Emby for Kodi", utils.language(33007))
Exemple #6
0
    def client_update(self):
        self.update_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM,
                                         socket.IPPROTO_UDP)
        update_sock = self.update_sock

        # Set socket reuse, may not work on all OSs.
        try:
            update_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        except:
            pass

        # Attempt to bind to the socket to recieve and send data.  If we cant
        # do this, then we cannot send registration
        try:
            update_sock.bind(('0.0.0.0', self.client_update_port))
        except:
            log.error("Unable to bind to port [%s] - Plex Companion will not "
                      "be registered. Change the Plex Companion update port!" %
                      self.client_update_port)
            if settings('companion_show_gdm_port_warning') == 'true':
                if dialog(
                        'yesno',
                        language(29999),
                        'Port %s' % self.client_update_port,
                        language(39079),
                        yeslabel=language(30013),  # Never show again
                        nolabel=language(30012)):  # OK
                    settings('companion_show_gdm_port_warning', value='false')
                from xbmc import executebuiltin
                executebuiltin(
                    'Addon.OpenSettings(plugin.video.plexkodiconnect)')
            return

        update_sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 255)
        update_sock.setsockopt(
            socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP,
            socket.inet_aton(self._multicast_address) +
            socket.inet_aton('0.0.0.0'))
        update_sock.setblocking(0)

        # Send initial client registration
        self.register_as_client()

        # Now, listen format client discovery reguests and respond.
        while self._registration_is_running:
            try:
                data, addr = update_sock.recvfrom(1024)
                log.debug("Recieved UDP packet from [%s] containing [%s]" %
                          (addr, data.strip()))
            except socket.error:
                pass
            else:
                if "M-SEARCH * HTTP/1." in data:
                    log.debug("Detected client discovery request from %s. "
                              " Replying" % str(addr))
                    try:
                        update_sock.sendto(
                            "HTTP/1.0 200 OK\n%s" % self.client_data, addr)
                    except:
                        log.error("Unable to send client update message")

                    log.debug("Sending registration data HTTP/1.0 200 OK")
                    self.client_registered = True
            sleep(500)
        log.info("Client Update loop stopped")
        # When we are finished, then send a final goodbye message to
        # deregister cleanly.
        log.debug("Sending registration data: BYE %s\n%s" %
                  (self.client_header, self.client_data))
        try:
            update_sock.sendto(
                "BYE %s\n%s" % (self.client_header, self.client_data),
                self.client_register_group)
        except:
            log.error("Unable to send client update message")
        self.client_registered = False
    def viewNode(self, indexnumber, tagname, mediatype, viewtype, delete=False):

        kodiversion = self.kodiversion

        if mediatype == "homevideos":
            # Treat homevideos as movies
            mediatype = "movies"

        tagname = tagname.encode('utf-8')
        cleantagname = utils.normalize_nodes(tagname)
        if viewtype == "mixed":
            dirname = "%s - %s" % (cleantagname, mediatype)
        else:
            dirname = cleantagname
        
        path = xbmc.translatePath("special://profile/library/video/").decode('utf-8')
        nodepath = xbmc.translatePath(
                    "special://profile/library/video/Emby - %s/" % dirname).decode('utf-8')

        # Verify the video directory
        if not xbmcvfs.exists(path):
            shutil.copytree(
                src=xbmc.translatePath("special://xbmc/system/library/video/").decode('utf-8'),
                dst=xbmc.translatePath("special://profile/library/video/").decode('utf-8'))
            xbmcvfs.exists(path)

        # Create the node directory
        if not xbmcvfs.exists(nodepath):
            # We need to copy over the default items
            xbmcvfs.mkdirs(nodepath)
        else:
            if delete:
                dirs, files = xbmcvfs.listdir(nodepath)
                for file in files:
                    xbmcvfs.delete(nodepath + file)

                self.logMsg("Sucessfully removed videonode: %s." % tagname, 1)
                return

        # Create index entry
        nodeXML = "%sindex.xml" % nodepath
        # Set windows property
        path = "library://video/Emby - %s/" % dirname
        for i in range(1, indexnumber):
            # Verify to make sure we don't create duplicates
            if utils.window('Emby.nodes.%s.index' % i) == path:
                return

        utils.window('Emby.nodes.%s.index' % indexnumber, value=path)
        # Root
        root = self.commonRoot(order=0, label=dirname, tagname=tagname, roottype=0)
        try:
            utils.indent(root)
        except: pass
        etree.ElementTree(root).write(nodeXML)


        nodetypes = {

            '1': "all",
            '2': "recent",
            '3': "recentepisodes",
            '4': "inprogress",
            '5': "inprogressepisodes",
            '6': "unwatched",
            '7': "nextupepisodes",
            '8': "sets",
            '9': "genres",
            '10': "random",
            '11': "recommended"
        }
        mediatypes = {
            # label according to nodetype per mediatype
            'movies': {
                '1': tagname,
                '2': 30174,
                '4': 30177,
                '6': 30189,
                '8': 20434,
                '9': 135,
                '10': 30229,
                '11': 30230},

            'tvshows': {
                '1': tagname,
                '2': 30170,
                '3': 30175,
                '4': 30171,
                '5': 30178,
                '7': 30179,
                '9': 135,
                '10': 30229,
                '11': 30230},
        }

        nodes = mediatypes[mediatype]
        for node in nodes:

            nodetype = nodetypes[node]
            nodeXML = "%s%s_%s.xml" % (nodepath, cleantagname, nodetype)
            # Get label
            stringid = nodes[node]
            if node != '1':
                label = utils.language(stringid)
                if not label:
                    label = xbmc.getLocalizedString(stringid)
            else:
                label = stringid

            # Set window properties
            if nodetype == "nextupepisodes":
                # Custom query
                path = "plugin://plugin.video.emby/?id=%s&mode=nextup&limit=25" % tagname
            elif kodiversion == 14 and nodetype == "recentepisodes":
                # Custom query
                path = "plugin://plugin.video.emby/?id=%s&mode=recentepisodes&limit=25" % tagname
            elif kodiversion == 14 and nodetype == "inprogressepisodes":
                # Custom query
                path = "plugin://plugin.video.emby/?id=%s&mode=inprogressepisodes&limit=25"% tagname
            else:
                path = "library://video/Emby - %s/%s_%s.xml" % (dirname, cleantagname, nodetype)
            windowpath = "ActivateWindow(Video, %s, return)" % path
            
            if nodetype == "all":

                if viewtype == "mixed":
                    templabel = dirname
                else:
                    templabel = label

                embynode = "Emby.nodes.%s" % indexnumber
                utils.window('%s.title' % embynode, value=templabel)
                utils.window('%s.path' % embynode, value=windowpath)
                utils.window('%s.content' % embynode, value=path)
                utils.window('%s.type' % embynode, value=mediatype)
            else:
                embynode = "Emby.nodes.%s.%s" % (indexnumber, nodetype)
                utils.window('%s.title' % embynode, value=label)
                utils.window('%s.path' % embynode, value=windowpath)
                utils.window('%s.content' % embynode, value=path)

            if xbmcvfs.exists(nodeXML):
                # Don't recreate xml if already exists
                continue


            # Create the root
            if nodetype == "nextupepisodes" or (kodiversion == 14 and
                                        nodetype in ('recentepisodes', 'inprogressepisodes')):
                # Folder type with plugin path
                root = self.commonRoot(order=node, label=label, tagname=tagname, roottype=2)
                etree.SubElement(root, 'path').text = path
                etree.SubElement(root, 'content').text = "episodes"
            else:
                root = self.commonRoot(order=node, label=label, tagname=tagname)
                if nodetype in ('recentepisodes', 'inprogressepisodes'):
                    etree.SubElement(root, 'content').text = "episodes"
                else:
                    etree.SubElement(root, 'content').text = mediatype

                limit = "25"
                # Elements per nodetype
                if nodetype == "all":
                    etree.SubElement(root, 'order', {'direction': "ascending"}).text = "sorttitle"
                
                elif nodetype == "recent":
                    etree.SubElement(root, 'order', {'direction': "descending"}).text = "dateadded"
                    etree.SubElement(root, 'limit').text = limit
                    rule = etree.SubElement(root, 'rule', {'field': "playcount", 'operator': "is"})
                    etree.SubElement(rule, 'value').text = "0"
                
                elif nodetype == "inprogress":
                    etree.SubElement(root, 'rule', {'field': "inprogress", 'operator': "true"})
                    etree.SubElement(root, 'limit').text = limit

                elif nodetype == "genres":
                    etree.SubElement(root, 'order', {'direction': "ascending"}).text = "sorttitle"
                    etree.SubElement(root, 'group').text = "genres"
                
                elif nodetype == "unwatched":
                    etree.SubElement(root, 'order', {'direction': "ascending"}).text = "sorttitle"
                    rule = etree.SubElement(root, "rule", {'field': "playcount", 'operator': "is"})
                    etree.SubElement(rule, 'value').text = "0"

                elif nodetype == "sets":
                    etree.SubElement(root, 'order', {'direction': "ascending"}).text = "sorttitle"
                    etree.SubElement(root, 'group').text = "sets"

                elif nodetype == "random":
                    etree.SubElement(root, 'order', {'direction': "ascending"}).text = "random"
                    etree.SubElement(root, 'limit').text = limit

                elif nodetype == "recommended":
                    etree.SubElement(root, 'order', {'direction': "descending"}).text = "rating"
                    etree.SubElement(root, 'limit').text = limit
                    rule = etree.SubElement(root, 'rule', {'field': "playcount", 'operator': "is"})
                    etree.SubElement(rule, 'value').text = "0"
                    rule2 = etree.SubElement(root, 'rule',
                        attrib={'field': "rating", 'operator': "greaterthan"})
                    etree.SubElement(rule2, 'value').text = "7"

                elif nodetype == "recentepisodes":
                    # Kodi Isengard, Jarvis
                    etree.SubElement(root, 'order', {'direction': "descending"}).text = "dateadded"
                    etree.SubElement(root, 'limit').text = limit
                    rule = etree.SubElement(root, 'rule', {'field': "playcount", 'operator': "is"})
                    etree.SubElement(rule, 'value').text = "0"

                elif nodetype == "inprogressepisodes":
                    # Kodi Isengard, Jarvis
                    etree.SubElement(root, 'limit').text = "25"
                    rule = etree.SubElement(root, 'rule',
                        attrib={'field': "inprogress", 'operator':"true"})

            try:
                utils.indent(root)
            except: pass
            etree.ElementTree(root).write(nodeXML)
Exemple #8
0
    def viewNode(self,
                 indexnumber,
                 tagname,
                 mediatype,
                 viewtype,
                 viewid,
                 delete=False):
        # Plex: reassign mediatype due to Kodi inner workings
        # How many items do we get at most?
        limit = "100"
        mediatypes = {
            'movie': 'movies',
            'show': 'tvshows',
            'photo': 'photos',
            'homevideo': 'homevideos',
            'musicvideos': 'musicvideos'
        }
        mediatype = mediatypes[mediatype]

        window = utils.window
        kodiversion = self.kodiversion

        if viewtype == "mixed":
            dirname = "%s-%s" % (viewid, mediatype)
        else:
            dirname = viewid

        path = xbmc.translatePath("special://profile/library/video/").decode(
            'utf-8')
        nodepath = xbmc.translatePath(
            "special://profile/library/video/Plex-%s/" %
            dirname).decode('utf-8')

        # Verify the video directory
        # KODI BUG
        # Kodi caches the result of exists for directories
        #  so try creating a file
        if utils.IfExists(path) is False:
            shutil.copytree(
                src=xbmc.translatePath(
                    "special://xbmc/system/library/video").decode('utf-8'),
                dst=xbmc.translatePath(
                    "special://profile/library/video").decode('utf-8'))

        # Create the node directory
        if mediatype != "photo":
            if utils.IfExists(nodepath) is False:
                # folder does not exist yet
                self.logMsg('Creating folder %s' % nodepath, 1)
                xbmcvfs.mkdirs(nodepath.encode('utf-8'))
                if delete:
                    dirs, files = xbmcvfs.listdir(nodepath.encode('utf-8'))
                    for file in files:
                        xbmcvfs.delete(
                            (nodepath + file.decode('utf-8')).encode('utf-8'))

                    self.logMsg("Sucessfully removed videonode: %s." % tagname,
                                1)
                    return

        # Create index entry
        nodeXML = "%sindex.xml" % nodepath
        # Set windows property
        path = "library://video/Plex-%s/" % dirname
        for i in range(1, indexnumber):
            # Verify to make sure we don't create duplicates
            if window('Emby.nodes.%s.index' % i) == path:
                return

        if mediatype == "photo":
            path = "plugin://plugin.video.plexkodiconnect/?id=%s&mode=getsubfolders" % indexnumber

        window('Emby.nodes.%s.index' % indexnumber, value=path)

        # Root
        if not mediatype == "photo":
            if viewtype == "mixed":
                specialtag = "%s-%s" % (tagname, mediatype)
                root = self.commonRoot(order=0,
                                       label=specialtag,
                                       tagname=tagname,
                                       roottype=0)
            else:
                root = self.commonRoot(order=0,
                                       label=tagname,
                                       tagname=tagname,
                                       roottype=0)
            try:
                utils.indent(root)
            except:
                pass
            etree.ElementTree(root).write(nodeXML)

        nodetypes = {
            '1': "all",
            '2': "recent",
            '3': "recentepisodes",
            '4': "inprogress",
            '5': "inprogressepisodes",
            '6': "unwatched",
            '7': "nextepisodes",
            '8': "sets",
            '9': "genres",
            '10': "random",
            '11': "recommended",
            '12': "ondeck"
        }
        mediatypes = {
            # label according to nodetype per mediatype
            'movies': {
                '1': tagname,
                '2': 30174,
                # '4': 30177,
                # '6': 30189,
                '8': 39501,
                '9': 135,
                '10': 30227,
                '11': 30230,
                '12': 39500,
            },
            'tvshows': {
                '1': tagname,
                # '2': 30170,
                '3': 30174,
                # '4': 30171,
                # '5': 30178,
                # '7': 30179,
                '9': 135,
                '10': 30227,
                # '11': 30230,
                '12': 39500,
            },
            'homevideos': {
                '1': tagname,
                '2': 30251,
                '11': 30253
            },
            'photos': {
                '1': tagname,
                '2': 30252,
                '8': 30255,
                '11': 30254
            },
            'musicvideos': {
                '1': tagname,
                '2': 30256,
                '4': 30257,
                '6': 30258
            }
        }

        # Key: nodetypes, value: sort order in Kodi
        sortorder = {
            '1': '3',  # "all",
            '2': '2',  # "recent",
            '3': '2',  # "recentepisodes",
            # '4': # "inprogress",
            # '5': # "inprogressepisodes",
            # '6': # "unwatched",
            # '7': # "nextepisodes",
            '8': '7',  # "sets",
            '9': '6',  # "genres",
            '10': '8',  # "random",
            '11': '5',  # "recommended",
            '12': '1',  # "ondeck"
        }

        nodes = mediatypes[mediatype]
        for node in nodes:

            nodetype = nodetypes[node]
            nodeXML = "%s%s_%s.xml" % (nodepath, viewid, nodetype)
            # Get label
            stringid = nodes[node]
            if node != "1":
                label = utils.language(stringid)
                if not label:
                    label = xbmc.getLocalizedString(stringid)
            else:
                label = stringid

            # Set window properties
            if (mediatype == "homevideos"
                    or mediatype == "photo") and nodetype == "all":
                # Custom query
                path = (
                    "plugin://plugin.video.plexkodiconnect/?id=%s&mode=browsecontent&type=%s"
                    % (tagname, mediatype))
            elif (mediatype == "homevideos" or mediatype == "photo"):
                # Custom query
                path = (
                    "plugin://plugin.video.plexkodiconnect/?id=%s&mode=browsecontent&type=%s&folderid=%s"
                    % (tagname, mediatype, nodetype))
            elif nodetype == "nextepisodes":
                # Custom query
                path = "plugin://plugin.video.plexkodiconnect/?id=%s&mode=nextup&limit=%s" % (
                    tagname, limit)
            # elif kodiversion == 14 and nodetype == "recentepisodes":
            elif nodetype == "recentepisodes":
                # Custom query
                path = (
                    "plugin://plugin.video.plexkodiconnect/?id=%s&mode=recentepisodes&type=%s&tagname=%s&limit=%s"
                    % (viewid, mediatype, tagname, limit))
            elif kodiversion == 14 and nodetype == "inprogressepisodes":
                # Custom query
                path = "plugin://plugin.video.plexkodiconnect/?id=%s&mode=inprogressepisodes&limit=%s" % (
                    tagname, limit)
            elif nodetype == 'ondeck':
                # PLEX custom query
                if mediatype == "tvshows":
                    path = (
                        "plugin://plugin.video.plexkodiconnect/?id=%s&mode=ondeck&type=%s&tagname=%s&limit=%s"
                        % (viewid, mediatype, tagname, limit))
                elif mediatype == "movies":
                    # Reset nodetype; we got the label
                    nodetype = 'inprogress'
            else:
                path = "library://video/Plex-%s/%s_%s.xml" % (dirname, viewid,
                                                              nodetype)

            if mediatype == "photo":
                windowpath = "ActivateWindow(Pictures,%s,return)" % path
            else:
                windowpath = "ActivateWindow(Video,%s,return)" % path

            if nodetype == "all":

                if viewtype == "mixed":
                    templabel = "%s-%s" % (tagname, mediatype)
                else:
                    templabel = label

                embynode = "Emby.nodes.%s" % indexnumber
                window('%s.title' % embynode, value=templabel)
                window('%s.path' % embynode, value=windowpath)
                window('%s.content' % embynode, value=path)
                window('%s.type' % embynode, value=mediatype)
            else:
                embynode = "Emby.nodes.%s.%s" % (indexnumber, nodetype)
                window('%s.title' % embynode, value=label)
                window('%s.path' % embynode, value=windowpath)
                window('%s.content' % embynode, value=path)

            if mediatype == "photo":
                # For photos, we do not create a node in videos but we do want the window props
                # to be created.
                # To do: add our photos nodes to kodi picture sources somehow
                continue

            if xbmcvfs.exists(nodeXML.encode('utf-8')):
                # Don't recreate xml if already exists
                continue

            # Create the root
            if (nodetype in ("nextepisodes", "ondeck", 'recentepisodes')
                    or mediatype == "homevideos"):
                # Folder type with plugin path
                root = self.commonRoot(order=sortorder[node],
                                       label=label,
                                       tagname=tagname,
                                       roottype=2)
                etree.SubElement(root, 'path').text = path
                etree.SubElement(root, 'content').text = "episodes"
            else:
                root = self.commonRoot(order=sortorder[node],
                                       label=label,
                                       tagname=tagname)
                if nodetype in ('recentepisodes', 'inprogressepisodes'):
                    etree.SubElement(root, 'content').text = "episodes"
                else:
                    etree.SubElement(root, 'content').text = mediatype

                # Elements per nodetype
                if nodetype == "all":
                    etree.SubElement(root, 'order', {
                        'direction': "ascending"
                    }).text = "sorttitle"

                elif nodetype == "recent":
                    etree.SubElement(root, 'order', {
                        'direction': "descending"
                    }).text = "dateadded"
                    etree.SubElement(root, 'limit').text = limit
                    rule = etree.SubElement(root, 'rule', {
                        'field': "playcount",
                        'operator': "is"
                    })
                    etree.SubElement(rule, 'value').text = "0"

                elif nodetype == "inprogress":
                    etree.SubElement(root, 'rule', {
                        'field': "inprogress",
                        'operator': "true"
                    })
                    etree.SubElement(root, 'limit').text = limit
                    etree.SubElement(root, 'order', {
                        'direction': 'descending'
                    }).text = 'lastplayed'

                elif nodetype == "genres":
                    etree.SubElement(root, 'order', {
                        'direction': "ascending"
                    }).text = "sorttitle"
                    etree.SubElement(root, 'group').text = "genres"

                elif nodetype == "unwatched":
                    etree.SubElement(root, 'order', {
                        'direction': "ascending"
                    }).text = "sorttitle"
                    rule = etree.SubElement(root, "rule", {
                        'field': "playcount",
                        'operator': "is"
                    })
                    etree.SubElement(rule, 'value').text = "0"

                elif nodetype == "sets":
                    etree.SubElement(root, 'order', {
                        'direction': "ascending"
                    }).text = "sorttitle"
                    etree.SubElement(root, 'group').text = "tags"

                elif nodetype == "random":
                    etree.SubElement(root, 'order', {
                        'direction': "ascending"
                    }).text = "random"
                    etree.SubElement(root, 'limit').text = limit

                elif nodetype == "recommended":
                    etree.SubElement(root, 'order', {
                        'direction': "descending"
                    }).text = "rating"
                    etree.SubElement(root, 'limit').text = limit
                    rule = etree.SubElement(root, 'rule', {
                        'field': "playcount",
                        'operator': "is"
                    })
                    etree.SubElement(rule, 'value').text = "0"
                    rule2 = etree.SubElement(root,
                                             'rule',
                                             attrib={
                                                 'field': "rating",
                                                 'operator': "greaterthan"
                                             })
                    etree.SubElement(rule2, 'value').text = "7"

                elif nodetype == "recentepisodes":
                    # Kodi Isengard, Jarvis
                    etree.SubElement(root, 'order', {
                        'direction': "descending"
                    }).text = "dateadded"
                    etree.SubElement(root, 'limit').text = limit
                    rule = etree.SubElement(root, 'rule', {
                        'field': "playcount",
                        'operator': "is"
                    })
                    etree.SubElement(rule, 'value').text = "0"

                elif nodetype == "inprogressepisodes":
                    # Kodi Isengard, Jarvis
                    etree.SubElement(root, 'limit').text = limit
                    rule = etree.SubElement(root,
                                            'rule',
                                            attrib={
                                                'field': "inprogress",
                                                'operator': "true"
                                            })

            try:
                utils.indent(root)
            except:
                pass
            etree.ElementTree(root).write(nodeXML)
Exemple #9
0
           (plexid, itemtype))

    if plexid:
        item = PF.GetPlexMetadata(plexid)
        if item is None or item == 401:
            logMsg('Could not get item metadata for item %s' % plexid, -1)
            return
        API = PlexAPI.API(item[0])
        userdata = API.getUserData()
        likes = userdata['Likes']
        favourite = userdata['Favorite']

        options = []
        if likes == True:
            #clear like for the item
            options.append(utils.language(30402))
        if likes == False or likes == None:
            #Like the item
            options.append(utils.language(30403))
        if likes == True or likes == None:
            #Dislike the item
            options.append(utils.language(30404))
        if favourite == False:
            #Add to emby favourites
            options.append(utils.language(30405))
        if favourite == True:
            #Remove from emby favourites
            options.append(utils.language(30406))
        if itemtype == "song":
            #Set custom song rating
            options.append(utils.language(30407))
    def viewNode(self,
                 indexnumber,
                 tagname,
                 mediatype,
                 viewtype,
                 viewid,
                 delete=False):

        window = utils.window
        kodiversion = self.kodiversion

        if viewtype == "mixed":
            dirname = "%s - %s" % (viewid, mediatype)
        else:
            dirname = viewid

        path = xbmc.translatePath("special://profile/library/video/").decode(
            'utf-8')
        nodepath = xbmc.translatePath(
            "special://profile/library/video/Emby - %s/" %
            dirname).decode('utf-8')

        # Verify the video directory
        if not xbmcvfs.exists(path):
            shutil.copytree(
                src=xbmc.translatePath(
                    "special://xbmc/system/library/video").decode('utf-8'),
                dst=xbmc.translatePath(
                    "special://profile/library/video").decode('utf-8'))
            xbmcvfs.exists(path)

        # Create the node directory
        if not xbmcvfs.exists(nodepath) and not mediatype == "photos":
            # We need to copy over the default items
            xbmcvfs.mkdirs(nodepath)
        else:
            if delete:
                dirs, files = xbmcvfs.listdir(nodepath)
                for file in files:
                    xbmcvfs.delete(nodepath + file)

                self.logMsg("Sucessfully removed videonode: %s." % tagname, 1)
                return

        # Create index entry
        nodeXML = "%sindex.xml" % nodepath
        # Set windows property
        path = "library://video/Emby - %s/" % dirname
        for i in range(1, indexnumber):
            # Verify to make sure we don't create duplicates
            if window('Emby.nodes.%s.index' % i) == path:
                return

        if mediatype == "photos":
            path = "plugin://plugin.video.emby/?id=%s&mode=getsubfolders" % indexnumber

        window('Emby.nodes.%s.index' % indexnumber, value=path)

        # Root
        if not mediatype == "photos":
            if viewtype == "mixed":
                specialtag = "%s - %s" % (tagname, mediatype)
                root = self.commonRoot(order=0,
                                       label=specialtag,
                                       tagname=tagname,
                                       roottype=0)
            else:
                root = self.commonRoot(order=0,
                                       label=tagname,
                                       tagname=tagname,
                                       roottype=0)
            try:
                utils.indent(root)
            except:
                pass
            etree.ElementTree(root).write(nodeXML)

        nodetypes = {
            '1': "all",
            '2': "recent",
            '3': "recentepisodes",
            '4': "inprogress",
            '5': "inprogressepisodes",
            '6': "unwatched",
            '7': "nextepisodes",
            '8': "sets",
            '9': "genres",
            '10': "random",
            '11': "recommended",
        }
        mediatypes = {
            # label according to nodetype per mediatype
            'movies': {
                '1': tagname,
                '2': 30174,
                '4': 30177,
                '6': 30189,
                '8': 20434,
                '9': 135,
                '10': 30229,
                '11': 30230
            },
            'tvshows': {
                '1': tagname,
                '2': 30170,
                '3': 30175,
                '4': 30171,
                '5': 30178,
                '7': 30179,
                '9': 135,
                '10': 30229,
                '11': 30230
            },
            'homevideos': {
                '1': tagname,
                '2': 30251,
                '11': 30253
            },
            'photos': {
                '1': tagname,
                '2': 30252,
                '8': 30255,
                '11': 30254
            },
            'musicvideos': {
                '1': tagname,
                '2': 30256,
                '4': 30257,
                '6': 30258
            }
        }

        nodes = mediatypes[mediatype]
        for node in nodes:

            nodetype = nodetypes[node]
            nodeXML = "%s%s_%s.xml" % (nodepath, viewid, nodetype)
            # Get label
            stringid = nodes[node]
            if node != "1":
                label = utils.language(stringid)
                if not label:
                    label = xbmc.getLocalizedString(stringid)
            else:
                label = stringid

            # Set window properties
            if (mediatype == "homevideos"
                    or mediatype == "photos") and nodetype == "all":
                # Custom query
                path = (
                    "plugin://plugin.video.emby/?id=%s&mode=browsecontent&type=%s"
                    % (tagname, mediatype))
            elif (mediatype == "homevideos" or mediatype == "photos"):
                # Custom query
                path = (
                    "plugin://plugin.video.emby/?id=%s&mode=browsecontent&type=%s&folderid=%s"
                    % (tagname, mediatype, nodetype))
            elif nodetype == "nextepisodes":
                # Custom query
                path = "plugin://plugin.video.emby/?id=%s&mode=nextup&limit=25" % tagname
            elif kodiversion == 14 and nodetype == "recentepisodes":
                # Custom query
                path = "plugin://plugin.video.emby/?id=%s&mode=recentepisodes&limit=25" % tagname
            elif kodiversion == 14 and nodetype == "inprogressepisodes":
                # Custom query
                path = "plugin://plugin.video.emby/?id=%s&mode=inprogressepisodes&limit=25" % tagname
            else:
                path = "library://video/Emby - %s/%s_%s.xml" % (
                    dirname, viewid, nodetype)

            if mediatype == "photos":
                windowpath = "ActivateWindow(Pictures,%s,return)" % path
            else:
                windowpath = "ActivateWindow(Video,%s,return)" % path

            if nodetype == "all":

                if viewtype == "mixed":
                    templabel = "%s - %s" % (tagname, mediatype)
                else:
                    templabel = label

                embynode = "Emby.nodes.%s" % indexnumber
                window('%s.title' % embynode, value=templabel)
                window('%s.path' % embynode, value=windowpath)
                window('%s.content' % embynode, value=path)
                window('%s.type' % embynode, value=mediatype)
            else:
                embynode = "Emby.nodes.%s.%s" % (indexnumber, nodetype)
                window('%s.title' % embynode, value=label)
                window('%s.path' % embynode, value=windowpath)
                window('%s.content' % embynode, value=path)

            if mediatype == "photos":
                # For photos, we do not create a node in videos but we do want the window props
                # to be created.
                # To do: add our photos nodes to kodi picture sources somehow
                continue

            if xbmcvfs.exists(nodeXML):
                # Don't recreate xml if already exists
                continue

            # Create the root
            if (nodetype == "nextepisodes" or mediatype == "homevideos" or
                (kodiversion == 14
                 and nodetype in ('recentepisodes', 'inprogressepisodes'))):
                # Folder type with plugin path
                root = self.commonRoot(order=node,
                                       label=label,
                                       tagname=tagname,
                                       roottype=2)
                etree.SubElement(root, 'path').text = path
                etree.SubElement(root, 'content').text = "episodes"
            else:
                root = self.commonRoot(order=node,
                                       label=label,
                                       tagname=tagname)
                if nodetype in ('recentepisodes', 'inprogressepisodes'):
                    etree.SubElement(root, 'content').text = "episodes"
                else:
                    etree.SubElement(root, 'content').text = mediatype

                limit = "25"
                # Elements per nodetype
                if nodetype == "all":
                    etree.SubElement(root, 'order', {
                        'direction': "ascending"
                    }).text = "sorttitle"

                elif nodetype == "recent":
                    etree.SubElement(root, 'order', {
                        'direction': "descending"
                    }).text = "dateadded"
                    etree.SubElement(root, 'limit').text = limit
                    rule = etree.SubElement(root, 'rule', {
                        'field': "playcount",
                        'operator': "is"
                    })
                    etree.SubElement(rule, 'value').text = "0"

                elif nodetype == "inprogress":
                    etree.SubElement(root, 'rule', {
                        'field': "inprogress",
                        'operator': "true"
                    })
                    etree.SubElement(root, 'limit').text = limit

                elif nodetype == "genres":
                    etree.SubElement(root, 'order', {
                        'direction': "ascending"
                    }).text = "sorttitle"
                    etree.SubElement(root, 'group').text = "genres"

                elif nodetype == "unwatched":
                    etree.SubElement(root, 'order', {
                        'direction': "ascending"
                    }).text = "sorttitle"
                    rule = etree.SubElement(root, "rule", {
                        'field': "playcount",
                        'operator': "is"
                    })
                    etree.SubElement(rule, 'value').text = "0"

                elif nodetype == "sets":
                    etree.SubElement(root, 'order', {
                        'direction': "ascending"
                    }).text = "sorttitle"
                    etree.SubElement(root, 'group').text = "sets"

                elif nodetype == "random":
                    etree.SubElement(root, 'order', {
                        'direction': "ascending"
                    }).text = "random"
                    etree.SubElement(root, 'limit').text = limit

                elif nodetype == "recommended":
                    etree.SubElement(root, 'order', {
                        'direction': "descending"
                    }).text = "rating"
                    etree.SubElement(root, 'limit').text = limit
                    rule = etree.SubElement(root, 'rule', {
                        'field': "playcount",
                        'operator': "is"
                    })
                    etree.SubElement(rule, 'value').text = "0"
                    rule2 = etree.SubElement(root,
                                             'rule',
                                             attrib={
                                                 'field': "rating",
                                                 'operator': "greaterthan"
                                             })
                    etree.SubElement(rule2, 'value').text = "7"

                elif nodetype == "recentepisodes":
                    # Kodi Isengard, Jarvis
                    etree.SubElement(root, 'order', {
                        'direction': "descending"
                    }).text = "dateadded"
                    etree.SubElement(root, 'limit').text = limit
                    rule = etree.SubElement(root, 'rule', {
                        'field': "playcount",
                        'operator': "is"
                    })
                    etree.SubElement(rule, 'value').text = "0"

                elif nodetype == "inprogressepisodes":
                    # Kodi Isengard, Jarvis
                    etree.SubElement(root, 'limit').text = "25"
                    rule = etree.SubElement(root,
                                            'rule',
                                            attrib={
                                                'field': "inprogress",
                                                'operator': "true"
                                            })

            try:
                utils.indent(root)
            except:
                pass
            etree.ElementTree(root).write(nodeXML)
        embycursor.close()
        if item: embyid = item[0]
    
    logMsg("Contextmenu opened for embyid: %s  - itemtype: %s" %(embyid,itemtype))

    if embyid:
        item = emby.getItem(embyid)
        API = api.API(item)
        userdata = API.getUserData()
        likes = userdata['Likes']
        favourite = userdata['Favorite']
        
        options=[]
        if likes == True:
            #clear like for the item
            options.append(utils.language(30402))
        if likes == False or likes == None:
            #Like the item
            options.append(utils.language(30403))
        if likes == True or likes == None:
            #Dislike the item
            options.append(utils.language(30404)) 
        if favourite == False:
            #Add to emby favourites
            options.append(utils.language(30405)) 
        if favourite == True:
            #Remove from emby favourites
            options.append(utils.language(30406))
        if itemtype == "song":
            #Set custom song rating
            options.append(utils.language(30407))
Exemple #12
0
def db_reset():

    dialog = xbmcgui.Dialog()

    if not dialog.yesno(language(29999), language(33074)):
        return

    # first stop any db sync
    window('emby_online', value="reset")
    window('emby_shouldStop', value="true")
    count = 10
    while window('emby_dbScan') == "true":
        log.info("Sync is running, will retry: %s..." % count)
        count -= 1
        if count == 0:
            dialog.ok(language(29999), language(33085))
            return
        xbmc.sleep(1000)

    # Clean up the playlists
    Playlist().delete_playlists()

    # Clean up the video nodes
    VideoNodes().deleteNodes()

    # Wipe the kodi databases
    log.warn("Resetting the Kodi video database.")
    with DatabaseConn('video') as cursor:
        cursor.execute('SELECT tbl_name FROM sqlite_master WHERE type="table"')
        rows = cursor.fetchall()
        for row in rows:
            tablename = row[0]
            if tablename != "version":
                cursor.execute("DELETE FROM " + tablename)

    if settings('enableMusic') == "true":
        log.warn("Resetting the Kodi music database.")
        with DatabaseConn('music') as cursor:
            cursor.execute(
                'SELECT tbl_name FROM sqlite_master WHERE type="table"')
            rows = cursor.fetchall()
            for row in rows:
                tablename = row[0]
                if tablename != "version":
                    cursor.execute("DELETE FROM " + tablename)

    # Wipe the emby database
    log.warn("Resetting the Emby database.")
    with DatabaseConn('emby') as cursor:
        cursor.execute('SELECT tbl_name FROM sqlite_master WHERE type="table"')
        rows = cursor.fetchall()
        for row in rows:
            tablename = row[0]
            if tablename != "version":
                cursor.execute("DELETE FROM " + tablename)
        cursor.execute('DROP table IF EXISTS emby')
        cursor.execute('DROP table IF EXISTS view')
        cursor.execute("DROP table IF EXISTS version")

    # Offer to wipe cached thumbnails
    if dialog.yesno(language(29999), language(33086)):
        log.warn("Resetting all cached artwork")
        # Remove all existing textures first
        import artwork
        artwork.Artwork().delete_cache()

    # reset the install run flag
    settings('SyncInstallRunDone', value="false")

    # Remove emby info
    resp = dialog.yesno(language(29999), language(33087))
    if resp:
        import connectmanager
        # Delete the settings
        addondir = xbmc.translatePath(
            "special://profile/addon_data/plugin.video.emby/").decode('utf-8')
        dataPath = "%ssettings.xml" % addondir
        xbmcvfs.delete(dataPath)
        connectmanager.ConnectManager().clear_data()

    dialog.ok(heading=language(29999), line1=language(33088))
    xbmc.executebuiltin('RestartApp')
    try:
        xbmcplugin.setResolvedUrl(int(sys.argv[1]), False, xbmcgui.ListItem())
    except:
        pass
Exemple #13
0
def db_reset():

    dialog = xbmcgui.Dialog()

    if not dialog.yesno(language(29999), language(33074)):
        return

    # first stop any db sync
    window('emby_online', value="reset")
    window('emby_shouldStop', value="true")
    count = 10
    while window('emby_dbScan') == "true":
        log.info("Sync is running, will retry: %s..." % count)
        count -= 1
        if count == 0:
            dialog.ok(language(29999), language(33085))
            return
        xbmc.sleep(1000)

    # Clean up the playlists
    Playlist().delete_playlists()

    # Clean up the video nodes
    VideoNodes().deleteNodes()

    # Wipe the kodi databases
    log.warn("Resetting the Kodi video database.")
    with DatabaseConn('video') as cursor:
        cursor.execute('SELECT tbl_name FROM sqlite_master WHERE type="table"')
        rows = cursor.fetchall()
        for row in rows:
            tablename = row[0]
            if tablename != "version":
                cursor.execute("DELETE FROM " + tablename)

    if settings('enableMusic') == "true":
        log.warn("Resetting the Kodi music database.")
        with DatabaseConn('music') as cursor:         
            cursor.execute('SELECT tbl_name FROM sqlite_master WHERE type="table"')
            rows = cursor.fetchall()
            for row in rows:
                tablename = row[0]
                if tablename != "version":
                    cursor.execute("DELETE FROM " + tablename)

    # Wipe the emby database
    log.warn("Resetting the Emby database.")
    with DatabaseConn('emby') as cursor:    
        cursor.execute('SELECT tbl_name FROM sqlite_master WHERE type="table"')
        rows = cursor.fetchall()
        for row in rows:
            tablename = row[0]
            if tablename != "version":
                cursor.execute("DELETE FROM " + tablename)
        cursor.execute('DROP table IF EXISTS emby')
        cursor.execute('DROP table IF EXISTS view')
        cursor.execute("DROP table IF EXISTS version")

    # Offer to wipe cached thumbnails
    if dialog.yesno(language(29999), language(33086)):
        log.warn("Resetting all cached artwork")
        # Remove all existing textures first
        import artwork
        artwork.Artwork().delete_cache()

    # reset the install run flag
    settings('SyncInstallRunDone', value="false")

    # Remove emby info
    resp = dialog.yesno(language(29999), language(33087))
    if resp:
        import connectmanager
        # Delete the settings
        addondir = xbmc.translatePath(
                   "special://profile/addon_data/plugin.video.emby/").decode('utf-8')
        dataPath = "%ssettings.xml" % addondir
        xbmcvfs.delete(dataPath)
        connectmanager.ConnectManager().clear_data()

    dialog.ok(heading=language(29999), line1=language(33088))
    xbmc.executebuiltin('RestartApp')
    try:
        xbmcplugin.setResolvedUrl(int(sys.argv[1]), False, xbmcgui.ListItem())
    except:
        pass
Exemple #14
0
    def viewNode(self, indexnumber, tagname, mediatype, viewtype, viewid, delete=False):
        # Plex: reassign mediatype due to Kodi inner workings
        # How many items do we get at most?
        limit = "100"
        mediatypes = {
            'movie': 'movies',
            'show': 'tvshows',
            'photo': 'photos',
            'homevideo': 'homevideos',
            'musicvideos': 'musicvideos'
        }
        mediatype = mediatypes[mediatype]

        window = utils.window
        kodiversion = self.kodiversion

        if viewtype == "mixed":
            dirname = "%s-%s" % (viewid, mediatype)
        else:
            dirname = viewid
        
        path = xbmc.translatePath("special://profile/library/video/").decode('utf-8')
        nodepath = xbmc.translatePath(
                    "special://profile/library/video/Plex-%s/" % dirname).decode('utf-8')

        # Verify the video directory
        # KODI BUG
        # Kodi caches the result of exists for directories
        #  so try creating a file
        if utils.IfExists(path) is False:
            shutil.copytree(
                src=xbmc.translatePath("special://xbmc/system/library/video").decode('utf-8'),
                dst=xbmc.translatePath("special://profile/library/video").decode('utf-8'))

        # Create the node directory
        if mediatype != "photo":
            if utils.IfExists(nodepath) is False:
                # folder does not exist yet
                self.logMsg('Creating folder %s' % nodepath, 1)
                xbmcvfs.mkdirs(nodepath.encode('utf-8'))
                if delete:
                    dirs, files = xbmcvfs.listdir(nodepath.encode('utf-8'))
                    for file in files:
                        xbmcvfs.delete(
                            (nodepath + file.decode('utf-8')).encode('utf-8'))

                    self.logMsg("Sucessfully removed videonode: %s."
                                % tagname, 1)
                    return

        # Create index entry
        nodeXML = "%sindex.xml" % nodepath
        # Set windows property
        path = "library://video/Plex-%s/" % dirname
        for i in range(1, indexnumber):
            # Verify to make sure we don't create duplicates
            if window('Emby.nodes.%s.index' % i) == path:
                return

        if mediatype == "photo":
            path = "plugin://plugin.video.plexkodiconnect/?id=%s&mode=getsubfolders" % indexnumber
            
        window('Emby.nodes.%s.index' % indexnumber, value=path)
        
        # Root
        if not mediatype == "photo":
            if viewtype == "mixed":
                specialtag = "%s-%s" % (tagname, mediatype)
                root = self.commonRoot(order=0, label=specialtag, tagname=tagname, roottype=0)
            else:
                root = self.commonRoot(order=0, label=tagname, tagname=tagname, roottype=0)
            try:
                utils.indent(root)
            except: pass
            etree.ElementTree(root).write(nodeXML)

        nodetypes = {

            '1': "all",
            '2': "recent",
            '3': "recentepisodes",
            '4': "inprogress",
            '5': "inprogressepisodes",
            '6': "unwatched",
            '7': "nextepisodes",
            '8': "sets",
            '9': "genres",
            '10': "random",
            '11': "recommended",
            '12': "ondeck"
        }
        mediatypes = {
            # label according to nodetype per mediatype
            'movies': 
                {
                '1': tagname,
                '2': 30174,
                # '4': 30177,
                # '6': 30189,
                '8': 20434,
                '9': 135,
                '10': 30227,
                '11': 30230,
                '12': 39500,
                },

            'tvshows': 
                {
                '1': tagname,
                # '2': 30170,
                '3': 30174,
                # '4': 30171,
                # '5': 30178,
                # '7': 30179,
                '9': 135,
                '10': 30227,
                # '11': 30230,
                '12': 39500,
                },
                
            'homevideos': 
                {
                '1': tagname,
                '2': 30251,
                '11': 30253
                },
                
            'photos': 
                {
                '1': tagname,
                '2': 30252,
                '8': 30255,
                '11': 30254
                },

            'musicvideos': 
                {
                '1': tagname,
                '2': 30256,
                '4': 30257,
                '6': 30258
                }
        }

        # Key: nodetypes, value: sort order in Kodi
        sortorder = {
            '1': '3',  # "all",
            '2': '2',  # "recent",
            '3': '2',  # "recentepisodes",
            # '4': # "inprogress",
            # '5': # "inprogressepisodes",
            # '6': # "unwatched",
            # '7': # "nextepisodes",
            '8': '7',  # "sets",
            '9': '6',  # "genres",
            '10': '8',  # "random",
            '11': '5',  # "recommended",
            '12': '1',  # "ondeck"
        }

        nodes = mediatypes[mediatype]
        for node in nodes:

            nodetype = nodetypes[node]
            nodeXML = "%s%s_%s.xml" % (nodepath, viewid, nodetype)
            # Get label
            stringid = nodes[node]
            if node != "1":
                label = utils.language(stringid)
                if not label:
                    label = xbmc.getLocalizedString(stringid)
            else:
                label = stringid

            # Set window properties
            if (mediatype == "homevideos" or mediatype == "photo") and nodetype == "all":
                # Custom query
                path = ("plugin://plugin.video.plexkodiconnect/?id=%s&mode=browsecontent&type=%s"
                        % (tagname, mediatype))
            elif (mediatype == "homevideos" or mediatype == "photo"):
                # Custom query
                path = ("plugin://plugin.video.plexkodiconnect/?id=%s&mode=browsecontent&type=%s&folderid=%s"
                        % (tagname, mediatype, nodetype))
            elif nodetype == "nextepisodes":
                # Custom query
                path = "plugin://plugin.video.plexkodiconnect/?id=%s&mode=nextup&limit=%s" % (tagname, limit)
            # elif kodiversion == 14 and nodetype == "recentepisodes":
            elif nodetype == "recentepisodes":
                # Custom query
                path = ("plugin://plugin.video.plexkodiconnect/?id=%s&mode=recentepisodes&type=%s&tagname=%s&limit=%s"
                    % (viewid, mediatype, tagname, limit))
            elif kodiversion == 14 and nodetype == "inprogressepisodes":
                # Custom query
                path = "plugin://plugin.video.plexkodiconnect/?id=%s&mode=inprogressepisodes&limit=%s" % (tagname, limit)
            elif nodetype == 'ondeck':
                # PLEX custom query
                if mediatype == "tvshows":
                    path = ("plugin://plugin.video.plexkodiconnect/?id=%s&mode=ondeck&type=%s&tagname=%s&limit=%s"
                        % (viewid, mediatype, tagname, limit))
                elif mediatype =="movies":
                    # Reset nodetype; we got the label
                    nodetype = 'inprogress'
            else:
                path = "library://video/Plex-%s/%s_%s.xml" % (dirname, viewid, nodetype)
            
            if mediatype == "photo":
                windowpath = "ActivateWindow(Pictures,%s,return)" % path
            else:
                windowpath = "ActivateWindow(Video,%s,return)" % path
            
            if nodetype == "all":

                if viewtype == "mixed":
                    templabel = "%s-%s" % (tagname, mediatype)
                else:
                    templabel = label

                embynode = "Emby.nodes.%s" % indexnumber
                window('%s.title' % embynode, value=templabel)
                window('%s.path' % embynode, value=windowpath)
                window('%s.content' % embynode, value=path)
                window('%s.type' % embynode, value=mediatype)
            else:
                embynode = "Emby.nodes.%s.%s" % (indexnumber, nodetype)
                window('%s.title' % embynode, value=label)
                window('%s.path' % embynode, value=windowpath)
                window('%s.content' % embynode, value=path)

            if mediatype == "photo":
                # For photos, we do not create a node in videos but we do want the window props
                # to be created.
                # To do: add our photos nodes to kodi picture sources somehow
                continue
            
            if xbmcvfs.exists(nodeXML.encode('utf-8')):
                # Don't recreate xml if already exists
                continue

            # Create the root
            if (nodetype in ("nextepisodes", "ondeck", 'recentepisodes') or mediatype == "homevideos"):
                # Folder type with plugin path
                root = self.commonRoot(order=sortorder[node], label=label, tagname=tagname, roottype=2)
                etree.SubElement(root, 'path').text = path
                etree.SubElement(root, 'content').text = "episodes"
            else:
                root = self.commonRoot(order=sortorder[node], label=label, tagname=tagname)
                if nodetype in ('recentepisodes', 'inprogressepisodes'):
                    etree.SubElement(root, 'content').text = "episodes"
                else:
                    etree.SubElement(root, 'content').text = mediatype

                # Elements per nodetype
                if nodetype == "all":
                    etree.SubElement(root, 'order', {'direction': "ascending"}).text = "sorttitle"
                
                elif nodetype == "recent":
                    etree.SubElement(root, 'order', {'direction': "descending"}).text = "dateadded"
                    etree.SubElement(root, 'limit').text = limit
                    rule = etree.SubElement(root, 'rule', {'field': "playcount", 'operator': "is"})
                    etree.SubElement(rule, 'value').text = "0"
                
                elif nodetype == "inprogress":
                    etree.SubElement(root, 'rule', {'field': "inprogress", 'operator': "true"})
                    etree.SubElement(root, 'limit').text = limit

                elif nodetype == "genres":
                    etree.SubElement(root, 'order', {'direction': "ascending"}).text = "sorttitle"
                    etree.SubElement(root, 'group').text = "genres"
                
                elif nodetype == "unwatched":
                    etree.SubElement(root, 'order', {'direction': "ascending"}).text = "sorttitle"
                    rule = etree.SubElement(root, "rule", {'field': "playcount", 'operator': "is"})
                    etree.SubElement(rule, 'value').text = "0"

                elif nodetype == "sets":
                    etree.SubElement(root, 'order', {'direction': "ascending"}).text = "sorttitle"
                    etree.SubElement(root, 'group').text = "sets"

                elif nodetype == "random":
                    etree.SubElement(root, 'order', {'direction': "ascending"}).text = "random"
                    etree.SubElement(root, 'limit').text = limit

                elif nodetype == "recommended":
                    etree.SubElement(root, 'order', {'direction': "descending"}).text = "rating"
                    etree.SubElement(root, 'limit').text = limit
                    rule = etree.SubElement(root, 'rule', {'field': "playcount", 'operator': "is"})
                    etree.SubElement(rule, 'value').text = "0"
                    rule2 = etree.SubElement(root, 'rule',
                        attrib={'field': "rating", 'operator': "greaterthan"})
                    etree.SubElement(rule2, 'value').text = "7"

                elif nodetype == "recentepisodes":
                    # Kodi Isengard, Jarvis
                    etree.SubElement(root, 'order', {'direction': "descending"}).text = "dateadded"
                    etree.SubElement(root, 'limit').text = limit
                    rule = etree.SubElement(root, 'rule', {'field': "playcount", 'operator': "is"})
                    etree.SubElement(rule, 'value').text = "0"

                elif nodetype == "inprogressepisodes":
                    # Kodi Isengard, Jarvis
                    etree.SubElement(root, 'limit').text = limit
                    rule = etree.SubElement(root, 'rule',
                        attrib={'field': "inprogress", 'operator':"true"})

            try:
                utils.indent(root)
            except: pass
            etree.ElementTree(root).write(nodeXML)
Exemple #15
0
    def play(self, itemid, dbid=None):

        log = self.logMsg
        window = utils.window
        settings = utils.settings

        doUtils = self.doUtils
        item = self.item
        API = self.API
        listitem = xbmcgui.ListItem()
        playutils = putils.PlayUtils(item)

        log("Play called.", 1)
        playurl = playutils.getPlayUrl()
        if not playurl:
            return xbmcplugin.setResolvedUrl(int(sys.argv[1]), False, listitem)

        if dbid is None:
            # Item is not in Kodi database
            listitem.setPath(playurl)
            self.setProperties(playurl, listitem)
            return xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, listitem)

        ############### ORGANIZE CURRENT PLAYLIST ################
        
        homeScreen = xbmc.getCondVisibility('Window.IsActive(home)')
        playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO)
        startPos = max(playlist.getposition(), 0) # Can return -1
        sizePlaylist = playlist.size()
        currentPosition = startPos

        propertiesPlayback = window('emby_playbackProps') == "true"
        introsPlaylist = False
        dummyPlaylist = False

        log("Playlist start position: %s" % startPos, 2)
        log("Playlist plugin position: %s" % currentPosition, 2)
        log("Playlist size: %s" % sizePlaylist, 2)

        ############### RESUME POINT ################
        
        userdata = API.getUserData()
        seektime = API.adjustResume(userdata['Resume'])

        # We need to ensure we add the intro and additional parts only once.
        # Otherwise we get a loop.
        if not propertiesPlayback:

            window('emby_playbackProps', value="true")
            log("Setting up properties in playlist.", 1)

            if (not homeScreen and not seektime and 
                    window('emby_customPlaylist') != "true"):
                
                log("Adding dummy file to playlist.", 2)
                dummyPlaylist = True
                playlist.add(playurl, listitem, index=startPos)
                # Remove the original item from playlist 
                self.pl.removefromPlaylist(startPos+1)
                # Readd the original item to playlist - via jsonrpc so we have full metadata
                self.pl.insertintoPlaylist(currentPosition+1, dbid, item['Type'].lower())
                currentPosition += 1
            
            ############### -- CHECK FOR INTROS ################

            if settings('enableCinema') == "true" and not seektime:
                # if we have any play them when the movie/show is not being resumed
                url = "{server}/emby/Users/{UserId}/Items/%s/Intros?format=json" % itemid    
                intros = doUtils(url)

                if intros['TotalRecordCount'] != 0:
                    getTrailers = True

                    if settings('askCinema') == "true":
                        resp = xbmcgui.Dialog().yesno("Emby for Kodi", utils.language(33016))
                        if not resp:
                            # User selected to not play trailers
                            getTrailers = False
                            log("Skip trailers.", 1)
                    
                    if getTrailers:
                        for intro in intros['Items']:
                            # The server randomly returns intros, process them.
                            introListItem = xbmcgui.ListItem()
                            introPlayurl = putils.PlayUtils(intro).getPlayUrl()
                            log("Adding Intro: %s" % introPlayurl, 1)

                            # Set listitem and properties for intros
                            pbutils = PlaybackUtils(intro)
                            pbutils.setProperties(introPlayurl, introListItem)

                            self.pl.insertintoPlaylist(currentPosition, url=introPlayurl)
                            introsPlaylist = True
                            currentPosition += 1


            ############### -- ADD MAIN ITEM ONLY FOR HOMESCREEN ###############

            if homeScreen and not seektime and not sizePlaylist:
                # Extend our current playlist with the actual item to play
                # only if there's no playlist first
                log("Adding main item to playlist.", 1)
                self.pl.addtoPlaylist(dbid, item['Type'].lower())

            # Ensure that additional parts are played after the main item
            currentPosition += 1

            ############### -- CHECK FOR ADDITIONAL PARTS ################
            
            if item.get('PartCount'):
                # Only add to the playlist after intros have played
                partcount = item['PartCount']
                url = "{server}/emby/Videos/%s/AdditionalParts?format=json" % itemid
                parts = doUtils(url)
                for part in parts['Items']:

                    additionalListItem = xbmcgui.ListItem()
                    additionalPlayurl = putils.PlayUtils(part).getPlayUrl()
                    log("Adding additional part: %s" % partcount, 1)

                    # Set listitem and properties for each additional parts
                    pbutils = PlaybackUtils(part)
                    pbutils.setProperties(additionalPlayurl, additionalListItem)
                    pbutils.setArtwork(additionalListItem)

                    playlist.add(additionalPlayurl, additionalListItem, index=currentPosition)
                    self.pl.verifyPlaylist()
                    currentPosition += 1

            if dummyPlaylist:
                # Added a dummy file to the playlist,
                # because the first item is going to fail automatically.
                log("Processed as a playlist. First item is skipped.", 1)
                return xbmcplugin.setResolvedUrl(int(sys.argv[1]), False, listitem)
                

        # We just skipped adding properties. Reset flag for next time.
        elif propertiesPlayback:
            log("Resetting properties playback flag.", 2)
            window('emby_playbackProps', clear=True)

        #self.pl.verifyPlaylist()
        ########## SETUP MAIN ITEM ##########

        # For transcoding only, ask for audio/subs pref
        if window('emby_%s.playmethod' % playurl) == "Transcode":
            playurl = playutils.audioSubsPref(playurl, listitem)
            window('emby_%s.playmethod' % playurl, value="Transcode")

        listitem.setPath(playurl)
        self.setProperties(playurl, listitem)

        ############### PLAYBACK ################

        if homeScreen and seektime and window('emby_customPlaylist') != "true":
            log("Play as a widget item.", 1)
            self.setListItem(listitem)
            xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, listitem)

        elif ((introsPlaylist and window('emby_customPlaylist') == "true") or
                (homeScreen and not sizePlaylist)):
            # Playlist was created just now, play it.
            log("Play playlist.", 1)
            xbmc.Player().play(playlist, startpos=startPos)

        else:
            log("Play as a regular item.", 1)
            xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, listitem)
Exemple #16
0
    def client_update(self):
        self.update_sock = socket.socket(socket.AF_INET,
                                         socket.SOCK_DGRAM,
                                         socket.IPPROTO_UDP)
        update_sock = self.update_sock

        # Set socket reuse, may not work on all OSs.
        try:
            update_sock.setsockopt(socket.SOL_SOCKET,
                                   socket.SO_REUSEADDR,
                                   1)
        except:
            pass

        # Attempt to bind to the socket to recieve and send data.  If we cant
        # do this, then we cannot send registration
        try:
            update_sock.bind(('0.0.0.0', self.client_update_port))
        except:
            log.error("Unable to bind to port [%s] - Plex Companion will not "
                      "be registered. Change the Plex Companion update port!"
                      % self.client_update_port)
            if settings('companion_show_gdm_port_warning') == 'true':
                if dialog('yesno',
                          language(29999),
                          'Port %s' % self.client_update_port,
                          language(39079),
                          yeslabel=language(30013),  # Never show again
                          nolabel=language(30012)):  # OK
                    settings('companion_show_gdm_port_warning', value='false')
                from xbmc import executebuiltin
                executebuiltin(
                    'Addon.OpenSettings(plugin.video.plexkodiconnect)')
            return

        update_sock.setsockopt(socket.IPPROTO_IP,
                               socket.IP_MULTICAST_TTL,
                               255)
        update_sock.setsockopt(socket.IPPROTO_IP,
                               socket.IP_ADD_MEMBERSHIP,
                               socket.inet_aton(
                                   self._multicast_address) +
                               socket.inet_aton('0.0.0.0'))
        update_sock.setblocking(0)

        # Send initial client registration
        self.register_as_client()

        # Now, listen format client discovery reguests and respond.
        while self._registration_is_running:
            try:
                data, addr = update_sock.recvfrom(1024)
                log.debug("Recieved UDP packet from [%s] containing [%s]"
                          % (addr, data.strip()))
            except socket.error:
                pass
            else:
                if "M-SEARCH * HTTP/1." in data:
                    log.debug("Detected client discovery request from %s. "
                              " Replying" % str(addr))
                    try:
                        update_sock.sendto("HTTP/1.0 200 OK\n%s"
                                           % self.client_data,
                                           addr)
                    except:
                        log.error("Unable to send client update message")

                    log.debug("Sending registration data HTTP/1.0 200 OK")
                    self.client_registered = True
            sleep(500)
        log.info("Client Update loop stopped")
        # When we are finished, then send a final goodbye message to
        # deregister cleanly.
        log.debug("Sending registration data: BYE %s\n%s"
                  % (self.client_header, self.client_data))
        try:
            update_sock.sendto("BYE %s\n%s"
                               % (self.client_header, self.client_data),
                               self.client_register_group)
        except:
            log.error("Unable to send client update message")
        self.client_registered = False