search.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. package main
  2. import (
  3. "encoding/json"
  4. "log"
  5. "regexp"
  6. "time"
  7. )
  8. // Segment stores source and translated texts.
  9. type Segment struct {
  10. Source, Target string
  11. }
  12. func (s *Segment) clean() {
  13. re := regexp.MustCompile("</?seg>")
  14. s.Source = re.ReplaceAllString(s.Source, "")
  15. s.Target = re.ReplaceAllString(s.Target, "")
  16. }
  17. // CleanedResults stores processed results from given TM.
  18. type CleanedResults struct {
  19. TMName string
  20. Segments []Segment
  21. }
  22. // SearchResults stores processed results from all TMs.
  23. type SearchResults struct {
  24. SearchPhrase string
  25. Results []CleanedResults
  26. TotalResults int
  27. }
  28. // ResultsFromServer stores results as received from server.
  29. type ResultsFromServer struct {
  30. ConcResult []struct {
  31. ConcordanceTextRanges []struct {
  32. Length, Start int
  33. }
  34. ConcordanceTranslationRanges []string
  35. Length, StartPos int
  36. TMEntry struct {
  37. SourceSegment, TargetSegment string
  38. }
  39. }
  40. ConcTransResult, Errors []string
  41. TotalConcResult int
  42. }
  43. func getCleanedResults(tempResults ResultsFromServer, TMFriendlyName string) CleanedResults {
  44. var tmResults CleanedResults
  45. maxReturnedBySever := 64
  46. numberOfSegments := tempResults.TotalConcResult
  47. if numberOfSegments > maxReturnedBySever {
  48. numberOfSegments = maxReturnedBySever
  49. }
  50. tmResults.Segments = make([]Segment, numberOfSegments)
  51. tmResults.TMName = TMFriendlyName
  52. for index := 0; index < numberOfSegments; index++ {
  53. result := tempResults.ConcResult[index]
  54. segment := Segment{result.TMEntry.SourceSegment, result.TMEntry.TargetSegment}
  55. segment.clean()
  56. tmResults.Segments[index] = segment
  57. }
  58. return tmResults
  59. }
  60. type searchQuery struct {
  61. SearchExpression []string
  62. }
  63. func getSearchJSON(text string) []byte {
  64. query := searchQuery{}
  65. query.SearchExpression = append(query.SearchExpression, text)
  66. queryJSON, err := json.Marshal(query)
  67. if err != nil {
  68. log.Printf("Error marshalling query: %s", err)
  69. return []byte{}
  70. }
  71. return queryJSON
  72. }
  73. func (app *Application) search(TMs []TM, text string) SearchResults {
  74. var finalResults SearchResults
  75. finalResults.SearchPhrase = text
  76. searchJSON := getSearchJSON(text)
  77. if len(searchJSON) == 0 {
  78. return finalResults
  79. }
  80. tmURL := app.BaseURL + "tms/"
  81. for _, tm := range TMs {
  82. getTM := tmURL + tm.TMGuid
  83. concordanceURL := getTM + "/concordance"
  84. requestURL := concordanceURL + app.AuthString
  85. resp, err := postQuery(requestURL, searchJSON)
  86. if err != nil {
  87. log.Println(err)
  88. return finalResults
  89. }
  90. defer resp.Body.Close()
  91. if resp.StatusCode == http.StatusUnauthorized {
  92. time.Sleep(app.Delay)
  93. status, err := app.login()
  94. if !status || err != nil {
  95. log.Printf("Couldn't log in: %s", err)
  96. return finalResults
  97. }
  98. return app.search(TMs, text)
  99. }
  100. var tempResults ResultsFromServer
  101. jsonDecoder(resp.Body, &tempResults)
  102. if tempResults.TotalConcResult > 0 {
  103. tmResults := getCleanedResults(tempResults, tm.FriendlyName)
  104. finalResults.Results = append(finalResults.Results, tmResults)
  105. finalResults.TotalResults += len(tmResults.Segments)
  106. }
  107. }
  108. return finalResults
  109. }