0

I would like a way of changing the status of watched movies in YAMJ's xml files. I can provide baseFilenameBase, fileLocation and fileURL. I nned to change the two watched eleiments to true.

<library count="1">
   <category count="1" current="true" name="Other">
      <index </index>
   </category>
   <movies cols="18" count="18" indexCount="673" totalCount="737">
      <movie isExtra="false" isSet="false" isTV="false">
         <baseFilenameBase>FILE NAME</baseFilenameBase>
         <watched>false</watched>
         <files>
            <file firstPart="1" lastPart="1" season="-1" size="0" subtitlesExchange="NO"
                  title="UNKNOWN"
                  watched="false"
                  zcd="2">
               <fileLocation>PATH TO FILE</fileLocation>
               <fileURL>PATH TO FILE</fileURL>
            </file>
         </files>
      </movie>
      <movie

      And repeats .....
    </movies>
</library>    

I have managed to replace watched in other xml files dy doing

                doc = parse(file)
                node = doc.getElementsByTagName('watched')
                node[0].firstChild.nodeValue = 'true'    

That was very simple compared to trying to get to grips with siblings/neighbors

MostafaR
  • 3,547
  • 1
  • 17
  • 24
jhmiller
  • 99
  • 1
  • 8

4 Answers4

0

The following will set watched as true in all movies and files, you should adapt it to only change the ones you want, and change movies.xml to the name of your file.

from xml.etree import ElementTree

tree = ElementTree.parse('movies.xml')

for movie in tree.findall('movies/movie'):
    movie.find('watched').text = 'true'
    for mfile in movie.findall('files/file'):
        mfile.set('watched', 'true')

tree.write('movies.xml')
sp.
  • 1,336
  • 11
  • 7
  • Thanks, that does change all to true, the set command was good to find. I did try only replacing for the watched files needed by adding if unicode(movie.find('baseFilenamebase').text) == myMedia.oStatus.fileName[:-4]: after the first for movie in tree, but this did not work :( I have tried a few variations on this but none work. – jhmiller Aug 24 '12 at 00:49
  • tree = ElementTree.parse(name) for movie in tree.findall('movies/movie'): penContents = movie.getchildren() for content in penContents: if content.text == myMedia.oStatus.fileName[:-4]: movie.find('watched').text = 'true' for mfile in movie.findall('files/file'): mfile.set('watched', 'true') bak_name = name[:-4]+'.bak' tree.write(bak_name) os.rename(bak_name, name) – jhmiller Aug 24 '12 at 11:55
0
                msg = 'Starting xml update in '.format(updatexmlwatched)
            Debug(msg)
            pchtrakt.logger.info(msg)
            if pchtrakt.isMovie:
                xmlpath = updatexmlwatched + "Other*.xml"
                for name in glob.glob(xmlpath):
                    if myMedia.oStatus.fileName[:-4] in open(name).read():#gets xml file name as name
                        tree = ElementTree.parse(name)
                        for movie in tree.findall('movies/movie'):
                            if movie.find('baseFilenameBase').text == myMedia.oStatus.fileName[:-4]:#for  content in penContents:
                                movie.find('watched').text = 'true'
                                for mfile in movie.findall('files/file'):
                                    mfile.set('watched', 'true')
                                    bak_name = name[:-4]+'.bak'
                                    tree.write(bak_name)
                                    os.rename(bak_name, name)
                                    txt = name.replace(updatexmlwatched, '') + ' has been modified as watched for ' + myMedia.oStatus.fileName
                                    Debug(txt)
                                    pchtrakt.logger.info(txt)
                                    break
            elif pchtrakt.isTvShow:
                a = re.split("([-|.]*[Ss]\\d\\d[Ee]\\d\\d.)", myMedia.oStatus.fileName)
                ep_name = a[2][:-4].replace(".", " ").replace("- ", "")
                season_xml = a[0][:-3].replace(".", " ").replace(" - ", "")
                f_size = str(os.path.getsize(myMedia.oStatus.fullPath))
                ep_no = '01'
                fileinfo = updatexmlwatched + "Set_" + season_xml + "*.xml"
                for name in glob.glob(fileinfo):
                    if myMedia.oStatus.fileName in open(name).read():
                        tree = ElementTree.parse(name)
                        for movie in tree.findall('*/movie/files/file'):
                            if movie.get('firstPart') == str(myMedia.parsedInfo.episode_numbers[myMedia.idxEpisode]) and movie.get('season') == str(myMedia.parsedInfo.season_number):
                                movie.set('watched', 'true')
                                bak_name = name[:-4]+'.bak'
                                tree.write(bak_name)
                                os.rename(bak_name, name)
                                txt = name.replace(updatexmlwatched, '') + ' has been modified as watched for ' + myMedia.oStatus.fileName
                                Debug(txt)
                                pchtrakt.logger.info(txt)
                                break
                fileinfo = updatexmlwatched + "Other*.xml"
                for name in glob.glob(fileinfo):
                    if myMedia.oStatus.fileName in open(name).read():
                        tree = ElementTree.parse(name)
                        for movie in tree.findall('*/movie/files/file'):
                            if movie.get('size') == f_size and movie.get('firstPart') == str(myMedia.parsedInfo.episode_numbers[myMedia.idxEpisode]) and movie.get('season') == str(myMedia.parsedInfo.season_number):
                                movie.set('watched', 'true')
                                bak_name = name[:-4]+'.bak'
                                tree.write(bak_name)
                                os.rename(bak_name, name)
                                txt = name.replace(updatexmlwatched, '') + ' has been modified as watched for ' + myMedia.oStatus.fileName
                                Debug(txt)
                                pchtrakt.logger.info(txt)
                                break

This is what i have ended up with. It does work but sometimes causes media being played to stutter if xml's are on a network share. I beleive it is happening while it is searching for the xml that contains the variable. Is there a less system hungry way of doing this as its running on a low power media player.

Thanks

jhmiller
  • 99
  • 1
  • 8
0

Maybe python isn't the answer if you're running on a small media server it should have sed on it.

sed -i 's/<watched>false/<watched>true/g' movies.xml

Just check which version of sed you have sed -h so you know what options are available.

jeedo
  • 361
  • 2
  • 5
0

Assuming that your baseFilenameBase is unique, a simple way to do this is as follows: I cannot comment, so I can't add this to sp's answer.

The magic is the xpath expression "//movie[baseFilenameBase/text() = 'PATHHERE']" This is an xpath expression that says:

  • //movie -- Find all movie nodes
  • [CONDITION] -- Where the condition is true
  • baseFilenameBase/text() = 'PATHHERE' -- A condition saying that it must have a baseFilenameBase node, containing the text 'PATHHERE'

I then use format to put the contents of the path variable in. XPath is a wonderful syntax for refering to xml nodes, check here for more infomation

p.s. I must admit I haven't run this. But I don't think there are any syntax errors, and it should work.

from xml.etree import ElementTree

tree = ElementTree.parse('movies.xml')
movie = tree.find("//movie[baseFilenameBase/text() = '{}']".format(path))
movie.find('watched').text = 'true'
for file in movie.find('files').findall('file')
    file.set("watched", 'true')

tree.write('movies.xml')