diff --git a/ChangeLog b/ChangeLog index 68ead922..d24a60cf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -15278,3 +15278,6 @@ method in 'lib/rdcart.cpp'. * Removed the 'validity' and 'localCounter' fields from the output of the 'RDCut::xml()' method in 'lib/rdcut.cpp'. +2016-07-12 Fred Gleason + * Added an '--xml' switch to rdimport(1) in + 'utils/rdimport/rdimport.cpp' and 'utils/rdimport/rdimport.h'. diff --git a/docs/docbook/rdimport.xml b/docs/docbook/rdimport.xml index 658ae797..942e8642 100644 --- a/docs/docbook/rdimport.xml +++ b/docs/docbook/rdimport.xml @@ -243,7 +243,8 @@ Attempt to read metadata parameters from the source filename, using the pattern pattern. Patterns consist of a sequence of wildcards and regular characters to - indicate boundaries between metadata fields. + indicate boundaries between metadata fields. This option is + mutually exclusive with the option. The available wildcards are: @@ -774,6 +775,20 @@ + + + + + + + Attempt to read file metadata in RDXML format from the file + basename.xml. + This option is mututally exclusive with the + option. + + + + diff --git a/lib/rdcart.cpp b/lib/rdcart.cpp index d5b988fd..07f53c97 100644 --- a/lib/rdcart.cpp +++ b/lib/rdcart.cpp @@ -1610,85 +1610,109 @@ unsigned RDCart::readXml(std::vector *data,const QString &xml) case 1: // Cart-level objects if(f0[i].contains("")) { cartdata.setCartNumber(GetXmlValue("number",f0[i]).toUInt()); + cartdata.setMetadataFound(true); } if(f0[i].contains("")) { cartdata.setCategory(GetXmlValue("groupName",f0[i]).toString()); + cartdata.setMetadataFound(true); } if(f0[i].contains("")) { cartdata.setTitle(GetXmlValue("title",f0[i]).toString()); + cartdata.setMetadataFound(true); } if(f0[i].contains("<artist>")) { cartdata.setArtist(GetXmlValue("artist",f0[i]).toString()); + cartdata.setMetadataFound(true); } if(f0[i].contains("<album>")) { cartdata.setAlbum(GetXmlValue("album",f0[i]).toString()); + cartdata.setMetadataFound(true); } if(f0[i].contains("<label>")) { cartdata.setLabel(GetXmlValue("label",f0[i]).toString()); + cartdata.setMetadataFound(true); } if(f0[i].contains("<client>")) { cartdata.setClient(GetXmlValue("client",f0[i]).toString()); + cartdata.setMetadataFound(true); } if(f0[i].contains("<agency>")) { cartdata.setAgency(GetXmlValue("agency",f0[i]).toString()); + cartdata.setMetadataFound(true); } if(f0[i].contains("<composer>")) { cartdata.setComposer(GetXmlValue("composer",f0[i]).toString()); + cartdata.setMetadataFound(true); } if(f0[i].contains("<publisher>")) { cartdata.setPublisher(GetXmlValue("publisher",f0[i]).toString()); + cartdata.setMetadataFound(true); } if(f0[i].contains("<conductor>")) { cartdata.setConductor(GetXmlValue("conductor",f0[i]).toString()); + cartdata.setMetadataFound(true); } if(f0[i].contains("<userDefined>")) { cartdata.setUserDefined(GetXmlValue("userDefined",f0[i]).toString()); + cartdata.setMetadataFound(true); } if(f0[i].contains("<year>")) { cartdata.setReleaseYear(GetXmlValue("year",f0[i]).toInt()); + cartdata.setMetadataFound(true); } if(f0[i].contains("<forcedLength>")) { cartdata. setForcedLength(RDSetTimeLength(GetXmlValue("forcedLength",f0[i]). toString())); + cartdata.setMetadataFound(true); } if(f0[i].contains("<averageLength>")) { cartdata. setAverageLength(RDSetTimeLength(GetXmlValue("averageLength",f0[i]). toString())); + cartdata.setMetadataFound(true); } if(f0[i].contains("<lengthDeviation>")) { cartdata.setLengthDeviation(RDSetTimeLength(GetXmlValue("lengthDeviation",f0[i]). toString())); + cartdata.setMetadataFound(true); } if(f0[i].contains("<averageHookLength>")) { cartdata. setAverageHookLength(RDSetTimeLength(GetXmlValue("averageHookLength",f0[i]). toString())); + cartdata.setMetadataFound(true); } if(f0[i].contains("<averageSegueLength>")) { cartdata. setAverageSegueLength(RDSetTimeLength(GetXmlValue("averageSegueLength",f0[i]). toString())); + cartdata.setMetadataFound(true); } if(f0[i].contains("<cutQuantity>")) { cartdata.setCutQuantity(GetXmlValue("cutQuantity",f0[i]).toInt()); + cartdata.setMetadataFound(true); } if(f0[i].contains("<lastCutPlayed>")) { cartdata.setLastCutPlayed(GetXmlValue("lastCutPlayed",f0[i]).toInt()); + cartdata.setMetadataFound(true); } if(f0[i].contains("<enforceLength>")) { cartdata.setEnforceLength(GetXmlValue("enforceLength",f0[i]).toBool()); + cartdata.setMetadataFound(true); } if(f0[i].contains("<asyncronous>")) { cartdata.setAsyncronous(GetXmlValue("asyncronous",f0[i]).toBool()); + cartdata.setMetadataFound(true); } if(f0[i].contains("<owner>")) { cartdata.setOwner(GetXmlValue("owner",f0[i]).toString()); + cartdata.setMetadataFound(true); } if(f0[i].contains("<metadataDatetime>")) { cartdata.setMetadataDatetime(GetXmlValue("metadataDatetime",f0[i]). toDateTime()); + cartdata.setMetadataFound(true); } if(f0[i]=="</cart>") { @@ -1716,108 +1740,139 @@ unsigned RDCart::readXml(std::vector<RDWaveData> *data,const QString &xml) case 3: // Cut Object if(f0[i].contains("<description>")) { - data->back().setDescription(GetXmlValue("description",f0[i]).toString()); + data-> + back().setDescription(GetXmlValue("description",f0[i]).toString()); + cartdata.setMetadataFound(true); } if(f0[i].contains("<cutNumber>")) { data->back().setCutNumber(GetXmlValue("cutNumber",f0[i]).toInt()); + cartdata.setMetadataFound(true); } if(f0[i].contains("<cutName>")) { data->back().setCutName(GetXmlValue("cutName",f0[i]).toString()); + cartdata.setMetadataFound(true); } if(f0[i].contains("<evergreen>")) { data->back().setEvergreen(GetXmlValue("evergreen",f0[i]).toBool()); + cartdata.setMetadataFound(true); } if(f0[i].contains("<outcue>")) { data->back().setOutCue(GetXmlValue("outcue",f0[i]).toString()); + cartdata.setMetadataFound(true); } if(f0[i].contains("<isrc>")) { data->back().setIsrc(GetXmlValue("isrc",f0[i]).toString()); + cartdata.setMetadataFound(true); } if(f0[i].contains("<isci>")) { data->back().setIsci(GetXmlValue("isci",f0[i]).toString()); + cartdata.setMetadataFound(true); } if(f0[i].contains("<length>")) { data->back().setLength(GetXmlValue("length",f0[i]).toInt()); + cartdata.setMetadataFound(true); } if(f0[i].contains("<originName>")) { data->back().setOriginator(GetXmlValue("originName",f0[i]).toString()); + cartdata.setMetadataFound(true); } if(f0[i].contains("<originDatetime>")) { data->back().setOriginationDate(GetXmlValue("originDatetime",f0[i]). toDateTime().date()); data->back().setOriginationTime(GetXmlValue("originDatetime",f0[i]). toDateTime().time()); + cartdata.setMetadataFound(true); } if(f0[i].contains("<playCounter>")) { data->back().setPlayCounter(GetXmlValue("playCounter",f0[i]).toInt()); + cartdata.setMetadataFound(true); } if(f0[i].contains("<startDatetime>")) { data->back().setStartDate(GetXmlValue("startDatetime",f0[i]). toDateTime().date()); data->back().setStartTime(GetXmlValue("startDatetime",f0[i]). toDateTime().time()); + cartdata.setMetadataFound(true); } if(f0[i].contains("<endDatetime>")) { data->back().setEndDate(GetXmlValue("endDatetime",f0[i]). toDateTime().date()); data->back().setEndTime(GetXmlValue("endDatetime",f0[i]). toDateTime().time()); + cartdata.setMetadataFound(true); } if(f0[i].contains("<lastPlayDatetime>")) { data->back().setLastPlayDatetime(GetXmlValue("lastPlayDatetime",f0[i]). toDateTime()); + cartdata.setMetadataFound(true); } if(f0[i].contains("<codingFormat>")) { settings->setFormat((RDSettings::Format)GetXmlValue("codingFormat",f0[i]). toUInt()); + cartdata.setMetadataFound(true); } if(f0[i].contains("<sampleRate>")) { settings->setSampleRate(GetXmlValue("sampleRate",f0[i]).toUInt()); + cartdata.setMetadataFound(true); } if(f0[i].contains("<bitRate>")) { settings->setBitRate(GetXmlValue("bitRate",f0[i]).toUInt()); + cartdata.setMetadataFound(true); } if(f0[i].contains("<channels>")) { settings->setChannels(GetXmlValue("channels",f0[i]).toUInt()); + cartdata.setMetadataFound(true); } if(f0[i].contains("<playGain>")) { data->back().setPlayGain(GetXmlValue("playGain",f0[i]).toInt()); + cartdata.setMetadataFound(true); } if(f0[i].contains("<startPoint>")) { data->back().setStartPos(GetXmlValue("startPoint",f0[i]).toInt()); + cartdata.setMetadataFound(true); } if(f0[i].contains("<endPoint>")) { data->back().setEndPos(GetXmlValue("endPoint",f0[i]).toInt()); + cartdata.setMetadataFound(true); } if(f0[i].contains("<segueStartPoint>")) { data->back().setSegueStartPos(GetXmlValue("segueStartPoint",f0[i]). toInt()); + cartdata.setMetadataFound(true); } if(f0[i].contains("<segueEndPoint>")) { data->back().setSegueEndPos(GetXmlValue("segueEndPoint",f0[i]).toInt()); + cartdata.setMetadataFound(true); } if(f0[i].contains("<segueGain>")) { data->back().setSegueGain(GetXmlValue("segueGain",f0[i]).toInt()); + cartdata.setMetadataFound(true); } if(f0[i].contains("<talkStartPoint>")) { data->back().setIntroStartPos(GetXmlValue("talkStartPoint",f0[i]). toInt()); + cartdata.setMetadataFound(true); } if(f0[i].contains("<talkEndPoint>")) { data->back().setIntroEndPos(GetXmlValue("talkEndPoint",f0[i]).toInt()); + cartdata.setMetadataFound(true); } if(f0[i].contains("<hookStartPoint>")) { data->back().setHookStartPos(GetXmlValue("hookStartPoint",f0[i]). toInt()); + cartdata.setMetadataFound(true); } if(f0[i].contains("<hookEndPoint>")) { data->back().setHookEndPos(GetXmlValue("hookEndPoint",f0[i]).toInt()); + cartdata.setMetadataFound(true); } if(f0[i].contains("<fadeupPoint>")) { data->back().setFadeUpPos(GetXmlValue("fadeupPoint",f0[i]).toInt()); + cartdata.setMetadataFound(true); } if(f0[i].contains("<fadedownPoint>")) { data->back().setFadeDownPos(GetXmlValue("fadedownPoint",f0[i]).toInt()); + cartdata.setMetadataFound(true); } if(f0[i]=="</cut>") { // End of cut @@ -1829,9 +1884,6 @@ unsigned RDCart::readXml(std::vector<RDWaveData> *data,const QString &xml) break; } } - - // printf("DUMP:\n%s\n",(const char *)cartdata.dump()); - return data->size(); } diff --git a/utils/rdimport/rdimport.cpp b/utils/rdimport/rdimport.cpp index 31c7faf7..33d22589 100644 --- a/utils/rdimport/rdimport.cpp +++ b/utils/rdimport/rdimport.cpp @@ -89,6 +89,7 @@ MainObject::MainObject(QObject *parent) import_string_year=0; import_clear_datetimes=false; import_clear_dayparts=false; + import_xml=false; // // Read Command Options @@ -379,7 +380,15 @@ MainObject::MainObject(QObject *parent) } import_cmd->setProcessed(i,true); } + if(import_cmd->key(i)=="--xml") { + import_xml=true; + import_cmd->setProcessed(i,true); + } } + + // + // Sanity Checks + // if(import_datetimes[0].isValid()&&import_clear_datetimes) { fprintf(stderr,"rdimport: --set-datetimes and --clear-datetimes are mutually exclusive\n"); exit(255); @@ -388,6 +397,10 @@ MainObject::MainObject(QObject *parent) fprintf(stderr,"rdimport: --set-daypart-times and --clear-daypart-times are mutually exclusive\n"); exit(255); } + if((!import_metadata_pattern.isEmpty())&&import_xml) { + fprintf(stderr,"rdimport: --metadata-pattern and --xml are mutually exclusive\n"); + exit(255); + } import_cut_markers=new MarkerSet(); import_cut_markers->loadMarker(import_cmd,"cut"); @@ -722,6 +735,9 @@ MainObject::MainObject(QObject *parent) if(import_string_year!=0) { printf(" Year set to: %d\n",import_string_year); } + if(import_xml) { + printf(" Importing RDXML metadata from external file\n"); + } import_cut_markers->dump(); import_talk_markers->dump(); import_hook_markers->dump(); @@ -1026,6 +1042,10 @@ MainObject::Result MainObject::ImportFile(const QString &filename, } } + if(import_xml) { + ReadXmlFile(filename,wavedata); + } + if(import_use_cartchunk_cutid||found_cart) { *cartnum=0; sscanf(wavedata->cutId(),"%u",cartnum); @@ -1897,6 +1917,53 @@ bool MainObject::SchedulerCodeExists(const QString &code) const } +void MainObject::ReadXmlFile(const QString &basename,RDWaveData *wavedata) const +{ + QString xmlname=""; + FILE *f=NULL; + char line[1024]; + QString xml=""; + std::vector<RDWaveData> wavedatas; + + // + // Get XML Filename + // + QStringList f0=f0.split(".",basename); + for(unsigned i=0;i<f0.size()-1;i++) { + xmlname+=f0[i]+"."; + } + xmlname+="xml"; + if(import_verbose) { + printf(" Reading xml metadata from \"%s\": ",(const char *)xmlname); + } + + // + // Read XML + // + wavedata->clear(); + if((f=fopen(xmlname,"r"))==NULL) { + if(import_verbose) { + printf("failed [%s]\n",strerror(errno)); + return; + } + } + if(import_verbose) { + printf("success\n"); + } + while(fgets(line,1024,f)!=NULL) { + xml+=line; + } + fclose(f); + + // + // Parse + // + if(RDCart::readXml(&wavedatas,xml)>0) { + *wavedata=wavedatas[1]; + } +} + + int main(int argc,char *argv[]) { QApplication a(argc,argv,false); diff --git a/utils/rdimport/rdimport.h b/utils/rdimport/rdimport.h index a4cfa523..8ebc560d 100644 --- a/utils/rdimport/rdimport.h +++ b/utils/rdimport/rdimport.h @@ -78,6 +78,7 @@ class MainObject : public QObject QDateTime GetCachedTimestamp(const QString &filename); void WriteTimestampCache(const QString &filename,const QDateTime &dt); bool SchedulerCodeExists(const QString &code) const; + void ReadXmlFile(const QString &basename,RDWaveData *wavedata) const; RDConfig *import_config; RDCmdSwitch *import_cmd; unsigned import_file_key; @@ -107,6 +108,7 @@ class MainObject : public QObject bool import_clear_dayparts; bool import_fix_broken_formats; int import_persistent_dropbox_id; + bool import_xml; unsigned import_format; unsigned import_samprate; unsigned import_bitrate;