diff --git a/src/fastwq/query.py b/src/fastwq/query.py index 2025aad..d71203f 100644 --- a/src/fastwq/query.py +++ b/src/fastwq/query.py @@ -32,7 +32,7 @@ from .constants import Endpoint, Template from .context import config from .lang import _, _sl from .progress import ProgressWindow -from .service import service_manager, QueryResult, copy_static_file +from .service import service_manager, service_pool, QueryResult, copy_static_file from .utils import Empty, MapDict, Queue, wrap_css @@ -257,15 +257,16 @@ def update_note_field(note, fld_index, fld_result): def promot_choose_css(): for local_service in service_manager.local_services: try: - missed_css = local_service.missed_css.pop() + service = service_pool.get(local_service.__unique__) + missed_css = service.missed_css.pop() showInfo(Template.miss_css.format( - dict=local_service.title, css=missed_css)) + dict=service.title, css=missed_css)) filepath = QFileDialog.getOpenFileName( caption=u'Choose css file', filter=u'CSS (*.css)') if filepath: shutil.copy(filepath, u'_' + missed_css) wrap_css(u'_' + missed_css) - local_service.missed_css.clear() + service.missed_css.clear() except KeyError as e: pass @@ -343,36 +344,3 @@ def query_all_flds(note): service_pool.put(service) return result, success_num - - -class ServicePool(object): - """ - Service instance pool - """ - def __init__(self): - self.pools = {} - - def get(self, unique): - queue = self.pools.get(unique, None) - if queue: - try: - return queue.get(True, timeout=0.1) - except Empty: - pass - - return service_manager.get_service(unique) - - def put(self, service): - unique = service.unique - queue = self.pools.get(unique, None) - if queue == None: - queue = Queue() - self.pools[unique] = queue - - queue.put(service) - - def clean(self): - self.pools = {} - - -service_pool = ServicePool() # Service Instance Pool Manager diff --git a/src/fastwq/service/__init__.py b/src/fastwq/service/__init__.py index f90aa5d..73ed884 100644 --- a/src/fastwq/service/__init__.py +++ b/src/fastwq/service/__init__.py @@ -18,6 +18,8 @@ # along with this program. If not, see . from .manager import ServiceManager +from .pool import ServicePool from .base import QueryResult, copy_static_file -service_manager = ServiceManager() \ No newline at end of file +service_manager = ServiceManager() # Service Manager +service_pool = ServicePool(service_manager) # Service Instance Pool Manager \ No newline at end of file diff --git a/src/fastwq/service/manager.py b/src/fastwq/service/manager.py index 3b003b8..e57e0e8 100644 --- a/src/fastwq/service/manager.py +++ b/src/fastwq/service/manager.py @@ -1,8 +1,8 @@ #-*- coding:utf-8 -*- # -# Copyright © 2016–2017 Liang Feng +# Copyright © 2016–2017 ST.Huang # -# Support: Report an issue at https://github.com/finalion/WordQuery/issues +# Support: Report an issue at https://github.com/sth2018/FastWordQuery/issues # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -29,7 +29,18 @@ from ..context import config from ..utils import MapDict, importlib +def service_wrap(service, *args): + """ + wrap the service class constructor + """ + def _service(): + return service(*args) + return _service + class ServiceManager(object): + """ + Query service class manager + """ def __init__(self): self.update_services() @@ -52,13 +63,13 @@ class ServiceManager(object): # combine the customized local services into local services self.local_services.update(self.local_custom_services) - def get_service(self, unique, *args): + def get_service(self, unique): # webservice unique: class name # mdxservice unique: dict filepath for each in self.services: - if each.unique == unique: - cls = getattr(each,"__class__") - return cls(*args) + if each.__unique__ == unique: + #cls = getattr(each,"__class__") + return each() def get_service_action(self, service, label): for each in service.fields: @@ -73,7 +84,7 @@ class ServiceManager(object): web_services, local_custom_services = set(), set() mypath = os.path.dirname(os.path.realpath(__file__)) files = [f for f in os.listdir(mypath) - if f not in ('__init__.py', 'base.py', 'manager.py') and not f.endswith('.pyc')] + if f not in ('__init__.py', 'base.py', 'manager.py', 'pool.py') and not f.endswith('.pyc')] base_class = (WebService, LocalService, MdxService, StardictService) @@ -84,29 +95,36 @@ class ServiceManager(object): for name, cls in inspect.getmembers(module, predicate=inspect.isclass): if cls in base_class: continue - try: - service = cls(*args) - if issubclass(cls, WebService): - web_services.add(service) - # get the customized local services - if issubclass(cls, LocalService): - local_custom_services.add(service) - except Exception: + #try: + #service = cls(*args) + service = service_wrap(cls, *args) + service.__unique__ = name + if issubclass(cls, WebService): + web_services.add(service) + # get the customized local services + if issubclass(cls, LocalService): + local_custom_services.add(service) + #except Exception: # exclude the local service whose path has error. - pass + # pass except ImportError: continue return web_services, local_custom_services def _get_available_local_services(self): + services = set() for each in config.dirs: for dirpath, dirnames, filenames in os.walk(each): for filename in filenames: + service = None dict_path = os.path.join(dirpath, filename) if MdxService.support(dict_path): - services.add(MdxService(dict_path)) + service = service_wrap(MdxService, dict_path) if StardictService.support(dict_path): - services.add(StardictService(dict_path)) + service = service_wrap(StardictService, dict_path) + if service: + service.__unique__ = dict_path + services.add(service) # support mdx dictionary and stardict format dictionary return services diff --git a/src/fastwq/service/pool.py b/src/fastwq/service/pool.py new file mode 100644 index 0000000..2446c10 --- /dev/null +++ b/src/fastwq/service/pool.py @@ -0,0 +1,51 @@ +#-*- coding:utf-8 -*- +# +# Copyright © 2016–2017 ST.Huang +# +# Support: Report an issue at https://github.com/sth2018/FastWordQuery/issues +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# any later version; http://www.gnu.org/copyleft/gpl.html. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +from ..utils import Empty, Queue + + +class ServicePool(object): + """ + Service instance pool + """ + def __init__(self, manager): + self.pools = {} + self.manager = manager + + def get(self, unique): + queue = self.pools.get(unique, None) + if queue: + try: + return queue.get(True, timeout=0.1) + except Empty: + pass + + return self.manager.get_service(unique) + + def put(self, service): + unique = service.unique + queue = self.pools.get(unique, None) + if queue == None: + queue = Queue() + self.pools[unique] = queue + + queue.put(service) + + def clean(self): + self.pools = {} diff --git a/src/fastwq/ui.py b/src/fastwq/ui.py index 9ad350d..09b2700 100644 --- a/src/fastwq/ui.py +++ b/src/fastwq/ui.py @@ -32,7 +32,7 @@ from aqt.utils import shortcut, showInfo from .constants import VERSION, Endpoint, Template from .context import APP_ICON, config from .lang import _, _sl -from .service import service_manager +from .service import service_manager, service_pool from .utils import MapDict, get_icon, get_model_byId, get_ord_from_fldname DICT_COMBOS, DICT_FILED_COMBOS, ALL_COMBOS = [0, 1, 2] @@ -340,15 +340,21 @@ class OptionsDialog(QDialog): def fill_dict_combo_options(self, dict_combo, current_text): dict_combo.clear() dict_combo.addItem(_('NOT_DICT_FIELD')) + dict_combo.insertSeparator(dict_combo.count()) - for service in service_manager.local_services: + for cls in service_manager.local_services: # combo_data.insert("data", each.label) + service = service_pool.get(cls.__unique__) dict_combo.addItem( service.title, userData=service.unique) + service_pool.put(service) + dict_combo.insertSeparator(dict_combo.count()) - for service in service_manager.web_services: + for cls in service_manager.web_services: + service = service_pool.get(cls.__unique__) dict_combo.addItem( service.title, userData=service.unique) + service_pool.put(service) def set_dict_combo_index(): dict_combo.setCurrentIndex(-1) @@ -371,13 +377,14 @@ class OptionsDialog(QDialog): else: field_text = field_combo.currentText() service_unique = dict_combo_itemdata - current_service = service_manager.get_service(service_unique) + current_service = service_pool.get(service_unique) # problem if current_service and current_service.fields: for each in current_service.fields: field_combo.addItem(each) if each == field_text: field_combo.setEditText(field_text) + service_pool.put(current_service) def radio_btn_checked(self): rbs = self.findChildren(QRadioButton)