/** finds tags that have been added or removed or updated */ void update_tags( const comment_object& c )const { try { auto hot = calculate_hot(c); comment_metadata meta; if( c.json_metadata.size() ){ meta = fc::json::from_string( c.json_metadata ).as<comment_metadata>(); } set<string> lower_tags; for( const auto& tag : meta.tags ) lower_tags.insert(fc::to_lower( tag ) ); lower_tags.insert( fc::to_lower(c.category) ); /// the universal tag applies to everything safe for work or nsfw with a positive payout if( c.net_rshares >= 0 || (lower_tags.find( "spam" ) == lower_tags.end() && lower_tags.find( "nsfw" ) == lower_tags.end() && lower_tags.find( "test" ) == lower_tags.end() ) ) { lower_tags.insert( string() ); /// add it to the universal tag } meta.tags = lower_tags; /// TODO: std::move??? const auto& comment_idx = _db.get_index_type<tag_index>().indices().get<by_comment>(); auto citr = comment_idx.lower_bound( c.id ); map<string, const tag_object*> existing_tags; vector<const tag_object*> remove_queue; while( citr != comment_idx.end() && citr->comment == c.id ) { const tag_object* tag = &*citr; ++citr; if( meta.tags.find( tag->tag ) == meta.tags.end() ) { remove_queue.push_back(tag); } else { existing_tags[tag->tag] = tag; } } for( const auto& tag : meta.tags ) { auto existing = existing_tags.find(tag); if( existing == existing_tags.end() ) { create_tag( tag, c, hot ); } else { update_tag( *existing->second, c, hot ); } } for( const auto& item : remove_queue ) remove_tag(*item); if( c.parent_author.size() ) { update_tags( _db.get_comment( c.parent_author, c.parent_permlink ) ); } } FC_CAPTURE_LOG_AND_RETHROW( (c) ) }
/** finds tags that have been added or removed or updated */ void update_tags( const comment_object& c )const { try { auto hot = calculate_hot(c); comment_metadata meta; if( c.json_metadata.size() ) { try { meta = fc::json::from_string( c.json_metadata ).as<comment_metadata>(); } catch( const fc::exception& e ) { // Do nothing on malformed json_metadata } } set<string> lower_tags; for( const auto& tag : meta.tags ) lower_tags.insert(fc::to_lower( tag ) ); lower_tags.insert( fc::to_lower(c.category) ); bool safe_for_work = false; /// the universal tag applies to everything safe for work or nsfw with a positive payout if( c.net_rshares >= 0 || (lower_tags.find( "spam" ) == lower_tags.end() && lower_tags.find( "nsfw" ) == lower_tags.end() && lower_tags.find( "test" ) == lower_tags.end() ) ) { safe_for_work = true; lower_tags.insert( string() ); /// add it to the universal tag } meta.tags = lower_tags; /// TODO: std::move??? if( meta.tags.size() > 7 ) { //wlog( "ignoring post ${a} because it has ${n} tags",("a", c.author + "/"+c.permlink)("n",meta.tags.size())); if( safe_for_work ) meta.tags = set<string>({"", c.parent_permlink}); else meta.tags.clear(); } const auto& comment_idx = _db.get_index_type<tag_index>().indices().get<by_comment>(); auto citr = comment_idx.lower_bound( c.id ); map<string, const tag_object*> existing_tags; vector<const tag_object*> remove_queue; while( citr != comment_idx.end() && citr->comment == c.id ) { const tag_object* tag = &*citr; ++citr; if( meta.tags.find( tag->tag ) == meta.tags.end() ) { remove_queue.push_back(tag); } else { existing_tags[tag->tag] = tag; } } for( const auto& tag : meta.tags ) { auto existing = existing_tags.find(tag); if( existing == existing_tags.end() ) { create_tag( tag, c, hot ); } else { update_tag( *existing->second, c, hot ); } } for( const auto& item : remove_queue ) remove_tag(*item); if( c.parent_author.size() ) { update_tags( _db.get_comment( c.parent_author, c.parent_permlink ) ); } } FC_CAPTURE_LOG_AND_RETHROW( (c) ) }