summaryrefslogtreecommitdiff
path: root/xml-cache.c
diff options
context:
space:
mode:
Diffstat (limited to 'xml-cache.c')
-rw-r--r--xml-cache.c280
1 files changed, 280 insertions, 0 deletions
diff --git a/xml-cache.c b/xml-cache.c
new file mode 100644
index 0000000..14204b9
--- /dev/null
+++ b/xml-cache.c
@@ -0,0 +1,280 @@
+/*
+ * xml-cache.c
+ */
+
+#include "xml-cache.h"
+#include "cache.h"
+#include "audiorecorder.h"
+
+#include <taglib/mpegfile.h>
+#include <taglib/tag.h>
+
+#include <dirent.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <iostream>
+
+#include "setup.h"
+
+
+using namespace std;
+using namespace a_land;
+
+/* --- cXmlCache ------------------------------------------------------------ */
+
+
+cXmlCache::cXmlCache(void)
+:cXmlBase("cache") {}
+
+
+void cXmlCache::ReadDir(int level, std::string path)
+{
+ DIR *dir;
+ struct dirent entry, *result;
+ struct stat attribute;
+ string fullpath;
+ string file;
+
+ dsyslog("[audiorecorder]: level : %d - %s (%s, %s())", level, path.c_str(), __FILE__, __func__);
+
+
+ dir = opendir(path.c_str());
+ if (! dir)
+ return;
+
+
+ for (readdir_r(dir, &entry, &result); result; readdir_r(dir, &entry, &result)) {
+ file = result->d_name;
+
+ int len = file.length() - 8;
+ if (len < 0)
+ len = 0;
+
+ if (file == "." || file == ".." ||
+ file.substr(len, 8) == ".tmp.mp2")
+ continue;
+
+ fullpath = path;
+
+ string::reverse_iterator i = fullpath.rbegin();
+
+ if (*i != '/') {
+ fullpath.append("/");
+ }
+ fullpath.append(file);
+
+ stat(fullpath.c_str(), &attribute);
+
+ if (! attribute.st_mode & S_IFREG)
+ continue;
+
+ if ( attribute.st_mode & S_IFDIR) {
+ ReadDir(level + 1, fullpath);
+ } else {
+ for (int i1 = 0; i1 < NUM_CODECS; i1++) {
+ std::string tmp1;
+ tmp1 = ".";
+ tmp1.append(audio_codecs[i1]);
+ if (file.substr(file.length() - tmp1.length(), tmp1.length()) == tmp1) {
+ char date_str[11], time_str[6];
+ struct tm *tm_now, tm_store;
+ tm_now = localtime_r(&attribute.st_mtime, &tm_store);
+ strftime(date_str, 11, "%Y-%m-%d", tm_now);
+ strftime(time_str, 6, "%H.%M", tm_now);
+ rebuild_track(fullpath, date_str, time_str);
+ break;
+ }
+ }
+ }
+ }
+ closedir(dir);
+}
+
+void cXmlCache::rebuild(void)
+{
+ clear();
+
+ ReadDir(0, cPluginAudiorecorder::get_recdir().c_str());
+
+ get_document()->InsertEndChild(*get_root());
+
+ get_document()->SaveFile();
+
+ set_root();
+}
+
+
+void cXmlCache::add_track(const cTrackInfo &trackinfo, bool save)
+{
+ if (! get_root() || trackinfo.get_artist().empty() ||
+ trackinfo.get_title().empty())
+ return;
+
+ a_land::TiXmlElement track("track");
+ track.SetAttribute("path", trackinfo.get_partial_path());
+ track.SetAttribute("date", trackinfo.get_date());
+ track.SetAttribute("time", trackinfo.get_time());
+
+ add_subelement(track, "artist", trackinfo.get_artist());
+ add_subelement(track, "title", trackinfo.get_title());
+ add_subelement(track, "album", trackinfo.get_album());
+
+ stringstream tmp;
+ if (trackinfo.get_track() != 0)
+ tmp << trackinfo.get_track();
+
+ add_subelement(track, "tracknr", tmp.str());
+
+ tmp.str("");
+ tmp.clear();
+ if (trackinfo.get_year() != 0)
+ tmp << trackinfo.get_year();
+
+ add_subelement(track, "year", tmp.str());
+ add_subelement(track, "genre", trackinfo.get_genre());
+ add_subelement(track, "channel", trackinfo.get_channel());
+ add_subelement(track, "event", trackinfo.get_event());
+
+ get_root()->InsertEndChild(track);
+
+ if (save) {
+ get_document()->SaveFile();
+ }
+}
+
+
+void cXmlCache::copy_to_objects(void)
+{
+ a_land::TiXmlElement *xml_track = get_root()->FirstChildElement("track");
+
+ while (xml_track) {
+ cTrackInfo trackinfo;
+
+ string path = xml_track->Attribute("path");
+
+ if (path.empty()) {
+ /* remove deleted files from the xml-cache */
+ a_land::TiXmlElement *tmp = xml_track;
+ xml_track = xml_track->NextSiblingElement("track");
+ get_root()->RemoveChild(tmp);
+
+ continue;
+ }
+
+ path.insert(0, cPluginAudiorecorder::get_recdir());
+
+ trackinfo.set_path(path);
+
+ if (access(path.c_str(), F_OK) == -1) {
+ dsyslog("[audiorecorder]: copy %s : (%s, %s())", path.c_str(), __FILE__, __func__);
+ /* remove deleted files from the xml-cache */
+ a_land::TiXmlElement *tmp = xml_track;
+ xml_track = xml_track->NextSiblingElement("track");
+ get_root()->RemoveChild(tmp);
+
+ continue;
+ }
+
+ if (xml_track->Attribute("date"))
+ trackinfo.set_date(xml_track->Attribute("date"));
+ if (xml_track->Attribute("time"))
+ trackinfo.set_time(xml_track->Attribute("time"));
+
+ for (a_land::TiXmlElement *element = xml_track->FirstChildElement();
+ element; element = element->NextSiblingElement()) {
+ if (element->FirstChild() == NULL)
+ continue;
+ else if (element->ValueStr() == "artist")
+ trackinfo.set_artist(
+ element->FirstChild()->Value());
+ else if (element->ValueStr() == "title")
+ trackinfo.set_title(
+ element->FirstChild()->Value());
+ else if (element->ValueStr() == "album")
+ trackinfo.set_album(
+ element->FirstChild()->Value());
+ else if (element->ValueStr() == "tracknr")
+ trackinfo.set_track(
+ atoi(element->FirstChild()->Value()));
+ else if (element->ValueStr() == "year")
+ trackinfo.set_year(
+ atoi(element->FirstChild()->Value()));
+ else if (element->ValueStr() == "genre")
+ trackinfo.set_genre(
+ element->FirstChild()->Value());
+ else if (element->ValueStr() == "channel")
+ trackinfo.set_channel(
+ element->FirstChild()->Value());
+ else if (element->ValueStr() == "event")
+ trackinfo.set_event(
+ element->FirstChild()->Value());
+ }
+
+ if (! trackinfo.get_title().empty() &&
+ ! trackinfo.get_artist().empty())
+ Cache.add_track(trackinfo, false);
+
+ xml_track = xml_track->NextSiblingElement("track");
+ }
+ get_document()->SaveFile();
+}
+
+
+void cXmlCache::rebuild_track(const string &path, const char *date,
+ const char *time)
+{
+ if (cPluginAudiorecorder::get_dbg_level() > 1)
+ cout << "rebuilding track: " << path << endl;
+
+ TagLib::MPEG::File file(path.c_str());
+ TagLib::Tag *tag = file.tag();
+
+ if (! tag)
+ return;
+
+ cTrackInfo trackinfo;
+
+ trackinfo.set_path(path);
+ trackinfo.set_date(date);
+ trackinfo.set_time(time);
+
+ if (! tag->artist().isEmpty())
+ trackinfo.set_artist(tag->artist().toCString());
+
+ if (! tag->title().isEmpty())
+ trackinfo.set_title(tag->title().toCString());
+
+ if (! tag->album().isEmpty())
+ trackinfo.set_album(tag->album().toCString());
+
+ if (tag->track() != 0)
+ trackinfo.set_track(tag->track());
+
+ if (tag->year() != 0)
+ trackinfo.set_year(tag->year());
+
+ if (! tag->genre().isEmpty())
+ trackinfo.set_genre(tag->genre().toCString());
+
+ if (! tag->comment().isEmpty()) {
+ string com = tag->comment().toCString();
+ trackinfo.set_comment(com.c_str());
+ string::size_type f1 = com.find("recorded on \"");
+ string::size_type f2 = com.find("(vdr-audiorecorder ");
+ if (f1 != string::npos && f2 != string::npos) {
+ com.erase(0, 13);
+ string::size_type p1 = com.find_last_of('@');
+ string::size_type p2 = com.find_last_of('"');
+ if (p1 != string::npos) {
+ trackinfo.set_event(com.substr(0, p1));
+ if (p2 != string::npos)
+ trackinfo.set_channel(com.substr(p1 + 1,
+ p2 - p1 - 1));
+ }
+ }
+ }
+
+ Cache.add_track(trackinfo, false);
+ add_track(trackinfo, false);
+}