示例#1
0
SearchResultList ShareManager::search(SearchQuery&& query, size_t maxResults) noexcept {
	SearchResultList results;

	Lock l(cs);

	if(query.root != NULL) {
		auto i = tthIndex.find(*(query.root));
		if(i != tthIndex.end()) {
			results.push_back(new SearchResult(SearchResult::TYPE_FILE, i->second->getSize(),
				i->second->getParent()->getFullName() + i->second->getName(), i->second->tth));
			addHits(1);
		}
		return results;
	}

	for(auto& i: query.includeInit) {
		if(!bloom.match(i.getPattern()))
			return results;
	}

	for(auto& dir: directories) {
		dir.second->search(results, query, maxResults);

		if(results.size() >= maxResults) { return results; }
	}

	return results;
}
示例#2
0
	api_return SearchResultInfo::download(const string& aTargetDirectory, const string& aTargetName, TargetUtil::TargetType aTargetType, QueueItemBase::Priority aPrio) {
		bool fileDownload = sr->getType() == SearchResult::TYPE_FILE;

		auto download = [&](const SearchResultPtr& aSR) {
			if (fileDownload) {
				QueueManager::getInstance()->createFileBundle(aTargetDirectory + aTargetName, sr->getSize(), sr->getTTH(), sr->getUser(), sr->getDate(), 0, aPrio);
			} else {
				DirectoryListingManager::getInstance()->addDirectoryDownload(aSR->getFilePath(), aTargetName, aSR->getUser(), aTargetDirectory, aTargetType,
					false, aPrio, false, 0, false, false);
			}
		};

		if (hits >= 1) {
			//perform also for the children
			SearchResultList results = { sr };
			for (auto si : children)
				results.push_back(si->sr);

			SearchResult::pickResults(results, SETTING(MAX_AUTO_MATCH_SOURCES));

			boost::for_each(results, download);
		} else {
			//perform for the parent
			download(sr);
		}

		return websocketpp::http::status_code::ok;
	}
示例#3
0
/**
 * Alright, the main point here is that when searching, a search string is most often found in
 * the filename, not directory name, so we want to make that case faster. Also, we want to
 * avoid changing StringLists unless we absolutely have to --> this should only be done if a string
 * has been matched in the directory name. This new stringlist should also be used in all descendants,
 * but not the parents...
 */
void ShareManager::Directory::search(SearchResultList& results, SearchQuery& query, size_t maxResults) const noexcept {
	if(query.isExcluded(name))
		return;

	// Find any matches in the directory name and removed matched terms from the query.
	StringSearch::List newTerms;

	for(auto& term: query.include) {
		if(term.match(name)) {
			if(!newTerms.empty()) {
				newTerms = query.include;
			}
			newTerms.erase(remove(newTerms.begin(), newTerms.end(), term), newTerms.end());
		}
	}

//	auto const old = query.include;

	if(!newTerms.empty()) {
		query.include = newTerms;
	}

	if(query.include.empty() && query.ext.empty() && query.gt == 0) {
		// We satisfied all the search words! Add the directory...
		/// @todo send the directory hash when we have one
		results.push_back(new SearchResult(SearchResult::TYPE_DIRECTORY, getSize(), getFullName(), TTHValue(string(39, 'A'))));
		ShareManager::getInstance()->addHits(1);
	}

	if(!query.isDirectory) {
		for(auto& i: files) {
			if(!i.tth) { continue; }

			// check the size
			if(!(i.getSize() >= query.gt)) {
				continue;
			} else if(!(i.getSize() <= query.lt)) {
				continue;
			}

			if(query.isExcluded(i.getName()))
				continue;

			// check if the name matches
			auto j = query.include.begin();
			for(; j != query.include.end() && j->match(i.getName()); ++j)
				;	// Empty
			if(j != query.include.end())
				continue;

			// check extensions
			if(!query.hasExt(i.getName()))
				continue;

			results.push_back(new SearchResult(SearchResult::TYPE_FILE, i.getSize(),
				getFullName() + i.getName(), (i.tth)));
			ShareManager::getInstance()->addHits(1);

			if(results.size() >= maxResults) { return; }
		}
	}

	for(auto& dir: directories) {
		dir.second->search(results, query, maxResults);

		if(results.size() >= maxResults) { return; }
	}
}
示例#4
0
文件: search.cpp 项目: soubok/libset
  bool Search::handleIqID( Stanza *stanza, int context )
  {
    TrackMap::iterator it = m_track.find( stanza->id() );
    if( it != m_track.end() )
    {
      switch( stanza->subtype() )
      {
        case StanzaIqResult:
          switch( context )
          {
            case FetchSearchFields:
            {
              Tag *q = stanza->findChild( "query" );
              if( q && q->hasAttribute( "xmlns", XMLNS_SEARCH ) )
              {
                Tag *x = q->findChild( "x", "xmlns", XMLNS_X_DATA );
                if( x )
                {
                  DataForm *df = new DataForm( x );
                  (*it).second->handleSearchFields( stanza->from(), df );
                }
                else
                {
                  int fields = 0;
                  std::string instructions;

                  if( q->hasChild( "first" ) )
                    fields |= SearchFieldFirst;
                  if( q->hasChild( "last" ) )
                    fields |= SearchFieldLast;
                  if( q->hasChild( "nick" ) )
                    fields |= SearchFieldNick;
                  if( q->hasChild( "email" ) )
                    fields |= SearchFieldEmail;
                  if( q->hasChild( "instructions" ) )
                    instructions = q->findChild( "instructions" )->cdata();

                  (*it).second->handleSearchFields( stanza->from(), fields, instructions );
                }
              }
              break;
            }
            case DoSearch:
            {
              Tag *q = stanza->findChild( "query" );
              if( q && q->hasAttribute( "xmlns", XMLNS_SEARCH ) )
              {
                Tag *x = q->findChild( "x", "xmlns", XMLNS_X_DATA );
                if( x )
                {
                  DataForm *df = new DataForm( x );
                  (*it).second->handleSearchResult( stanza->from(), df );
                }
                else
                {
                  SearchResultList e;
                  SearchFieldStruct s;
                  const Tag::TagList &l = q->children();
                  Tag::TagList::const_iterator itl = l.begin();
                  for( ; itl != l.end(); ++itl )
                  {
                    if( (*itl)->name() == "item" )
                    {
                      s.jid.setJID( (*itl)->findAttribute( "jid" ) );
                      Tag *t = 0;
                      if( ( t = (*itl)->findChild( "first" ) ) != 0 )
                        s.first = t->cdata();
                      if( ( t = (*itl)->findChild( "last" ) ) != 0 )
                        s.last = t->cdata();
                      if( ( t = (*itl)->findChild( "nick" ) ) != 0 )
                        s.nick = t->cdata();
                      if( ( t = (*itl)->findChild( "email" ) ) != 0 )
                        s.email = t->cdata();
                      e.push_back( s );
                    }
                  }

                  (*it).second->handleSearchResult( stanza->from(), e );
                }
              }
              break;
            }
          }
          break;
        case StanzaIqError:
          (*it).second->handleSearchError( stanza->from(), stanza );
          break;

        default:
          break;
      }

      m_track.erase( it );
    }

    return false;
  }