Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions pywikibot/data/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -3268,3 +3268,9 @@ def update_page(page, pagedict, props=[]):

if "flowinfo" in pagedict:
page._flowinfo = pagedict['flowinfo']['flow']

if 'lintId' in pagedict:
page._lintinfo = pagedict
page._lintinfo.pop('pageid')
page._lintinfo.pop('title')
page._lintinfo.pop('ns')
2 changes: 1 addition & 1 deletion pywikibot/page.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ class BasePage(UnicodeMixin, ComparableMixin):
'_contentmodel', '_langlinks', '_isredir', '_coords',
'_preloadedtext', '_timestamp', '_applicable_protections',
'_flowinfo', '_quality', '_pageprops', '_revid', '_quality_text',
'_pageimage', '_item'
'_pageimage', '_item', '_lintinfo',
)

def __init__(self, source, title=u"", ns=0):
Expand Down
54 changes: 51 additions & 3 deletions pywikibot/pagegenerators.py
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,19 @@
"-pageid:pageid1,pageid2,." or "-pageid:'pageid1|pageid2|..'"
and supplied multiple times for multiple pages.

-linter Work on pages that contains lint errors. Extension Linter
must be available on the site.
-linter select all categories.
-linter:high, -linter:medium or -linter:low select all
categories for that prio.
Single categories can be selected with commas as in
-linter:cat1,cat2,cat3

Adding '/int' indentifies Lint ID to start querying from:
e.g. -linter:high/10000

-linter:show just shows available categories.


FILTER OPTIONS
==============
Expand Down Expand Up @@ -312,9 +325,9 @@
-ns:not:2,3
-ns:not:Help,File

If used with -newpages/-random/-randomredirect generators,
-namespace/ns must be provided before
-newpages/-random/-randomredirect.
If used with -newpages/-random/-randomredirect/linter
generators, -namespace/ns must be provided before
-newpages/-random/-randomredirect/linter.
If used with -recentchanges generator, efficiency is
improved if -namespace is provided before -recentchanges.

Expand Down Expand Up @@ -699,6 +712,41 @@ def intNone(v):
value = 'Image:' + value
page = pywikibot.FilePage(self.site, value)
gen = FileLinksGenerator(page)
elif arg == '-linter':
if not self.site.has_extension('Linter'):
raise UnknownExtension(
'-linter needs a site with Linter extension.')
cats = self.site.siteinfo.get('linter') # Get linter categories.
valid_cats = [c for _list in cats.values() for c in _list]

cat, sep, lint_from = value.partition('/')
if not lint_from:
lint_from = None

if cat == 'show': # Display categories of lint errors.
_i = ' ' * 4
txt = 'Available categories of lint errors:\n'
for prio, _list in cats.items():
txt += '{indent}{prio}\n'.format(indent=_i, prio=prio)
for c in _list:
txt += '{indent}{cat}\n'.format(indent=2 * _i, cat=c)
pywikibot.output('%s' % txt)
return True

if not cat:
lint_cats = valid_cats
elif cat in ['low', 'medium', 'high']:
lint_cats = cats[cat]
else:
lint_cats = cat.split(',')
for lint_cat in lint_cats:
if lint_cat not in valid_cats:
raise ValueError('Invalid category of lint errors: %s'
% cat)

gen = self.site.linter_pages(lint_categories='|'.join(lint_cats),
namespaces=self.namespaces,
lint_from=lint_from)
elif arg == '-unusedfiles':
gen = UnusedFilesGenerator(total=intNone(value), site=self.site)
elif arg == '-lonelypages':
Expand Down
55 changes: 55 additions & 0 deletions pywikibot/site.py
Original file line number Diff line number Diff line change
Expand Up @@ -6883,6 +6883,61 @@ def get_param(item):
comparison = data['compare']['*']
return comparison

@need_extension('Linter')
def linter_pages(self, lint_categories=None, total=None,
namespaces=None, pageids=None, lint_from=None):
"""Return a generator to pages containing linter errors.

@param lint_categories: categories of lint errors
@type lntcategories: an iterable that returns values (str),
or a pipe-separated string of values.

@param total: if not None, yielding this many items in total
@type total: int

@param namespaces: only iterate pages in these namespaces
@type namespaces: iterable of basestring or Namespace key,
or a single instance of those types. May be a '|' separated
list of namespace identifiers.

@param pageids: only include lint errors from the specified pageids
@type pageids: an iterable that returns pageids (str or int),
or a comma- or pipe-separated string of pageids
(e.g. '945097,1483753, 956608' or '945097|483753|956608')

@param lint_from: Lint ID to start querying from
@type lint_from: str representing digit or integer

@return: pages with Linter errors.
@rtype: generator of Page

"""
query = self._generator(api.ListGenerator, type_arg='linterrors',
total=total, # Will set lntlimit
namespaces=namespaces)

if lint_categories:
if isinstance(lint_categories, basestring):
lint_categories = lint_categories.split('|')
lint_categories = [p.strip() for p in lint_categories]
query.request['lntcategories'] = '|'.join(lint_categories)

if pageids:
if isinstance(pageids, basestring):
pageids = pageids.split('|')
pageids = [p.strip() for p in pageids]
# Validate pageids.
pageids = (str(int(p)) for p in pageids if int(p) > 0)
query.request['lntpageid'] = '|'.join(pageids)

if lint_from:
query.request['lntfrom'] = int(lint_from)

for pageitem in query:
page = pywikibot.Page(self, pageitem['title'])
api.update_page(page, pageitem)
yield page

# Thanks API calls
@need_extension('Thanks')
def thank_revision(self, revid, source=None):
Expand Down
12 changes: 12 additions & 0 deletions tests/pagegenerators_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -1177,6 +1177,18 @@ def test_positionalargument_with_colon(self):
self.assertIsNotNone(gen2)
self.assertEqual(list(gen1), list(gen2))

def test_linter_generator_ns_multi(self):
"""Test random generator with multiple namespaces."""
gf = pagegenerators.GeneratorFactory(site=self.site)
gf.handleArg('-ns:1')
gf.handleArg('-limit:3')
gf.handleArg('-linter:obsolete-tag')
gen = gf.getCombinedGenerator()
self.assertIsNotNone(gen)
pages = list(gen)
self.assertPagesInNamespaces(pages, set([1, ]))
self.assertEqual(len(pages), 3)


class TestFactoryGeneratorWikibase(WikidataTestCase):

Expand Down
15 changes: 15 additions & 0 deletions tests/site_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -1065,6 +1065,21 @@ def test_unconnected(self):
self.assertLessEqual(len(tuple(upgen)), 3)


class TestLinterPages(DefaultSiteTestCase):

"""Test linter_pages methods."""

def test_linter_pages(self):
"""Test the deprecated site.logpages() method."""
le = list(self.site.linter_pages(
lint_categories='obsolete-tag|missing-end-tag', total=5))
self.assertLessEqual(len(le), 5)
for entry in le:
self.assertIsInstance(entry, pywikibot.Page)
self.assertIn(entry._lintinfo['category'],
['obsolete-tag', 'missing-end-tag'])


class TestImageUsage(DefaultSiteTestCase):

"""Test cases for Site.imageusage method."""
Expand Down