/* Copyright (C) 2003-2006 Paul Davis This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include #include #include #include #include "i18n.h" using namespace std; using namespace ARDOUR; static const char* TAG = "http://ardour.org/ontology/Tag"; AudioLibrary::AudioLibrary () { /* XXX URL - '/' is always the separator */ src = "file:" + get_user_ardour_path() + "/sfdb"; // workaround for possible bug in raptor that crashes when saving to a // non-existant file. touch_file(Glib::build_filename (get_user_ardour_path(), "sfdb")); lrdf_read_file(src.c_str()); } AudioLibrary::~AudioLibrary () { } void AudioLibrary::save_changes () { if (lrdf_export_by_source(src.c_str(), src.substr(5).c_str())) { PBD::warning << string_compose(_("Could not open %1. Audio Library not saved"), src) << endmsg; } } string AudioLibrary::path2uri (string path) { xmlURI temp; memset(&temp, 0, sizeof(temp)); xmlChar *cal = xmlCanonicPath((xmlChar*) path.c_str()); temp.path = (char *) cal; xmlChar *ret = xmlSaveUri(&temp); xmlFree(cal); stringstream uri; uri << "file:" << (const char*) ret; xmlFree (ret); return uri.str(); } string AudioLibrary::uri2path (string uri) { string path = xmlURIUnescapeString(uri.c_str(), 0, 0); return path.substr(5); } void AudioLibrary::set_tags (string member, vector tags) { sort (tags.begin(), tags.end()); tags.erase (unique(tags.begin(), tags.end()), tags.end()); string file_uri(path2uri(member)); lrdf_remove_uri_matches (file_uri.c_str()); for (vector::iterator i = tags.begin(); i != tags.end(); ++i) { lrdf_add_triple (src.c_str(), file_uri.c_str(), TAG, (*i).c_str(), lrdf_literal); } } vector AudioLibrary::get_tags (string member) { vector tags; lrdf_statement pattern; pattern.subject = strdup(path2uri(member).c_str()); pattern.predicate = (char*)TAG; pattern.object = 0; pattern.object_type = lrdf_literal; lrdf_statement* matches = lrdf_matches (&pattern); free (pattern.subject); lrdf_statement* current = matches; while (current != 0) { tags.push_back (current->object); current = current->next; } lrdf_free_statements (matches); sort (tags.begin(), tags.end()); return tags; } void AudioLibrary::search_members_and (vector& members, const vector tags) { lrdf_statement **head; lrdf_statement* pattern = 0; lrdf_statement* old = 0; head = &pattern; vector::const_iterator i; for (i = tags.begin(); i != tags.end(); ++i){ pattern = new lrdf_statement; pattern->subject = (char*)"?"; pattern->predicate = (char*)TAG; pattern->object = strdup((*i).c_str()); pattern->next = old; old = pattern; } if (*head != 0) { lrdf_uris* ulist = lrdf_match_multi(*head); for (uint32_t j = 0; ulist && j < ulist->count; ++j) { // cerr << "AND: " << uri2path(ulist->items[j]) << endl; members.push_back(uri2path(ulist->items[j])); } lrdf_free_uris(ulist); sort(members.begin(), members.end()); unique(members.begin(), members.end()); } // memory clean up pattern = *head; while(pattern){ free(pattern->object); old = pattern; pattern = pattern->next; delete old; } }