mitk::PropertyPersistence::InfoResultType mitk::PropertyPersistence::GetInfo(const std::string &propertyName, const MimeTypeNameType &mime, bool allowMimeWildCard, bool allowNameRegEx) const { SelectFunctionType select = [propertyName, mime](const InfoMap::value_type &x) { return infoPredicate(x, propertyName, mime); }; InfoMap selection = SelectInfo(m_InfoMap, select); if (allowNameRegEx) { select = [propertyName, mime](const InfoMap::value_type &x) { return infoPredicateRegEx(x, propertyName, mime); }; InfoMap regExSelection = SelectInfo(m_InfoMap, select); selection.insert(regExSelection.begin(), regExSelection.end()); } if (selection.empty() && allowMimeWildCard) { // no perfect match => second run through with "any mime type" select = [propertyName](const InfoMap::value_type &x) { return infoPredicate(x, propertyName, PropertyPersistenceInfo::ANY_MIMETYPE_NAME()); }; selection = SelectInfo(m_InfoMap, select); if (allowNameRegEx) { select = [propertyName](const InfoMap::value_type &x) { return infoPredicateRegEx(x, propertyName, PropertyPersistenceInfo::ANY_MIMETYPE_NAME()); }; InfoMap regExSelection = SelectInfo(m_InfoMap, select); selection.insert(regExSelection.begin(), regExSelection.end()); } } InfoResultType result; for (const auto &pos : selection) { result.push_back(pos.second->UnRegExByName(propertyName).GetPointer()); } return result; }
mitk::PropertyPersistence::InfoMap mitk::PropertyPersistence::SelectInfo(const InfoMap &infoMap, const SelectFunctionType &selectFunction) { InfoMap result; for (auto pos : infoMap) { if (selectFunction(pos)) { result.insert(pos); } } return result; };
void MediaAddonServer::_AddOnAdded(const char* path, ino_t fileNode) { TRACE("\n\nMediaAddonServer::_AddOnAdded: path %s\n", path); media_addon_id id = gDormantNodeManager->RegisterAddOn(path); if (id <= 0) { ERROR("MediaAddonServer::_AddOnAdded: failed to register add-on %s\n", path); return; } TRACE("MediaAddonServer::_AddOnAdded: loading addon %ld now...\n", id); BMediaAddOn* addon = gDormantNodeManager->GetAddOn(id); if (addon == NULL) { ERROR("MediaAddonServer::_AddOnAdded: failed to get add-on %s\n", path); gDormantNodeManager->UnregisterAddOn(id); return; } TRACE("MediaAddonServer::_AddOnAdded: loading finished, id %ld\n", id); try { // put file's inode and addon's id into map fFileMap.insert(std::make_pair(fileNode, id)); AddOnInfo info; fInfoMap.insert(std::make_pair(id, info)); } catch (std::bad_alloc& exception) { fFileMap.erase(fileNode); return; } InfoMap::iterator found = fInfoMap.find(id); AddOnInfo& info = found->second; info.id = id; info.wants_autostart = false; // temporary default info.flavor_count = 0; info.addon = addon; // scan the flavors _ScanAddOnFlavors(addon); // need to call BMediaNode::WantsAutoStart() // after the flavors have been scanned info.wants_autostart = addon->WantsAutoStart(); if (info.wants_autostart) TRACE("add-on %ld WantsAutoStart!\n", id); // During startup, first all add-ons are loaded, then all // nodes (flavors) representing physical inputs and outputs // are instantiated. Next, all add-ons that need autostart // will be autostarted. Finally, add-ons that don't have // any active nodes (flavors) will be unloaded. // After startup is done, we simply do it for each new // loaded add-on, too. if (!fStartup) { _InstantiatePhysicalInputsAndOutputs(info); _InstantiateAutostartFlavors(info); _PutAddonIfPossible(info); // since something might have changed server_rescan_defaults_command cmd; SendToServer(SERVER_RESCAN_DEFAULTS, &cmd, sizeof(cmd)); } // we do not call gDormantNodeManager->PutAddOn(id) // since it is done by _PutAddonIfPossible() }
bool UPNPSubscription::ProcessRequest(HTTPRequest *pRequest) { if (!pRequest) return false; if (pRequest->m_sBaseUrl != "/Subscriptions") return false; if (pRequest->m_sMethod != "event") return false; LOG(VB_UPNP, LOG_DEBUG, LOC + QString("%1\n%2") .arg(pRequest->m_sRawRequest).arg(pRequest->m_sPayload)); if (pRequest->m_sPayload.isEmpty()) return true; pRequest->m_eResponseType = ResponseTypeHTML; QString nt = pRequest->m_mapHeaders["nt"]; QString nts = pRequest->m_mapHeaders["nts"]; bool no = (pRequest->m_eType == RequestTypeNotify); if (nt.isEmpty() || nts.isEmpty() || !no) { pRequest->m_nResponseStatus = 400; return true; } pRequest->m_nResponseStatus = 412; if (nt != "upnp:event" || nts != "upnp:propchange") return true; QString usn = pRequest->m_mapParams["usn"]; QString sid = pRequest->m_mapHeaders["sid"]; if (usn.isEmpty() || sid.isEmpty()) return true; // N.B. Validating the usn and uuid here might mean blocking for some time // while waiting for a subscription to complete. While this operates in a // worker thread, worker threads are a limited resource which we could // rapidly overload if a number of events arrive. Instead let the // subscribing objects validate the usn - the uuid should be superfluous. QString seq = pRequest->m_mapHeaders["seq"]; // mediatomb sends some extra character(s) at the end of the payload // which throw Qt, so try and trim them off int loc = pRequest->m_sPayload.lastIndexOf("propertyset>"); QString payload = (loc > -1) ? pRequest->m_sPayload.left(loc + 12) : pRequest->m_sPayload; LOG(VB_UPNP, LOG_DEBUG, LOC + QString("Payload:\n%1").arg(payload)); pRequest->m_nResponseStatus = 400; QDomDocument body; QString error; int errorCol = 0; int errorLine = 0; if (!body.setContent(payload, true, &error, &errorLine, &errorCol)) { LOG(VB_GENERAL, LOG_ERR, LOC + QString("Failed to parse event: Line: %1 Col: %2 Error: '%3'") .arg(errorLine).arg(errorCol).arg(error)); return true; } LOG(VB_UPNP, LOG_DEBUG, LOC + "/n/n" + body.toString(4) + "/n/n"); QDomNodeList properties = body.elementsByTagName("property"); InfoMap results; // this deals with both one argument per property (compliant) and mutliple // arguments per property as sent by mediatomb for (int i = 0; i < properties.size(); i++) { QDomNodeList arguments = properties.at(i).childNodes(); for (int j = 0; j < arguments.size(); j++) { QDomElement e = arguments.at(j).toElement(); if (!e.isNull() && !e.text().isEmpty() && !e.tagName().isEmpty()) results.insert(e.tagName(), e.text()); } } // using MythObservable allows multiple objects to subscribe to the same // service but is less efficient from an eventing perspective, especially // if multiple objects are subscribing if (!results.isEmpty()) { pRequest->m_nResponseStatus = 200; results.insert("usn", usn); results.insert("seq", seq); MythInfoMapEvent me("UPNP_EVENT", results); dispatch(me); } return true; }
bool CAddonDatabase::GetAddon(int id, AddonPtr &addon) { try { if (NULL == m_pDB.get()) return false; if (NULL == m_pDS2.get()) return false; std::string sql = "SELECT addon.*," " broken.reason," " addonextra.key, addonextra.value," " dependencies.addon, dependencies.version, dependencies.optional" " FROM addon" " LEFT JOIN broken" " ON broken.addonID = addon.addonID" " LEFT JOIN addonextra" " ON addonextra.id = addon.id" " LEFT JOIN dependencies" " ON dependencies.id = addon.id"; sql += PrepareSQL(" WHERE addon.id=%i", id); m_pDS2->query(sql); if (!m_pDS2->eof()) { const dbiplus::query_data &data = m_pDS2->get_result_set().records; const dbiplus::sql_record* const record = data[0]; CAddonBuilder builder; builder.SetId(record->at(addon_addonID).get_asString()); builder.SetType(TranslateType(record->at(addon_type).get_asString())); builder.SetVersion(AddonVersion(record->at(addon_version).get_asString())); builder.SetMinVersion(AddonVersion(record->at(addon_minversion).get_asString())); builder.SetName(record->at(addon_name).get_asString()); builder.SetSummary(record->at(addon_summary).get_asString()); builder.SetDescription(record->at(addon_description).get_asString()); builder.SetChangelog(record->at(addon_changelog).get_asString()); builder.SetDisclaimer(record->at(addon_disclaimer).get_asString()); builder.SetAuthor(record->at(addon_author).get_asString()); builder.SetBroken(record->at(broken_reason).get_asString()); builder.SetPath(record->at(addon_path).get_asString()); builder.SetIcon(record->at(addon_icon).get_asString()); builder.SetFanart(record->at(addon_fanart).get_asString()); InfoMap extrainfo; ADDONDEPS dependencies; /* while this is a cartesion join and we'll typically get multiple rows, we rely on the fact that extrainfo and dependencies are maps, so insert() will insert the first instance only */ for (dbiplus::query_data::const_iterator i = data.begin(); i != data.end(); ++i) { const dbiplus::sql_record* const record = *i; if (!record->at(addonextra_key).get_asString().empty()) extrainfo.insert(std::make_pair(record->at(addonextra_key).get_asString(), record->at(addonextra_value).get_asString())); if (!m_pDS2->fv(dependencies_addon).get_asString().empty()) dependencies.insert(std::make_pair(record->at(dependencies_addon).get_asString(), std::make_pair(AddonVersion(record->at(dependencies_version).get_asString()), record->at(dependencies_optional).get_asBool()))); } builder.SetExtrainfo(std::move(extrainfo)); builder.SetDependencies(std::move(dependencies)); addon = builder.Build(); return NULL != addon.get(); } } catch (...) { CLog::Log(LOGERROR, "%s failed on addon %i", __FUNCTION__, id); } addon.reset(); return false; }
/** \fn GalleryWidget::ShowFileDetails() * \brief Shows the available details of the current image file. The details will only be shown if the file is an image. * \return void */ void GalleryWidget::ShowFileDetails() { ImageMetadata *im = m_fileDataList->at(m_index); if (!im) { delete im; return; } if (im->m_type != kImageFile) { delete im; return; } // First remove all entries m_infoList->Reset(); // This map holds all the exif tag values QMap<QString, QString> infoList; // Get all the available exif header information from the file // and create a data structure that can be displayed nicely QByteArray ba = m_fh->GetExifValues(im); if (ba.count() > 0) { bool readTagValues = false; QString key, value; QXmlStreamReader xml(ba); while (!xml.atEnd()) { xml.readNext(); // Read the general information if (xml.isStartElement() && (xml.name() == "Count" || xml.name() == "File" || xml.name() == "Path" || xml.name() == "Size" || xml.name() == "Extension")) infoList.insert(xml.name().toString(), xml.readElementText()); if (xml.isStartElement() && xml.name() == "ImageMetadataInfo") readTagValues = true; if (readTagValues) { if (xml.isStartElement() && xml.name() == "Label") key = xml.readElementText(); if (xml.isStartElement() && xml.name() == "Value") value = xml.readElementText(); } if (xml.isEndElement() && xml.name() == "ImageMetadataInfo") { readTagValues = false; infoList.insert(key, value); } } } // Now go through the info list and create a map for the mythui buttonlist QMap<QString, QString>::const_iterator i = infoList.constBegin(); while (i != infoList.constEnd()) { MythUIButtonListItem *item = new MythUIButtonListItem(m_infoList, ""); InfoMap infoMap; infoMap.insert("name", i.key()); QString value = tr("Not defined"); if (!i.value().isEmpty()) value = i.value(); infoMap.insert("value", value); item->SetTextFromMap(infoMap); ++i; } m_infoList->SetVisible(true); // All widgets are visible, remember this m_infoVisible = true; SetFocusWidget(m_infoList); delete im; }