Album* Album::forId(int albumId) { if (cache.contains(albumId)) { // get from cache // qDebug() << "Album was cached" << albumId; return cache.value(albumId); } QSqlDatabase db = Database::instance().getConnection(); QSqlQuery query(db); query.prepare("select title, year, artist from albums where id=?"); query.bindValue(0, albumId); bool success = query.exec(); if (!success) qDebug() << query.lastQuery() << query.lastError().text(); if (query.next()) { Album* album = new Album(); album->setId(albumId); album->setTitle(query.value(0).toString()); album->setYear(query.value(1).toInt()); // relations int artistId = query.value(2).toInt(); // TODO this could be made lazy album->setArtist(Artist::forId(artistId)); // put into cache cache.insert(albumId, album); return album; } cache.insert(albumId, 0); return 0; }
vector<string> MusicVideoService::downloadAudio(const string& url) { LOG(INFO) << "downloadYouTubeAudio with url " << url; vector<string> filepaths; boost::filesystem::path tmpPath(SoulSifterSettings::getInstance().get<string>("dir.tmp")); // todo: use os.tmpdir() if (!boost::filesystem::exists(tmpPath)) { if (!boost::filesystem::create_directories(tmpPath)) { LOG(WARNING) << "Unable to create temporary directory " << tmpPath; return filepaths; } } else if (!boost::filesystem::is_directory(tmpPath)) { LOG(WARNING) << "Temporary directory is not a directory " << tmpPath; return filepaths; } FILE *fpipe; stringstream command; command << "cd " << tmpPath << "; youtube-dl --print-json --write-all-thumbnails --restrict-filenames --extract-audio --audio-format mp3 --audio-quality 0 --quiet " << url; if (!(fpipe = (FILE*)popen(command.str().c_str(), "r"))) { LOG(WARNING) << "Problem with youtube-dl pipe."; return filepaths; } char buffer[1024]; stringstream ss; LOG(INFO) << "Running command '" << command.str() << "'"; while (fgets(buffer, sizeof buffer, fpipe)) { ss << buffer; } pclose(fpipe); // read output string json; while (std::getline(ss, json, '\n')) { if (json.at(0) == '{') { boost::property_tree::ptree ptree; std::stringstream tmp(json); read_json(tmp, ptree); Song* song = new Song(); Album* album = new Album(); song->setAlbum(album); string baseFileName = ptree.get<string>("_filename").substr(0, ptree.get<string>("_filename").size() - ptree.get<string>("ext").size()); song->setFilepath(SoulSifterSettings::getInstance().get<string>("dir.tmp") + '/' + baseFileName + "mp3"); album->setCoverFilepath(SoulSifterSettings::getInstance().get<string>("dir.tmp") + '/' + baseFileName + "jpg"); string title = ptree.get<string>("title"); if (!MusicManager::getInstance().splitArtistAndTitle(title, song)) { song->setArtist(ptree.get<string>("uploader")); song->setTitle(title); } MusicManager::getInstance().moveFeaturing(song); MusicManager::getInstance().copyRemixer(song); song->setLowQuality(true); song->setCurator(ptree.get<string>("uploader")); string date = ptree.get<string>("upload_date", "00000000"); if (!date.empty() && !!date.compare("null")) { album->setReleaseDateYear(std::stoi(date.substr(0, 4))); album->setReleaseDateMonth(std::stoi(date.substr(4, 2))); album->setReleaseDateDay(std::stoi(date.substr(6, 4))); } album->setArtist(song->getArtist()); album->setName(song->getTitle()); TagService::writeId3v2Tag(song); filepaths.push_back(song->getFilepath()); filepaths.push_back(album->getCoverFilepath()); delete song; return filepaths; } } return filepaths; }