* Site's __init__() takes more args, all optional. As long as enough are provided to do an API query, the missing ones will be filled in automatically by _load_attributes(), which is called in __init__(). * User: _get_attribute_from_api() -> _get_attribute(); _load_attributes_from_api() -> _load_attributes. * Sites in config.json are stored with different keys/values.tags/v0.1^2
| @@ -35,12 +35,26 @@ def _get_site_object_from_dict(name, d): | |||||
| """Return a Site object based on the contents of a dict, probably acquired | """Return a Site object based on the contents of a dict, probably acquired | ||||
| through our config file, and a separate name. | through our config file, and a separate name. | ||||
| """ | """ | ||||
| project = d["project"] | |||||
| lang = d["lang"] | |||||
| try: | try: | ||||
| api = d["apiURL"] | |||||
| project = d["project"] | |||||
| except KeyError: | except KeyError: | ||||
| api = None | |||||
| project = None | |||||
| try: | |||||
| lang = d["lang"] | |||||
| except KeyError: | |||||
| lang = None | |||||
| try: | |||||
| base_url = d["baseURL"] | |||||
| except KeyError: | |||||
| base_url = None | |||||
| try: | |||||
| article_path = d["articlePath"] | |||||
| except KeyError: | |||||
| article_path = None | |||||
| try: | |||||
| script_path = d["scriptPath"] | |||||
| except KeyError: | |||||
| script_path = None | |||||
| try: | try: | ||||
| sql_server = d["sqlServer"] | sql_server = d["sqlServer"] | ||||
| except KeyError: | except KeyError: | ||||
| @@ -49,7 +63,14 @@ def _get_site_object_from_dict(name, d): | |||||
| sql_db = d["sqlDB"] | sql_db = d["sqlDB"] | ||||
| except KeyError: | except KeyError: | ||||
| sql_db = None | sql_db = None | ||||
| return Site(name, project, lang, api, (sql_server, sql_db)) | |||||
| try: | |||||
| namespaces = d["namespaces"] | |||||
| except KeyError: | |||||
| namespaces = None | |||||
| return Site(name=name, project=project, lang=lang, base_url=base_url, | |||||
| article_path=article_path, script_path=script_path, | |||||
| sql=(sql_server, sql_db), namespaces=namespaces) | |||||
| def get_site(name=None, project=None, lang=None): | def get_site(name=None, project=None, lang=None): | ||||
| """Returns a Site instance based on information from our config file. | """Returns a Site instance based on information from our config file. | ||||
| @@ -15,29 +15,71 @@ class Site(object): | |||||
| EarwigBot's Wiki Toolset: Site Class | EarwigBot's Wiki Toolset: Site Class | ||||
| """ | """ | ||||
| def __init__(self, name, project, lang, api=None, sql=(None, None)): | |||||
| def __init__(self, name=None, project=None, lang=None, base_url=None, | |||||
| article_path=None, script_path=None, sql=(None, None), | |||||
| namespaces=None): | |||||
| """ | """ | ||||
| Docstring needed | Docstring needed | ||||
| """ | """ | ||||
| self.name = name | |||||
| self.project = project | |||||
| self.lang = lang | |||||
| self._api = api | |||||
| self._name = name | |||||
| self._project = project | |||||
| self._lang = lang | |||||
| self._base_url = base_url | |||||
| self._article_path = article_path | |||||
| self._script_path = script_path | |||||
| self._sql = sql | self._sql = sql | ||||
| self._namespaces = None | |||||
| self._namespaces = namespaces | |||||
| # get all of the above attributes that were not specified by the user | |||||
| self._load_attributes() | |||||
| def _get_namespaces_from_api(self): | |||||
| def _load_attributes(self, force=False): | |||||
| """ | """ | ||||
| Docstring needed | Docstring needed | ||||
| """ | """ | ||||
| params = {"action": "query", "meta": "siteinfo", | |||||
| "siprop": "namespaces|namespacealiases"} | |||||
| result = self.api_query(params) | |||||
| if self._namespaces is None: | |||||
| self._namespaces = {} | |||||
| # all attributes to be loaded, except _namespaces, which is a special | |||||
| # case because it requires additional params in the API query | |||||
| attrs = [self._name, self._project, self._lang, self._base_url, | |||||
| self._article_path, self._script_path] | |||||
| params = {"action": "query", "meta": "siteinfo"} | |||||
| if self._namespaces is None or force: | |||||
| params["siprop"] = "general|namespaces|namespacealiases" | |||||
| result = self.api_query(params) | |||||
| self._load_namespaces(result) | |||||
| elif all(attrs): # everything is already specified and we're not told | |||||
| return # to force a reload, so do nothing | |||||
| else: # we're only loading attributes other than _namespaces | |||||
| params["siprop"] = "general" | |||||
| result = self.api_query(params) | |||||
| res = result["query"]["general"] | |||||
| if self._name is None or force: | |||||
| self._name = res["wikiid"] | |||||
| if self._project is None or force: | |||||
| self._project = res["sitename"].lower() | |||||
| if self._lang is None or force: | |||||
| self._lang = res["lang"] | |||||
| if self._base_url is None or force: | |||||
| self._base_url = res["server"] | |||||
| if self._article_path is None or force: | |||||
| self._article_path = res["articlepath"] | |||||
| if self._script_path is None or force: | |||||
| self._script_path = res["scriptpath"] | |||||
| def _load_namespaces(self, result): | |||||
| """ | |||||
| Docstring needed | |||||
| """ | |||||
| self._namespaces = {} | |||||
| for namespace in result["query"]["namespaces"].values(): | for namespace in result["query"]["namespaces"].values(): | ||||
| ns_id = namespace["id"] | ns_id = namespace["id"] | ||||
| name = namespace["*"] | name = namespace["*"] | ||||
| @@ -60,27 +102,58 @@ class Site(object): | |||||
| """ | """ | ||||
| Docstring needed | Docstring needed | ||||
| """ | """ | ||||
| url = ''.join((self._base_url, self._script_path, "/api.php")) | |||||
| params["format"] = "json" | params["format"] = "json" | ||||
| data = urlencode(params) | data = urlencode(params) | ||||
| result = urlopen(self._api, data).read() | |||||
| result = urlopen(url, data).read() | |||||
| return loads(result) | return loads(result) | ||||
| def name(self): | |||||
| """ | |||||
| Docstring needed | |||||
| """ | |||||
| return self._name | |||||
| def project(self): | |||||
| """ | |||||
| Docstring needed | |||||
| """ | |||||
| return self._project | |||||
| def lang(self): | |||||
| """ | |||||
| Docstring needed | |||||
| """ | |||||
| return self._lang | |||||
| def base_url(self): | |||||
| """ | |||||
| Docstring needed | |||||
| """ | |||||
| return self._base_url | |||||
| def article_path(self): | |||||
| """ | |||||
| Docstring needed | |||||
| """ | |||||
| return self._article_path | |||||
| def script_path(self): | |||||
| """ | |||||
| Docstring needed | |||||
| """ | |||||
| return self._script_path | |||||
| def namespaces(self): | def namespaces(self): | ||||
| """ | """ | ||||
| Docstring needed | Docstring needed | ||||
| """ | """ | ||||
| if self._namespaces is None: | |||||
| self._get_namespaces_from_api() | |||||
| return self._namespaces | return self._namespaces | ||||
| def namespace_id_to_name(self, ns_id, all=False): | def namespace_id_to_name(self, ns_id, all=False): | ||||
| """ | """ | ||||
| Docstring needed | Docstring needed | ||||
| """ | """ | ||||
| if self._namespaces is None: | |||||
| self._get_namespaces_from_api() | |||||
| try: | try: | ||||
| if all: | if all: | ||||
| return self._namespaces[ns_id] | return self._namespaces[ns_id] | ||||
| @@ -94,9 +167,6 @@ class Site(object): | |||||
| """ | """ | ||||
| Docstring needed | Docstring needed | ||||
| """ | """ | ||||
| if self._namespaces is None: | |||||
| self._get_namespaces_from_api() | |||||
| lname = name.lower() | lname = name.lower() | ||||
| for ns_id, names in self._namespaces.items(): | for ns_id, names in self._namespaces.items(): | ||||
| lnames = [n.lower() for n in names] # be case-insensitive | lnames = [n.lower() for n in names] # be case-insensitive | ||||
| @@ -30,18 +30,18 @@ class User(object): | |||||
| self._emailable = None | self._emailable = None | ||||
| self._gender = None | self._gender = None | ||||
| def _get_attribute_from_api(self, attr, force): | |||||
| def _get_attribute(self, attr, force): | |||||
| """ | """ | ||||
| Docstring needed | Docstring needed | ||||
| """ | """ | ||||
| if self._exists is None or force: | if self._exists is None or force: | ||||
| self._load_attributes_from_api() | |||||
| self._load_attributes() | |||||
| if self._exists is False: | if self._exists is False: | ||||
| e = "User '{0}' does not exist.".format(self._name) | e = "User '{0}' does not exist.".format(self._name) | ||||
| raise UserNotFoundError(e) | raise UserNotFoundError(e) | ||||
| return getattr(self, attr) | return getattr(self, attr) | ||||
| def _load_attributes_from_api(self): | |||||
| def _load_attributes(self): | |||||
| """ | """ | ||||
| Docstring needed | Docstring needed | ||||
| """ | """ | ||||
| @@ -84,61 +84,61 @@ class User(object): | |||||
| """ | """ | ||||
| Docstring needed | Docstring needed | ||||
| """ | """ | ||||
| return self._get_attribute_from_api("_name", force) | |||||
| return self._get_attribute("_name", force) | |||||
| def exists(self, force=False): | def exists(self, force=False): | ||||
| """ | """ | ||||
| Docstring needed | Docstring needed | ||||
| """ | """ | ||||
| return self._get_attribute_from_api("_exists", force) | |||||
| return self._get_attribute("_exists", force) | |||||
| def userid(self, force=False): | def userid(self, force=False): | ||||
| """ | """ | ||||
| Docstring needed | Docstring needed | ||||
| """ | """ | ||||
| return self._get_attribute_from_api("_userid", force) | |||||
| return self._get_attribute("_userid", force) | |||||
| def blockinfo(self, force=False): | def blockinfo(self, force=False): | ||||
| """ | """ | ||||
| Docstring needed | Docstring needed | ||||
| """ | """ | ||||
| return self._get_attribute_from_api("_blockinfo", force) | |||||
| return self._get_attribute("_blockinfo", force) | |||||
| def groups(self, force=False): | def groups(self, force=False): | ||||
| """ | """ | ||||
| Docstring needed | Docstring needed | ||||
| """ | """ | ||||
| return self._get_attribute_from_api("_groups", force) | |||||
| return self._get_attribute("_groups", force) | |||||
| def rights(self, force=False): | def rights(self, force=False): | ||||
| """ | """ | ||||
| Docstring needed | Docstring needed | ||||
| """ | """ | ||||
| return self._get_attribute_from_api("_rights", force) | |||||
| return self._get_attribute("_rights", force) | |||||
| def editcount(self, force=False): | def editcount(self, force=False): | ||||
| """ | """ | ||||
| Docstring needed | Docstring needed | ||||
| """ | """ | ||||
| return self._get_attribute_from_api("_editcount", force) | |||||
| return self._get_attribute("_editcount", force) | |||||
| def registration(self, force=False): | def registration(self, force=False): | ||||
| """ | """ | ||||
| Docstring needed | Docstring needed | ||||
| """ | """ | ||||
| return self._get_attribute_from_api("_registration", force) | |||||
| return self._get_attribute("_registration", force) | |||||
| def is_emailable(self, force=False): | def is_emailable(self, force=False): | ||||
| """ | """ | ||||
| Docstring needed | Docstring needed | ||||
| """ | """ | ||||
| return self._get_attribute_from_api("_emailable", force) | |||||
| return self._get_attribute("_emailable", force) | |||||
| def gender(self, force=False): | def gender(self, force=False): | ||||
| """ | """ | ||||
| Docstring needed | Docstring needed | ||||
| """ | """ | ||||
| return self._get_attribute_from_api("_gender", force) | |||||
| return self._get_attribute("_gender", force) | |||||
| def userpage(self): | def userpage(self): | ||||
| """ | """ | ||||