Esempio n. 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;
}
Esempio n. 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;
	}
void SearchManager::respond(const AdcCommand& adc, const CID& from) {
	// Filter own searches
	if(from == ClientManager::getInstance()->getMe()->getCID())
		return;

	UserPtr p = ClientManager::getInstance()->findUser(from);
	if(!p)
		return;

	SearchResultList results;
	ShareManager::getInstance()->search(results, adc.getParameters(), 10);

	string token;

	adc.getParam("TO", 0, token);

	if(results.empty())
		return;

	for(SearchResultList::const_iterator i = results.begin(); i != results.end(); ++i) {
		AdcCommand cmd = (*i)->toRES(AdcCommand::TYPE_UDP);
		if(!token.empty())
			cmd.addParam("TO", token);
		ClientManager::getInstance()->send(cmd, from);
	}
}
Esempio n. 4
0
void FindResultsTab::OnSearchMatch(wxCommandEvent& e)
{
    SearchResultList* res = (SearchResultList*)e.GetClientData();
    if(!res) return;

    int m = m_book ? m_book->GetPageIndex(m_recv) : 0;
    if(m == wxNOT_FOUND) {
        wxDELETE(res);
        return;
    }

    MatchInfo& matchInfo = GetMatchInfo(m);
    for(SearchResultList::iterator iter = res->begin(); iter != res->end(); iter++) {
        if(matchInfo.empty() || matchInfo.rbegin()->second.GetFileName() != iter->GetFileName()) {
            if(!matchInfo.empty()) {
                AppendText("\n");
            }
            wxFileName fn(iter->GetFileName());
            fn.MakeRelativeTo();
            AppendText(fn.GetFullPath() + wxT("\n"));
        }

        int lineno = m_recv->GetLineCount() - 1;
        matchInfo.insert(std::make_pair(lineno, *iter));
        wxString text = iter->GetPattern();
        int delta = -text.Length();
        text.Trim(false);
        delta += text.Length();
        text.Trim();

        wxString linenum;
        if(iter->GetMatchState() == CppWordScanner::STATE_CPP_COMMENT ||
           iter->GetMatchState() == CppWordScanner::STATE_C_COMMENT)
            linenum = wxString::Format(wxT(" %5u //"), iter->GetLineNumber());
        else
            linenum = wxString::Format(wxT(" %5u "), iter->GetLineNumber());

        SearchData* d = GetSearchData(m_recv);
        // Print the scope name
        if(d->GetDisplayScope()) {
            TagEntryPtr tag = TagsManagerST::Get()->FunctionFromFileLine(iter->GetFileName(), iter->GetLineNumber());
            wxString scopeName(wxT("global"));
            if(tag) {
                scopeName = tag->GetPath();
            }

            linenum << wxT("[ ") << scopeName << wxT(" ] ");
            iter->SetScope(scopeName);
        }

        delta += linenum.Length();
        AppendText(linenum + text + wxT("\n"));
        m_recv->IndicatorFillRange(m_sci->PositionFromLine(lineno) + iter->GetColumn() + delta, iter->GetLen());
    }
    wxDELETE(res);
}
Esempio n. 5
0
void FindResultsTab::OnSearchMatch(wxCommandEvent& e)
{
    SearchResultList* res = (SearchResultList*)e.GetClientData();
    if(!res) return;

    SearchResultList::iterator iter = res->begin();
    for(; iter != res->end(); ++iter) {
        if(m_matchInfo.empty() || m_matchInfo.rbegin()->second.GetFileName() != iter->GetFileName()) {
            if(!m_matchInfo.empty()) {
                AppendText("\n");
            }
            wxFileName fn(iter->GetFileName());
            fn.MakeRelativeTo();
            AppendText(fn.GetFullPath() + wxT("\n"));
        }

        int lineno = m_sci->GetLineCount() - 1;
        m_matchInfo.insert(std::make_pair(lineno, *iter));
        wxString text = iter->GetPattern();
        // int delta = -text.Length();
        // text.Trim(false);
        // delta += text.Length();
        // text.Trim();

        wxString linenum = wxString::Format(wxT(" %5u: "), iter->GetLineNumber());
        SearchData* d = GetSearchData();
        // Print the scope name
        if(d->GetDisplayScope()) {
            TagEntryPtr tag = TagsManagerST::Get()->FunctionFromFileLine(iter->GetFileName(), iter->GetLineNumber());
            wxString scopeName(wxT("global"));
            if(tag) {
                scopeName = tag->GetPath();
            }

            linenum << wxT("[ ") << scopeName << wxT(" ] ");
            iter->SetScope(scopeName);
        }

        AppendText(linenum + text + wxT("\n"));
        int indicatorStartPos = m_sci->PositionFromLine(lineno) + iter->GetColumn() + linenum.Length();
        int indicatorLen = iter->GetLen();
        m_indicators.push_back(indicatorStartPos);
        m_sci->IndicatorFillRange(indicatorStartPos, indicatorLen);
    }
    wxDELETE(res);
}
Esempio n. 6
0
void SearchManager::respond(const AdcCommand& adc, const CID& from,  bool isUdpActive, const string& hubIpPort) {
    // Filter own searches
    if(from == ClientManager::getInstance()->getMe()->getCID())
        return;

    UserPtr p = ClientManager::getInstance()->findUser(from);
    if(!p)
        return;

    SearchResultList results;
    ShareManager::getInstance()->search(results, adc.getParameters(), isUdpActive ? 10 : 5);

    string token;

    adc.getParam("TO", 0, token);

    // TODO: don't send replies to passive users
    if(results.empty()) {
        string tth;
        if(!adc.getParam("TR", 0, tth))
                return;

        PartsInfo partialInfo;
        if(!QueueManager::getInstance()->handlePartialSearch(TTHValue(tth), partialInfo)) {
                // if not found, try to find in finished list
                if(!FinishedManager::getInstance()->handlePartialRequest(TTHValue(tth), partialInfo)) {
                        return;
                }
        }

        AdcCommand cmd = toPSR(true, Util::emptyString, hubIpPort, tth, partialInfo);
        ClientManager::getInstance()->send(cmd, from);
        return;
    }

    for(SearchResultList::const_iterator i = results.begin(); i != results.end(); ++i) {
        AdcCommand cmd = (*i)->toRES(AdcCommand::TYPE_UDP);
        if(!token.empty())
            cmd.addParam("TO", token);
        ClientManager::getInstance()->send(cmd, from);
    }
}
Esempio n. 7
0
void SearchResult::pickResults(SearchResultList& aResults, int aMaxCount) noexcept {
	if (static_cast<int>(aResults.size()) <= aMaxCount) {
		// we can pick all matches
	} else {
		// pick the best matches
		sort(aResults.begin(), aResults.end(), SearchResult::SpeedSortOrder());
		aResults.erase(aResults.begin() + aMaxCount, aResults.end());
	}
}
Esempio n. 8
0
void SearchResult::pickResults(SearchResultList& aResults, int pickedNum) {
	if (static_cast<int>(aResults.size()) <= pickedNum) {
		//we can pick all matches
	} else {
		//pick the best matches
		sort(aResults.begin(), aResults.end(), SearchResult::SpeedSortOrder());
		aResults.erase(aResults.begin()+pickedNum, aResults.end());
	}
}
Esempio n. 9
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; }
	}
}
Esempio n. 10
0
int main( int /*argc*/, char** /*argv*/ )
{
  int fail = 0;
  std::string name;

  // -------
  {
    name = "fetch fields";
    Search::Query sq;
    Tag* t = sq.tag();
    if( !t || t->xml() != "<query xmlns='" + XMLNS_SEARCH + "'/>" )
    {
      ++fail;
      printf( "test '%s' failed\n", name.c_str() );
    }
    delete t;
  }

  // -------
  {
    name = "receive search fields";
    Tag* d = new Tag( "query" );
    d->setXmlns( XMLNS_SEARCH );
    new Tag( d, "instructions", "foobar" );
    new Tag( d, "first" );
    new Tag( d, "last" );
    new Tag( d, "email" );
    new Tag( d, "nick" );
    Search::Query sq( d );
    Tag* t = sq.tag();
    if( !t || t->xml() != "<query xmlns='" + XMLNS_SEARCH + "'>"
         "<instructions>foobar</instructions>"
         "<first/>"
         "<last/>"
         "<nick/>"
         "<email/>"
         "</query>"
         || sq.instructions() != "foobar"
         || sq.fields() != ( SearchFieldFirst | SearchFieldLast | SearchFieldNick | SearchFieldEmail ) )
    {
      ++fail;
      printf( "test '%s' failed\n", name.c_str() );
    }
    delete t;
    delete d;
  }

  // -------
  {
    name = "receive search form";
    Tag* d = new Tag( "query" );
    d->setXmlns( XMLNS_SEARCH );
    Tag* f = new Tag( d, "x" );
    f->setXmlns( XMLNS_X_DATA );
    f->addAttribute( "type", "form" );
    Search::Query sq( d );
    Tag* t = sq.tag();
    if( !t || t->xml() != "<query xmlns='" + XMLNS_SEARCH + "'>"
         "<x xmlns='" + XMLNS_X_DATA + "' type='form'/>"
         "</query>"
         || !sq.form() )
    {
      ++fail;
      printf( "test '%s' failed: %s\n", name.c_str(), t->xml().c_str() );
    }
    delete t;
    delete d;
  }

  // -------
  {
    name = "search by form";
    DataForm* form = new DataForm( TypeSubmit );
    Search::Query sq( form );
    Tag* t = sq.tag();
    if( !t || t->xml() != "<query xmlns='" + XMLNS_SEARCH + "'>"
       "<x xmlns='" + XMLNS_X_DATA + "' type='submit'/>"
       "</query>" )
    {
      ++fail;
      printf( "test '%s' failed\n", name.c_str() );
    }
    delete t;
  }

  // -------
  {
    name = "search by fields";
    SearchFieldStruct sfs( "first", "last", "nick", "email" );
    Search::Query sq( SearchFieldFirst | SearchFieldLast | SearchFieldNick | SearchFieldEmail, sfs );
    Tag* t = sq.tag();
    if( !t || t->xml() != "<query xmlns='" + XMLNS_SEARCH + "'>"
         "<first>first</first>"
         "<last>last</last>"
         "<nick>nick</nick>"
         "<email>email</email>"
         "</query>" )
    {
      ++fail;
      printf( "test '%s' failed\n", name.c_str() );
    }
    delete t;
  }

  // -------
  {
    name = "receive form result";
    Tag* d = new Tag( "query" );
    d->setXmlns( XMLNS_SEARCH );
    Tag* f = new Tag( d, "x" );
    f->setXmlns( XMLNS_X_DATA );
    f->addAttribute( "type", "result" );
    Search::Query sq( d );
    Tag* t = sq.tag();
    if( !t || t->xml() != "<query xmlns='" + XMLNS_SEARCH + "'>"
         "<x xmlns='" + XMLNS_X_DATA + "' type='result'/>"
         "</query>" )
    {
      ++fail;
      printf( "test '%s' failed\n", name.c_str() );
    }
    delete t;
    delete d;
  }

  // -------
  {
    name = "receive fields result";
    Tag* d = new Tag( "query" );
    d->setXmlns( XMLNS_SEARCH );
    Tag* i = new Tag( d, "item" );
    i->addAttribute( "jid", "foo@bar" );
    new Tag( i, "first", "first1" );
    new Tag( i, "last", "last1" );
    new Tag( i, "email", "email1" );
    new Tag( i, "nick", "nick1" );
    i = new Tag( d, "item" );
    i->addAttribute( "jid", "foo@bar2" );
    new Tag( i, "first", "first2" );
    new Tag( i, "last", "last2" );
    new Tag( i, "nick", "nick2" );
    new Tag( i, "email", "email2" );
    Search::Query sq( d );
    Tag* t = sq.tag();
    SearchResultList srl = sq.result();
    if( !t || t->xml() != "<query xmlns='" + XMLNS_SEARCH + "'>"
         "<item jid='foo@bar'>"
         "<first>first1</first>"
         "<last>last1</last>"
         "<nick>nick1</nick>"
         "<email>email1</email></item>"
         "<item jid='foo@bar2'>"
         "<first>first2</first>"
         "<last>last2</last>"
         "<nick>nick2</nick>"
         "<email>email2</email></item>"
         "</query>"
       || srl.size() != 2 )
    {
      ++fail;
      printf( "test '%s' failed: %s\n", name.c_str(), t->xml().c_str() );
    }
    delete t;
    delete d;
  }




  // -------
  name = "Search::Query/SEFactory test";
  StanzaExtensionFactory sef;
  sef.registerExtension( new Search::Query() );
  Tag* f = new Tag( "iq" );
  new Tag( f, "query", "xmlns", XMLNS_SEARCH );
  IQ iq( IQ::Get, JID() );
  sef.addExtensions( iq, f );
  const Search::Query* se = iq.findExtension<Search::Query>( ExtSearch );
  if( se == 0 )
  {
    ++fail;
    printf( "test '%s' failed\n", name.c_str() );
  }
  delete f;



  printf( "Search::Query: " );
  if( fail == 0 )
  {
    printf( "OK\n" );
    return 0;
  }
  else
  {
    printf( "%d test(s) failed\n", fail );
    return 1;
  }

}
Esempio n. 11
0
  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;
  }