Hi all,

I need your help, I have got a problem with my python script. I'm using XBMC media application which they are using python 2.6v which they works the same way as the other version for python.

When I'm pressing on the enter button of the keyboard, the code will keep re-fetching the same values from each XML tag which it will print 5 same values for each tag when there is one value from each tag.

Here's the code:

import xbmc
import xbmcgui
import xbmcaddon
import os
import urllib2
import StringIO
import sqlite3
from sqlite3 import dbapi2 as database
from xml.etree import ElementTree

class Channel:
     def __init__(self):
         self.__display_name = None
         self.__icon = None
         self.__programs = []


     def get_display_name(self):
         return self.__display_name


     def get_icon(self):
         return self.__icon


     def get_programs(self):
         return self.__programs



     def set_display_name(self, value):
         self.__display_name = value


     def set_icon(self, value):
         self.__icon = value


     def set_programs(self, value):
         self.__programs = value


     def del_display_name(self):
         del self.__display_name


     def del_icon(self):
         del self.__icon


     def del_programs(self):
         del self.__programs

     display_name = property(get_display_name, set_display_name, del_display_name, "display_name's docstring")
     icon = property(get_icon, set_icon, del_icon, "icon's docstring")
     programs = property(get_programs, set_programs, del_programs, "programs's docstring")




class Programme:
     def __init__(self):
         self.__start = None
         self.__stop = None
         self.__title = None
         self.__sub_title = None
         self.__desc = None
         self.__category = []
         self.__credits = []
         self.__icon = None
         self.__episode_num = None

     def get_episode_num(self):
         return self.__episode_num


     def set_episode_num(self, value):
         self.__episode_num = value


     def del_episode_num(self):
         del self.__episode_num


     def get_start(self):
         return self.__start


     def get_stop(self):
         return self.__stop


     def get_title(self):
         return self.__title


     def get_sub_title(self):
         return self.__sub_title


     def get_desc(self):
         return self.__desc


     def get_category(self):
         return self.__category


     def get_credits(self):
         return self.__credits


     def get_icon(self):
         return self.__icon


     def set_start(self, value):
         self.__start = value


     def set_stop(self, value):
         self.__stop = value


     def set_title(self, value):
         self.__title = value


     def set_sub_title(self, value):
         self.__sub_title = value


     def set_desc(self, value):
         self.__desc = value


     def set_category(self, value):
         self.__category = value


     def set_credits(self, value):
         self.__credits = value


     def set_icon(self, value):
         self.__icon = value


     def del_start(self):
         del self.__start


     def del_stop(self):
         del self.__stop


     def del_title(self):
         del self.__title


     def del_sub_title(self):
         del self.__sub_title


     def del_desc(self):
         del self.__desc


     def del_category(self):
         del self.__category


     def del_credits(self):
         del self.__credits


     def del_icon(self):
         del self.__icon

     start = property(get_start, set_start, del_start, "start's docstring")
     stop = property(get_stop, set_stop, del_stop, "stop's docstring")
     title = property(get_title, set_title, del_title, "title's docstring")
     sub_title = property(get_sub_title, set_sub_title, del_sub_title, "sub_title's docstring")
     desc = property(get_desc, set_desc, del_desc, "desc's docstring")
     category = property(get_category, set_category, del_category, "category's docstring")
     creditss = property(get_credits, set_credits, del_credits, "credits's docstring")
     icon = property(get_icon, set_icon, del_icon, "icon's docstring")
     episode_num = property(get_episode_num, set_episode_num, del_episode_num, "episode_num's docstring")



class Credits:
     def __init__(self):
         self.__type = None
         self.__role = None
         self.__name = None

     def get_type(self):
         return self.__type


     def get_role(self):
         return self.__role


     def get_name(self):
         return self.__name


     def set_type(self, value):
         self.__type = value


     def set_role(self, value):
         self.__role = value


     def set_name(self, value):
         self.__name = value


     def del_type(self):
         del self.__type


     def del_role(self):
         del self.__role


     def del_name(self):
         del self.__name

     type = property(get_type, set_type, del_type, "type's docstring")
     role = property(get_role, set_role, del_role, "role's docstring")
     name = property(get_name, set_name, del_name, "name's docstring")




class MyClass(xbmcgui.WindowXML):

     def __new__(cls):
         return super(MyClass, cls).__new__(cls, 'script-tvguide-mainmenu.xml', ADDON.getAddonInfo('path'))



def onInit(self):
    pass


