* 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 | |||
through our config file, and a separate name. | |||
""" | |||
project = d["project"] | |||
lang = d["lang"] | |||
try: | |||
api = d["apiURL"] | |||
project = d["project"] | |||
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: | |||
sql_server = d["sqlServer"] | |||
except KeyError: | |||
@@ -49,7 +63,14 @@ def _get_site_object_from_dict(name, d): | |||
sql_db = d["sqlDB"] | |||
except KeyError: | |||
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): | |||
"""Returns a Site instance based on information from our config file. | |||
@@ -15,29 +15,71 @@ class Site(object): | |||
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 | |||
""" | |||
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._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 | |||
""" | |||
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(): | |||
ns_id = namespace["id"] | |||
name = namespace["*"] | |||
@@ -60,27 +102,58 @@ class Site(object): | |||
""" | |||
Docstring needed | |||
""" | |||
url = ''.join((self._base_url, self._script_path, "/api.php")) | |||
params["format"] = "json" | |||
data = urlencode(params) | |||
result = urlopen(self._api, data).read() | |||
result = urlopen(url, data).read() | |||
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): | |||
""" | |||
Docstring needed | |||
""" | |||
if self._namespaces is None: | |||
self._get_namespaces_from_api() | |||
return self._namespaces | |||
def namespace_id_to_name(self, ns_id, all=False): | |||
""" | |||
Docstring needed | |||
""" | |||
if self._namespaces is None: | |||
self._get_namespaces_from_api() | |||
try: | |||
if all: | |||
return self._namespaces[ns_id] | |||
@@ -94,9 +167,6 @@ class Site(object): | |||
""" | |||
Docstring needed | |||
""" | |||
if self._namespaces is None: | |||
self._get_namespaces_from_api() | |||
lname = name.lower() | |||
for ns_id, names in self._namespaces.items(): | |||
lnames = [n.lower() for n in names] # be case-insensitive | |||
@@ -30,18 +30,18 @@ class User(object): | |||
self._emailable = None | |||
self._gender = None | |||
def _get_attribute_from_api(self, attr, force): | |||
def _get_attribute(self, attr, force): | |||
""" | |||
Docstring needed | |||
""" | |||
if self._exists is None or force: | |||
self._load_attributes_from_api() | |||
self._load_attributes() | |||
if self._exists is False: | |||
e = "User '{0}' does not exist.".format(self._name) | |||
raise UserNotFoundError(e) | |||
return getattr(self, attr) | |||
def _load_attributes_from_api(self): | |||
def _load_attributes(self): | |||
""" | |||
Docstring needed | |||
""" | |||
@@ -84,61 +84,61 @@ class User(object): | |||
""" | |||
Docstring needed | |||
""" | |||
return self._get_attribute_from_api("_name", force) | |||
return self._get_attribute("_name", force) | |||
def exists(self, force=False): | |||
""" | |||
Docstring needed | |||
""" | |||
return self._get_attribute_from_api("_exists", force) | |||
return self._get_attribute("_exists", force) | |||
def userid(self, force=False): | |||
""" | |||
Docstring needed | |||
""" | |||
return self._get_attribute_from_api("_userid", force) | |||
return self._get_attribute("_userid", force) | |||
def blockinfo(self, force=False): | |||
""" | |||
Docstring needed | |||
""" | |||
return self._get_attribute_from_api("_blockinfo", force) | |||
return self._get_attribute("_blockinfo", force) | |||
def groups(self, force=False): | |||
""" | |||
Docstring needed | |||
""" | |||
return self._get_attribute_from_api("_groups", force) | |||
return self._get_attribute("_groups", force) | |||
def rights(self, force=False): | |||
""" | |||
Docstring needed | |||
""" | |||
return self._get_attribute_from_api("_rights", force) | |||
return self._get_attribute("_rights", force) | |||
def editcount(self, force=False): | |||
""" | |||
Docstring needed | |||
""" | |||
return self._get_attribute_from_api("_editcount", force) | |||
return self._get_attribute("_editcount", force) | |||
def registration(self, force=False): | |||
""" | |||
Docstring needed | |||
""" | |||
return self._get_attribute_from_api("_registration", force) | |||
return self._get_attribute("_registration", force) | |||
def is_emailable(self, force=False): | |||
""" | |||
Docstring needed | |||
""" | |||
return self._get_attribute_from_api("_emailable", force) | |||
return self._get_attribute("_emailable", force) | |||
def gender(self, force=False): | |||
""" | |||
Docstring needed | |||
""" | |||
return self._get_attribute_from_api("_gender", force) | |||
return self._get_attribute("_gender", force) | |||
def userpage(self): | |||
""" | |||