├── .github └── workflows │ └── ci.yml ├── .gitignore ├── README.md ├── autoload ├── codelf.vim └── codelf │ ├── browser.vim │ └── util.vim ├── doc └── codelf.txt ├── plugin └── codelf.vim └── script └── codelf.py /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: [push, pull_request] 3 | 4 | jobs: 5 | # vader-tests: 6 | # name: Vader tests 7 | # strategy: 8 | # matrix: 9 | # os: [ubuntu-latest, macos-latest] 10 | # neovim: [true] # only test on neovim currently 11 | # runs-on: ${{ matrix.os }} 12 | # steps: 13 | # - uses: actions/checkout@v2 14 | # - name: Checkout vader.vim 15 | # uses: actions/checkout@v2 16 | # with: 17 | # repository: junegunn/vader.vim 18 | # path: vader.vim 19 | # - name: Install Neovim 20 | # uses: rhysd/action-setup-vim@v1 21 | # id: vim 22 | # with: 23 | # neovim: ${{ matrix.neovim }} 24 | # - name: Run vader tests 25 | # env: 26 | # VIM_EXEC: ${{ steps.vim.outputs.executable }} 27 | # run: | 28 | # $VIM_EXEC --version 29 | # $VIM_EXEC -u test/vimrc -c 'Vader! test/codelf.vader' 30 | 31 | vint: 32 | name: Run vint 33 | runs-on: ubuntu-latest 34 | steps: 35 | - uses: actions/checkout@v2 36 | - uses: actions/setup-python@v1 37 | - run: pip install vim-vint 38 | - run: vint --warning --verbose --enable-neovim --color --style ./autoload ./plugin 39 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # For current directory only 2 | # ---------------------------------------------------------------------------- 3 | /.vim 4 | # General 5 | # ---------------------------------------------------------------------------- 6 | *.o 7 | *.out 8 | 9 | # log 10 | *.log 11 | 12 | # cache 13 | *.cache 14 | cache/ 15 | 16 | # Windows 17 | # ---------------------------------------------------------------------------- 18 | Thumbs.db 19 | Desktop.ini 20 | 21 | # Tags 22 | # ----------------------------------------------------------------------------- 23 | TAGS 24 | !TAGS/ 25 | tags 26 | tags-cn 27 | !tags/ 28 | .tags 29 | .tags1 30 | tags.lock 31 | tags.temp 32 | gtags.files 33 | GTAGS 34 | GRTAGS 35 | GPATH 36 | cscope.files 37 | cscope.out 38 | cscope.in.out 39 | cscope.po.out 40 | 41 | # Vim 42 | # ------------------------------------------------------------------------------ 43 | [._]*.s[a-w][a-z] 44 | [._]s[a-w][a-z] 45 | *.un~ 46 | Session.vim 47 | .netrwhist 48 | *~ 49 | 50 | # Test % Tmp 51 | # ------------------------------------------------------------------------------- 52 | test.* 53 | tmp.* 54 | temp.* 55 | 56 | # Java 57 | # ------------------------------------------------------------------------------- 58 | *.class 59 | 60 | # JavaScript 61 | # ------------------------------------------------------------------------------- 62 | node_modules 63 | 64 | # Python 65 | # ------------------------------------------------------------------------------- 66 | *.pyc 67 | .idea/ 68 | /.idea 69 | build/ 70 | __pycache__ 71 | 72 | # Rust 73 | # ------------------------------------------------------------------------------- 74 | target/ 75 | **/*.rs.bk 76 | 77 | # C/Cpp 78 | # ------------------------------------------------------------------------------- 79 | /cmake-build-debug/ 80 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vim-codelf 2 | 3 | ![CI](https://github.com/voldikss/vim-codelf/workflows/CI/badge.svg) 4 | 5 | (Neo)Vim plugin for searching useful variable names from [CODELF](https://github.com/unbug/codelf) 6 | 7 |
8 | 9 |
10 |
11 | 12 |
13 | 14 | ## Install 15 | 16 | ```vim 17 | Plug 'voldikss/vim-codelf' 18 | ``` 19 | 20 | ## Keymap 21 | 22 | ```vim 23 | " Example key mappings configuration 24 | inoremap =codelf#start() 25 | nnoremap :call codelf#start() 26 | ``` 27 | 28 | ## Configuration 29 | 30 | #### `g:codelf_enable_popup_menu` 31 | 32 | If set `v:true`, the available variable names will displayed in popup menu, which behaviors just like code completion. 33 | Otherwise, they will be displayed in cmdline, prompting the user to select one(like `:z=`) to replace the word under the cursor. 34 | 35 | #### `g:codelf_proxy_url` 36 | 37 | e.g. `let g:codelf_proxy_url=http://127.0.0.1:1081` 38 | 39 | ## Commands 40 | 41 | #### `:Codelf [word]` 42 | 43 | Query the `word` from [codelf](https://github.com/unbug/codelf), return the variable name. 44 | 45 | #### `:CodelfOpenBrowser [word]` 46 | 47 | Go to [CODELF](https://github.com/unbug/codelf) for the `word`. If no `word`, use the word under the cursor. [vim-browser-search](https://github.com/voldikss/vim-browser-search) supplies the same function. 48 | 49 | ## Statusline 50 | 51 | - `g:codelf_status` 52 | 53 | ## Q&As 54 | 55 | - How to stop it from displaying after triggering a codelf query? 56 | 57 | If the cursor was moved to another place, the callback function will be disabled. 58 | 59 | - Will it frozen my Vim? 60 | 61 | If your (Neo)Vim has `job` feature, this plugin won't stop your behavior. Otherwise, yes(and this plugin is not recommended in that case). 62 | -------------------------------------------------------------------------------- /autoload/codelf.vim: -------------------------------------------------------------------------------- 1 | " ======================================================================== 2 | " FileName: codelf.vim 3 | " Description: 4 | " Author: voldikss 5 | " GitHub: https://github.com/voldikss 6 | " ======================================================================== 7 | 8 | let s:py_file = expand(':p:h') . '/../script/codelf.py' 9 | 10 | if !exists('s:python_executable') 11 | if executable('python3') 12 | let s:python_executable = 'python3' 13 | elseif executable('python') 14 | let s:python_executable = 'python' 15 | elseif exists('g:python3_host_prog') 16 | let s:python_executable = g:python3_host_prog 17 | else 18 | call codelf#util#show_msg('Python is required but not found', 'error') 19 | finish 20 | endif 21 | endif 22 | 23 | if has('nvim') 24 | function! s:on_stdout_nvim(jobid, data, event) abort 25 | call s:callback(a:data) 26 | endfunction 27 | 28 | function! s:on_exit_nvim(jobid, code, event) abort 29 | endfunction 30 | else 31 | function! s:on_stdout_vim(event, ch, msg) abort 32 | call s:callback(a:msg) 33 | endfunction 34 | 35 | function! s:on_exit_vim(ch, code) abort 36 | endfunction 37 | endif 38 | 39 | function! s:callback(data) abort 40 | let g:codelf_status = '' 41 | if type(a:data) == 3 42 | let message = join(a:data, ' ') 43 | else 44 | let message = a:data 45 | endif 46 | 47 | try 48 | let candidates = eval(message) 49 | if message ==# '' || type(candidates) != 3 50 | call codelf#util#show_msg('No queries', 'info') 51 | return 52 | endif 53 | catch /.*/ 54 | return 55 | endtry 56 | 57 | call s:display(candidates) 58 | endfunction 59 | 60 | "" 61 | " Display the candidates in popup menu or inputlist 62 | function! s:display(candidates) abort 63 | " If user moved the cursor, codelf displaying will be cancelled 64 | if exists('s:cursor_pos') && getpos('.') != s:cursor_pos 65 | call codelf#util#show_msg('Codelf cancelled since the cursor was moved', 'warning') 66 | return 67 | endif 68 | unlet s:cursor_pos 69 | 70 | if g:codelf_enable_popup_menu == v:true && mode() ==# 'i' 71 | let pos = col('.') 72 | normal! diw 73 | call complete(pos, a:candidates) 74 | else 75 | let candidates = ['Choose from:'] 76 | for i in range(min([len(a:candidates), &lines-5])) 77 | call add(candidates, i . '. ' . a:candidates[i]) 78 | endfor 79 | let selection = str2nr(inputlist(candidates)) 80 | let reg_tmp = @a 81 | let @a = a:candidates[selection] 82 | normal! viw"ap 83 | let @a = reg_tmp 84 | endif 85 | endfunction 86 | 87 | function! s:job_start(cmd) abort 88 | if has('nvim') 89 | let callback = { 90 | \ 'on_stdout': function('s:on_stdout_nvim'), 91 | \ 'on_stderr': function('s:on_stdout_nvim'), 92 | \ 'on_exit': function('s:on_exit_nvim') 93 | \ } 94 | call jobstart(a:cmd, callback) 95 | else 96 | let callback = { 97 | \ 'out_cb': function('s:on_stdout_vim', ['stdout']), 98 | \ 'err_cb': function('s:on_stdout_vim', ['stderr']), 99 | \ 'exit_cb': function('s:on_exit_vim'), 100 | \ 'out_io': 'pipe', 101 | \ 'err_io': 'pipe', 102 | \ 'in_io': 'null', 103 | \ 'out_mode': 'nl', 104 | \ 'err_mode': 'nl', 105 | \ 'timeout': '2000' 106 | \ } 107 | call job_start(a:cmd, callback) 108 | endif 109 | endfunction 110 | 111 | function! codelf#start(...) abort 112 | let g:codelf_status = 'requesting codelf' 113 | let s:cursor_pos = getpos('.') 114 | if a:0 == 0 115 | let word = expand('') 116 | else 117 | let word = a:1 118 | endif 119 | if g:codelf_enable_popup_menu == v:true 120 | startinsert 121 | endif 122 | let cmd = 'python3 ' . s:py_file . ' --text=' . shellescape(word) 123 | if empty(g:codelf_proxy_url) 124 | let cmd .= ' --proxy=' . g:codelf_proxy_url 125 | endif 126 | call s:job_start(cmd) 127 | return '' 128 | endfunction 129 | -------------------------------------------------------------------------------- /autoload/codelf/browser.vim: -------------------------------------------------------------------------------- 1 | " ============================================================================ 2 | " FileName: browser.vim 3 | " Description: 4 | " Author: voldikss 5 | " GitHub: https://github.com/voldikss 6 | " ============================================================================ 7 | 8 | function! s:open_url(url) abort 9 | if has('win32') || has('win64') || has('win32unix') 10 | let cmd = 'rundll32 url.dll,FileProtocolHandler ' . shellescape(a:url) 11 | elseif has('mac') || has('macunix') || has('gui_macvim') || system('uname') =~? '^darwin' 12 | let cmd = 'open ' . shellescape(a:url) 13 | elseif executable('xdg-open') 14 | let cmd = 'xdg-open ' . shellescape(a:url) 15 | else 16 | call codelf#util#show_msg('Browser was not found', 'error') 17 | return 18 | endif 19 | 20 | if exists('*jobstart') 21 | call jobstart(cmd) 22 | elseif exists('*job_start') 23 | call job_start(cmd) 24 | else 25 | call system(cmd) 26 | endif 27 | endfunction 28 | 29 | function! codelf#browser#open(...) abort 30 | let codelf_api = 'https://unbug.github.io/codelf#' 31 | if a:0 == 0 32 | let word = expand('') 33 | else 34 | let word = a:1 35 | endif 36 | call s:open_url(codelf_api . word) 37 | endfunction 38 | -------------------------------------------------------------------------------- /autoload/codelf/util.vim: -------------------------------------------------------------------------------- 1 | " ============================================================================ 2 | " FileName: util.vim 3 | " Description: 4 | " Author: voldikss 5 | " GitHub: https://github.com/voldikss 6 | " ============================================================================ 7 | 8 | function! codelf#util#echo(group, msg) abort 9 | if a:msg ==# '' | return | endif 10 | execute 'echohl' a:group 11 | echo a:msg 12 | echon ' ' 13 | echohl NONE 14 | endfunction 15 | 16 | function! codelf#util#echon(group, msg) abort 17 | if a:msg ==# '' | return | endif 18 | execute 'echohl' a:group 19 | echon a:msg 20 | echon ' ' 21 | echohl NONE 22 | endfunction 23 | 24 | function! codelf#util#show_msg(message, ...) abort 25 | if a:0 == 0 26 | let msg_type = 'info' 27 | else 28 | let msg_type = a:1 29 | endif 30 | 31 | if type(a:message) != 1 32 | let message = string(a:message) 33 | else 34 | let message = a:message 35 | endif 36 | 37 | call codelf#util#echo('Constant', '[vim-codelf]') 38 | 39 | if msg_type ==# 'info' 40 | call codelf#util#echon('Normal', message) 41 | elseif msg_type ==# 'warning' 42 | call codelf#util#echon('WarningMsg', message) 43 | elseif msg_type ==# 'error' 44 | call codelf#util#echon('Error', message) 45 | endif 46 | endfunction 47 | -------------------------------------------------------------------------------- /doc/codelf.txt: -------------------------------------------------------------------------------- 1 | *codelf.txt* vim-codelf 2 | 3 | =============================================================================== 4 | Contents ~ 5 | 6 | 1. Introduction |codelf-introduction| 7 | 2. Install |codelf-install| 8 | 3. Keymap |codelf-keymap| 9 | 4. Configuration |codelf-configuration| 10 | 1. g:codelf_enable_popup_menu |g-codelf_enable_popup_menu| 11 | 2. g:codelf_proxy_url |g-codelf_proxy_url| 12 | 5. Commands |codelf-commands| 13 | 1. :Codelf [word] |codelf-word| 14 | 2. :CodelfOpenBrowser [word] |codelfopenbrowser-word| 15 | 6. Statusline |codelf-statusline| 16 | 1. g:codelf_status |g-codelf_status| 17 | 7. Q&As |codelf-q-as| 18 | 8. References |codelf-references| 19 | 20 | =============================================================================== 21 | *codelf-introduction* 22 | Introduction ~ 23 | 24 | (Neo)Vim plugin for searching useful variable names from CODELF [1] 25 | 26 | Image: (see reference [2])Image: (see reference [3]) 27 | 28 | =============================================================================== 29 | *codelf-install* 30 | Install ~ 31 | > 32 | Plug 'voldikss/vim-codelf' 33 | < 34 | =============================================================================== 35 | *codelf-keymap* 36 | Keymap ~ 37 | > 38 | " Example key mappings configuration 39 | inoremap =codelf#start() 40 | nnoremap :call codelf#start() 41 | < 42 | =============================================================================== 43 | *codelf-configuration* 44 | Configuration ~ 45 | 46 | ------------------------------------------------------------------------------- 47 | *g:codelf_enable_popup_menu* 48 | g:codelf_enable_popup_menu ~ 49 | 50 | If set 'v:true', the available variable names will displayed in popup menu, 51 | which behaviors just like code completion. Otherwise, they will be displayed in 52 | cmdline, prompting the user to select one(like ':z=') to replace the word under 53 | the cursor. 54 | 55 | ------------------------------------------------------------------------------- 56 | *g:codelf_proxy_url* 57 | g:codelf_proxy_url ~ 58 | 59 | e.g. 'let g:codelf_proxy_url=http://127.0.0.1:1081' 60 | 61 | =============================================================================== 62 | *codelf-commands* 63 | Commands ~ 64 | 65 | ------------------------------------------------------------------------------- 66 | *Codelf* 67 | :Codelf [word] ~ 68 | 69 | Query the 'word' from codelf [1], return the variable name. 70 | 71 | ------------------------------------------------------------------------------- 72 | *CodelfOpenBrowser* 73 | :CodelfOpenBrowser [word] ~ 74 | 75 | Go to CODELF [1] for the 'word'. If 'word' is not given, use the word under the cursor. 76 | vim-browser-search [4] supplies the same function. 77 | 78 | =============================================================================== 79 | *codelf-statusline* 80 | Statusline ~ 81 | 82 | ------------------------------------------------------------------------------- 83 | *g-codelf_status* 84 | g:codelf_status ~ 85 | 86 | =============================================================================== 87 | *codelf-q-as* 88 | Q&As ~ 89 | 90 | - How to stop it from displaying after triggering a codelf query? 91 | 92 | If the cursor was moved to another place, the callback function will be 93 | disabled. 94 | 95 | - Will it frozen my Vim? 96 | 97 | If your (Neo)Vim has 'job' feature, this plugin won't stop your behavior. 98 | Otherwise, yes(and this plugin is not recommended in that case). 99 | 100 | =============================================================================== 101 | *codelf-references* 102 | References ~ 103 | 104 | [1] https://github.com/unbug/codelf 105 | [2] https://user-images.githubusercontent.com/20282795/71583991-a2acda00-2b4b-11ea-99aa-097762e92383.gif 106 | [3] https://user-images.githubusercontent.com/20282795/71583992-a2acda00-2b4b-11ea-8f72-1d0068b020ff.gif 107 | [4] https://github.com/voldikss/vim-browser-search 108 | 109 | vim: ft=help 110 | -------------------------------------------------------------------------------- /plugin/codelf.vim: -------------------------------------------------------------------------------- 1 | " ============================================================================ 2 | " FileName: codelf.vim 3 | " Description: 4 | " Author: voldikss 5 | " GitHub: https://github.com/voldikss 6 | " ============================================================================ 7 | 8 | 9 | if exists('g:loaded_codelf') 10 | finish 11 | endif 12 | let g:loaded_codelf= 1 13 | let g:codelf_status = '' 14 | 15 | let g:codelf_enable_popup_menu = get(g:, 'codelf_enable_popup_menu', v:true) 16 | let g:codelf_proxy_url = get(g:, 'codelf_proxy_url', '') 17 | 18 | command! -nargs=? Codelf call codelf#start() 19 | command! -nargs=? CodelfOpenBrowser call codelf#browser#open() 20 | -------------------------------------------------------------------------------- /script/codelf.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # =========================================================================== 3 | # FileName: search.py 4 | # Description: Search usage variable names from https://unbug.github.io/codelf/ 5 | # Author: voldikss 6 | # GitHub: https://github.com/voldikss 7 | # =========================================================================== 8 | 9 | import codecs 10 | import argparse 11 | import json 12 | import time 13 | import socket 14 | import random 15 | import re 16 | import sys 17 | 18 | if sys.version_info[0] < 3: 19 | is_py3 = False 20 | reload(sys) 21 | sys.setdefaultencoding("utf-8") 22 | sys.stdout = codecs.getwriter("utf-8")(sys.stdout) 23 | sys.stderr = codecs.getwriter("utf-8")(sys.stderr) 24 | from urlparse import urlparse 25 | from urllib import urlencode 26 | from urllib import quote_plus as url_quote 27 | from urllib2 import urlopen 28 | from urllib2 import Request 29 | from urllib2 import URLError 30 | from urllib2 import HTTPError 31 | else: 32 | is_py3 = True 33 | sys.stdout = codecs.getwriter("utf-8")(sys.stdout.buffer) 34 | sys.stderr = codecs.getwriter("utf-8")(sys.stderr.buffer) 35 | from urllib.parse import urlencode 36 | from urllib.parse import quote_plus as url_quote 37 | from urllib.parse import urlparse 38 | from urllib.request import urlopen 39 | from urllib.request import Request 40 | from urllib.error import URLError 41 | from urllib.error import HTTPError 42 | 43 | 44 | CODELF_API = "https://searchcode.com/api/codesearch_I/?callback=searchcodeRequestVariableCallback&p=0&per_page=42&q=" 45 | FILTER_WORDS = [ 46 | "at", 47 | "are", 48 | "am", 49 | "the", 50 | "of", 51 | "at", 52 | "a", 53 | "an", 54 | "is", 55 | "not", 56 | "no", 57 | "a", 58 | "b", 59 | "c", 60 | "d", 61 | "e", 62 | "f", 63 | "g", 64 | "h", 65 | "i", 66 | "j", 67 | "k", 68 | "l", 69 | "m", 70 | "n", 71 | "o", 72 | "p", 73 | "q", 74 | "r", 75 | "s", 76 | "t", 77 | "u", 78 | "v", 79 | "w", 80 | "x", 81 | "y", 82 | "z", 83 | ] 84 | 85 | 86 | class Base: 87 | def http_request(self, url, data=None, headers=None): 88 | if data: 89 | req = Request(url, data, headers) 90 | else: 91 | req = Request(url, headers) 92 | try: 93 | res = urlopen(req, timeout=10) 94 | except (URLError, HTTPError, socket.timeout): 95 | return None 96 | return res.read().decode("utf-8") 97 | 98 | def set_proxy(self, proxy_url=None): 99 | try: 100 | import socks 101 | except ImportError: 102 | sys.stderr.write("pySocks module should be installed\n") 103 | return None 104 | 105 | try: 106 | import ssl 107 | 108 | ssl._create_default_https_context = ssl._create_unverified_context 109 | except Exception: 110 | pass 111 | 112 | self._proxy_url = proxy_url 113 | 114 | proxy_types = { 115 | "http": socks.PROXY_TYPE_HTTP, 116 | "socks": socks.PROXY_TYPE_SOCKS4, 117 | "socks4": socks.PROXY_TYPE_SOCKS4, 118 | "socks5": socks.PROXY_TYPE_SOCKS5, 119 | } 120 | 121 | url_component = urlparse(proxy_url) 122 | 123 | proxy_args = { 124 | "proxy_type": proxy_types[url_component.scheme], 125 | "addr": url_component.hostname, 126 | "port": url_component.port, 127 | "username": url_component.username, 128 | "password": url_component.password, 129 | } 130 | 131 | socks.set_default_proxy(**proxy_args) 132 | socket.socket = socks.socksocket 133 | 134 | def test_request(self, test_url): 135 | print("test url: %s" % test_url) 136 | print(self.http_request(test_url)) 137 | 138 | 139 | class YoudaoTranslator(Base): 140 | def __init__(self): 141 | self.url = ( 142 | "https://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule" 143 | ) 144 | self.D = "97_3(jkMYg@T[KZQmqjTK" 145 | 146 | def get_md5(self, value): 147 | import hashlib 148 | 149 | m = hashlib.md5() 150 | m.update(value.encode("utf-8")) 151 | return m.hexdigest() 152 | 153 | def sign(self, text, salt): 154 | s = "fanyideskweb" + text + salt + self.D 155 | return self.get_md5(s) 156 | 157 | def callback(self, r_json): 158 | paraphrase = self.get_paraphrase(r_json) 159 | if paraphrase: 160 | translation = paraphrase 161 | else: 162 | explain = self.get_explain(r_json) 163 | if len(explain) == 0: 164 | return None 165 | translation = explain[0] 166 | return "".join( 167 | filter(lambda x: x.lower() not in FILTER_WORDS, translation.split()) 168 | ) 169 | 170 | def translate(self, text): 171 | self.text = text 172 | salt = str(int(time.time() * 1000) + random.randint(0, 10)) 173 | sign = self.sign(text, salt) 174 | header = { 175 | "Cookie": "OUTFOX_SEARCH_USER_ID=-2022895048@10.168.8.76;", 176 | "Referer": "http://fanyi.youdao.com/", 177 | "User-Agent": "Mozilla/5.0 (Windows NT 6.2; rv:51.0) Gecko/20100101 Firefox/51.0", 178 | } 179 | data = { 180 | "i": text, 181 | "from": "zh", 182 | "to": "en", 183 | "smartresult": "dict", 184 | "client": "fanyideskweb", 185 | "salt": salt, 186 | "sign": sign, 187 | "doctype": "json", 188 | "version": "2.1", 189 | "keyfrom": "fanyi.web", 190 | "action": "FY_BY_CL1CKBUTTON", 191 | "typoResult": "true", 192 | } 193 | 194 | data = urlencode(data).encode("utf-8") 195 | res = self.http_request(self.url, data, header) 196 | r_json = json.loads(res) 197 | return self.callback(r_json) 198 | 199 | def get_paraphrase(self, obj): 200 | translation = "" 201 | t = obj.get("translateResult") 202 | if t: 203 | for n in t: 204 | part = [] 205 | for m in n: 206 | x = m.get("tgt") 207 | if x: 208 | part.append(x) 209 | if part: 210 | translation += ", ".join(part) 211 | return translation 212 | 213 | def get_explain(self, obj): 214 | explain = [] 215 | if "smartResult" in obj: 216 | smarts = obj["smartResult"]["entries"] 217 | for entry in smarts: 218 | if entry: 219 | entry = entry.replace("\r", "") 220 | entry = entry.replace("\n", "") 221 | explain.append(entry) 222 | return explain 223 | 224 | 225 | class Codelf(Base): 226 | def search(self, word): 227 | if self.is_chinese(word): 228 | translator = YoudaoTranslator() 229 | word = translator.translate(word) 230 | url = CODELF_API + url_quote(word) 231 | r_json = self.http_request(url) 232 | if r_json: 233 | self.callback(r_json, word) 234 | else: 235 | sys.stdout.write(str([word])) 236 | 237 | def callback(self, r_json, word): 238 | res = json.loads(r_json) 239 | result = [] 240 | for item in res["results"]: 241 | for lnum in item["lines"]: 242 | line = item["lines"][lnum] 243 | line = re.sub(r"[^a-zA-Z_\-]+", " ", line).strip() 244 | for target in word.split(): 245 | for w in re.split(r"\s+", line): 246 | if target.lower() in w.lower() and w not in result: 247 | result.append(w) 248 | sys.stdout.write(str(result)) 249 | 250 | def is_chinese(self, s): 251 | return any([u"\u4e00" <= ch <= u"\u9fff" for ch in s]) 252 | 253 | 254 | def main(): 255 | parser = argparse.ArgumentParser() 256 | parser.add_argument("--text", required=True) 257 | parser.add_argument("--proxy", required=False) 258 | args = parser.parse_args() 259 | 260 | text = args.text.strip("'") 261 | text = text.strip('"') 262 | text = text.strip() 263 | proxy = args.proxy 264 | 265 | codelf = Codelf() 266 | if proxy: 267 | codelf.set_proxy(proxy) 268 | 269 | codelf.search(text) 270 | 271 | 272 | if __name__ == "__main__": 273 | 274 | def test_proxy(): 275 | t = Base() 276 | t.set_proxy("http://localhost:8087") 277 | t.test_request("https://www.google.com") 278 | 279 | def test_codelf(): 280 | codelf = Codelf() 281 | codelf.search("图片") 282 | 283 | def test_youdao(): 284 | translator = YoudaoTranslator() 285 | res = translator.translate("图片") 286 | print(res) 287 | 288 | # test_codelf() 289 | # test_youdao() 290 | main() 291 | --------------------------------------------------------------------------------