def load_channel(self, elem):
         channel = Channel()
         for elem in elem.getchildren():
             if elem.tag == 'display-name':
                 channel.set_display_name(elem.text)
             elif elem.tag == 'icon':
                 channel.set_icon(elem.attrib['src'])
         return channel



     def load_programme(self, elem):
         programme = Programme()
         programme.set_start(elem.attrib['start'])
         programme.set_stop(elem.attrib['stop'])

         for elem in elem.getchildren():
             if elem.tag == 'title':
                 programme.set_title(elem.text)
             elif elem.tag == 'sub-title':
                 programme.set_title(elem.text)
             elif elem.tag == 'desc':
                 programme.set_desc(elem.text)
             elif elem.tag == 'category':
                 categories = programme.get_category()
                 categories.append(elem.text)
             elif elem.tag == 'episode-num':
                 programme.set_episode_num(elem.text)
             elif elem.tag == 'credits':
                 creditss = programme.get_credits()
                 creditss.append(self.load_credits(elem))
             elif elem.tag == 'icon':
                 programme.set_icon(elem.attrib['src'])
         return programme



     def load_credits(self, elem):
         creditss = Credits()
         for elem in elem.getchildren():
             if elem.tag == 'actor':
                 creditss.set_name(elem.text)
                 creditss.set_type('actor')
             elif elem.tag == 'presenter':
                 creditss.set_name(elem.text)
                 creditss.set_type('presenter')
             elif elem.tag == 'director':
                 creditss.set_name(elem.text)
                 creditss.set_type('director')
         return credits



def onAction(self, action):

if action == ACTION_ENTER:
    #OPEN THE XML SOURCE
    url = ADDON.getSetting('ontv.url')
    req = urllib2.Request(url)
    response = urllib2.urlopen(req)
    data = response.read()
    response.close()

    profilePath = xbmc.translatePath(os.path.join('special://userdata/addon_data/script.tvguide', ''))

   if os.path.exists(profilePath):
       profilePath = profilePath + 'source.db'
       con = database.connect(profilePath)
       cur = con.cursor()
       cur.execute('CREATE TABLE programs(id TEXT, channel TEXT, title TEXT, start_date TIMESTAMP, end_date TIMESTAMP, description TEXT)')
       con.commit()
       con.close
       tv_elem = ElementTree.parse(StringIO.StringIO(data)).getroot()
       channels = {}

       for elem in tv_elem.getchildren():
        if elem.tag == 'channel':
           channels[elem.attrib['id']] = self.load_channel(elem)

           for channel_key in channels:
               channel = channels[channel_key]
               display_name = channel.get_display_name()
               print display_name
               profilePath = xbmc.translatePath(os.path.join('special://userdata/addon_data/script.tvguide', ''))
               profilePath = profilePath + 'source.db'
               con = database.connect(profilePath)
               cur = con.cursor()

               if not display_name in cur:
                  cur.execute("INSERT INTO programs(id, channel)" + " VALUES(?, ?)", [display_name, 0])
                  con.commit()
                  cur.close
                  print 'Channels store into database are now successfully!'

I guess the problem must be somewhere in this code:

for elem in tv_elem.getchildren():
    if elem.tag == 'channel':
       channels[elem.attrib['id']] = self.load_channel(elem)

       for channel_key in channels:
           channel = channels[channel_key]
           display_name = channel.get_display_name()
           print display_name
           profilePath = xbmc.translatePath(os.path.join('special://userdata/addon_data/script.tvguide', ''))
           profilePath = profilePath + 'source.db'
           con = database.connect(profilePath)
           cur = con.cursor()

           if not display_name in cur:
              cur.execute("INSERT INTO programs(id, channel)" + " VALUES(?, ?)", [display_name, 0])
              con.commit()
              cur.close
              print 'Channels store into database are now successfully!'[/code]

Here's the xml file:

<?xml version="1.0" encoding="UTF-8" ?>
<tv generator-info-name="www.timefor.tv/xmltv">
        <channel id="www.timefor.tv/tv/162">
            <display-name lang="de">ARD DE DE</display-name>
                    <icon src="http://static.timefor.tv/imgs/epg/logos/ard_big.png" />
        </channel>
        <channel id="www.timefor.tv/tv/1">
            <display-name lang="dk">DR1 DK DK</display-name>
                    <icon src="http://static.timefor.tv/imgs/epg/logos/dr1_dk_big.png" />
        </channel>
        <channel id="www.timefor.tv/tv/130">
            <display-name lang="no">NRK1 NO NO</display-name>
                    <icon src="http://static.timefor.tv/imgs/epg/logos/nrk1_big.png" />
        </channel>
        <channel id="www.timefor.tv/tv/135">
            <display-name lang="se">SVT 1 SE SE</display-name>
                    <icon src="http://static.timefor.tv/imgs/epg/logos/svt1_big.png" />
        </channel>
        <channel id="www.timefor.tv/tv/10769">
            <display-name lang="en">BBC One UK EN</display-name>
                    <icon src="http://static.timefor.tv/imgs/epg/logos/bbcone_big.png" />
        </channel>
        <channel id="www.timefor.tv/tv/10214">
            <display-name lang="en">National Geographic Channel UK EN</display-name>
                    <icon src="http://static.timefor.tv/imgs/epg/logos/nationalgeographicchannel_fr_big.png" />
        </channel>
        <channel id="www.timefor.tv/tv/10847">
            <display-name lang="en">Discovery Channel UK EN</display-name>
                    <icon src="http://static.timefor.tv/imgs/epg/logos/discoverychannel_big.png" />
        </channel></tv>

