jenkins-bot has submitted this change and it was merged. Change subject: proofreadpage.py: save page with format application/json ......................................................................
proofreadpage.py: save page with format application/json This is the preferred format to save ProofreadPage as it avoids to reconstruct the wikitext given header, body and footer. Change-Id: If4ec33d61b43b242b0061a3696d2c2ad1012570d --- M pywikibot/proofreadpage.py M tests/proofreadpage_tests.py 2 files changed, 87 insertions(+), 25 deletions(-) Approvals: John Vandenberg: Looks good to me, approved jenkins-bot: Verified diff --git a/pywikibot/proofreadpage.py b/pywikibot/proofreadpage.py index 2acb362..234dee2 100644 --- a/pywikibot/proofreadpage.py +++ b/pywikibot/proofreadpage.py @@ -1,6 +1,8 @@ # -*- coding: utf-8 -*- """ -Objects representing objects used with ProofreadPage Extensions. +Objects representing objects used with ProofreadPage Extension. + +The extension is supported by MW 1.21+. This module includes objects: * ProofreadPage(Page) @@ -18,6 +20,7 @@ # import re +import json import pywikibot @@ -36,9 +39,9 @@ def __init__(self, text=None): """Constructor.""" - self.text = text or '' + self._text = text or '' - m = self.p_header.search(self.text) + m = self.p_header.search(self._text) if m: self.ql = int(m.group('ql')) self.user = m.group('user') @@ -165,6 +168,7 @@ return self._full_header.header @header.setter + @decompose def header(self, value): """Set editable part of Page header.""" self._full_header.header = value @@ -198,6 +202,7 @@ self._full_header = FullHeader() self._body = '' self._footer = '' + self.user = self.site.username() # Fill user field in empty header. self._compose_page() @property @@ -211,17 +216,20 @@ if hasattr(self, '_text'): return self._text # If page does not exist, preload it - if not self.exists(): + if self.exists(): + # If page exists, load it + super(ProofreadPage, self).text + else: self._text = self.preloadText() - # If page exists, load it - super(ProofreadPage, self).text + self.user = self.site.username() # Fill user field in empty header. return self._text @text.setter def text(self, value): - """Update the current text. + """Update current text. Mainly for use within the class, called by other methods. + Use self.header, self.body and self.footer to set page content, @param value: New value or None @param value: basestring @@ -231,12 +239,14 @@ extension. """ self._text = value - self._decompose_page() - if not self._text: + if self._text: + self._decompose_page() + else: self._create_empty_page() @text.deleter def text(self): + """Delete current text.""" if hasattr(self, '_text'): del self._text @@ -247,12 +257,12 @@ exception Error: the page is not formatted according to ProofreadPage extension. """ - if not self.text: + if not self.text: # Property force page text loading. self._create_empty_page() return - open_queue = list(self.p_open.finditer(self.text)) - close_queue = list(self.p_close.finditer(self.text)) + open_queue = list(self.p_open.finditer(self._text)) + close_queue = list(self.p_close.finditer(self._text)) len_oq = len(open_queue) len_cq = len(close_queue) @@ -261,27 +271,48 @@ % self.title(asLink=True)) f_open, f_close = open_queue[0], close_queue[0] - self._full_header = FullHeader(self.text[f_open.end():f_close.start()]) + self._full_header = FullHeader(self._text[f_open.end():f_close.start()]) l_open, l_close = open_queue[-1], close_queue[-1] - self._footer = self.text[l_open.end():l_close.start()] + self._footer = self._text[l_open.end():l_close.start()] - self._body = self.text[f_close.end():l_open.start()] + self._body = self._text[f_close.end():l_open.start()] def _compose_page(self): """Compose Proofread Page text from header, body and footer.""" fmt = ('{0.open_tag}{0._full_header}{0.close_tag}' '{0._body}' '{0.open_tag}{0._footer}</div>{0.close_tag}') - self.text = fmt.format(self) - return self.text + self._text = fmt.format(self) + return self._text + + def _page_to_json(self): + """Convert page text to json format. + + This is the format accepted by action=edit specifying + contentformat=application/json. This format is recommended to save the + page, as it is not subject to possible errors done in composing the + wikitext header and footer of the page or changes in the ProofreadPage + extension format. + """ + page_dict = {'header': self.header, + 'body': self.body, + 'footer': self.footer, + 'level': {'level': self.ql, 'user': self.user}, + } + # ensure_ascii=False returns a unicode + return json.dumps(page_dict, ensure_ascii=False) def save(self, *args, **kwargs): # see Page.save() """Save page content after recomposing the page.""" - self._compose_page() summary = kwargs.pop('summary', '') summary = self.pre_summary + summary - super(ProofreadPage, self).save(*args, summary=summary, **kwargs) + # Save using contentformat='application/json' + kwargs['contentformat'] = 'application/json' + kwargs['contentmodel'] = 'proofread-page' + text = self._page_to_json() + super(ProofreadPage, self).save(*args, text=text, summary=summary, + **kwargs) @property def pre_summary(self): diff --git a/tests/proofreadpage_tests.py b/tests/proofreadpage_tests.py index b13e9e2..be73ac1 100644 --- a/tests/proofreadpage_tests.py +++ b/tests/proofreadpage_tests.py @@ -9,9 +9,12 @@ __version__ = '$Id$' -import pywikibot -from pywikibot.proofreadpage import ProofreadPage +import json +import pywikibot + +from pywikibot.proofreadpage import ProofreadPage +from pywikibot.data import api from tests.aspects import unittest, TestCase from tests.basepage_tests import ( @@ -43,6 +46,7 @@ code = 'en' def setUp(self): + """Set up test case.""" self._page = ProofreadPage( self.site, 'Page:Popular Science Monthly Volume 1.djvu/12') super(TestBasePageMethods, self).setUp() @@ -61,6 +65,7 @@ code = 'en' def setUp(self): + """Set up test case.""" self._page = ProofreadPage( self.site, 'Page:Popular Science Monthly Volume 1.djvu/12') super(TestLoadRevisionsCaching, self).setUp() @@ -158,18 +163,44 @@ """Test ProofreadPage page decomposing/composing text.""" page = ProofreadPage(self.site, 'dummy test page') self.assertEqual(page.text, - '<noinclude><pagequality level="1" user="" />' + '<noinclude><pagequality level="1" user="%s" />' '<div class="pagetext">\n\n\n</noinclude>' - '<noinclude><references/></div></noinclude>') + '<noinclude><references/></div></noinclude>' + % self.site.username()) def test_preload_from_empty_text(self): """Test ProofreadPage page decomposing/composing text.""" page = ProofreadPage(self.site, 'dummy test page') page.text = '' self.assertEqual(page.text, - '<noinclude><pagequality level="1" user="" />' + '<noinclude><pagequality level="1" user="%s" />' '<div class="pagetext">\n\n\n</noinclude>' - '<noinclude></div></noinclude>') + '<noinclude></div></noinclude>' + % self.site.username()) + + def test_json_format(self): + """Test conversion to json format.""" + page = ProofreadPage(self.site, self.valid['title']) + + rvargs = {'rvprop': 'ids|flags|timestamp|user|comment|content', + 'rvcontentformat': 'application/json', + 'titles': page, + } + + rvgen = self.site._generator(api.PropertyGenerator, + type_arg='info|revisions', + total=1, **rvargs) + rvgen.set_maximum_items(-1) # suppress use of rvlimit parameter + + try: + pagedict = next(iter(rvgen)) + loaded_text = pagedict.get('revisions')[0].get('*') + except (StopIteration, TypeError, KeyError, ValueError, IndexError): + page_text = '' + + page_text = page._page_to_json() + self.assertEqual(json.loads(page_text), json.loads(loaded_text)) + if __name__ == '__main__': try: -- To view, visit https://gerrit.wikimedia.org/r/217066 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: merged Gerrit-Change-Id: If4ec33d61b43b242b0061a3696d2c2ad1012570d Gerrit-PatchSet: 8 Gerrit-Project: pywikibot/core Gerrit-Branch: master Gerrit-Owner: Mpaa <mpaa.w...@gmail.com> Gerrit-Reviewer: John Vandenberg <jay...@gmail.com> Gerrit-Reviewer: Ladsgroup <ladsgr...@gmail.com> Gerrit-Reviewer: Merlijn van Deen <valhall...@arctus.nl> Gerrit-Reviewer: Mpaa <mpaa.w...@gmail.com> Gerrit-Reviewer: Tpt <thoma...@hotmail.fr> Gerrit-Reviewer: XZise <commodorefabia...@gmx.de> Gerrit-Reviewer: jenkins-bot <> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits