jenkins-bot has submitted this change and it was merged.
Change subject: replace 'number' argument names with 'total'
......................................................................
replace 'number' argument names with 'total'
for consistency reasons, as in site.py
per change I981d45342ed7f9eca07b2c0431b51240c496f285
Change-Id: I5d07bce3cc422cbae5122ea23d66bcc217f4ce75
---
M pywikibot/pagegenerators.py
1 file changed, 56 insertions(+), 32 deletions(-)
Approvals:
Xqt: Looks good to me, approved
jenkins-bot: Verified
diff --git a/pywikibot/pagegenerators.py b/pywikibot/pagegenerators.py
index e1d510f..385e613 100644
--- a/pywikibot/pagegenerators.py
+++ b/pywikibot/pagegenerators.py
@@ -306,19 +306,19 @@
if len(arg) == 12:
gen = UnusedFilesGenerator()
else:
- gen = UnusedFilesGenerator(number=int(arg[13:]))
+ gen = UnusedFilesGenerator(total=int(arg[13:]))
elif arg.startswith('-unwatched'):
if len(arg) == 10:
gen = UnwatchedPagesPageGenerator()
else:
- gen = UnwatchedPagesPageGenerator(number=int(arg[11:]))
+ gen = UnwatchedPagesPageGenerator(total=int(arg[11:]))
elif arg.startswith('-usercontribs'):
gen = UserContributionsGenerator(arg[14:])
elif arg.startswith('-withoutinterwiki'):
if len(arg) == 17:
gen = WithoutInterwikiPageGenerator()
else:
- gen = WithoutInterwikiPageGenerator(number=int(arg[18:]))
+ gen = WithoutInterwikiPageGenerator(total=int(arg[18:]))
elif arg.startswith('-interwiki'):
title = arg[11:]
if not title:
@@ -330,12 +330,12 @@
if len(arg) == 15:
gen = RandomRedirectPageGenerator()
else:
- gen = RandomRedirectPageGenerator(number=int(arg[16:]))
+ gen = RandomRedirectPageGenerator(total=int(arg[16:]))
elif arg.startswith('-random'):
if len(arg) == 7:
gen = RandomPageGenerator()
else:
- gen = RandomPageGenerator(number=int(arg[8:]))
+ gen = RandomPageGenerator(total=int(arg[8:]))
elif arg.startswith('-recentchanges'):
if len(arg) >= 15:
gen = RecentChangesPageGenerator(total=int(arg[15:]))
@@ -558,7 +558,7 @@
@deprecate_arg("number", "total")
@deprecate_arg("namespace", "namespaces")
@deprecate_arg("repeat", None)
-def NewpagesPageGenerator(get_redirect=False, repeat=False, site=None,
+def NewpagesPageGenerator(get_redirect=False, site=None,
namespaces=[0, ], step=None, total=None):
"""
Iterate Page objects for all new titles in a single namespace.
@@ -937,52 +937,66 @@
#TODO below
@deprecate_arg("extension", None)
-def UnusedFilesGenerator(number=100, repeat=False, site=None, extension=None):
+@deprecate_arg("number", "total")
+@deprecate_arg("repeat", None)
+def UnusedFilesGenerator(total=100, site=None, extension=None):
if site is None:
site = pywikibot.Site()
- for page in site.unusedfiles(number=number, repeat=repeat):
+ for page in site.unusedfiles(total=total):
yield pywikibot.ImagePage(page.site, page.title())
-def WithoutInterwikiPageGenerator(number=100, repeat=False, site=None):
+@deprecate_arg("number", "total")
+@deprecate_arg("repeat", None)
+def WithoutInterwikiPageGenerator(total=100, site=None):
if site is None:
site = pywikibot.Site()
- for page in site.withoutinterwiki(number=number, repeat=repeat):
+ for page in site.withoutinterwiki(total=total):
yield page
-def UnCategorizedCategoryGenerator(number=100, repeat=False, site=None):
+@deprecate_arg("number", "total")
+@deprecate_arg("repeat", None)
+def UnCategorizedCategoryGenerator(total=100, site=None):
if site is None:
site = pywikibot.Site()
- for page in site.uncategorizedcategories(number=number, repeat=repeat):
+ for page in site.uncategorizedcategories(total=total):
yield page
-def UnCategorizedImageGenerator(number=100, repeat=False, site=None):
+@deprecate_arg("number", "total")
+@deprecate_arg("repeat", None)
+def UnCategorizedImageGenerator(total=100, site=None):
if site is None:
site = pywikibot.Site()
- for page in site.uncategorizedimages(number=number, repeat=repeat):
+ for page in site.uncategorizedimages(total=total):
yield page
-def UnCategorizedPageGenerator(number=100, repeat=False, site=None):
+@deprecate_arg("number", "total")
+@deprecate_arg("repeat", None)
+def UnCategorizedPageGenerator(total=100, site=None):
if site is None:
site = pywikibot.Site()
- for page in site.uncategorizedpages(number=number, repeat=repeat):
+ for page in site.uncategorizedpages(total=total):
yield page
-def LonelyPagesPageGenerator(number=100, repeat=False, site=None):
+@deprecate_arg("number", "total")
+@deprecate_arg("repeat", None)
+def LonelyPagesPageGenerator(total=100, site=None):
if site is None:
site = pywikibot.Site()
- for page in site.lonelypages(number=number, repeat=repeat):
+ for page in site.lonelypages(total=total):
yield page
-def UnwatchedPagesPageGenerator(number=100, repeat=False, site=None):
+@deprecate_arg("number", "total")
+@deprecate_arg("repeat", None)
+def UnwatchedPagesPageGenerator(total=100, site=None):
if site is None:
site = pywikibot.Site()
- for page in site.unwatchedpages(number=number, repeat=repeat):
+ for page in site.unwatchedpages(total=total):
yield page
@@ -993,45 +1007,55 @@
yield page
-def AncientPagesPageGenerator(number=100, repeat=False, site=None):
+@deprecate_arg("number", "total")
+@deprecate_arg("repeat", None)
+def AncientPagesPageGenerator(total=100, site=None):
if site is None:
site = pywikibot.Site()
- for page, date in site.ancientpages(number=number, repeat=repeat):
+ for page, date in site.ancientpages(total=total):
yield page
-def DeadendPagesPageGenerator(number=100, repeat=False, site=None):
+@deprecate_arg("number", "total")
+@deprecate_arg("repeat", None)
+def DeadendPagesPageGenerator(total=100, site=None):
if site is None:
site = pywikibot.Site()
- for page in site.deadendpages(number=number, repeat=repeat):
+ for page in site.deadendpages(total=total):
yield page
-def LongPagesPageGenerator(number=100, repeat=False, site=None):
+@deprecate_arg("number", "total")
+@deprecate_arg("repeat", None)
+def LongPagesPageGenerator(total=100, site=None):
if site is None:
site = pywikibot.Site()
- for page, length in site.longpages(number=number, repeat=repeat):
+ for page, length in site.longpages(total=total):
yield page
-def ShortPagesPageGenerator(number=100, repeat=False, site=None):
+@deprecate_arg("number", "total")
+@deprecate_arg("repeat", None)
+def ShortPagesPageGenerator(total=100, site=None):
if site is None:
site = pywikibot.Site()
- for page, length in site.shortpages(total=number, repeat=repeat):
+ for page, length in site.shortpages(total=total):
yield page
-def RandomPageGenerator(number=10, site=None):
+@deprecate_arg("number", "total")
+def RandomPageGenerator(total=10, site=None):
if site is None:
site = pywikibot.Site()
- for page in site.randompages(total=number):
+ for page in site.randompages(total=total):
yield page
-def RandomRedirectPageGenerator(number=10, site=None):
+@deprecate_arg("number", "total")
+def RandomRedirectPageGenerator(total=10, site=None):
if site is None:
site = pywikibot.Site()
- for page in site.randompages(total=number, redirects=True):
+ for page in site.randompages(total=total, redirects=True):
yield page
--
To view, visit https://gerrit.wikimedia.org/r/124778
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: I5d07bce3cc422cbae5122ea23d66bcc217f4ce75
Gerrit-PatchSet: 2
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Owner: Ricordisamoa <ricordisamoa(a)live.it>
Gerrit-Reviewer: Ladsgroup <ladsgroup(a)gmail.com>
Gerrit-Reviewer: Merlijn van Deen <valhallasw(a)arctus.nl>
Gerrit-Reviewer: Nullzero <nullzero.free(a)gmail.com>
Gerrit-Reviewer: Xqt <info(a)gno.de>
Gerrit-Reviewer: jenkins-bot <>
jenkins-bot has submitted this change and it was merged.
Change subject: Added WikidataQuery page generator
......................................................................
Added WikidataQuery page generator
The generator takes a WikidataQuery string and works on the resulting
page set. This allows complex queries like "Places in the U.S. that are
named after Francis of Assisi":
-wikidataquery:tree[30][150][17,131] AND claim[138:676555]
Change-Id: If35fbc947889dc4d7a6afcebedd899d5e1ae54db
---
M pywikibot/pagegenerators.py
1 file changed, 39 insertions(+), 3 deletions(-)
Approvals:
Mpaa: Looks good to me, approved
jenkins-bot: Verified
diff --git a/pywikibot/pagegenerators.py b/pywikibot/pagegenerators.py
index d66de77..e1d510f 100644
--- a/pywikibot/pagegenerators.py
+++ b/pywikibot/pagegenerators.py
@@ -25,11 +25,11 @@
import re
import time
import pywikibot
-from . import date
+from pywikibot import date
from pywikibot import config
from pywikibot import deprecate_arg, i18n
from pywikibot.comms import http
-
+import pywikibot.data.wikidataquery as wdquery
# ported from version 1 for backwards-compatibility
# most of these functions just wrap a Site or Page method that returns
@@ -144,6 +144,9 @@
Argument can be given as "-withoutinterwiki:n" where
n is some number (??).
+-wikidataquery Takes a WikidataQuery query string like claim[31:12280]
+ and works on the resulting pages.
+
-random Work on random pages returned by [[Special:Random]].
Can also be given as "-random:n" where n is the number
of pages to be returned, otherwise the default is 10 pages.
@@ -218,7 +221,8 @@
self.gens[i].set_maximum_items(self.limit)
else:
if self.namespaces:
- self.gens[i] = NamespaceFilterPageGenerator(self.gens[i], namespaces)
+ self.gens[i] = NamespaceFilterPageGenerator(self.gens[i],
+ namespaces)
if self.limit:
self.gens[i] = itertools.islice(self.gens[i], self.limit)
if len(self.gens) == 0:
@@ -490,6 +494,12 @@
gen = YahooSearchPageGenerator(arg[7:])
elif arg.startswith('-untagged'):
gen = UntaggedPageGenerator(arg[10:])
+ elif arg.startswith('-wikidataquery'):
+ query = arg[len('-wikidataquery:'):]
+ if not query:
+ query = pywikibot.input(
+ u'WikidataQuery string:')
+ gen = WikidataQueryPageGenerator(query)
if gen:
self.gens.append(gen)
@@ -1300,5 +1310,31 @@
for day in range(1, date.getNumberOfDaysInMonth(month) + 1):
yield pywikibot.Page(pywikibot.Link(fd(month, day), site))
+
+def WikidataQueryPageGenerator(query, site=None):
+ """Generate pages that result from the given WikidataQuery.
+
+ @param query: the WikidataQuery query string.
+
+ """
+ if site is None:
+ site = pywikibot.Site()
+ repo = site.data_repository()
+
+ wd_queryset = wdquery.QuerySet(query)
+
+ wd_query = wdquery.WikidataQuery(cacheMaxAge=0)
+ data = wd_query.query(wd_queryset)
+
+ pywikibot.output(u'retrieved %d items' % data[u'status'][u'items'])
+ for item in data[u'items']:
+ page = pywikibot.ItemPage(repo, u'Q' + unicode(item))
+ try:
+ link = page.getSitelink(site)
+ except pywikibot.NoPage:
+ continue
+ yield pywikibot.Page(pywikibot.Link(link, site))
+
+
if __name__ == "__main__":
pywikibot.output('Pagegenerators cannot be run as script - are you looking for listpages.py?')
--
To view, visit https://gerrit.wikimedia.org/r/118698
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: If35fbc947889dc4d7a6afcebedd899d5e1ae54db
Gerrit-PatchSet: 5
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Owner: FelixReimann <felix(a)fex-it.de>
Gerrit-Reviewer: Ladsgroup <ladsgroup(a)gmail.com>
Gerrit-Reviewer: Merlijn van Deen <valhallasw(a)arctus.nl>
Gerrit-Reviewer: Mpaa <mpaa.wiki(a)gmail.com>
Gerrit-Reviewer: jenkins-bot <>
jenkins-bot has submitted this change and it was merged.
Change subject: Revert "Make it possible to define a custom families folder"
......................................................................
Revert "Make it possible to define a custom families folder"
This reverts commit 6f464a0b3a06e1c2803aa5345ac4c0647c84584c.
Change-Id: Ic9b24c6e1119acd93f301da5c5fcf00d36ccc65e
---
M generate_user_files.py
M pywikibot/config2.py
M pywikibot/site.py
3 files changed, 39 insertions(+), 74 deletions(-)
Approvals:
Merlijn van Deen: Looks good to me, approved
jenkins-bot: Verified
diff --git a/generate_user_files.py b/generate_user_files.py
index 75130aa..0df0b15 100644
--- a/generate_user_files.py
+++ b/generate_user_files.py
@@ -237,34 +237,9 @@
# This is an automatically generated file. You can find more configuration
# parameters in 'config.py' file.
-# The family of sites to work on by default.
-#
-# ‘wikipedia.py’ imports ‘families/xxx_family.py’, so if you want to change
-# this variable, you need to use the name of one of the existing family files
-# in that folder or write your own, custom family file.
-#
-# For ‘wikipedia.py’ to be able to read your custom family file, you must
-# save it to ‘families/xxx_family.py’, where ‘xxx‘ is the codename of the
-# family that your custom ‘xxx_family.py’ family file defines.
-#
-# You can also save your custom family files to a different folder. As long
-# as you follow the ‘xxx_family.py’ naming convention, you can register your
-# custom folder in this configuration file with the following global function:
-#
-# register_families_folder(folder_path)
-#
-# Alternatively, you can register particular family files that do not need
-# to follow the ‘xxx_family.py’ naming convention using the following
-# global function:
-#
-# register_family_file(family_name, file_path)
-#
-# Where ‘family_name’ is the family code (the ‘xxx’ in standard family file
-# names) and ‘file_path’ is the absolute path to the target family file.
-#
-# If you use either of these functions to define the family to work on by
-# default (the ‘family’ variable below), you must place the function call
-# before the definition of the ‘family’ variable.
+# The family of sites we are working on. wikipedia.py will import
+# families/xxx_family.py so if you want to change this variable,
+# you need to write such a file.
family = '%s'
# The language code of the site we're working on.
diff --git a/pywikibot/config2.py b/pywikibot/config2.py
index d83009d..3f6342c 100644
--- a/pywikibot/config2.py
+++ b/pywikibot/config2.py
@@ -106,6 +106,8 @@
default_edit_summary = u'Wikipedia python library v.2'
+# Get the names of all known families, and initialize
+# with empty dictionaries
def _get_base_dir():
"""Return the directory in which user-specific information is stored.
@@ -160,27 +162,14 @@
return base_dir
_base_dir = _get_base_dir()
-
-
-family_files = {}
-
-
-def register_family_file(family_name, file_path):
- usernames[family_name] = {}
- sysopnames[family_name] = {}
- disambiguation_comment[family_name] = {}
- family_files[family_name] = file_path
-
-
-def register_families_folder(folder_path):
- for file_name in os.listdir(folder_path):
- if file_name.endswith("_family.py"):
- family_name = file_name[:-len("_family.py")]
- register_family_file(family_name, os.path.join(folder_path, file_name))
-
-# Get the names of all known families, and initialize with empty dictionaries.
-# ‘families/’ is a subdirectory of the directory in which config2.py is found.
-register_families_folder(os.path.join(os.path.dirname(__file__), 'families'))
+# families/ is a subdirectory of the directory in which config.py is found
+for _filename in os.listdir(
+ os.path.join(os.path.dirname(__file__), 'families')):
+ if _filename.endswith("_family.py"):
+ familyName = _filename[:-len("_family.py")]
+ usernames[familyName] = {}
+ sysopnames[familyName] = {}
+ disambiguation_comment[familyName] = {}
# Set to True to override the {{bots}} exclusion protocol (at your own risk!)
ignore_bot_templates = False
diff --git a/pywikibot/site.py b/pywikibot/site.py
index 2df94e3..141f0e9 100644
--- a/pywikibot/site.py
+++ b/pywikibot/site.py
@@ -16,7 +16,6 @@
except ImportError:
from md5 import md5
import datetime
-import imp
import itertools
import os
import re
@@ -85,16 +84,24 @@
if fam is None:
fam = config.family
try:
- myfamily = imp.load_source(name, config.family_files[fam])
- except (ImportError, KeyError):
- if fatal:
- pywikibot.error(u"""\
+ # first try the built-in families
+ name = "pywikibot.families.%s_family" % fam
+ __import__(name)
+ myfamily = sys.modules[name]
+ except ImportError:
+ # next see if user has defined a local family module
+ try:
+ sys.path.append(config.datafilepath('families'))
+ myfamily = __import__("%s_family" % fam)
+ except ImportError:
+ if fatal:
+ pywikibot.error(u"""\
Error importing the %s family. This probably means the family
does not exist. Also check your configuration file."""
- % fam, exc_info=True)
- sys.exit(1)
- else:
- raise Error("Family %s does not exist" % fam)
+ % fam, exc_info=True)
+ sys.exit(1)
+ else:
+ raise Error("Family %s does not exist" % fam)
return myfamily.Family()
@@ -874,13 +881,10 @@
self._loginstatus = LoginStatus.IN_PROGRESS
if hasattr(self, "_userinfo"):
del self._userinfo
- try:
- self.getuserinfo()
- if self.userinfo['name'] == self._username[sysop] and \
- self.logged_in(sysop):
- return
- except pywikibot.data.api.APIError: # May occur if you are not logged in (no API read permissions).
- pass
+ self.getuserinfo()
+ if self.userinfo['name'] == self._username[sysop] and \
+ self.logged_in(sysop):
+ return
loginMan = api.LoginManager(site=self, sysop=sysop,
user=self._username[sysop])
if loginMan.login(retry=True):
@@ -1327,15 +1331,12 @@
version numbers and any other text contained in the version.
"""
- try:
- if force:
- self._getsiteinfo(force=True) # drop/expire cache and reload
- versionstring = self.siteinfo['generator']
- m = re.match(r"^MediaWiki ([0-9]+)\.([0-9]+)(.*)$", versionstring)
- if m:
- return (int(m.group(1)), int(m.group(2)), m.group(3))
- except pywikibot.data.api.APIError: # May occur if you are not logged in (no API read permissions).
- return (0, 0, 0)
+ if force:
+ self._getsiteinfo(force=True) # drop/expire cache and reload
+ versionstring = self.siteinfo['generator']
+ m = re.match(r"^MediaWiki ([0-9]+)\.([0-9]+)(.*)$", versionstring)
+ if m:
+ return (int(m.group(1)), int(m.group(2)), m.group(3))
def loadpageinfo(self, page):
"""Load page info from api and save in page attributes"""
--
To view, visit https://gerrit.wikimedia.org/r/124739
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: Ic9b24c6e1119acd93f301da5c5fcf00d36ccc65e
Gerrit-PatchSet: 1
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Owner: Merlijn van Deen <valhallasw(a)arctus.nl>
Gerrit-Reviewer: Merlijn van Deen <valhallasw(a)arctus.nl>
Gerrit-Reviewer: jenkins-bot <>
jenkins-bot has submitted this change and it was merged.
Change subject: Make it possible to define a custom families folder
......................................................................
Make it possible to define a custom families folder
Allow to define a custom family folder with a global function from the user-config.py file.
Add try-except structures that prevent issues when you try to use the API from login.py on
a wiki that requires you to first log in to use any part of the API.
Change-Id: I631ecc551900cefb85d45b860dc45e187c0a7395
---
M generate_user_files.py
M pywikibot/config2.py
M pywikibot/site.py
3 files changed, 74 insertions(+), 39 deletions(-)
Approvals:
Merlijn van Deen: Looks good to me, approved
jenkins-bot: Verified
diff --git a/generate_user_files.py b/generate_user_files.py
index 0df0b15..75130aa 100644
--- a/generate_user_files.py
+++ b/generate_user_files.py
@@ -237,9 +237,34 @@
# This is an automatically generated file. You can find more configuration
# parameters in 'config.py' file.
-# The family of sites we are working on. wikipedia.py will import
-# families/xxx_family.py so if you want to change this variable,
-# you need to write such a file.
+# The family of sites to work on by default.
+#
+# ‘wikipedia.py’ imports ‘families/xxx_family.py’, so if you want to change
+# this variable, you need to use the name of one of the existing family files
+# in that folder or write your own, custom family file.
+#
+# For ‘wikipedia.py’ to be able to read your custom family file, you must
+# save it to ‘families/xxx_family.py’, where ‘xxx‘ is the codename of the
+# family that your custom ‘xxx_family.py’ family file defines.
+#
+# You can also save your custom family files to a different folder. As long
+# as you follow the ‘xxx_family.py’ naming convention, you can register your
+# custom folder in this configuration file with the following global function:
+#
+# register_families_folder(folder_path)
+#
+# Alternatively, you can register particular family files that do not need
+# to follow the ‘xxx_family.py’ naming convention using the following
+# global function:
+#
+# register_family_file(family_name, file_path)
+#
+# Where ‘family_name’ is the family code (the ‘xxx’ in standard family file
+# names) and ‘file_path’ is the absolute path to the target family file.
+#
+# If you use either of these functions to define the family to work on by
+# default (the ‘family’ variable below), you must place the function call
+# before the definition of the ‘family’ variable.
family = '%s'
# The language code of the site we're working on.
diff --git a/pywikibot/config2.py b/pywikibot/config2.py
index 3f6342c..d83009d 100644
--- a/pywikibot/config2.py
+++ b/pywikibot/config2.py
@@ -106,8 +106,6 @@
default_edit_summary = u'Wikipedia python library v.2'
-# Get the names of all known families, and initialize
-# with empty dictionaries
def _get_base_dir():
"""Return the directory in which user-specific information is stored.
@@ -162,14 +160,27 @@
return base_dir
_base_dir = _get_base_dir()
-# families/ is a subdirectory of the directory in which config.py is found
-for _filename in os.listdir(
- os.path.join(os.path.dirname(__file__), 'families')):
- if _filename.endswith("_family.py"):
- familyName = _filename[:-len("_family.py")]
- usernames[familyName] = {}
- sysopnames[familyName] = {}
- disambiguation_comment[familyName] = {}
+
+
+family_files = {}
+
+
+def register_family_file(family_name, file_path):
+ usernames[family_name] = {}
+ sysopnames[family_name] = {}
+ disambiguation_comment[family_name] = {}
+ family_files[family_name] = file_path
+
+
+def register_families_folder(folder_path):
+ for file_name in os.listdir(folder_path):
+ if file_name.endswith("_family.py"):
+ family_name = file_name[:-len("_family.py")]
+ register_family_file(family_name, os.path.join(folder_path, file_name))
+
+# Get the names of all known families, and initialize with empty dictionaries.
+# ‘families/’ is a subdirectory of the directory in which config2.py is found.
+register_families_folder(os.path.join(os.path.dirname(__file__), 'families'))
# Set to True to override the {{bots}} exclusion protocol (at your own risk!)
ignore_bot_templates = False
diff --git a/pywikibot/site.py b/pywikibot/site.py
index 141f0e9..2df94e3 100644
--- a/pywikibot/site.py
+++ b/pywikibot/site.py
@@ -16,6 +16,7 @@
except ImportError:
from md5 import md5
import datetime
+import imp
import itertools
import os
import re
@@ -84,24 +85,16 @@
if fam is None:
fam = config.family
try:
- # first try the built-in families
- name = "pywikibot.families.%s_family" % fam
- __import__(name)
- myfamily = sys.modules[name]
- except ImportError:
- # next see if user has defined a local family module
- try:
- sys.path.append(config.datafilepath('families'))
- myfamily = __import__("%s_family" % fam)
- except ImportError:
- if fatal:
- pywikibot.error(u"""\
+ myfamily = imp.load_source(name, config.family_files[fam])
+ except (ImportError, KeyError):
+ if fatal:
+ pywikibot.error(u"""\
Error importing the %s family. This probably means the family
does not exist. Also check your configuration file."""
- % fam, exc_info=True)
- sys.exit(1)
- else:
- raise Error("Family %s does not exist" % fam)
+ % fam, exc_info=True)
+ sys.exit(1)
+ else:
+ raise Error("Family %s does not exist" % fam)
return myfamily.Family()
@@ -881,10 +874,13 @@
self._loginstatus = LoginStatus.IN_PROGRESS
if hasattr(self, "_userinfo"):
del self._userinfo
- self.getuserinfo()
- if self.userinfo['name'] == self._username[sysop] and \
- self.logged_in(sysop):
- return
+ try:
+ self.getuserinfo()
+ if self.userinfo['name'] == self._username[sysop] and \
+ self.logged_in(sysop):
+ return
+ except pywikibot.data.api.APIError: # May occur if you are not logged in (no API read permissions).
+ pass
loginMan = api.LoginManager(site=self, sysop=sysop,
user=self._username[sysop])
if loginMan.login(retry=True):
@@ -1331,12 +1327,15 @@
version numbers and any other text contained in the version.
"""
- if force:
- self._getsiteinfo(force=True) # drop/expire cache and reload
- versionstring = self.siteinfo['generator']
- m = re.match(r"^MediaWiki ([0-9]+)\.([0-9]+)(.*)$", versionstring)
- if m:
- return (int(m.group(1)), int(m.group(2)), m.group(3))
+ try:
+ if force:
+ self._getsiteinfo(force=True) # drop/expire cache and reload
+ versionstring = self.siteinfo['generator']
+ m = re.match(r"^MediaWiki ([0-9]+)\.([0-9]+)(.*)$", versionstring)
+ if m:
+ return (int(m.group(1)), int(m.group(2)), m.group(3))
+ except pywikibot.data.api.APIError: # May occur if you are not logged in (no API read permissions).
+ return (0, 0, 0)
def loadpageinfo(self, page):
"""Load page info from api and save in page attributes"""
--
To view, visit https://gerrit.wikimedia.org/r/124636
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: I631ecc551900cefb85d45b860dc45e187c0a7395
Gerrit-PatchSet: 4
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Owner: Gallaecio <adriyetichaves(a)gmail.com>
Gerrit-Reviewer: Ladsgroup <ladsgroup(a)gmail.com>
Gerrit-Reviewer: Merlijn van Deen <valhallasw(a)arctus.nl>
Gerrit-Reviewer: jenkins-bot <>
jenkins-bot has submitted this change and it was merged.
Change subject: Allow multiple "{{PLURAL}}" with i18n.twntranslate method
......................................................................
Allow multiple "{{PLURAL}}" with i18n.twntranslate method
avoid duplicate code by extracting parts from pywikibot.translate()
and i18n.twntranslate() to "internal" method _extract_plural()
enable tuple or list as parameters and check whether the items
count is equal to the number of plural items found by re.findall()
Some test stuff added.
Change-Id: I6420b22835ec8db9c70806f46bf2efda65944c34
---
M pywikibot/i18n.py
M tests/i18n/test.py
M tests/i18n_tests.py
3 files changed, 132 insertions(+), 61 deletions(-)
Approvals:
Merlijn van Deen: Looks good to me, approved
jenkins-bot: Verified
diff --git a/pywikibot/i18n.py b/pywikibot/i18n.py
index 8e93f89..40fed49 100644
--- a/pywikibot/i18n.py
+++ b/pywikibot/i18n.py
@@ -225,6 +225,45 @@
pass
+def _extract_plural(code, message, parameters):
+ """Check for the plural variants in message and replace them depending on
+ parameter settings.
+ @param message: the message to be replaced
+ @type message: unicode string
+ @param parameters: plural parameters passed from other methods
+ @type parameters: int, basestring, tuple, list, dict
+
+ """
+ plural_items = re.findall(PLURAL_PATTERN, message)
+ if plural_items: # we found PLURAL patterns, process it
+ if len(plural_items) > 1 and isinstance(parameters, (tuple, list)) and \
+ len(plural_items) != len(parameters):
+ raise ValueError("Length of parameter does not match PLURAL "
+ "occurences.")
+ i = 0
+ for selector, variants in plural_items:
+ if type(parameters) == dict:
+ num = int(parameters[selector])
+ elif isinstance(parameters, basestring):
+ num = int(parameters)
+ elif isinstance(parameters, (tuple, list)):
+ num = int(parameters[i])
+ i += 1
+ else:
+ num = parameters
+ # TODO: check against plural_rules[code]['nplurals']
+ try:
+ index = plural_rules[code]['plural'](num)
+ except KeyError:
+ index = plural_rules['_default']['plural'](num)
+ except TypeError:
+ # we got an int, not a function
+ index = plural_rules[code]['plural']
+ repl = variants.split('|')[index]
+ message = re.sub(PLURAL_PATTERN, repl, message, count=1)
+ return message
+
+
def translate(code, xdict, parameters=None, fallback=True):
"""Return the most appropriate translation from a translation dict.
@@ -253,10 +292,6 @@
For PLURAL support have a look at the twntranslate method
"""
- param = None
- if type(parameters) == dict:
- param = parameters
-
family = pywikibot.config.family
# If a site is given instead of a code, use its language
if hasattr(code, 'code'):
@@ -291,31 +326,11 @@
return trans
# else we check for PLURAL variants
- while re.search(PLURAL_PATTERN, trans):
+ trans = _extract_plural(code, trans, parameters)
+ if parameters:
try:
- selector, variants = re.search(PLURAL_PATTERN, trans).groups()
- except AttributeError:
- pass
- else: # we found PLURAL patterns, process it
- if type(parameters) == dict:
- num = param[selector]
- elif isinstance(parameters, basestring):
- num = int(parameters)
- else:
- num = parameters
- # TODO: check against plural_rules[lang]['nplurals']
- try:
- index = plural_rules[code]['plural'](num)
- except KeyError:
- index = plural_rules['_default']['plural'](num)
- except TypeError:
- # we got an int, not a function
- index = plural_rules[code]['plural']
- trans = re.sub(PLURAL_PATTERN, variants.split('|')[index], trans, count=1)
- if param:
- try:
- return trans % param
- except KeyError:
+ return trans % parameters
+ except (KeyError, TypeError):
# parameter is for PLURAL variants only, don't change the string
pass
return trans
@@ -388,7 +403,7 @@
contains a plural tag inside which looks like
{{PLURAL:<number>|<variant1>|<variant2>[|<variantn>]}}
it takes that variant calculated by the plural_rules depending on the number
- value.
+ value. Multiple plurals are allowed.
Examples:
If we had a test dictionary in test.py like
@@ -429,45 +444,22 @@
import table.
"""
- param = None
- if type(parameters) == dict:
- param = parameters
# If a site is given instead of a code, use its language
if hasattr(code, 'code'):
code = code.code
# we send the code via list and get the alternate code back
code = [code]
- trans = twtranslate(code, twtitle, None)
- try:
- selector, variants = re.search(PLURAL_PATTERN, trans).groups()
- # No PLURAL tag found: nothing to replace
- except AttributeError:
- pass
- else:
- if type(parameters) == dict:
- num = param[selector]
- elif isinstance(parameters, basestring):
- num = int(parameters)
- else:
- num = parameters
- # get the alternate language code modified by twtranslate
- lang = code.pop()
- # we only need the lang or _default, not a _altlang code
- # maybe we should implement this to i18n.translate()
- # TODO: check against plural_rules[lang]['nplurals']
+ trans = twtranslate(code, twtitle)
+ # get the alternate language code modified by twtranslate
+ lang = code.pop()
+ # check for PLURAL variants
+ trans = _extract_plural(lang, trans, parameters)
+ # we always have a dict for replacement of translatewiki messages
+ if parameters and type(parameters) == dict:
try:
- index = plural_rules[lang]['plural'](num)
+ return trans % parameters
except KeyError:
- index = plural_rules['_default']['plural'](num)
- except TypeError:
- # we got an int not a function
- index = plural_rules[lang]['plural']
- repl = variants.split('|')[index]
- trans = re.sub(PLURAL_PATTERN, repl, trans)
- if param:
- try:
- return trans % param
- except KeyError:
+ # parameter is for PLURAL variants only, don't change the string
pass
return trans
diff --git a/tests/i18n/test.py b/tests/i18n/test.py
index 9e030ca..048b063 100644
--- a/tests/i18n/test.py
+++ b/tests/i18n/test.py
@@ -2,6 +2,7 @@
msg = {
'de': {
'test-plural': u'Bot: Ändere %(num)d {{PLURAL:num|Seite|Seiten}}.',
+ 'test-multiple-plurals': u'Bot: %(action)s %(line)s {{PLURAL:line|Zeile|Zeilen}} von {{PLURAL:%(page)d|einer|mehreren}} {{PLURAL:page|Seite|Seiten}}.',
},
'en': {
'test-localized': u'test-localized EN',
diff --git a/tests/i18n_tests.py b/tests/i18n_tests.py
index e996fbb..6df9a46 100644
--- a/tests/i18n_tests.py
+++ b/tests/i18n_tests.py
@@ -154,6 +154,84 @@
i18n.twntranslate('fr', 'test-plural', 1) % {'descr': 'seulement'},
u'Robot: Changer seulement une page.')
+ def testMultiple(self):
+ self.assertEqual(
+ i18n.twntranslate('de', 'test-multiple-plurals', 1)
+ % {'action': u'Ändere', 'line': u'eine'},
+ u'Bot: Ändere eine Zeile von einer Seite.')
+ self.assertEqual(
+ i18n.twntranslate('de', 'test-multiple-plurals', 2)
+ % {'action': u'Ändere', 'line': u'zwei'},
+ u'Bot: Ändere zwei Zeilen von mehreren Seiten.')
+ self.assertEqual(
+ i18n.twntranslate('de', 'test-multiple-plurals', 3)
+ % {'action': u'Ändere', 'line': u'drei'},
+ u'Bot: Ändere drei Zeilen von mehreren Seiten.')
+ self.assertEqual(
+ i18n.twntranslate('de', 'test-multiple-plurals', (1, 2, 2))
+ % {'action': u'Ändere', 'line': u'eine'},
+ u'Bot: Ändere eine Zeile von mehreren Seiten.')
+ self.assertEqual(
+ i18n.twntranslate('de', 'test-multiple-plurals', [3, 1, 1])
+ % {'action': u'Ändere', 'line': u'drei'},
+ u'Bot: Ändere drei Zeilen von einer Seite.')
+ self.assertEqual(
+ i18n.twntranslate('de', 'test-multiple-plurals', ["3", 1, 1])
+ % {'action': u'Ändere', 'line': u'drei'},
+ u'Bot: Ändere drei Zeilen von einer Seite.')
+ self.assertEqual(
+ i18n.twntranslate('de', 'test-multiple-plurals', "321")
+ % {'action': u'Ändere', 'line': u'dreihunderteinundzwanzig'},
+ u'Bot: Ändere dreihunderteinundzwanzig Zeilen von mehreren Seiten.')
+ self.assertEqual(
+ i18n.twntranslate('de', 'test-multiple-plurals',
+ {'action': u'Ändere', 'line': 1, 'page': 1}),
+ u'Bot: Ändere 1 Zeile von einer Seite.')
+ self.assertEqual(
+ i18n.twntranslate('de', 'test-multiple-plurals',
+ {'action': u'Ändere', 'line': 1, 'page': 2}),
+ u'Bot: Ändere 1 Zeile von mehreren Seiten.')
+ self.assertEqual(
+ i18n.twntranslate('de', 'test-multiple-plurals',
+ {'action': u'Ändere', 'line': "11", 'page': 2}),
+ u'Bot: Ändere 11 Zeilen von mehreren Seiten.')
+
+ def testMultipleWrongParameterLength(self):
+ """ Test wrong parameter lenght"""
+ with self.assertRaisesRegexp(ValueError, "Length of parameter does not match PLURAL occurences"):
+ self.assertEqual(
+ i18n.twntranslate('de', 'test-multiple-plurals', (1, 2))
+ % {'action': u'Ändere', 'line': u'drei'},
+ u'Bot: Ändere drei Zeilen von mehreren Seiten.')
+
+ with self.assertRaisesRegexp(ValueError, "Length of parameter does not match PLURAL occurences"):
+ self.assertEqual(
+ i18n.twntranslate('de', 'test-multiple-plurals', ["321"])
+ % {'action': u'Ändere', 'line': u'dreihunderteinundzwanzig'},
+ u'Bot: Ändere dreihunderteinundzwanzig Zeilen von mehreren Seiten.')
+
+ def testMultipleNonNumbers(self):
+ """ Numbers or string numbers are required for tuple or list items """
+ with self.assertRaisesRegexp(ValueError, "invalid literal for int\(\) with base 10: 'drei'"):
+ self.assertEqual(
+ i18n.twntranslate('de', 'test-multiple-plurals', ["drei", "1", 1])
+ % {'action': u'Ändere', 'line': u'drei'},
+ u'Bot: Ändere drei Zeilen von einer Seite.')
+ with self.assertRaisesRegexp(ValueError, "invalid literal for int\(\) with base 10: 'elf'"):
+ self.assertEqual(
+ i18n.twntranslate('de', 'test-multiple-plurals',
+ {'action': u'Ändere', 'line': "elf", 'page': 2}),
+ u'Bot: Ändere elf Zeilen von mehreren Seiten.')
+
+ def testAllParametersExist(self):
+ with self.assertRaisesRegexp(KeyError, "u'line'"):
+ # all parameters must be inside twntranslate
+ self.assertEqual(
+ i18n.twntranslate('de', 'test-multiple-plurals',
+ {'line': 1, 'page': 1})
+ % {'action': u'Ändere'},
+ u'Bot: Ändere 1 Zeile von einer Seite.')
+
if __name__ == '__main__':
try:
--
To view, visit https://gerrit.wikimedia.org/r/119338
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: I6420b22835ec8db9c70806f46bf2efda65944c34
Gerrit-PatchSet: 8
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Owner: Xqt <info(a)gno.de>
Gerrit-Reviewer: Ladsgroup <ladsgroup(a)gmail.com>
Gerrit-Reviewer: Merlijn van Deen <valhallasw(a)arctus.nl>
Gerrit-Reviewer: Pyfisch <pyfisch(a)gmail.com>
Gerrit-Reviewer: Ricordisamoa <ricordisamoa(a)live.it>
Gerrit-Reviewer: jenkins-bot <>
jenkins-bot has submitted this change and it was merged.
Change subject: Bug 63671 - Wikidataquery ip or url (wikidataquery.eu) seems broken
......................................................................
Bug 63671 - Wikidataquery ip or url (wikidataquery.eu) seems broken
Change-Id: I5d03bd7725fd03ed6dc3b7d5b0d94f59ac17268d
---
M pywikibot/data/wikidataquery.py
M tests/wikidataquery_tests.py
2 files changed, 2 insertions(+), 3 deletions(-)
Approvals:
Xqt: Looks good to me, approved
jenkins-bot: Verified
diff --git a/pywikibot/data/wikidataquery.py b/pywikibot/data/wikidataquery.py
index f7ea1a6..fdd66c7 100644
--- a/pywikibot/data/wikidataquery.py
+++ b/pywikibot/data/wikidataquery.py
@@ -393,7 +393,7 @@
class WikidataQuery():
"""
An interface to the WikidatQuery API. Default host is
- wikidataquery.eu (http://208.80.153.172), but you can substitute
+ http://wdq.wmflabs.org, but you can substitute
a different one.
Caching defaults to a subdir of the system temp directory with a
@@ -402,7 +402,7 @@
Set a zero or negative maxCacheAge to disable caching
"""
- def __init__(self, host="http://208.80.153.172", cacheDir=None,
+ def __init__(self, host="http://wdq.wmflabs.org", cacheDir=None,
cacheMaxAge=60):
self.host = host
self.cacheMaxAge = cacheMaxAge
diff --git a/tests/wikidataquery_tests.py b/tests/wikidataquery_tests.py
index 1e08420..cb8373e 100644
--- a/tests/wikidataquery_tests.py
+++ b/tests/wikidataquery_tests.py
@@ -228,7 +228,6 @@
class TestApiSlowFunctions(unittest.TestCase):
- @unittest.expectedFailure
def testQueryApiGetter(self):
"""
Test that we can actually retreive data and that caching works
--
To view, visit https://gerrit.wikimedia.org/r/124652
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: I5d03bd7725fd03ed6dc3b7d5b0d94f59ac17268d
Gerrit-PatchSet: 1
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Owner: Mpaa <mpaa.wiki(a)gmail.com>
Gerrit-Reviewer: Ladsgroup <ladsgroup(a)gmail.com>
Gerrit-Reviewer: Merlijn van Deen <valhallasw(a)arctus.nl>
Gerrit-Reviewer: Xqt <info(a)gno.de>
Gerrit-Reviewer: jenkins-bot <>