jenkins-bot has submitted this change and it was merged. ( https://gerrit.wikimedia.org/r/445414 )
Change subject: [doc] Fix typo in pagegenerators.py
......................................................................
[doc] Fix typo in pagegenerators.py
Change-Id: Id3384fd8b2e6cf52a06da1ffe5836080939e3236
---
M pywikibot/pagegenerators.py
1 file changed, 1 insertion(+), 1 deletion(-)
Approvals:
Dalba: Looks good to me, approved
jenkins-bot: Verified
diff --git a/pywikibot/pagegenerators.py b/pywikibot/pagegenerators.py
index db23262..facac41 100644
--- a/pywikibot/pagegenerators.py
+++ b/pywikibot/pagegenerators.py
@@ -287,7 +287,7 @@
Single categories can be selected with commas as in
-linter:cat1,cat2,cat3
- Adding '/int' indentifies Lint ID to start querying from:
+ Adding '/int' identifies Lint ID to start querying from:
e.g. -linter:high/10000
-linter:show just shows available categories.
--
To view, visit https://gerrit.wikimedia.org/r/445414
To unsubscribe, or for help writing mail filters, visit https://gerrit.wikimedia.org/r/settings
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-MessageType: merged
Gerrit-Change-Id: Id3384fd8b2e6cf52a06da1ffe5836080939e3236
Gerrit-Change-Number: 445414
Gerrit-PatchSet: 1
Gerrit-Owner: Dvorapa <dvorapa(a)seznam.cz>
Gerrit-Reviewer: Dalba <dalba.wiki(a)gmail.com>
Gerrit-Reviewer: Framawiki <framawiki(a)tools.wmflabs.org>
Gerrit-Reviewer: John Vandenberg <jayvdb(a)gmail.com>
Gerrit-Reviewer: Xqt <info(a)gno.de>
Gerrit-Reviewer: Zhuyifei1999 <zhuyifei1999(a)gmail.com>
Gerrit-Reviewer: Zoranzoki21 <zorandori4444(a)gmail.com>
Gerrit-Reviewer: jenkins-bot
jenkins-bot has submitted this change and it was merged. ( https://gerrit.wikimedia.org/r/272990 )
Change subject: [IMPR] Add documentation for sql parameter in replace.py
......................................................................
[IMPR] Add documentation for sql parameter in replace.py
+ also unify -sql parameters to -mysqlquery between scripts
+ move ImportError from scripts/table2wiki.py to pywikibot/data/mysql.py
+ improve documentation
+ narrow database replica hostname for Toolforge
Bug: T124869
Bug: T182523
Change-Id: I257edc61c6919542227e4b8c47799af640f40cce
---
M pywikibot/config2.py
M pywikibot/data/mysql.py
M pywikibot/pagegenerators.py
M scripts/replace.py
M scripts/table2wiki.py
5 files changed, 54 insertions(+), 34 deletions(-)
Approvals:
Zhuyifei1999: Looks good to me, approved
jenkins-bot: Verified
diff --git a/pywikibot/config2.py b/pywikibot/config2.py
index 11d2ae4..bd66798 100644
--- a/pywikibot/config2.py
+++ b/pywikibot/config2.py
@@ -685,7 +685,7 @@
# Setting to connect the database or replica of the database of the wiki.
# db_name_format can be used to manipulate the dbName of site.
# Example for a pywikibot running on wmflabs:
-# db_hostname = 'enwiki.labsdb'
+# db_hostname = 'enwiki.analytics.db.svc.eqiad.wmflabs'
# db_name_format = '{0}_p'
# db_connect_file = user_home_path('replica.my.cnf')
db_hostname = 'localhost'
@@ -694,7 +694,8 @@
db_name_format = '{0}'
db_connect_file = user_home_path('.my.cnf')
# local port for mysql server
-# ssh -L 4711:enwiki.labsdb:3306 user(a)tools-login.wmflabs.org
+# ssh -L 4711:enwiki.analytics.db.svc.eqiad.wmflabs:3306 \
+# user(a)login.tools.wmflabs.org
db_port = 3306
# ############# SEARCH ENGINE SETTINGS ##############
diff --git a/pywikibot/data/mysql.py b/pywikibot/data/mysql.py
index c3757ce..e07b180 100644
--- a/pywikibot/data/mysql.py
+++ b/pywikibot/data/mysql.py
@@ -14,9 +14,14 @@
try:
import pymysql as mysqldb
except ImportError:
- import MySQLdb as mysqldb
- pywikibot.warning('PyMySql not found.')
- pywikibot.warning('MySQLdb is deprecated. Use PyMySql instead.')
+ try:
+ import MySQLdb as mysqldb
+ except ImportError:
+ raise ImportError('No supported MySQL library installed. '
+ 'Please install PyMySQL.')
+ else:
+ pywikibot.warning("PyMySQL not found. It'll fallback "
+ 'on the deprecated library MySQLdb.')
else:
mysqldb.install_as_MySQLdb()
diff --git a/pywikibot/pagegenerators.py b/pywikibot/pagegenerators.py
index 180b6a0..5cd45f9 100644
--- a/pywikibot/pagegenerators.py
+++ b/pywikibot/pagegenerators.py
@@ -234,9 +234,12 @@
Argument can be given as "-withoutinterwiki:n" where
n is the total to fetch.
--mysqlquery Takes a Mysql query string like
- "SELECT page_namespace, page_title, FROM page
- WHERE page_namespace = 0" and works on the resulting pages.
+-mysqlquery Takes a MySQL query string like
+ "SELECT page_namespace, page_title FROM page
+ WHERE page_namespace = 0" and treats
+ the resulting pages. See
+ https://www.mediawiki.org/wiki/Manual:Pywikibot/MySQL
+ for more details.
-sparql Takes a SPARQL SELECT query string including ?item
and works on the resulting pages.
diff --git a/scripts/replace.py b/scripts/replace.py
index fe56b4c..fa8464c 100755
--- a/scripts/replace.py
+++ b/scripts/replace.py
@@ -12,9 +12,14 @@
Furthermore, the following command line parameters are supported:
--xml Retrieve information from a local XML dump (pages-articles
- or pages-meta-current, see https://dumps.wikimedia.org).
- Argument can also be given as "-xml:filename".
+-mysqlquery Retrieve information from a local database mirror.
+ If no query specified, bot searches for pages with
+ given replacements.
+
+-xml Retrieve information from a local XML dump
+ (pages-articles or pages-meta-current, see
+ https://dumps.wikimedia.org). Argument can also
+ be given as "-xml:filename".
-regex Make replacements using regular expressions. If this argument
isn't given, the bot will make simple text replacements.
@@ -890,6 +895,7 @@
# if -xml flag is present
xmlFilename = None
useSql = False
+ sql_query = None
# will become True when the user presses a ('yes to all') or uses the
# -always flag.
acceptall = False
@@ -933,8 +939,12 @@
xmlFilename = i18n.input('pywikibot-enter-xml-filename')
else:
xmlFilename = arg[5:]
- elif arg == '-sql':
+ elif arg.startswith(('-sql', '-mysqlquery')):
+ if arg.startswith('-sql'):
+ issue_deprecation_warning('The usage of "-sql"', '-mysqlquery',
+ 1, ArgumentDeprecationWarning)
useSql = True
+ sql_query = arg.partition(':')[2]
elif arg.startswith('-excepttitle:'):
exceptions['title'].append(arg[13:])
elif arg.startswith('-requiretitle:'):
@@ -1155,16 +1165,18 @@
gen = XmlDumpReplacePageGenerator(xmlFilename, xmlStart,
replacements, exceptions, site)
elif useSql:
- whereClause = 'WHERE (%s)' % ' OR '.join(
- ["old_text RLIKE '%s'" % prepareRegexForMySQL(old_regexp.pattern)
- for (old_regexp, new_text) in replacements])
- if exceptions:
- exceptClause = 'AND NOT (%s)' % ' OR '.join(
- ["old_text RLIKE '%s'" % prepareRegexForMySQL(exc.pattern)
- for exc in exceptions])
- else:
- exceptClause = ''
- query = u"""
+ if not sql_query:
+ whereClause = 'WHERE (%s)' % ' OR '.join(
+ ["old_text RLIKE '%s'" % prepareRegexForMySQL(
+ old_regexp.pattern) for (old_regexp, new_text)
+ in replacements])
+ if exceptions:
+ exceptClause = 'AND NOT (%s)' % ' OR '.join(
+ ["old_text RLIKE '%s'" % prepareRegexForMySQL(exc.pattern)
+ for exc in exceptions])
+ else:
+ exceptClause = ''
+ query = sql_query or """
SELECT page_namespace, page_title
FROM page
JOIN text ON (page_id = old_id)
diff --git a/scripts/table2wiki.py b/scripts/table2wiki.py
index 2cbe443..9c6e576 100644
--- a/scripts/table2wiki.py
+++ b/scripts/table2wiki.py
@@ -7,22 +7,24 @@
¶ms;
--always The bot won't ask for confirmation when putting a page
+-always The bot won't ask for confirmation when putting
+ a page.
-skipwarning Skip processing a page when a warning occurred.
Only used when -always is or becomes True.
--quiet Don't show diffs in -always mode
+-quiet Don't show diffs in -always mode.
--mysqlquery Retrieve information from a local mirror.
- Searches for pages with HTML tables, and tries to convert
- them on the live wiki.
+-mysqlquery Retrieve information from a local database mirror.
+ If no query specified, bot searches for pages with
+ HTML tables, and tries to convert them on the live
+ wiki.
-xml Retrieve information from a local XML dump
(pages_current, see https://dumps.wikimedia.org).
Argument can also be given as "-xml:filename".
- Searches for pages with HTML tables, and tries to convert
- them on the live wiki.
+ Searches for pages with HTML tables, and tries
+ to convert them on the live wiki.
Example:
@@ -57,7 +59,7 @@
from pywikibot.bot import (SingleSiteBot, ExistingPageBot, NoRedirectPageBot,
suggest_help, input_yn)
from pywikibot.exceptions import ArgumentDeprecationWarning
-from pywikibot.tools import has_module, issue_deprecation_warning
+from pywikibot.tools import issue_deprecation_warning
# This is required for the text that is shown when you run this script
# with the parameter -help.
@@ -539,10 +541,7 @@
elif option in ['-always', '-quiet', '-skipwarning']:
options[option[1:]] = True
else:
- if option in ['-sql', '-mysqlquery']:
- if not (has_module('oursql') or has_module('MySQLdb')):
- raise NotImplementedError(
- 'Neither "oursql" nor "MySQLdb" library is installed.')
+ if option in ('-sql', '-mysqlquery'):
if option == '-sql':
issue_deprecation_warning(
'The usage of "-sql"', '-mysqlquery',
--
To view, visit https://gerrit.wikimedia.org/r/272990
To unsubscribe, or for help writing mail filters, visit https://gerrit.wikimedia.org/r/settings
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-MessageType: merged
Gerrit-Change-Id: I257edc61c6919542227e4b8c47799af640f40cce
Gerrit-Change-Number: 272990
Gerrit-PatchSet: 17
Gerrit-Owner: UltimateSupreme <ultimatesupreme2212(a)gmail.com>
Gerrit-Reviewer: Dvorapa <dvorapa(a)seznam.cz>
Gerrit-Reviewer: Framawiki <framawiki(a)tools.wmflabs.org>
Gerrit-Reviewer: John Vandenberg <jayvdb(a)gmail.com>
Gerrit-Reviewer: Liuxinyu970226 <541329866(a)qq.com>
Gerrit-Reviewer: Magul <tomasz.magulski(a)gmail.com>
Gerrit-Reviewer: TerraCodes <terracodes(a)tools.wmflabs.org>
Gerrit-Reviewer: Xqt <info(a)gno.de>
Gerrit-Reviewer: Zhuyifei1999 <zhuyifei1999(a)gmail.com>
Gerrit-Reviewer: Zoranzoki21 <zorandori4444(a)gmail.com>
Gerrit-Reviewer: jenkins-bot
jenkins-bot has submitted this change and it was merged. ( https://gerrit.wikimedia.org/r/444434 )
Change subject: [IMPR] Give an error message instead raising an exception
......................................................................
[IMPR] Give an error message instead raising an exception
Print a wellformed error message instead of raising an OSError exception
Change-Id: I568b81e9d6d9b25f74fdf93ce30d4fd9442a3423
---
M pwb.py
1 file changed, 3 insertions(+), 1 deletion(-)
Approvals:
Zhuyifei1999: Looks good to me, approved
jenkins-bot: Verified
diff --git a/pwb.py b/pwb.py
index 33e265b..5270790 100755
--- a/pwb.py
+++ b/pwb.py
@@ -214,7 +214,9 @@
filename = testpath
break
else:
- raise OSError("%s not found!" % filename)
+ print('ERROR: {} not found! Misspelling?'.format(filename),
+ file=sys.stderr)
+ return True
# When both pwb.py and the filename to run are within the current
# working directory:
--
To view, visit https://gerrit.wikimedia.org/r/444434
To unsubscribe, or for help writing mail filters, visit https://gerrit.wikimedia.org/r/settings
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-MessageType: merged
Gerrit-Change-Id: I568b81e9d6d9b25f74fdf93ce30d4fd9442a3423
Gerrit-Change-Number: 444434
Gerrit-PatchSet: 4
Gerrit-Owner: Xqt <info(a)gno.de>
Gerrit-Reviewer: John Vandenberg <jayvdb(a)gmail.com>
Gerrit-Reviewer: Xqt <info(a)gno.de>
Gerrit-Reviewer: Zhuyifei1999 <zhuyifei1999(a)gmail.com>
Gerrit-Reviewer: Zoranzoki21 <zorandori4444(a)gmail.com>
Gerrit-Reviewer: jenkins-bot
jenkins-bot has submitted this change and it was merged. ( https://gerrit.wikimedia.org/r/445381 )
Change subject: Fix regressions in site.py and page.py
......................................................................
Fix regressions in site.py and page.py
After 13f6b0ba25f85a01c4fe23a9883536570154bf6d:
- cfdTemplates parameter of page.Category.copyAndKeep was renamed to
cfd_templates, but adding it to deprecated_args decorator was
forgotten.
- get_text parameter of site.APISite.deletedrevs was renamed to content
(in order to make it consistant with other similar paramters along
with page.getDeletedRevision), but was not added deprecated_args.
Change-Id: I35ed2b36ef3c525d872ed47e81a8ed09ccf3305a
---
M pywikibot/page.py
M pywikibot/site.py
2 files changed, 2 insertions(+), 1 deletion(-)
Approvals:
Zhuyifei1999: Looks good to me, approved
jenkins-bot: Verified
diff --git a/pywikibot/page.py b/pywikibot/page.py
index 2cd1fb6..9a6b470 100644
--- a/pywikibot/page.py
+++ b/pywikibot/page.py
@@ -3009,6 +3009,7 @@
target_cat.put(self.get(), creation_summary)
return True
+ @deprecated_args(cfdTemplates='cfd_templates')
def copyAndKeep(self, catname, cfd_templates, message):
"""
Copy partial category page text (not contents) to a new title.
diff --git a/pywikibot/site.py b/pywikibot/site.py
index a63f4d7..f504133 100644
--- a/pywikibot/site.py
+++ b/pywikibot/site.py
@@ -4909,7 +4909,7 @@
return wlgen
# TODO: T75370
- @deprecated_args(step=None)
+ @deprecated_args(step=None, get_text='content')
def deletedrevs(self, page, start=None, end=None, reverse=None,
content=False, total=None):
"""Iterate deleted revisions.
--
To view, visit https://gerrit.wikimedia.org/r/445381
To unsubscribe, or for help writing mail filters, visit https://gerrit.wikimedia.org/r/settings
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-MessageType: merged
Gerrit-Change-Id: I35ed2b36ef3c525d872ed47e81a8ed09ccf3305a
Gerrit-Change-Number: 445381
Gerrit-PatchSet: 1
Gerrit-Owner: Dalba <dalba.wiki(a)gmail.com>
Gerrit-Reviewer: Dalba <dalba.wiki(a)gmail.com>
Gerrit-Reviewer: John Vandenberg <jayvdb(a)gmail.com>
Gerrit-Reviewer: Xqt <info(a)gno.de>
Gerrit-Reviewer: Zhuyifei1999 <zhuyifei1999(a)gmail.com>
Gerrit-Reviewer: Zoranzoki21 <zorandori4444(a)gmail.com>
Gerrit-Reviewer: jenkins-bot
jenkins-bot has submitted this change and it was merged. ( https://gerrit.wikimedia.org/r/445343 )
Change subject: pywikibot/site.py : Fix N803 and N806 naming errors
......................................................................
pywikibot/site.py : Fix N803 and N806 naming errors
Change-Id: I580e5d09a4a3eb9ee787c64e0f7bd34ca47a1d8f
---
M pywikibot/page.py
M pywikibot/pagegenerators.py
M pywikibot/site.py
M tests/site_tests.py
M tox.ini
5 files changed, 140 insertions(+), 132 deletions(-)
Approvals:
Xqt: Looks good to me, approved
jenkins-bot: Verified
diff --git a/pywikibot/page.py b/pywikibot/page.py
index b75002e..ef3c2c9 100644
--- a/pywikibot/page.py
+++ b/pywikibot/page.py
@@ -1022,10 +1022,10 @@
# split up the results for the others.
return self.site.pagereferences(
self,
- followRedirects=follow_redirects,
- filterRedirects=redirectsOnly,
- withTemplateInclusion=withTemplateInclusion,
- onlyTemplateInclusion=onlyTemplateInclusion,
+ follow_redirects=follow_redirects,
+ filter_redirects=redirectsOnly,
+ with_template_inclusion=withTemplateInclusion,
+ only_template_inclusion=onlyTemplateInclusion,
namespaces=namespaces,
total=total,
content=content
@@ -1048,8 +1048,8 @@
"""
return self.site.pagebacklinks(
self,
- followRedirects=followRedirects,
- filterRedirects=filterRedirects,
+ follow_redirects=followRedirects,
+ filter_redirects=filterRedirects,
namespaces=namespaces,
total=total,
content=content
@@ -1070,7 +1070,7 @@
"""
return self.site.page_embeddedin(
self,
- filterRedirects=filter_redirects,
+ filter_redirects=filter_redirects,
namespaces=namespaces,
total=total,
content=content
@@ -4555,7 +4555,7 @@
@param item: The item to merge into
@type item: ItemPage
"""
- data = self.repo.mergeItems(fromItem=self, toItem=item, **kwargs)
+ data = self.repo.mergeItems(from_item=self, to_item=item, **kwargs)
if not data.get('success', 0):
return
self.latest_revision_id = data['from']['lastrevid']
diff --git a/pywikibot/pagegenerators.py b/pywikibot/pagegenerators.py
index 9c0cfdc..48c0803 100644
--- a/pywikibot/pagegenerators.py
+++ b/pywikibot/pagegenerators.py
@@ -1381,11 +1381,11 @@
gen = site.recentchanges(start=start, end=end, reverse=reverse,
namespaces=namespaces, pagelist=pagelist,
- changetype=changetype, showMinor=showMinor,
- showBot=showBot, showAnon=showAnon,
- showRedirects=showRedirects,
- showPatrolled=showPatrolled,
- topOnly=topOnly, total=total,
+ changetype=changetype, minor=showMinor,
+ bot=showBot, anon=showAnon,
+ redirect=showRedirects,
+ patrolled=showPatrolled,
+ top_only=topOnly, total=total,
user=user, excludeuser=excludeuser, tag=tag)
gen.request['rcprop'] = 'title'
diff --git a/pywikibot/site.py b/pywikibot/site.py
index 6df1114..9fcea40 100644
--- a/pywikibot/site.py
+++ b/pywikibot/site.py
@@ -1283,7 +1283,8 @@
return self.getUrl(address, data=predata)
@deprecated
- def postData(self, address, data, contentType=None, sysop=False,
+ @deprecated_args(contentType=None)
+ def postData(self, address, data, sysop=False,
compress=True, cookies=None):
"""DEPRECATED."""
return self.getUrl(address, data=data)
@@ -2089,10 +2090,10 @@
right=self._username[sysop]))
else:
raise NoUsername('Logging in on %s via OAuth failed' % self)
- loginMan = api.LoginManager(site=self, sysop=sysop,
- user=self._username[sysop])
- if loginMan.login(retry=True, autocreate=autocreate):
- self._username[sysop] = loginMan.username
+ login_manager = api.LoginManager(
+ site=self, sysop=sysop, user=self._username[sysop])
+ if login_manager.login(retry=True, autocreate=autocreate):
+ self._username[sysop] = login_manager.username
self.getuserinfo(force=True)
self._loginstatus = (LoginStatus.AS_SYSOP
if sysop else LoginStatus.AS_USER)
@@ -2466,7 +2467,7 @@
@rtype: unicode
"""
- NEEDED_MW_MESSAGES = ('and', 'comma-separator', 'word-separator')
+ needed_mw_messages = ('and', 'comma-separator', 'word-separator')
if not args:
return u''
if PY2 and any(isinstance(arg, str) for arg in args):
@@ -2474,10 +2475,10 @@
args = [unicode(e) for e in args]
try:
- msgs = self.mediawiki_messages(NEEDED_MW_MESSAGES)
+ msgs = self.mediawiki_messages(needed_mw_messages)
except KeyError:
raise NotImplementedError(
- 'MediaWiki messages missing: {0}'.format(NEEDED_MW_MESSAGES))
+ 'MediaWiki messages missing: {0}'.format(needed_mw_messages))
if MediaWikiVersion(self.version()) < MediaWikiVersion('1.16'):
for key, value in msgs.items():
@@ -3602,14 +3603,18 @@
# following group of methods map more-or-less directly to API queries
- def pagebacklinks(self, page, followRedirects=False, filterRedirects=None,
- namespaces=None, total=None, content=False):
+ @deprecated_args(
+ followRedirects='follow_redirects', filterRedirects='filter_redirects')
+ def pagebacklinks(
+ self, page, follow_redirects=False, filter_redirects=None,
+ namespaces=None, total=None, content=False
+ ):
"""Iterate all pages that link to the given page.
@param page: The Page to get links to.
- @param followRedirects: Also return links to redirects pointing to
+ @param follow_redirects: Also return links to redirects pointing to
the given page.
- @param filterRedirects: If True, only return redirects to the given
+ @param filter_redirects: If True, only return redirects to the given
page. If False, only return non-redirect links. If None, return
both (no filtering).
@param namespaces: If present, only return links from the namespaces
@@ -3626,13 +3631,13 @@
"""
bltitle = page.title(withSection=False).encode(self.encoding())
blargs = {"gbltitle": bltitle}
- if filterRedirects is not None:
- blargs['gblfilterredir'] = ('redirects' if filterRedirects
+ if filter_redirects is not None:
+ blargs['gblfilterredir'] = ('redirects' if filter_redirects
else 'nonredirects')
blgen = self._generator(api.PageGenerator, type_arg="backlinks",
namespaces=namespaces, total=total,
g_content=content, **blargs)
- if followRedirects:
+ if follow_redirects:
# links identified by MediaWiki as redirects may not really be,
# so we have to check each "redirect" page and see if it
# really redirects to this page
@@ -3653,21 +3658,21 @@
continue
if redir.getRedirectTarget() == page:
genlist[redir.title()] = self.pagebacklinks(
- redir, followRedirects=True,
- filterRedirects=filterRedirects,
+ redir, follow_redirects=True,
+ filter_redirects=filter_redirects,
namespaces=namespaces,
content=content
)
return itertools.chain(*list(genlist.values()))
return blgen
- @deprecated_args(step=None)
- def page_embeddedin(self, page, filterRedirects=None, namespaces=None,
+ @deprecated_args(step=None, filterRedirects='filter_redirects')
+ def page_embeddedin(self, page, filter_redirects=None, namespaces=None,
total=None, content=False):
"""Iterate all pages that embedded the given page as a template.
@param page: The Page to get inclusions for.
- @param filterRedirects: If True, only return redirects that embed
+ @param filter_redirects: If True, only return redirects that embed
the given page. If False, only return non-redirect links. If
None, return both (no filtering).
@param namespaces: If present, only return links from the namespaces
@@ -3683,17 +3688,23 @@
"""
eiargs = {"geititle":
page.title(withSection=False).encode(self.encoding())}
- if filterRedirects is not None:
- eiargs['geifilterredir'] = ('redirects' if filterRedirects
+ if filter_redirects is not None:
+ eiargs['geifilterredir'] = ('redirects' if filter_redirects
else 'nonredirects')
return self._generator(api.PageGenerator, type_arg='embeddedin',
namespaces=namespaces, total=total,
g_content=content, **eiargs)
- @deprecated_args(step=None)
- def pagereferences(self, page, followRedirects=False, filterRedirects=None,
- withTemplateInclusion=True, onlyTemplateInclusion=False,
- namespaces=None, total=None, content=False):
+ @deprecated_args(
+ step=None, followRedirects='follow_redirects',
+ filterRedirects='filter_redirects',
+ onlyTemplateInclusion='only_template_inclusion',
+ withTemplateInclusion='with_template_inclusion')
+ def pagereferences(
+ self, page, follow_redirects=False, filter_redirects=None,
+ with_template_inclusion=True, only_template_inclusion=False,
+ namespaces=None, total=None, content=False
+ ):
"""
Convenience method combining pagebacklinks and page_embeddedin.
@@ -3706,22 +3717,19 @@
@raises TypeError: a namespace identifier has an inappropriate
type such as NoneType or bool
"""
- if onlyTemplateInclusion:
- return self.page_embeddedin(page, namespaces=namespaces,
- filterRedirects=filterRedirects,
+ if only_template_inclusion:
+ return self.page_embeddedin(page, filter_redirects, namespaces,
total=total, content=content)
- if not withTemplateInclusion:
- return self.pagebacklinks(page, followRedirects=followRedirects,
- filterRedirects=filterRedirects,
- namespaces=namespaces,
- total=total, content=content)
+ if not with_template_inclusion:
+ return self.pagebacklinks(page, follow_redirects, filter_redirects,
+ namespaces, total=total, content=content)
return itertools.islice(
itertools.chain(
self.pagebacklinks(
- page, followRedirects, filterRedirects,
+ page, follow_redirects, filter_redirects,
namespaces=namespaces, content=content),
self.page_embeddedin(
- page, filterRedirects, namespaces=namespaces,
+ page, filter_redirects, namespaces=namespaces,
content=content)
), total)
@@ -4641,12 +4649,15 @@
@deprecated_args(returndict=None, nobots=None, rcshow=None, rcprop=None,
rctype='changetype', revision=None, repeat=None,
rcstart='start', rcend='end', rcdir=None, step=None,
- includeredirects='showRedirects', namespace='namespaces',
- rcnamespace='namespaces', number='total', rclimit='total')
+ includeredirects='redirect', namespace='namespaces',
+ rcnamespace='namespaces', number='total', rclimit='total',
+ showMinor='minor', showBot='bot', showAnon='anon',
+ showRedirects='redirect', showPatrolled='patrolled',
+ topOnly='top_only')
def recentchanges(self, start=None, end=None, reverse=False,
namespaces=None, pagelist=None, changetype=None,
- showMinor=None, showBot=None, showAnon=None,
- showRedirects=None, showPatrolled=None, topOnly=False,
+ minor=None, bot=None, anon=None,
+ redirect=None, patrolled=None, top_only=False,
total=None, user=None, excludeuser=None, tag=None):
"""Iterate recent changes.
@@ -4666,24 +4677,25 @@
edits to existing pages, "new" for new pages, "log" for log
entries)
@type changetype: basestring
- @param showMinor: if True, only list minor edits; if False, only list
+ @param minor: if True, only list minor edits; if False, only list
non-minor edits; if None, list all
- @type showMinor: bool or None
- @param showBot: if True, only list bot edits; if False, only list
+ @type minor: bool or None
+ @param bot: if True, only list bot edits; if False, only list
non-bot edits; if None, list all
- @type showBot: bool or None
- @param showAnon: if True, only list anon edits; if False, only list
+ @type bot: bool or None
+ @param anon: if True, only list anon edits; if False, only list
non-anon edits; if None, list all
- @type showAnon: bool or None
- @param showRedirects: if True, only list edits to redirect pages; if
+ @type anon: bool or None
+ @param redirect: if True, only list edits to redirect pages; if
False, only list edits to non-redirect pages; if None, list all
- @type showRedirects: bool or None
- @param showPatrolled: if True, only list patrolled edits; if False,
+ @type redirect: bool or None
+ @param patrolled: if True, only list patrolled edits; if False,
only list non-patrolled edits; if None, list all
- @type showPatrolled: bool or None
- @param topOnly: if True, only list changes that are the latest revision
+ @type patrolled: bool or None
+ @param top_only: if True, only list changes that are the latest
+ revision
(default False)
- @type topOnly: bool
+ @type top_only: bool
@param user: if not None, only list edits by this user or users
@type user: basestring|list
@param excludeuser: if not None, exclude edits by this user or users
@@ -4701,7 +4713,7 @@
rcprop="user|comment|timestamp|title|ids"
'|sizes|redirect|loginfo|flags|tags',
namespaces=namespaces,
- total=total, rctoponly=topOnly)
+ total=total, rctoponly=top_only)
if start is not None:
rcgen.request["rcstart"] = start
if end is not None:
@@ -4717,15 +4729,15 @@
for p in pagelist)
if changetype:
rcgen.request["rctype"] = changetype
- filters = {'minor': showMinor,
- 'bot': showBot,
- 'anon': showAnon,
- 'redirect': showRedirects,
+ filters = {'minor': minor,
+ 'bot': bot,
+ 'anon': anon,
+ 'redirect': redirect,
}
- if showPatrolled is not None and (
+ if patrolled is not None and (
self.has_right('patrol') or self.has_right('patrolmarks')):
rcgen.request['rcprop'] += ['patrolled']
- filters['patrolled'] = showPatrolled
+ filters['patrolled'] = patrolled
rcgen.request['rcshow'] = api.OptionSet(self, 'recentchanges', 'show',
filters)
@@ -4795,9 +4807,9 @@
srgen.request['gsrredirects'] = get_redirects
return srgen
- @deprecated_args(step=None)
+ @deprecated_args(step=None, showMinor='minor')
def usercontribs(self, user=None, userprefix=None, start=None, end=None,
- reverse=False, namespaces=None, showMinor=None,
+ reverse=False, namespaces=None, minor=None,
total=None, top_only=False):
"""Iterate contributions by a particular user.
@@ -4813,7 +4825,7 @@
@type namespaces: iterable of basestring or Namespace key,
or a single instance of those types. May be a '|' separated
list of namespace identifiers.
- @param showMinor: if True, iterate only minor edits; if False and
+ @param minor: if True, iterate only minor edits; if False and
not None, iterate only non-minor edits (default: iterate both)
@param total: limit result to this number of pages
@type total: int
@@ -4846,14 +4858,15 @@
if reverse:
ucgen.request["ucdir"] = "newer"
option_set = api.OptionSet(self, 'usercontribs', 'show')
- option_set['minor'] = showMinor
+ option_set['minor'] = minor
ucgen.request['ucshow'] = option_set
return ucgen
- @deprecated_args(step=None)
+ @deprecated_args(step=None, showMinor='minor', showAnon='anon',
+ showBot='bot')
def watchlist_revs(self, start=None, end=None, reverse=False,
- namespaces=None, showMinor=None, showBot=None,
- showAnon=None, total=None):
+ namespaces=None, minor=None, bot=None,
+ anon=None, total=None):
"""Iterate revisions to pages on the bot user's watchlist.
Iterated values will be in same format as recentchanges.
@@ -4865,11 +4878,11 @@
@type namespaces: iterable of basestring or Namespace key,
or a single instance of those types. May be a '|' separated
list of namespace identifiers.
- @param showMinor: if True, only list minor edits; if False (and not
+ @param minor: if True, only list minor edits; if False (and not
None), only list non-minor edits
- @param showBot: if True, only list bot edits; if False (and not
+ @param bot: if True, only list bot edits; if False (and not
None), only list non-bot edits
- @param showAnon: if True, only list anon edits; if False (and not
+ @param anon: if True, only list anon edits; if False (and not
None), only list non-anon edits
@raises KeyError: a namespace identifier was not resolved
@raises TypeError: a namespace identifier has an inappropriate
@@ -4890,9 +4903,7 @@
wlgen.request["wlend"] = end
if reverse:
wlgen.request["wldir"] = "newer"
- filters = {'minor': showMinor,
- 'bot': showBot,
- 'anon': showAnon}
+ filters = {'minor': minor, 'bot': bot, 'anon': anon}
wlgen.request['wlshow'] = api.OptionSet(self, 'watchlist', 'show',
filters)
return wlgen
@@ -5698,12 +5709,12 @@
token = self.tokens['protect']
self.lock_page(page)
- protectList = [ptype + '=' + level
+ protections = [ptype + '=' + level
for ptype, level in protections.items()
if level is not None]
parameters = merge_unique_dicts(kwargs, action='protect', title=page,
token=token,
- protections=protectList, reason=reason,
+ protections=protections, reason=reason,
expiry=expiry)
req = self._simple_request(**parameters)
@@ -6470,17 +6481,14 @@
filepage._load_file_revisions([result["imageinfo"]])
return result['result'] == 'Success'
- @deprecated_args(number='total',
- repeat=None,
- namespace="namespaces",
- rcshow=None,
- rc_show=None,
- get_redirect=None)
- @deprecated_args(step=None)
+ @deprecated_args(number='total', repeat=None, namespace='namespaces',
+ rcshow=None, rc_show=None, get_redirect=None, step=None,
+ showBot='bot', showRedirects='redirect',
+ showPatrolled='patrolled')
def newpages(self, user=None, returndict=False,
- start=None, end=None, reverse=False, showBot=False,
- showRedirects=False, excludeuser=None,
- showPatrolled=None, namespaces=None, total=None):
+ start=None, end=None, reverse=False, bot=False,
+ redirect=False, excludeuser=None,
+ patrolled=None, namespaces=None, total=None):
"""Yield new articles (as Page objects) from recent changes.
Starts with the newest article and fetches the number of articles
@@ -6509,8 +6517,8 @@
gen = self.recentchanges(
start=start, end=end, reverse=reverse,
namespaces=namespaces, changetype="new", user=user,
- excludeuser=excludeuser, showBot=showBot,
- showRedirects=showRedirects, showPatrolled=showPatrolled,
+ excludeuser=excludeuser, bot=bot,
+ redirect=redirect, patrolled=patrolled,
total=total
)
for pageitem in gen:
@@ -8025,16 +8033,17 @@
return data
@must_be(group='user')
- @deprecated_args(ignoreconflicts='ignore_conflicts')
- def mergeItems(self, fromItem, toItem, ignore_conflicts=None,
+ @deprecated_args(ignoreconflicts='ignore_conflicts', fromItem='from_item',
+ toItem='to_item')
+ def mergeItems(self, from_item, to_item, ignore_conflicts=None,
summary=None, bot=True):
"""
Merge two items together.
- @param fromItem: Item to merge from
- @type fromItem: pywikibot.ItemPage
- @param toItem: Item to merge into
- @type toItem: pywikibot.ItemPage
+ @param from_item: Item to merge from
+ @type from_item: pywikibot.ItemPage
+ @param to_item: Item to merge into
+ @type to_item: pywikibot.ItemPage
@param ignore_conflicts: Which type of conflicts
('description', 'sitelink', and 'statement')
should be ignored
@@ -8048,8 +8057,8 @@
"""
params = {
'action': 'wbmergeitems',
- 'fromid': fromItem.getID(),
- 'toid': toItem.getID(),
+ 'fromid': from_item.getID(),
+ 'toid': to_item.getID(),
'ignoreconflicts': ignore_conflicts,
'token': self.tokens['edit'],
'summary': summary,
diff --git a/tests/site_tests.py b/tests/site_tests.py
index b11501b..8c7ffb1 100644
--- a/tests/site_tests.py
+++ b/tests/site_tests.py
@@ -510,15 +510,15 @@
# only non-redirects:
filtered = set(self.site.pagebacklinks(
- self.mainpage, namespaces=0, filterRedirects=False))
+ self.mainpage, namespaces=0, filter_redirects=False))
# only redirects:
redirs = set(self.site.pagebacklinks(
- self.mainpage, namespaces=0, filterRedirects=True))
+ self.mainpage, namespaces=0, filter_redirects=True))
# including links to redirect pages (but not the redirects):
indirect = set(
self.site.pagebacklinks(self.mainpage, namespaces=[0],
- followRedirects=True,
- filterRedirects=False))
+ follow_redirects=True,
+ filter_redirects=False))
for bl in backlinks_ns_0:
self.assertIsInstance(bl, pywikibot.Page)
@@ -537,9 +537,9 @@
embedded_ns_0_2 = set(self.site.page_embeddedin(
self.mainpage, namespaces=[0, 2]))
redirs = set(self.site.page_embeddedin(
- self.mainpage, filterRedirects=True, namespaces=[0]))
+ self.mainpage, filter_redirects=True, namespaces=[0]))
no_redirs = set(self.site.page_embeddedin(
- self.mainpage, filterRedirects=False, namespaces=[0]))
+ self.mainpage, filter_redirects=False, namespaces=[0]))
for ei in embedded_ns_0:
self.assertIsInstance(ei, pywikibot.Page)
@@ -1461,26 +1461,26 @@
def test_flags(self):
"""Test the site.recentchanges() with boolean flags."""
mysite = self.site
- for change in mysite.recentchanges(showMinor=True, total=5):
+ for change in mysite.recentchanges(minor=True, total=5):
self.assertIsInstance(change, dict)
self.assertIn("minor", change)
- for change in mysite.recentchanges(showMinor=False, total=5):
+ for change in mysite.recentchanges(minor=False, total=5):
self.assertIsInstance(change, dict)
self.assertNotIn("minor", change)
- for change in mysite.recentchanges(showBot=True, total=5):
+ for change in mysite.recentchanges(bot=True, total=5):
self.assertIsInstance(change, dict)
self.assertIn("bot", change)
- for change in mysite.recentchanges(showBot=False, total=5):
+ for change in mysite.recentchanges(bot=False, total=5):
self.assertIsInstance(change, dict)
self.assertNotIn("bot", change)
- for change in mysite.recentchanges(showAnon=True, total=5):
+ for change in mysite.recentchanges(anon=True, total=5):
self.assertIsInstance(change, dict)
- for change in mysite.recentchanges(showAnon=False, total=5):
+ for change in mysite.recentchanges(anon=False, total=5):
self.assertIsInstance(change, dict)
- for change in mysite.recentchanges(showRedirects=True, total=5):
+ for change in mysite.recentchanges(redirect=True, total=5):
self.assertIsInstance(change, dict)
self.assertIn("redirect", change)
- for change in mysite.recentchanges(showRedirects=False, total=5):
+ for change in mysite.recentchanges(redirect=False, total=5):
self.assertIsInstance(change, dict)
self.assertNotIn("redirect", change)
@@ -1504,11 +1504,11 @@
def test_patrolled(self):
"""Test the site.recentchanges() with patrolled boolean flags."""
mysite = self.site
- for change in mysite.recentchanges(showPatrolled=True, total=5):
+ for change in mysite.recentchanges(patrolled=True, total=5):
self.assertIsInstance(change, dict)
if mysite.has_right('patrol'):
self.assertIn("patrolled", change)
- for change in mysite.recentchanges(showPatrolled=False, total=5):
+ for change in mysite.recentchanges(patrolled=False, total=5):
self.assertIsInstance(change, dict)
if mysite.has_right('patrol'):
self.assertNotIn("patrolled", change)
@@ -1637,12 +1637,12 @@
"""Test the site.usercontribs() method using showMinor."""
mysite = self.get_site()
for contrib in mysite.usercontribs(user=mysite.user(),
- showMinor=True, total=5):
+ minor=True, total=5):
self.assertIsInstance(contrib, dict)
self.assertIn("minor", contrib)
for contrib in mysite.usercontribs(user=mysite.user(),
- showMinor=False, total=5):
+ minor=False, total=5):
self.assertIsInstance(contrib, dict)
self.assertNotIn("minor", contrib)
@@ -1786,21 +1786,21 @@
prefix = title[:title.index(":")]
self.assertIn(self.site.namespaces.lookup_name(prefix).id, [6, 7])
self.assertIn(rev["ns"], [6, 7])
- for rev in mysite.watchlist_revs(showMinor=True, total=5):
+ for rev in mysite.watchlist_revs(minor=True, total=5):
self.assertIsInstance(rev, dict)
self.assertIn("minor", rev)
- for rev in mysite.watchlist_revs(showMinor=False, total=5):
+ for rev in mysite.watchlist_revs(minor=False, total=5):
self.assertIsInstance(rev, dict)
self.assertNotIn("minor", rev)
- for rev in mysite.watchlist_revs(showBot=True, total=5):
+ for rev in mysite.watchlist_revs(bot=True, total=5):
self.assertIsInstance(rev, dict)
self.assertIn("bot", rev)
- for rev in mysite.watchlist_revs(showBot=False, total=5):
+ for rev in mysite.watchlist_revs(bot=False, total=5):
self.assertIsInstance(rev, dict)
self.assertNotIn("bot", rev)
- for rev in mysite.watchlist_revs(showAnon=True, total=5):
+ for rev in mysite.watchlist_revs(anon=True, total=5):
self.assertIsInstance(rev, dict)
- for rev in mysite.watchlist_revs(showAnon=False, total=5):
+ for rev in mysite.watchlist_revs(anon=False, total=5):
self.assertIsInstance(rev, dict)
diff --git a/tox.ini b/tox.ini
index df5d598..ddc9eda 100644
--- a/tox.ini
+++ b/tox.ini
@@ -182,7 +182,6 @@
pywikibot/logging.py : N803
pywikibot/page.py : N803, N806
pywikibot/pagegenerators.py : N803, N806
- pywikibot/site.py : N803, N806
pywikibot/specialbots.py : N803, N806
pywikibot/textlib.py : E241, N801, N803, N806
pywikibot/tools/ip.py : N803
--
To view, visit https://gerrit.wikimedia.org/r/445343
To unsubscribe, or for help writing mail filters, visit https://gerrit.wikimedia.org/r/settings
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-MessageType: merged
Gerrit-Change-Id: I580e5d09a4a3eb9ee787c64e0f7bd34ca47a1d8f
Gerrit-Change-Number: 445343
Gerrit-PatchSet: 3
Gerrit-Owner: Dalba <dalba.wiki(a)gmail.com>
Gerrit-Reviewer: Dalba <dalba.wiki(a)gmail.com>
Gerrit-Reviewer: John Vandenberg <jayvdb(a)gmail.com>
Gerrit-Reviewer: Xqt <info(a)gno.de>
Gerrit-Reviewer: Zoranzoki21 <zorandori4444(a)gmail.com>
Gerrit-Reviewer: jenkins-bot
jenkins-bot has submitted this change and it was merged. ( https://gerrit.wikimedia.org/r/445084 )
Change subject: [doc] Prepare next release
......................................................................
[doc] Prepare next release
Change-Id: Iafe8c2e5af78fe9cca821e241ce430ce56276ece
---
M HISTORY.rst
M docs/conf.py
2 files changed, 7 insertions(+), 1 deletion(-)
Approvals:
Dalba: Looks good to me, approved
jenkins-bot: Verified
diff --git a/HISTORY.rst b/HISTORY.rst
index 28b87ea..83d69f2 100644
--- a/HISTORY.rst
+++ b/HISTORY.rst
@@ -4,6 +4,12 @@
Current release
---------------
+* Bugfixes and improvements
+* Localisation updates
+
+3.0.20180710
+------------
+
* Enable any LogEntry subclass for each logevent type (T199013)
* Deprecated pagegenerators options -<logtype>log aren't supported any longer (T199013)
* Open RotatingFileHandler with utf-8 encoding (T188231)
diff --git a/docs/conf.py b/docs/conf.py
index e6e4909..5c0e12f 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -71,7 +71,7 @@
# The short X.Y version.
version = '3.0'
# The full version, including alpha/beta/rc tags.
-release = '3.0.20180603'
+release = '3.0.20180710'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
--
To view, visit https://gerrit.wikimedia.org/r/445084
To unsubscribe, or for help writing mail filters, visit https://gerrit.wikimedia.org/r/settings
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-MessageType: merged
Gerrit-Change-Id: Iafe8c2e5af78fe9cca821e241ce430ce56276ece
Gerrit-Change-Number: 445084
Gerrit-PatchSet: 1
Gerrit-Owner: Xqt <info(a)gno.de>
Gerrit-Reviewer: Dalba <dalba.wiki(a)gmail.com>
Gerrit-Reviewer: John Vandenberg <jayvdb(a)gmail.com>
Gerrit-Reviewer: Zoranzoki21 <zorandori4444(a)gmail.com>
Gerrit-Reviewer: jenkins-bot
jenkins-bot has submitted this change and it was merged. ( https://gerrit.wikimedia.org/r/424586 )
Change subject: [IMPR] enable any LogEntry subclass for each log type
......................................................................
[IMPR] enable any LogEntry subclass for each log type
- Each logtype has its own LogEntry subclass either declared in logtype module
or as a subclass of OtherLogEntry created by get_entry_class class method
- A new instance method get_valid_entry_class was introduced in
LogEntryFactory to verify that logtype is valid for a given site. This
method is used by the initializer.
- The new site method logtypes returns all available log types. The result
is a set to speed up any searching inside that collection
- Deprecate logtypes class property
- Define ProtectEntry, DeleteEntry, ImportEntry NewUsersEntry and
ThanksEntry by the LogEntryFactory.get_entry_class constructor method
for backward compatibility
- pagegenerators uses new site.logtypes to verify the -logevents option.
This enables all other logtypes to be processed by pagegenerators.
- The old -<logtype>log pg options are no longer supported and ignored now.
The old options where deprecated 40 months ago which should be enough.
- update tests accordingly
- update HISTORY.rst
- fix spelling mistake in api.py
Bug: T199013
Change-Id: I0ba3ec7be0d0270ebc1930b149463ece3b53ea2b
---
M HISTORY.rst
M pywikibot/data/api.py
M pywikibot/logentries.py
M pywikibot/pagegenerators.py
M pywikibot/site.py
M tests/logentry_tests.py
M tests/pagegenerators_tests.py
7 files changed, 79 insertions(+), 165 deletions(-)
Approvals:
Dalba: Looks good to me, approved
jenkins-bot: Verified
diff --git a/HISTORY.rst b/HISTORY.rst
index ff5bd84..28b87ea 100644
--- a/HISTORY.rst
+++ b/HISTORY.rst
@@ -4,6 +4,8 @@
Current release
---------------
+* Enable any LogEntry subclass for each logevent type (T199013)
+* Deprecated pagegenerators options -<logtype>log aren't supported any longer (T199013)
* Open RotatingFileHandler with utf-8 encoding (T188231)
* Fix occasional failure of TestLogentries due to hidden namespace (T197506)
* Remove multiple empty sections at once in cosmetic_changes (T196324)
diff --git a/pywikibot/data/api.py b/pywikibot/data/api.py
index 0d1785c..be03877 100644
--- a/pywikibot/data/api.py
+++ b/pywikibot/data/api.py
@@ -3121,7 +3121,7 @@
self.entryFactory = logentries.LogEntryFactory(self.site, logtype)
def result(self, pagedata):
- """Instatiate LogEntry from data from api."""
+ """Instantiate LogEntry from data from api."""
return self.entryFactory.create(pagedata)
def _check_result_namespace(self, result):
diff --git a/pywikibot/logentries.py b/pywikibot/logentries.py
index d0a93be..f60b3ff 100644
--- a/pywikibot/logentries.py
+++ b/pywikibot/logentries.py
@@ -157,6 +157,13 @@
return self.data['comment']
+class OtherLogEntry(LogEntry):
+
+ """A log entry class for unspecified log events."""
+
+ pass
+
+
class UserTargetLogEntry(LogEntry):
"""A log entry whose target is a user page."""
@@ -260,13 +267,6 @@
return self._expiry
-class ProtectEntry(LogEntry):
-
- """Protection log entry."""
-
- _expectedType = 'protect'
-
-
class RightsEntry(LogEntry):
"""Rights log entry."""
@@ -288,13 +288,6 @@
return self._params['newgroups']
-class DeleteEntry(LogEntry):
-
- """Deletion log entry."""
-
- _expectedType = 'delete'
-
-
class UploadEntry(LogEntry):
"""Upload log entry."""
@@ -361,13 +354,6 @@
return 'suppressedredirect' in self._params
-class ImportEntry(LogEntry):
-
- """Import log entry."""
-
- _expectedType = 'import'
-
-
class PatrolEntry(LogEntry):
"""Patrol log entry."""
@@ -396,22 +382,6 @@
return 'auto' in self._params and self._params['auto'] != 0
-class NewUsersEntry(UserTargetLogEntry):
-
- """New user log entry."""
-
- _expectedType = 'newusers'
-
-
-class ThanksEntry(UserTargetLogEntry):
-
- """Thanks log entry."""
-
- _expectedType = 'thanks'
-
-# TODO entries for merge,suppress,makebot,gblblock,renameuser,globalauth,gblrights ?
-
-
class LogEntryFactory(object):
"""
@@ -420,17 +390,12 @@
Only available method is create()
"""
- logtypes = {
+ _logtypes = {
'block': BlockEntry,
- 'protect': ProtectEntry,
'rights': RightsEntry,
- 'delete': DeleteEntry,
'upload': UploadEntry,
'move': MoveEntry,
- 'import': ImportEntry,
'patrol': PatrolEntry,
- 'newusers': NewUsersEntry,
- 'thanks': ThanksEntry,
}
def __init__(self, site, logtype=None):
@@ -450,14 +415,14 @@
else:
# Bind a Class object to self._creator:
# When called, it will initialize a new object of that class
- logclass = LogEntryFactory._getEntryClass(logtype)
+ logclass = self.get_valid_entry_class(logtype)
self._creator = lambda data: logclass(data, self._site)
@classproperty
- @deprecated('LogEntryFactory.logtypes')
- def _logtypes(cls): # noqa: N805
+ @deprecated('Site.logtypes or LogEntryFactory.get_entry_class(logtype)')
+ def logtypes(cls): # noqa: N805
"""DEPRECATED LogEntryFactory class attribute of log types."""
- return cls.logtypes
+ return cls._logtypes
def create(self, logdata):
"""
@@ -470,20 +435,40 @@
"""
return self._creator(logdata)
- @classmethod
- def _getEntryClass(cls, logtype):
+ def get_valid_entry_class(self, logtype):
"""
Return the class corresponding to the @logtype string parameter.
- @return: specified subclass of LogEntry, or LogEntry
- @rtype: class
+ @return: specified subclass of LogEntry
+ @rtype: LogEntry
+ @raise KeyError: logtype is not valid
"""
- try:
- return cls.logtypes[logtype]
- except KeyError:
- pywikibot.warning(
- 'Log entry key {0} is not known.'.format(logtype))
- return LogEntry
+ if logtype not in self._site.logtypes:
+ raise KeyError('{} is not a valid logtype'.format(logtype))
+ return LogEntryFactory.get_entry_class(logtype)
+
+ @classmethod
+ def get_entry_class(cls, logtype):
+ """
+ Return the class corresponding to the @logtype string parameter.
+
+ @return: specified subclass of LogEntry
+ @rtype: LogEntry
+ @note: this class method cannot verify whether the given logtype
+ already exits for a given site; to verify use Site.logtypes
+ or use the get_valid_entry_class instance method instead.
+ """
+ if logtype not in cls._logtypes:
+ if logtype in ('newusers', 'thanks'):
+ bases = (UserTargetLogEntry, OtherLogEntry)
+ else:
+ bases = (OtherLogEntry, )
+ classname = str(logtype.capitalize() + 'Entry'
+ if logtype is not None
+ else OtherLogEntry.__name__)
+ cls._logtypes[logtype] = type(
+ classname, bases, {'_expectedType': logtype})
+ return cls._logtypes[logtype]
def _createFromData(self, logdata):
"""
@@ -499,4 +484,12 @@
pywikibot.debug('API log entry received:\n{0}'.format(logdata),
_logger)
raise Error("Log entry has no 'type' key")
- return LogEntryFactory._getEntryClass(logtype)(logdata, self._site)
+ return LogEntryFactory.get_entry_class(logtype)(logdata, self._site)
+
+
+# For backward compatibility
+ProtectEntry = LogEntryFactory.get_entry_class('protect')
+DeleteEntry = LogEntryFactory.get_entry_class('delete')
+ImportEntry = LogEntryFactory.get_entry_class('import')
+NewUsersEntry = LogEntryFactory.get_entry_class('newusers')
+ThanksEntry = LogEntryFactory.get_entry_class('thanks')
diff --git a/pywikibot/pagegenerators.py b/pywikibot/pagegenerators.py
index bceae51..6e73d33 100644
--- a/pywikibot/pagegenerators.py
+++ b/pywikibot/pagegenerators.py
@@ -53,7 +53,6 @@
ServerError,
UnknownExtension,
)
-from pywikibot.logentries import LogEntryFactory
from pywikibot.proofreadpage import ProofreadPage
from pywikibot.tools import MediaWikiVersion
@@ -1125,34 +1124,11 @@
def _handle_logevents(self, value):
"""Handle `-logevents` argument."""
params = value.split(',')
- if params[0] not in LogEntryFactory.logtypes:
+ if params[0] not in self.site.logtypes:
raise NotImplementedError(
'Invalid -logevents parameter "{0}"'.format(params[0]))
return self._parse_log_events(*params)
- def _old_eventlog_handler(self, logtype, value):
- """Help in handling arguments LogEntryFactory.logtypes."""
- total = 500
- if value:
- try:
- total = int(value)
- except ValueError:
- params = value.split(';')
- if len(params) == 2:
- value, total = params
- else:
- value = params[0]
- else:
- value = None
- else:
- value = None
- issue_deprecation_warning(
- 'The usage of "{0}"'.format('-%slog' % logtype),
- '-logevents:"{0}"'.format(
- ','.join((logtype, value or '', str(total)))),
- 4, ArgumentDeprecationWarning)
- return self._parse_log_events(logtype, value, total)
-
def handleArg(self, arg):
"""Parse one argument at a time.
@@ -1191,22 +1167,6 @@
return False
-def _old_eventlog_handler_method_factory(log_type):
- """Return an old type handler method to be assigned to LogEntryFactory."""
- # Using closure is a workaround for the lack of functools.partialmethod in
- # Python 2.7.
- def method(self, vaule):
- return self._old_eventlog_handler(log_type, vaule)
- return method
-
-
-for _log_type in LogEntryFactory.logtypes:
- setattr(
- GeneratorFactory,
- '_handle_' + _log_type + 'log',
- _old_eventlog_handler_method_factory(_log_type))
-
-
def _int_none(v):
"""Return None if v is None or '' else return int(v)."""
return v if (v is None or v is '') else int(v)
diff --git a/pywikibot/site.py b/pywikibot/site.py
index 0959fa5..6df1114 100644
--- a/pywikibot/site.py
+++ b/pywikibot/site.py
@@ -4539,6 +4539,12 @@
namespaces=namespaces,
total=total, g_content=content, **iuargs)
+ @property
+ def logtypes(self):
+ """Return a set of log types available on current site."""
+ return set(filter(None, self._paraminfo.parameter(
+ 'query+logevents', 'type')['type']))
+
@deprecated_args(step=None)
def logevents(self, logtype=None, user=None, page=None, namespace=None,
start=None, end=None, reverse=False, tag=None, total=None):
diff --git a/tests/logentry_tests.py b/tests/logentry_tests.py
index 2819f88..d1ecbde 100644
--- a/tests/logentry_tests.py
+++ b/tests/logentry_tests.py
@@ -12,7 +12,8 @@
import pywikibot
from pywikibot.exceptions import HiddenKeyError
-from pywikibot.logentries import LogEntryFactory, UserTargetLogEntry
+from pywikibot.logentries import (
+ LogEntryFactory, OtherLogEntry, UserTargetLogEntry)
from pywikibot.tools import (
MediaWikiVersion,
UnicodeType as unicode,
@@ -67,10 +68,10 @@
def _test_logevent(self, logtype):
"""Test a single logtype entry."""
logentry = self._get_logentry(logtype)
- if logtype in LogEntryFactory.logtypes:
- self.assertEqual(logentry._expectedType, logtype)
- else:
- self.assertIsNone(logentry._expectedType)
+ self.assertIn(logtype, logentry.__class__.__name__.lower())
+ self.assertEqual(logentry._expectedType, logtype)
+ if logtype not in LogEntryFactory._logtypes:
+ self.assertIsInstance(logentry, OtherLogEntry)
if self.site_key == 'old':
self.assertNotIn('params', logentry.data)
else:
@@ -123,7 +124,7 @@
return test_logevent
# create test methods for the support logtype classes
- for logtype in LogEntryFactory.logtypes:
+ for logtype in LogEntryFactory._logtypes:
cls.add_method(dct, 'test_%sEntry' % logtype.title(),
test_method(logtype))
@@ -147,9 +148,8 @@
# Unfortunately it's not possible to use the metaclass to create a
# bunch of test methods for this too as the site instances haven't been
# initialized yet.
- available_types = set(self.site._paraminfo.parameter(
- 'query+logevents', 'type')['type'])
- for simple_type in available_types - set(LogEntryFactory.logtypes):
+ for simple_type in (self.site.logtypes
+ - set(LogEntryFactory._logtypes)):
if not simple_type:
# paraminfo also reports an empty string as a type
continue
@@ -241,13 +241,20 @@
"""Test equality of LogEntry instances."""
site = self.get_site('dewp')
other_site = self.get_site('tewp')
- le1 = next(iter(site.logevents(reverse=True, total=1)))
- le2 = next(iter(site.logevents(reverse=True, total=1)))
+ gen1 = iter(site.logevents(reverse=True, total=2))
+ gen2 = iter(site.logevents(reverse=True, total=2))
+ le1 = next(gen1)
+ le2 = next(gen2)
le3 = next(iter(other_site.logevents(reverse=True, total=1)))
+ le4 = next(gen1)
+ le5 = next(gen2)
self.assertEqual(le1, le2)
self.assertFalse(le1 != le2) # __ne__ test
self.assertNotEqual(le1, le3)
self.assertNotEqual(le1, site)
+ self.assertIsInstance(le4, OtherLogEntry)
+ self.assertIsInstance(le5, OtherLogEntry)
+ self.assertEqual(type(le4), type(le5))
class TestDeprecatedMethods(TestLogentriesBase, DeprecationTestCase):
diff --git a/tests/pagegenerators_tests.py b/tests/pagegenerators_tests.py
index 8bcf3f7..4c6de1d 100755
--- a/tests/pagegenerators_tests.py
+++ b/tests/pagegenerators_tests.py
@@ -1325,60 +1325,6 @@
self.assertFalse(factory.handleArg(gf_mock, '-anotherlog'))
self.assertFalse(gf_mock.method_calls)
- def test_logevents_default(self):
- """Test old logevents option handling."""
- gf = pagegenerators.GeneratorFactory(site=self.site)
- self.assertTrue(gf.handleArg('-newuserslog'))
- self.assertOneDeprecationParts('The usage of "-newuserslog"',
- '-logevents:"newusers,,500"')
- gen = gf.getCombinedGenerator()
- self.assertIsNotNone(gen)
- pages = set(gen)
- self.assertLessEqual(len(pages), 500)
- self.assertTrue(all(isinstance(item, pywikibot.User)
- for item in pages))
-
- def test_logevents_default_multi(self):
- """Test old logevents option handling with limit argument."""
- gf = pagegenerators.GeneratorFactory(site=self.site)
- self.assertTrue(gf.handleArg('-newuserslog:10'))
- gen = gf.getCombinedGenerator()
- self.assertIsNotNone(gen)
- pages = set(gen)
- self.assertLessEqual(len(pages), 10)
- self.assertTrue(all(isinstance(item, pywikibot.User)
- for item in pages))
-
- def test_logevents_ns(self):
- """Test old logevents option with limit argument and namespace."""
- gf = pagegenerators.GeneratorFactory(site=self.site)
- gf.handleArg('-ns:1')
- gf.handleArg('-newuserslog:10')
- gen = gf.getCombinedGenerator()
- self.assertIsNotNone(gen)
- self.assertPagesInNamespaces(gen, 1)
- self.assertTrue(all(isinstance(item, pywikibot.User)
- for item in gen))
-
- def test_logevents_user_multi(self):
- """Test old logevents option for a given user."""
- gf = pagegenerators.GeneratorFactory(site=self.site)
- user = self.get_site().user()
- self.assertTrue(gf.handleArg('-newuserslog:' + user + ';10'))
- gen = gf.getCombinedGenerator()
- self.assertIsNotNone(gen)
- pages = set(gen)
-
- if not pages:
- raise unittest.SkipTest('No user creation log entries for ' + user)
-
- # TODO: Check if the pages generated correspond to the user
- # (no easy way of checking from pages)
-
- self.assertLessEqual(len(pages), 10)
- self.assertTrue(all(isinstance(item, pywikibot.User)
- for item in pages))
-
def test_logevents_with_start_timestamp(self):
"""Test -logevents which uses timestamp for start."""
gf = pagegenerators.GeneratorFactory(site=self.site)
--
To view, visit https://gerrit.wikimedia.org/r/424586
To unsubscribe, or for help writing mail filters, visit https://gerrit.wikimedia.org/r/settings
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-MessageType: merged
Gerrit-Change-Id: I0ba3ec7be0d0270ebc1930b149463ece3b53ea2b
Gerrit-Change-Number: 424586
Gerrit-PatchSet: 21
Gerrit-Owner: Xqt <info(a)gno.de>
Gerrit-Reviewer: Dalba <dalba.wiki(a)gmail.com>
Gerrit-Reviewer: John Vandenberg <jayvdb(a)gmail.com>
Gerrit-Reviewer: Xqt <info(a)gno.de>
Gerrit-Reviewer: Zhuyifei1999 <zhuyifei1999(a)gmail.com>
Gerrit-Reviewer: Zoranzoki21 <zorandori4444(a)gmail.com>
Gerrit-Reviewer: jenkins-bot