diff --git a/.gitignore b/.gitignore index bd6ebab..0329141 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ build/ logs/concordia-server.log logs/pgbouncer.log +logs/phrase-searches.json concordia.cfg concordia-server/config.hpp index/ diff --git a/CMakeLists.txt b/CMakeLists.txt index 04235b6..1403d70 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -62,6 +62,7 @@ configure_file ( set(CONFIG_FILE_PATH "${concordia-server_SOURCE_DIR}/concordia.cfg") set(LOG_FILE_PATH "${concordia-server_SOURCE_DIR}/logs/concordia-server.log") +set(PHRASE_LOG_FILE_PATH "${concordia-server_SOURCE_DIR}/logs/phrase-searches.json") # -------------- # db settings diff --git a/cat/css/iatagger.css b/cat/css/iatagger.css index a468bd3..dc5e900 100644 --- a/cat/css/iatagger.css +++ b/cat/css/iatagger.css @@ -34,7 +34,13 @@ display:none; } -#phrase-icon { +#phrase-on-icon { + cursor:pointer; + vertical-align:middle; + margin-right:20px; +} + +#phrase-off-icon { cursor:pointer; vertical-align:middle; margin-right:20px; diff --git a/cat/images/switchOff.png b/cat/images/switchOff.png new file mode 100644 index 0000000..55ba7f6 Binary files /dev/null and b/cat/images/switchOff.png differ diff --git a/cat/images/switchOn.png b/cat/images/switchOn.png new file mode 100644 index 0000000..07e8fc0 Binary files /dev/null and b/cat/images/switchOn.png differ diff --git a/cat/js/cat.js b/cat/js/cat.js index 152a8d0..e0c0291 100644 --- a/cat/js/cat.js +++ b/cat/js/cat.js @@ -34,7 +34,12 @@ function phraseSearchHandle(tmid, intervals) { type: 'post', dataType: 'json', success: function (data) { - $('#result').html(renderResult(data)); + if (data['found']) { + $('#result').html(renderResult(data)); + } else { + $('#phrase-prompt').html('Your phrase was not found. Try selecting another phrase: ').fadeOut(200).fadeIn(200); + clearTextSelections(); + } }, data: concordiaRequest }); @@ -43,10 +48,13 @@ function phraseSearchHandle(tmid, intervals) { function renderResult(data) { var res = ''; - var score = data['result']['bestOverlayScore']*100; - - res += '
Concordia score: '+score.toFixed(0)+'%
'; - res += '
phrase search
'; + if (typeof(data['result']['bestOverlayScore']) === 'undefined') { + // ignore + } else { + var score = data['result']['bestOverlayScore']*100; + res += '
Concordia score: '+score.toFixed(0)+'%
'; + } + res += '
Phrase search mode: enter phrase search mode
'; var inputSentence = $('#search-input').val(); var markedSentence = ''; @@ -104,7 +112,8 @@ function renderFragment(fragment, number) { function togglePhraseSearchMode() { $('#result-sentence').toggleClass('phrase-mode'); - $('#phrase-icon').toggleClass('hidden'); + $('#phrase-on-icon').toggleClass('hidden'); + $('#phrase-off-icon').toggleClass('hidden'); $('#phrase-prompt').toggleClass('hidden'); clearTextSelections(); } diff --git a/cat/versions/setimes_hren.cfg b/cat/versions/setimes_hren.cfg index e1f4fa1..b6f2247 100644 --- a/cat/versions/setimes_hren.cfg +++ b/cat/versions/setimes_hren.cfg @@ -8,4 +8,4 @@ prompt@#@Enter search pattern (Croatian sentence): suggestion@#@Kazna medijskom mogulu obnovila raspravu u Makedoniji suggestion@#@Član Predsjedništva BiH Komšić podnio ostavku u svojoj stranci suggestion@#@ozbiljno analizira proces -suggestion@#@Kazna medijskom podnio ostavku ozbiljno analizira proces +suggestion@#@Nagrada koja nosi ime po našem velikom snimatelju dodjeljuje se za izniman doprinos filmskoj umjetnosti. diff --git a/concordia-server/complete_concordia_search_result.cpp b/concordia-server/complete_concordia_search_result.cpp index 9aeca5d..c144f84 100644 --- a/concordia-server/complete_concordia_search_result.cpp +++ b/concordia-server/complete_concordia_search_result.cpp @@ -1,5 +1,7 @@ #include "complete_concordia_search_result.hpp" +#include + CompleteConcordiaSearchResult::CompleteConcordiaSearchResult( const double bestOverlayScore): _bestOverlayScore(bestOverlayScore) { @@ -8,3 +10,9 @@ CompleteConcordiaSearchResult::CompleteConcordiaSearchResult( CompleteConcordiaSearchResult::~CompleteConcordiaSearchResult() { } +void CompleteConcordiaSearchResult::offsetPattern(int offset) { + BOOST_FOREACH(SimpleSearchResult & simpleResult, _bestOverlay) { + simpleResult.offsetPattern(offset); + } + +} diff --git a/concordia-server/complete_concordia_search_result.hpp b/concordia-server/complete_concordia_search_result.hpp index f29513d..2a0ce46 100644 --- a/concordia-server/complete_concordia_search_result.hpp +++ b/concordia-server/complete_concordia_search_result.hpp @@ -23,6 +23,8 @@ public: return _bestOverlay; } + void offsetPattern(int offset); + private: double _bestOverlayScore; diff --git a/concordia-server/concordia_server.cpp b/concordia-server/concordia_server.cpp index d3b7365..8bdf5ee 100644 --- a/concordia-server/concordia_server.cpp +++ b/concordia-server/concordia_server.cpp @@ -2,6 +2,9 @@ #include #include +#include +#include +#include #include @@ -37,7 +40,7 @@ std::string ConcordiaServer::handleRequest(std::string & requestString) { outputString << "Content-type: application/json\r\n\r\n"; try { rapidjson::Document d; - Logger::logString("concordia request string", requestString); + // Logger::logString("concordia request string", requestString); bool hasError = d.Parse(requestString.c_str()).HasParseError(); if (hasError) { @@ -106,15 +109,13 @@ std::string ConcordiaServer::handleRequest(std::string & requestString) { std::string pattern = _getStringParameter(d, PATTERN_PARAM); int tmId = _getIntParameter(d, TM_ID_PARAM); Logger::logString("concordia phrase search pattern", pattern); + _logPhrase(requestString); std::vector intervals; const rapidjson::Value & intervalsArray = d[INTERVALS_PARAM]; for (rapidjson::SizeType i = 0; i < intervalsArray.Size(); i++) { - Logger::logInt("interval size", intervalsArray[i].Size()); - Logger::logInt("search interval start", intervalsArray[i][0].GetInt()); - Logger::logInt("search interval end", intervalsArray[i][1].GetInt()); + intervals.push_back(Interval(intervalsArray[i][0].GetInt(), intervalsArray[i][1].GetInt())); } - - //_searcherController->concordiaPhraseSearch(jsonWriter, pattern, tmId); + _searcherController->concordiaPhraseSearch(jsonWriter, pattern, intervals, tmId); } else if (operation == ADD_TM_OP) { int sourceLangId = _getIntParameter(d, SOURCE_LANG_PARAM); int targetLangId = _getIntParameter(d, TARGET_LANG_PARAM); @@ -177,3 +178,9 @@ void ConcordiaServer::_addTm(int tmId) { _concordiasMap->insert(tmId, new Concordia(indexPath.str(), _configFilePath)); } +void ConcordiaServer::_logPhrase(std::string phraseString) { + std::ofstream logFile; + logFile.open(PHRASE_LOG_FILE_PATH, std::ios::out | std::ios::app); + logFile << phraseString.substr(0, phraseString.size()-1) << ", \"timestamp\":" << std::time(0) << "}\n"; + logFile.close(); +} diff --git a/concordia-server/concordia_server.hpp b/concordia-server/concordia_server.hpp index 4d43107..4214694 100644 --- a/concordia-server/concordia_server.hpp +++ b/concordia-server/concordia_server.hpp @@ -30,6 +30,8 @@ public: std::string handleRequest(std::string & requestString); private: + void _logPhrase(std::string phraseString); + std::string _getStringParameter(rapidjson::Document & d, const char * name) throw (ConcordiaException); int _getIntParameter(rapidjson::Document & d, const char * name) throw (ConcordiaException); diff --git a/concordia-server/config.hpp.in b/concordia-server/config.hpp.in index e96fafd..093b494 100644 --- a/concordia-server/config.hpp.in +++ b/concordia-server/config.hpp.in @@ -1,5 +1,6 @@ #define CONFIG_FILE_PATH "@CONFIG_FILE_PATH@" #define LOG_FILE_PATH "@LOG_FILE_PATH@" +#define PHRASE_LOG_FILE_PATH "@PHRASE_LOG_FILE_PATH@" #define INDEX_DIRECTORY "@INDEX_DIRECTORY@" // database connection information diff --git a/concordia-server/searcher_controller.cpp b/concordia-server/searcher_controller.cpp index a9ac8ba..0be150e 100644 --- a/concordia-server/searcher_controller.cpp +++ b/concordia-server/searcher_controller.cpp @@ -36,6 +36,69 @@ void SearcherController::simpleSearch(rapidjson::Writer } } +void SearcherController::concordiaPhraseSearch(rapidjson::Writer & jsonWriter, + std::string & pattern, + const std::vector & intervals, + const int tmId) { + boost::ptr_map::iterator it = _concordiasMap->find(tmId); + if (it != _concordiasMap->end()) { + if (intervals.size() > 0) { + std::string shortPattern = pattern.substr(intervals[0].getStart(), intervals[0].getEnd() - intervals[0].getStart()); + + std::vector shortPatternResults = _unitDAO.getSearchResults(it->second->simpleSearch(shortPattern)); + + + + jsonWriter.StartObject(); + jsonWriter.String("status"); + jsonWriter.String("success"); + jsonWriter.String("found"); + if (shortPatternResults.size() > 0) { + jsonWriter.Bool(true); + + + std::vector bestOverlay; + + int currStart = 0; + BOOST_FOREACH(const Interval & interval, intervals) { + CompleteConcordiaSearchResult restResult = _unitDAO.getConcordiaResult( + it->second->concordiaSearch(pattern.substr(currStart, interval.getStart()-currStart))); + restResult.offsetPattern(currStart); + bestOverlay.insert(bestOverlay.end(), restResult.getBestOverlay().begin(), restResult.getBestOverlay().end()); + + SimpleSearchResult shortPatternresult = shortPatternResults[0]; + shortPatternresult.setMatchedPatternStart(interval.getStart()); + shortPatternresult.setMatchedPatternEnd(interval.getEnd()); + bestOverlay.push_back(shortPatternresult); + currStart = interval.getEnd(); + } + CompleteConcordiaSearchResult lastRestResult = _unitDAO.getConcordiaResult( + it->second->concordiaSearch(pattern.substr(currStart))); + lastRestResult.offsetPattern(currStart); + bestOverlay.insert(bestOverlay.end(), lastRestResult.getBestOverlay().begin(), lastRestResult.getBestOverlay().end()); + + jsonWriter.String("result"); + jsonWriter.StartObject(); + jsonWriter.String("bestOverlay"); + jsonWriter.StartArray(); + BOOST_FOREACH(SimpleSearchResult & simpleResult, bestOverlay) { + JsonGenerator::writeSearchResult(jsonWriter, simpleResult); + } + jsonWriter.EndArray(); + jsonWriter.EndObject(); + } else { + jsonWriter.Bool(false); + } + jsonWriter.EndObject(); + } else { + JsonGenerator::signalError(jsonWriter, "no intervals for phrase search"); + } + } else { + JsonGenerator::signalError(jsonWriter, "no such tm!"); + } +} + + void SearcherController::concordiaSearch(rapidjson::Writer & jsonWriter, std::string & pattern, const int tmId) { diff --git a/concordia-server/searcher_controller.hpp b/concordia-server/searcher_controller.hpp index 74f88ef..995c19b 100644 --- a/concordia-server/searcher_controller.hpp +++ b/concordia-server/searcher_controller.hpp @@ -6,6 +6,7 @@ #include #include #include +#include #include "unit_dao.hpp" #include "simple_search_result.hpp" @@ -30,6 +31,10 @@ public: std::string & pattern, const int tmId); + void concordiaPhraseSearch(rapidjson::Writer & jsonWriter, + std::string & pattern, + const std::vector & intervals, + const int tmId); private: boost::shared_ptr > _concordiasMap; diff --git a/concordia-server/simple_search_result.cpp b/concordia-server/simple_search_result.cpp index 37281cd..e097923 100644 --- a/concordia-server/simple_search_result.cpp +++ b/concordia-server/simple_search_result.cpp @@ -24,4 +24,8 @@ void SimpleSearchResult::addMatchedTargetFragment(const std::pair & tar _targetFragments.push_back(targetFragment); } +void SimpleSearchResult::offsetPattern(int offset) { + _matchedPatternStart += offset; + _matchedPatternEnd += offset; +} diff --git a/concordia-server/simple_search_result.hpp b/concordia-server/simple_search_result.hpp index c060c26..7e73da1 100644 --- a/concordia-server/simple_search_result.hpp +++ b/concordia-server/simple_search_result.hpp @@ -28,10 +28,18 @@ public: return _matchedPatternStart; } + void setMatchedPatternStart(int newStart) { + _matchedPatternStart = newStart; + } + int getMatchedPatternEnd() const { return _matchedPatternEnd; } + void setMatchedPatternEnd(int newEnd) { + _matchedPatternEnd = newEnd; + } + int getMatchedExampleStart() const { return _matchedExampleStart; } @@ -54,6 +62,8 @@ public: void addMatchedTargetFragment(const std::pair & targetFragment); + void offsetPattern(int offset); + private: int _id; diff --git a/concordia-server/unit_dao.cpp b/concordia-server/unit_dao.cpp index b7ed073..16a1e92 100644 --- a/concordia-server/unit_dao.cpp +++ b/concordia-server/unit_dao.cpp @@ -116,7 +116,7 @@ void UnitDAO::_getResultsFromFragments( delete param; } - //TODO now add all target fragments matched with this fragment + // now add all target fragments matched with this fragment std::string targetQuery = "SELECT target_token_pos, target_tokens[2*target_token_pos+1], target_tokens[2*target_token_pos+2] FROM unit INNER JOIN alignment ON alignment.unit_id = unit.id AND unit.id = $1::integer AND source_token_pos between $2::integer and $3::integer ORDER BY target_token_pos"; std::vector targetParams; targetParams.push_back(new IntParam(fragment.getExampleId()));