| 1 | # -*- coding: utf-8 -*-
|
|---|
| 2 | # SearchRepositoryWithNamazu plugin
|
|---|
| 3 |
|
|---|
| 4 | from trac.core import *
|
|---|
| 5 | from trac.Search import ISearchSource, query_to_sql, shorten_result
|
|---|
| 6 | from trac.util import NaivePopen
|
|---|
| 7 | from StringIO import StringIO
|
|---|
| 8 | import urllib
|
|---|
| 9 | import time
|
|---|
| 10 | from xml.dom.minidom import parseString
|
|---|
| 11 |
|
|---|
| 12 | class SearchHyperEstraierModule(Component):
|
|---|
| 13 | implements(ISearchSource)
|
|---|
| 14 |
|
|---|
| 15 | # ISearchProvider methods
|
|---|
| 16 | def get_search_filters(self, req):
|
|---|
| 17 | if req.perm.has_permission('BROWSER_VIEW'):
|
|---|
| 18 | # yield ('repository', 'リポジトリ')
|
|---|
| 19 | yield ('repositoryhyperest', 'リポジトリ')
|
|---|
| 20 |
|
|---|
| 21 | def get_search_results(self, req, query, filters):
|
|---|
| 22 | if not 'repositoryhyperest' in filters:
|
|---|
| 23 | return
|
|---|
| 24 |
|
|---|
| 25 | #estcmd.exeのパス
|
|---|
| 26 | estcmd_path = self.env.config.get('searchhyperestraier', 'estcmd_path','estcmd')
|
|---|
| 27 | #estcmd.exeの引数
|
|---|
| 28 | estcmd_arg = self.env.config.get('searchhyperestraier', 'estcmd_arg','search -vx -sf -ic Shift_JIS')
|
|---|
| 29 | #インデックスのパス
|
|---|
| 30 | index_path = self.env.config.get('searchhyperestraier', 'index_path','')
|
|---|
| 31 | #コマンド実行時のエンコード(Pythonでの形式)
|
|---|
| 32 | #estcmd_argと一致(?)させる必要有り。
|
|---|
| 33 | estcmd_encode = self.env.config.get('searchhyperestraier', 'estcmd_encode','mbcs')
|
|---|
| 34 |
|
|---|
| 35 | #検索結果のパスの頭で削る文字列
|
|---|
| 36 | replace_left = self.env.config.get('searchhyperestraier', 'replace_left','')
|
|---|
| 37 | #URLを生成する際に頭につける文字列
|
|---|
| 38 | #browse_trac=enabledの場合は/がリポジトリのルートになるように
|
|---|
| 39 | url_left = self.env.config.get('searchhyperestraier', 'url_left','')
|
|---|
| 40 |
|
|---|
| 41 | #Tracのブラウザへのリンクを作るか否か。
|
|---|
| 42 | #enabled:Tracのブラウザへのリンクを作る
|
|---|
| 43 | #上記以外:replace_left,url_leftで指定したURLへのリンクを作る
|
|---|
| 44 | browse_trac = self.env.config.get('searchhyperestraier', 'browse_trac','enabled')
|
|---|
| 45 |
|
|---|
| 46 |
|
|---|
| 47 | cmdline = "%s %s %s %s" % (estcmd_path,estcmd_arg,index_path,unicode(query,'utf-8').encode(estcmd_encode))
|
|---|
| 48 | self.log.debug('SearchHyperEstraier:%s' % cmdline)
|
|---|
| 49 | np = NaivePopen(cmdline)
|
|---|
| 50 | #self.log.debug('Result:%s' % unicode(np.out,'utf-8').encode('mbcs'))
|
|---|
| 51 | #self.log.debug('Result:%s' % np.out)
|
|---|
| 52 | if np.errorlevel or np.err:
|
|---|
| 53 | err = 'Running (%s) failed: %s, %s.' % (cmdline, np.errorlevel,
|
|---|
| 54 | np.err)
|
|---|
| 55 | raise Exception, err
|
|---|
| 56 |
|
|---|
| 57 | dom = parseString(np.out)
|
|---|
| 58 | root = dom.documentElement
|
|---|
| 59 | #estresult_node = root.getElementsByTagName("document")[0]
|
|---|
| 60 | element_array = root.getElementsByTagName("document")
|
|---|
| 61 | for element in element_array:
|
|---|
| 62 | #self.log.debug('Result:%s' % 'hoge')
|
|---|
| 63 | url = ""
|
|---|
| 64 | title = ""
|
|---|
| 65 | date = 0
|
|---|
| 66 | detail = ""
|
|---|
| 67 | author = "不明"
|
|---|
| 68 |
|
|---|
| 69 | #detailを生成
|
|---|
| 70 | elem_array = element.getElementsByTagName("snippet")
|
|---|
| 71 | detail = self._get_innerText("",elem_array)
|
|---|
| 72 |
|
|---|
| 73 | #その他の属性を生成
|
|---|
| 74 | attrelem_array = element.getElementsByTagName("attribute")
|
|---|
| 75 | for attrelem in attrelem_array:
|
|---|
| 76 | attr_name = attrelem.getAttribute("name")
|
|---|
| 77 | attr_value = unicode(attrelem.getAttribute("value")).encode('utf-8')
|
|---|
| 78 | #URLとタイトルを生成
|
|---|
| 79 | if attr_name == "_lreal":
|
|---|
| 80 | attr_value=attr_value[len(replace_left):].replace("\\","/")
|
|---|
| 81 | if browse_trac == "enabled":
|
|---|
| 82 | url = self.env.href.browser(url_left + attr_value)
|
|---|
| 83 | title = "source:"+ url_left + attr_value
|
|---|
| 84 | else:
|
|---|
| 85 | url = url_left + attr_value
|
|---|
| 86 | title = url_left + attr_value
|
|---|
| 87 | #更新日時を生成
|
|---|
| 88 | elif attr_name =="@mdate":
|
|---|
| 89 | date = time.strptime(attr_value,"%Y-%m-%dT%H:%M:%SZ")
|
|---|
| 90 | yield(url,title,date,author,detail)
|
|---|
| 91 |
|
|---|
| 92 | #XMLのElementを再帰的に探してテキストを生成
|
|---|
| 93 | def _get_innerText(self,text,node_array):
|
|---|
| 94 | for node in node_array:
|
|---|
| 95 | if node.nodeType == node.TEXT_NODE:
|
|---|
| 96 | text = text + unicode(node.data).encode('utf-8')
|
|---|
| 97 | else:
|
|---|
| 98 | text = self._get_innerText(text,node.childNodes)
|
|---|
| 99 | return text
|
|---|