search.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. package main
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "fmt"
  6. "log"
  7. "net/http"
  8. "regexp"
  9. "time"
  10. )
  11. // Segment stores source and translated texts.
  12. type Segment struct {
  13. Source, Target string
  14. }
  15. // Clean cleans <seg> tags from source and translated texts.
  16. func (s *Segment) Clean() {
  17. re := regexp.MustCompile("</?seg>")
  18. s.Source = re.ReplaceAllString(s.Source, "")
  19. s.Target = re.ReplaceAllString(s.Target, "")
  20. }
  21. // CleanedResults stores processed results from given TM.
  22. type CleanedResults struct {
  23. TMName string
  24. Segments []Segment
  25. }
  26. // SearchResults stores processed results from all TMs.
  27. type SearchResults struct {
  28. SearchPhrase string
  29. Results []CleanedResults
  30. TotalResults int
  31. }
  32. // ResultsFromServer stores results as received from server.
  33. type ResultsFromServer struct {
  34. ConcResult []struct {
  35. ConcordanceTextRanges []struct {
  36. Length, Start int
  37. }
  38. ConcordanceTranslationRanges []string
  39. Length, StartPos int
  40. TMEntry struct {
  41. SourceSegment, TargetSegment string
  42. }
  43. }
  44. ConcTransResult, Errors []string
  45. TotalConcResult int
  46. }
  47. func postQuery(requestURL string, searchJSON []byte) (*http.Response, error) {
  48. req, err := http.NewRequest("POST", requestURL, bytes.NewBuffer(searchJSON))
  49. if err != nil {
  50. return nil, fmt.Errorf("Error creating post request: %s", err)
  51. }
  52. req.Header.Set("Content-Type", "application/json")
  53. client := &http.Client{}
  54. resp, err := client.Do(req)
  55. if err != nil {
  56. return nil, fmt.Errorf("Error posting query: %v", err)
  57. }
  58. return resp, nil
  59. }
  60. func getCleanedResults(tempResults ResultsFromServer, TMFriendlyName string) CleanedResults {
  61. var tmResults CleanedResults
  62. //64 is maximum returned by server
  63. var numberOfSegments int
  64. if tempResults.TotalConcResult > 64 {
  65. numberOfSegments = 64
  66. } else {
  67. numberOfSegments = tempResults.TotalConcResult
  68. }
  69. //Allocating Segments array beforehand
  70. tmResults.Segments = make([]Segment, 0, numberOfSegments)
  71. tmResults.TMName = TMFriendlyName
  72. for _, result := range tempResults.ConcResult {
  73. segment := Segment{result.TMEntry.SourceSegment, result.TMEntry.TargetSegment}
  74. segment.Clean()
  75. tmResults.Segments = append(tmResults.Segments, segment)
  76. }
  77. return tmResults
  78. }
  79. type searchQuery struct {
  80. SearchExpression []string
  81. }
  82. func getSearchJSON(text string) []byte {
  83. query := searchQuery{}
  84. query.SearchExpression = append(query.SearchExpression, text)
  85. queryJSON, err := json.Marshal(query)
  86. if err != nil {
  87. log.Printf("Error marshalling query: %v", err)
  88. return []byte{}
  89. }
  90. return queryJSON
  91. }
  92. // Search for given phrase in given TMs.
  93. func (app *Application) Search(TMs []TM, text string) SearchResults {
  94. searchJSON := getSearchJSON(text)
  95. tmURL := app.BaseURL + "tms/"
  96. var finalResults SearchResults
  97. finalResults.SearchPhrase = text
  98. for _, tm := range TMs {
  99. getTM := tmURL + tm.TMGuid
  100. concordanceURL := getTM + "/concordance"
  101. requestURL := concordanceURL + app.AuthString
  102. resp, err := postQuery(requestURL, searchJSON)
  103. if err != nil {
  104. log.Println(err)
  105. return finalResults
  106. }
  107. defer resp.Body.Close()
  108. if resp.StatusCode == 401 {
  109. time.Sleep(app.Delay)
  110. app.Login()
  111. return app.Search(TMs, text)
  112. }
  113. var tempResults ResultsFromServer
  114. JSONDecoder(resp.Body, &tempResults)
  115. if tempResults.TotalConcResult > 0 {
  116. tmResults := getCleanedResults(tempResults, tm.FriendlyName)
  117. finalResults.Results = append(finalResults.Results, tmResults)
  118. finalResults.TotalResults += len(tmResults.Segments)
  119. }
  120. }
  121. return finalResults
  122. }