void playlist_removed(playlist_t &playlist_) { // TODO: call removing_queue_entry() for each entry before and after removing them queue_by_playlist_t &queue_by_playlist = queue.template get < playlist_tag > (); queue_by_playlist.erase(queue_by_playlist.lower_bound(&playlist_), queue_by_playlist.upper_bound(&playlist_)); if (queue.empty()) { get_derived().stop_watchdog_timer(); get_derived().scanning_in_progress(false); } }
void issue_scan_request(ion::uri const &uri_, playlist_t &playlist_) { bool queue_was_empty = queue.empty(); get_derived().adding_queue_entry(uri_, playlist_, true); queue.push_back(entry(uri_, &playlist_)); get_derived().adding_queue_entry(uri_, playlist_, false); if (queue_was_empty) { get_derived().scanning_in_progress(true); get_derived().restart_watchdog_timer(); request_next_metadata(); } }
void request_next_metadata() { if (queue.empty()) return; entry front_entry = queue.front(); get_derived().send_to_backend(std::string("get_metadata \"") + front_entry.uri_.get_full() + '"'); }
// called by the derived class when the backend dies unexpectedly void backend_crashed() { if (!queue.empty()) { entry front_entry = queue.front(); queue.pop_front(); get_derived().scanning_failed(front_entry.uri_, *(front_entry.playlist_)); } get_derived().restart_backend(); if (!queue.empty()) { get_derived().restart_watchdog_timer(); request_next_metadata(); } else { get_derived().stop_watchdog_timer(); get_derived().scanning_in_progress(false); } }
void cancel_scan() { queue.clear(); get_derived().stop_watchdog_timer(); get_derived().scanning_in_progress(false); }
Derived_& operator -=(Distance_ n) { get_derived().advance(-n); return get_derived(); }
Derived_ operator --(int) { Derived_ tmp(get_derived()); --*this; return tmp; }
Derived_ operator -(Distance_ n) const { Derived_ tmp(get_derived()); return tmp -= n; }
Derived_ operator ++(int) { Derived_ tmp(get_derived()); ++*this; return tmp; }
Derived_& operator ++() { get_derived().increment(); return get_derived(); }
const Pointer_ operator ->() const { return &(get_derived().dereference()); }
const Reference_ operator *() const { return get_derived().dereference(); }
bool operator >(Derived_ other) const { return get_derived().distance_to(other) > 0; }
bool operator ==(Derived_ other) const { return get_derived().equal(other); }
Reference_ operator [](Distance_ n) const { Derived_ tmp(get_derived()); tmp.advance(n); return tmp.dereference(); }
Derived_& operator --() { get_derived().decrement(); return get_derived(); }
void parse_backend_event(std::string const &line) { std::string command; params_t params; split_command_line(line, command, params); queue_by_uri_t &queue_by_uri = queue.template get < uri_tag > (); typename queue_by_uri_t::iterator resource_by_uri_iter = queue_by_uri.end(); if (params.size() > 0) resource_by_uri_iter = queue_by_uri.find(params[0]); if (resource_by_uri_iter != queue_by_uri.end()) { uri uri_ = resource_by_uri_iter->uri_; playlist_t *playlist_ = resource_by_uri_iter->playlist_; bool playlist_exists = has_playlist(playlists_, *playlist_); if (playlist_exists) { if ((command == "metadata") && (params.size() >= 2)) { metadata_optional_t new_metadata = parse_metadata(params[1]); if (new_metadata) { long num_sub_resources = get_metadata_value < long > (*new_metadata, "num_sub_resources", 0); long min_sub_resource_index = get_metadata_value < long > (*new_metadata, "min_sub_resource_index", 0); uri::options_t::const_iterator uri_resource_index_iter = uri_.get_options().find("sub_resource_index"); bool has_resource_index = (uri_resource_index_iter != uri_.get_options().end()); if ((num_sub_resources > 1) && !has_resource_index) { for (int i = 0; i < num_sub_resources; ++i) { unsigned int sub_resource_index = min_sub_resource_index + i; uri sub_uri = uri_; sub_uri.get_options()["sub_resource_index"] = boost::lexical_cast < std::string > (sub_resource_index); //queue_sequence_t &queue_sequence = queue.template get < sequence_tag > (); typename queue_sequence_t::iterator seq_iter = queue.template project < sequence_tag > (resource_by_uri_iter); queue.insert(seq_iter, entry(sub_uri, playlist_)); } } else { if (has_metadata_value(*new_metadata, "title") && has_resource_index) { std::string title = get_metadata_value < std::string > (*new_metadata, "title", ""); std::stringstream sstr; std::string resource_index_str = uri_resource_index_iter->second; try { // This compensates for the 0-starting indices int resource_index = boost::lexical_cast < int > (resource_index_str); resource_index_str = boost::lexical_cast < std::string > (resource_index + 1 - min_sub_resource_index); } catch (boost::bad_lexical_cast const &) { } sstr << title << " (" << resource_index_str << "/" << num_sub_resources << ")"; set_metadata_value(*new_metadata, "title", sstr.str()); } get_derived().resource_successfully_scanned(uri_, *playlist_, *new_metadata); } } else get_derived().unrecognized_resource(uri_, *playlist_); } else if (command == "resource_corrupted") { get_derived().resource_corrupted(uri_, *playlist_); } else if (command == "unrecognized_resource") { get_derived().unrecognized_resource(uri_, *playlist_); } /*else if (command == "error") { get_derived().resource_scan_error(uri_, *playlist_, (params.size() >= 2) ? params[1] : boost::none); }*/ } else std::cerr << "uri " << uri_.get_full() << " playlist is from a playlist that does not exist\n"; { if (playlist_exists) get_derived().removing_queue_entry(uri_, *playlist_, true); queue_by_uri.erase(resource_by_uri_iter); if (playlist_exists) get_derived().removing_queue_entry(uri_, *playlist_, false); } if (queue.empty()) { get_derived().stop_watchdog_timer(); get_derived().scanning_in_progress(false); } else { get_derived().restart_watchdog_timer(); request_next_metadata(); } } }
Distance_ operator -(Derived_ other) const { return other.distance_to(get_derived()); }