And here's the logs: http://xbmclogs.com/show.php?id=144672

I want to fetch one value from each tag without re-fetching.

Do you know how I can fetch one value from each tag without re-fetching the same values over and over?

To make it short, I think you are doing this with dict channels

D = {}

for i in range(5):
    D[i] = "v%d" % i
    for D_key in D:
        print D[D_key],

""" my output -->
v0 v0 v1 v0 v1 v2 v0 v1 v2 v3 v0 v1 v2 v3 v4
"""

Isn't this obviously wrong ?

Edited 2 Years Ago by Gribouillis

Little bit, but I want to output something is like: v0 v1 v2 v3 v4

you got it?

I want to output something is like: v0 v1 v2 v3 v4

Simply don't print the whole dict every time an item is inserted, so for example

D = {}

for i in range(5):
    D[i] = "v%d" % i
    print D[D_key],

or

D = {}

for i in range(5):
    D[i] = "v%d" % i

for D_key in D:
    print D[D_key],

Edited 2 Years Ago by Gribouillis

Thank you very much for this, the second one is working.

Can you please help me to fix the code for the channels to dict in alphabet order everytime an item is inserted by using this code:

channels = {}

for elem in tv_elem.getchildren():
    if elem.tag == 'channel':
       channels[elem.attrib['id']] = self.load_channel(elem)
       for channel_key in channels:
           channel = channels[channel_key]
           display_name = channel.get_display_name()
           print display_name

Here is what it print it out:

20:58:02 T:6548  NOTICE: BBC One UK EN
20:58:02 T:6548  NOTICE: SVT 1 SE SE
20:58:02 T:6548  NOTICE: National Geographic Channel UK EN
20:58:02 T:6548  NOTICE: NRK1 NO NO
20:58:02 T:6548  NOTICE: Discovery Channel UK EN
20:58:02 T:6548  NOTICE: ARD DE DE
20:58:02 T:6548  NOTICE: DR1 DK DK

Here is the XML tags:

<?xml version="1.0" encoding="UTF-8" ?>
<tv generator-info-name="www.timefor.tv/xmltv">
        <channel id="www.timefor.tv/tv/162">
            <display-name lang="de">ARD DE DE</display-name>
                    <icon src="http://static.timefor.tv/imgs/epg/logos/ard_big.png" />
        </channel>
        <channel id="www.timefor.tv/tv/1">
            <display-name lang="dk">DR1 DK DK</display-name>
                    <icon src="http://static.timefor.tv/imgs/epg/logos/dr1_dk_big.png" />
        </channel>
        <channel id="www.timefor.tv/tv/130">
            <display-name lang="no">NRK1 NO NO</display-name>
                    <icon src="http://static.timefor.tv/imgs/epg/logos/nrk1_big.png" />
        </channel>
        <channel id="www.timefor.tv/tv/135">
            <display-name lang="se">SVT 1 SE SE</display-name>
                    <icon src="http://static.timefor.tv/imgs/epg/logos/svt1_big.png" />
        </channel>
        <channel id="www.timefor.tv/tv/10769">
            <display-name lang="en">BBC One UK EN</display-name>
                    <icon src="http://static.timefor.tv/imgs/epg/logos/bbcone_big.png" />
        </channel>
        <channel id="www.timefor.tv/tv/10214">
            <display-name lang="en">National Geographic Channel UK EN</display-name>
                    <icon src="http://static.timefor.tv/imgs/epg/logos/nationalgeographicchannel_fr_big.png" />
        </channel>
        <channel id="www.timefor.tv/tv/10847">
            <display-name lang="en">Discovery Channel UK EN</display-name>
                    <icon src="http://static.timefor.tv/imgs/epg/logos/discoverychannel_big.png" />
        </channel></tv>

I want to print them in the same alphabet order. Can you please help?

Thanks!!!

Edited 2 Years Ago by mark103

You can iterate on sorted keys:

for channel_key in sorted(channels):
    ...

The other thing you can do is use

channels = OrderedDict()

instead of channels = {}. In py 2.6, ordereddict is here. Then the dict should be traversed in the insertion order (while sorted() yields alphabetic order, which could be different)

Edited 2 Years Ago by Gribouillis

Comments
Very good thank you

Thank you very much for your help Gribouillis, I'm using the channels = OrderedDict() which it have helping me to solve the problem. I have got the list of items that are in perfect alphabet order as the XML file, so problem are now solved.

This question has already been answered. Start a new discussion instead.