Q: Where to add file filter
#1
hello xbmc team,
first off thanks for your great job. i want to implement a feature where xbmc reads the title for a file from a xml with the same name. (say stream.ts and stream.xml).
i get those combinations as output from my xbox.
here's what i got:
1) i wrote a parsing function that gets the titles from the xml
2) i wrote a filter function cfileitemlist::filterxmlitems() (works like filtercueitems for audio) that does the label replacement

now i'm not sure where exactly i have to call it from. i had it working in an earlier version but it was more or less patchwork: i called it in
Quote:cguiwindowvideofiles::oninfo
cguiwindowvideofiles::getstackeddirectory
cguiwindowvideofiles::getdirectory
but it doesn't work like that anymore.
please, i'd be very glad im someone could let me know where to launch a filter like that and if replacing the labels of the .ts file is enough.



Reply
#2
the code has changed alot. there's now a base media window which all the other windows reference. that's a good starting point.

and you really just want to rename the items in the list, right? you're best bet would be to throw a call to your function in cfileitem::formatlabel. this is now the underlying function which sets the label for for the item.
Always read the XBMC online-manual, FAQ and search the forum before posting.
Do not e-mail XBMC-Team members directly asking for support. Read/follow the forum rules.
For troubleshooting and bug reporting please make sure you read this first.
Reply
#3
(kraqh3d @ jan. 27 2006,17:17 Wrote:the code has changed alot.  there's now a base media window which all the other windows reference.  that's a good starting point.

and you really just want to rename the items in the list, right?  you're best bet would be to throw a call to your function in cfileitem::formatlabel.  this is now the underlying function which sets the label for for the item.
the way i did it before is that i added the xml file to the video types so it would be included in the list.
i then went through all the files in the list, parsed the xml files and marked the corresponding files for renaming.
so yes, i only want to give the ts files a different label.
i'm doing all this since the dbox i use for tv recording puts out .ts files with the date only and i want to make it as easy as possible for the family to recognize this stuff.
thanks for the tipps, i'll take a look at the formatlabel function and put my stuff there.
if it wasn't such a dirty hack i would put it out for other dbox/dreambox users who record to their xboxen.
Reply
#4
well you shouldnt need to "see" the .xml files in the video listing for this to work. from what i can see, i think all you should need to do is this (in pseudo-code):

Quote:for each pitem:
{
cutil::replaceextension(pitem->m_strpath, ".xml", strxml)
if (cfile::exists(strxml))
{
process strxml
strlabel = xml->something
pitem->setlabel(strlabel)
}
}

check the cutil function to replace extension. i may have gotten the order of the arguments wrong.
Always read the XBMC online-manual, FAQ and search the forum before posting.
Do not e-mail XBMC-Team members directly asking for support. Read/follow the forum rules.
For troubleshooting and bug reporting please make sure you read this first.
Reply
#5
thanks a lot! it worked great.
all i had to do is add my existing xml filter function to cguimediawindow::formatitemlabels(). it might break other functionality but then again i only change labels. anyway its good enough for my purposes, thanks a lot for your help.
Reply
#6
i'm having a minor problem with special characters.
right now i'm getting my strings via tinyxml like this:

Quote:tixmltext* info2 = dochandle.firstchild( "neutrino" ).firstchild( "record" ).firstchild( "info2" ).firstchild().text();
cstdstringw info2 = info2->value();

however when i go that the special characters (ä,ö,ü...) show up as garbage (empty squares).
i've played around with cutil::unicode2ansi and tried other stuff but i just don't get it right.
it's not a big deal but if anyone knows how to convert them to the proper format it would be great help.

here's my sample xml:
Quote:<?xml version="1.0" encoding="utf-8"?>

<neutrino commandversion="1">
<record command="record">
<channelname>prosieben</channelname>
<epgtitle>friends</epgtitle>
<id>8717186</id>
<info1>friends</info1>
<info2>glück im unglück für rachel: sie hat ihren job verloren, bekommt aber gleichzeitig die chance auf einen neuen arbeitsplatz...</info2>
<epgid>9289245520966795</epgid>
<mode>1</mode>
<videopid>255</videopid>
<audiopids selected="256">
<audio pid="256" name="german"/>
<audio pid="257" name="german (ac3)"/>
</audiopids>
<vtxtpid>32</vtxtpid>
<genremajor>0</genremajor>
<genreminor>0</genreminor>
<seriename></seriename>
<length>30</length>
<productioncountry></productioncountry>
<productiondate>0</productiondate>
<qualitiy>0</qualitiy>
<parentallockage>0</parentallockage>
<dateoflastplay>949273200</dateoflastplay>
<bookmark>
<bookmarkstart>0</bookmarkstart>
<bookmarkend>0</bookmarkend>
<bookmarklast>0</bookmarklast>
<bookmarkuser bookmarkuserpos="0" bookmarkusertype="0" bookmarkusername=""/>
</bookmark>
</record>
</neutrino>



Reply
#7
never mind, figured it out:
Quote:g_charsetconverter.utf8tostringcharset(strwrong,strcorrect);
Reply
#8
one last thing (sorry, perfectionist here): how come that my addition (see below) only works locally on xbox hdd, not on samba shares?
Quote:void cguimediawindow::formatitemlabels()
{
if (!m_guistate.get())
return;

cguiviewstate::label_masks labelmasks;
m_guistate->getsortmethodlabelmasks(labelmasks);

for (int i=0; i<m_vecitems.size(); ++i)
{
cfileitem* pitem=m_vecitems[i];

if (pitem->islabelpreformated())
continue;

pitem->formatlabel(pitem->m_bisfolder ? labelmasks.m_strlabelfolder : labelmasks.m_strlabelfile);
pitem->formatlabel2(pitem->m_bisfolder ? labelmasks.m_strlabel2folder : labelmasks.m_strlabel2file);
}
m_vecitems.filterxmlitems(); //added by zak
}
Reply
#9
i have no idea... post cfileitemlist::filterxmlitems().
Always read the XBMC online-manual, FAQ and search the forum before posting.
Do not e-mail XBMC-Team members directly asking for support. Read/follow the forum rules.
For troubleshooting and bug reporting please make sure you read this first.
Reply
#10
ok but its a little embarassing. it's the first c/c++ code i ever wrote and more copy paste from filtercueitems then my own work. also its not the approach you suggested but the one i had originally used (for each file check if its an xml and if yes rename the corresponding .ts file(s)).
so here goes my crappy patchwork:
Quote:void cfileitemlist::filterxmlitems()
{
// handle dbox recorded files, e.g. numbers.001.ts with numbers.xml containing the description and name
 typedef std::pair<cstdstring, cstdstring> renamefromto_t;
 vector<renamefromto_t> renames;
 vecfileitems itemstodelete;
 for (int i = 0; i < (int)m_items.size(); i++)
 {
   cfileitem *pitem = m_items[i];
   if (!pitem->m_bisfolder)
   { // only apply filter to .xml files
     if (pitem->istype(".xml"))
     {
       tixmldocument xmldoc = null;
       cstdstring strxmlfile = pitem->m_strpath;
   if (!xmldoc.loadfile( strxmlfile ))
   {
     clog::log(lognotice, "%s, line %d\n%s", strxmlfile , xmldoc.errorrow(), xmldoc.errordesc());
     break;
   }
   tixmlhandle dochandle( &xmldoc );
   try {
           tixmltext* epgtitle = dochandle.firstchild( "neutrino" ).firstchild( "record" ).firstchild( "epgtitle" ).firstchild().text();
     tixmltext* channelname = dochandle.firstchild( "neutrino" ).firstchild( "record" ).firstchild( "channelname" ).firstchild().text();
     tixmltext* info2 = dochandle.firstchild( "neutrino" ).firstchild( "record" ).firstchild( "info2" ).firstchild().text();
     if ((epgtitle != null) & (channelname != null)) {
       cstdstring cname;
       cstdstring title;
       g_charsetconverter.utf8tostringcharset(channelname->value() ,cname);
       g_charsetconverter.utf8tostringcharset(epgtitle->value() ,title);
       cstdstring newname;
       if (info2!=null){
         cstdstring strinfo2;
         g_charsetconverter.utf8tostringcharset(info2->value() ,strinfo2);
         newname =cname + " - "+ title + ": " + strinfo2;
       }
       else {
         newname =cname + " - "+ title;
       }
       itemstodelete.push_back(pitem); //mark meta-data numbers.xml for deletion from list
       cstdstring strmediafileprefix = pitem->getlabel();
       cutil::removeextension(strmediafileprefix);
       renames.push_back(renamefromto_t(strmediafileprefix , newname)); //mark this xml's prefix for a corresponding rename
     }
   }
   catch (...) {
     clog::log(logdebug, "filterxmlitems tried to parse an xml file that isn't dbox2: %s\n", strxmlfile.c_str());
   }
   }
   }
 }
 // now delete the .xml files
 for (int i = 0; i < (int)itemstodelete.size(); i++)
 {
   for (int j = 0; j < (int)m_items.size(); j++)
   {
     cfileitem *pitem = m_items[j];
     if (stricmp(pitem->m_strpath.c_str(), itemstodelete[i]->m_strpath.c_str()) == 0)
     { // delete this item
       delete pitem;
       m_items.erase(m_items.begin() + j);
       break;
     }
   }
 }
 //rename all files with the same prefix
 for (int i = 0; i < (int)renames.size(); i++)
 {
   for (int j = 0; j < (int)m_items.size(); j++)
   {
     cfileitem *pitem = m_items[j];
   renamefromto_t renamefromto =  renames[i];
   cstdstring oldlabel = pitem->getlabel();
   //check for matching prefixes
   if( oldlabel.find(renamefromto.first) == 0)
     { // rename this item
     oldlabel.replace(renamefromto.first,renamefromto.second);
     pitem->setlabel(oldlabel);
     }
   }
 }
}

ps: i know the code sucks and that its not efficient at all. but it works and wasn't meant for others to be seen Smile



Reply
#11
please explain its purpose in english. i still dont understand why you want the xml files to appear in the filelisting. you shouldnt need that. i was under the impression that you just needed to consult some xml files to get metadata, in order to rename some generic filenames.
Always read the XBMC online-manual, FAQ and search the forum before posting.
Do not e-mail XBMC-Team members directly asking for support. Read/follow the forum rules.
For troubleshooting and bug reporting please make sure you read this first.
Reply
#12
(kraqh3d @ jan. 29 2006,14:32 Wrote:please explain its purpose in english.  i still dont understand why you want the xml files to appear in the filelisting.  you shouldnt need that.  i was under the impression that you just needed to consult some xml files to get metadata, in order to rename some generic filenames.
yes, i'm sorry i didn't go into detail.

my digital sat receiver (dbox) records tv to the xbox as 20060129.001.ts and writes a 20060129.xml (plus 20060129.002 and so on if filesize limit is reached or if it has to pick up recording of the same show after an error).

the xml contains the title from the epg (electr prog guide), the channel name and a short description.

here's what the code does:
if it finds an xml file it parses it to get a channelname + title + description string. this gets stored into the pair together with the prefix of the xml file, so the pair could be <"20060129", "prosieben - friends: rachel dies">.

after creating all those pairs for the folder, the code goes through all files and removes the .xml files from the vector.

in the final phase, it goes through all files again, checks if they start with one of the known "to-be-replaced-prefixes" and if yes replaces that prefix with the proper label (like i said inefficient but that's the "heritage" from the cue filter function i used as base).

of course your approach makes more sense in this case. for each .ts file check if there's a .xml with the same prefix and if yes, grab the title from it.
on the other hand my quick&dirty approach also works for any other file extension that gets accompanied with an xml description as long as the prefixes match.

however i don't see why my approach doesn't work for samba shares. since i don't have a debug setup its pretty hard to work stuff like this out and i'm lucky i made it this far. i can live with no samba support but i figured maybe someone knows the answer.

thanks again for helping me get there.
Reply
#13
you misunderstood. i never said you should limit it only to .ts files (because i originally didnt know the extent of what you were trying to do.) all i suggested is you traverse the current cfileitemlist and replace the extension of the items path with .xml. if said file exists, read it. since you have multipart items, i would make sure that you first pass the cfileitemlist through the stacking routines since they will compress your 20060129.001.ts, 20060129.002.ts, 20060129.003.ts, etc into a single 20060129.ts item. then you can simply match this filename to 20060129.xml to get the info.

one thing you want to do, however, is when you find a matching
"remote" xml file, to cache it locally before openning it. this is why you're having a problem with samba. tinyxml does not understand a path of "smb://mediaserver/recording/20060129.xml". xbmc uses a plug-in system for the filesystems, but these plugins are not extended to tinyxml which is used pretty much in its original code.

updating my original psuedo-code:

Quote:// either stack first or modify the code to change the file to correct match the xml file name
// if you want to keep the different parts then you should continue to use
// the matched pair as a cache so that you dont need to read any single
// xml file more than once
for each pitem:
{
// what xml file to look for?
cutil::replaceextension(pitem->m_strpath, ".xml", strxml)

// does xml file exist?
if (cfile::exists(strxml))
{
// remote file so we need to cache it first
if (cutil::isremote(strxml))
{
// cache file locally to z:\\temp.xml
if (cfile::cache(strxml:, "z:\\temp.xml", null, null))
{
// sucessful cache so update xml file name
strxml = "z:\\temp.xml"
}
// couldnt cache so skip it
else
next pitem
}

// process xml file and return label in strlabel
process(strxml, strlabel)

// change label if not empty
if (!strlabel.isempty())
pitem->setlabel(strlabel)
}
}



Always read the XBMC online-manual, FAQ and search the forum before posting.
Do not e-mail XBMC-Team members directly asking for support. Read/follow the forum rules.
For troubleshooting and bug reporting please make sure you read this first.
Reply

Logout Mark Read Team Forum Stats Members Help
Q: Where to add file filter0