jenkins-bot has submitted this change and it was merged.

Change subject: Lock and unlock Flow topics
......................................................................


Lock and unlock Flow topics

This patch allows bots to lock and unlock Flow topics using the API.
It also includes a property for Topic objects showing whether that
topic is locked or not. Post.reply() now raises a LockedPage exception
if the topic is locked. Two tests have been included, one to test
locking and unlocking and the other to test error handling in
Post.reply().

Bug: T108288
Change-Id: I4afb6c0fff6bf541a1a05aa2a5f9b0715e67541e
---
M pywikibot/flow.py
M pywikibot/site.py
M tests/flow_edit_tests.py
3 files changed, 100 insertions(+), 3 deletions(-)

Approvals:
  Merlijn van Deen: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/pywikibot/flow.py b/pywikibot/flow.py
index 1580edb..1c7f117 100644
--- a/pywikibot/flow.py
+++ b/pywikibot/flow.py
@@ -11,7 +11,7 @@
 
 import logging
 
-from pywikibot.exceptions import NoPage, UnknownExtension
+from pywikibot.exceptions import NoPage, UnknownExtension, LockedPage
 from pywikibot.page import BasePage
 from pywikibot.tools import PY2
 
@@ -213,6 +213,11 @@
             self._root = Post.fromJSON(self, self.uuid, self._data)
         return self._root
 
+    @property
+    def is_locked(self):
+        """Whether this topic is locked."""
+        return self.root._current_revision['isLocked']
+
     def replies(self, format='wikitext', force=False):
         """A list of replies to this topic's root post.
 
@@ -236,6 +241,24 @@
         @rtype: Post
         """
         return self.root.reply(content, format)
+
+    def lock(self, reason='Closed'):
+        """Lock this topic.
+
+        @param reason: The reason for locking this topic
+        @type reason: unicode
+        """
+        self.site.lock_topic(self, True, reason)
+        self.root._load(load_from_topic=True)
+
+    def unlock(self, reason='Reopened'):
+        """Unlock this topic.
+
+        @param reason: The reason for unlocking this topic
+        @type reason: unicode
+        """
+        self.site.lock_topic(self, False, reason)
+        self.root._load(load_from_topic=True)
 
 
 # Flow non-page-like objects
@@ -408,6 +431,9 @@
         @rtype: Post
         """
         self._load()
+        if self.page.is_locked:
+            raise LockedPage(self.page, 'Topic %s is locked.')
+
         reply_url = self._current_revision['actions']['reply']['url']
         parsed_url = urlparse(reply_url)
         params = parse_qs(parsed_url.query)
diff --git a/pywikibot/site.py b/pywikibot/site.py
index 4e87cb6..27d2ba0 100644
--- a/pywikibot/site.py
+++ b/pywikibot/site.py
@@ -5941,6 +5941,29 @@
         data = req.submit()
         return data['flow']['reply']['committed']['topic']
 
+    @must_be('user')
+    @need_extension('Flow')
+    def lock_topic(self, page, lock, reason):
+        """Lock or unlock a Flow topic.
+
+        @param page: A Flow topic
+        @type page: Topic
+        @param lock: Whether to lock or unlock the topic
+        @type lock: bool (True corresponds to locking the topic.)
+        @param reason: The reason to lock or unlock the topic
+        @type reason: unicode
+        @return: Metadata returned by the API
+        @rtype: dict
+        """
+        status = 'lock' if lock else 'unlock'
+        token = self.tokens['csrf']
+        params = {'action': 'flow', 'page': page, 'token': token,
+                  'submodule': 'lock-topic', 'cotreason': reason,
+                  'cotmoderationState': status}
+        req = self._request(parameters=params, use_get=False)
+        data = req.submit()
+        return data['flow']['lock-topic']['committed']['topic']
+
     def watched_pages(self, sysop=False, force=False, step=None, total=None):
         """
         Return watchlist.
diff --git a/tests/flow_edit_tests.py b/tests/flow_edit_tests.py
index 9844f5d..4a3ce11 100644
--- a/tests/flow_edit_tests.py
+++ b/tests/flow_edit_tests.py
@@ -9,6 +9,7 @@
 
 __version__ = '$Id$'
 
+from pywikibot.exceptions import LockedPage
 from pywikibot.flow import Board, Topic, Post
 from pywikibot.tools import PY2
 
@@ -30,9 +31,8 @@
 
     def test_create_topic(self):
         """Test creation of topic."""
-        site = self.get_site()
         content = 'If you can read this, the Flow code in Pywikibot works!'
-        board = Board(site, 'Talk:Pywikibot test')
+        board = Board(self.site, 'Talk:Pywikibot test')
         topic = board.new_topic('Pywikibot test', content, 'wikitext')
         first_post = topic.replies()[0]
         wikitext = first_post.get(format='wikitext')
@@ -149,3 +149,51 @@
         self.assertListEqual(old_nested_replies, [])
         more_root_replies = topic_root.replies(force=True)
         self.assertEqual(len(more_root_replies), len(new_root_replies) + 1)
+
+
+class TestFlowLockTopic(TestCase):
+
+    """Locking and unlocking topics."""
+
+    family = 'test'
+    code = 'test'
+
+    user = True
+    write = True
+
+    def test_lock_unlock_topic(self):
+        """Lock and unlock a test topic."""
+        # Setup
+        topic = Topic(self.site, 'Topic:Sn12rdih4iducjsd')
+        if topic.is_locked:
+            topic.unlock()
+        self.assertFalse(topic.is_locked)
+        # Lock topic
+        topic.lock('Pywikibot test')
+        self.assertTrue(topic.is_locked)
+        # Unlock topic
+        topic.unlock('Pywikibot test')
+        self.assertFalse(topic.is_locked)
+
+
+class TestFlowEditFailure(TestCase):
+
+    """Flow-related edit failure tests."""
+
+    family = 'test'
+    code = 'test'
+
+    user = True
+    write = -1
+
+    def test_reply_to_locked_topic(self):
+        """Test replying to locked topic (should raise exception)."""
+        # Setup
+        content = 'I am a reply to a locked topic. This is not good!'
+        topic = Topic(self.site, 'Topic:Smxnipjfs8umm1wt')
+        # Reply (should raise a LockedPage exception)
+        self.assertRaises(LockedPage, topic.reply, content, 'wikitext')
+        topic_root = topic.root
+        self.assertRaises(LockedPage, topic_root.reply, content, 'wikitext')
+        topic_reply = topic.root.replies(force=True)[0]
+        self.assertRaises(LockedPage, topic_reply.reply, content, 'wikitext')

-- 
To view, visit https://gerrit.wikimedia.org/r/231747
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I4afb6c0fff6bf541a1a05aa2a5f9b0715e67541e
Gerrit-PatchSet: 5
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Owner: Happy5214 <[email protected]>
Gerrit-Reviewer: Happy5214 <[email protected]>
Gerrit-Reviewer: John Vandenberg <[email protected]>
Gerrit-Reviewer: Ladsgroup <[email protected]>
Gerrit-Reviewer: Mattflaschen <[email protected]>
Gerrit-Reviewer: Merlijn van Deen <[email protected]>
Gerrit-Reviewer: XZise <[email protected]>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to