jenkins-bot has submitted this change and it was merged.
Change subject: site.py: check if site is enabled for uploads ......................................................................
site.py: check if site is enabled for uploads
Fix Bug 69090: upload.py attempts uploads on wikis that don't allow uploads.
Check APIError code to determine if Site is enabled for uploading. Currently it is done and cached at first upload attempt.
Added also a helper function is_uploaddisabled() to determine if a site has uploads enabled, based on a dummy upload attempt. Throttle has been disabled for such request to speed up the query (implementation taken from I80b2bba9e63832173d5b697db1f4ea419ca1122f).
Change-Id: Id8ae0cd51582d76b7bdd15c53e39b4105995b540 --- M pywikibot/site.py M scripts/upload.py M tests/site_tests.py 3 files changed, 60 insertions(+), 7 deletions(-)
Approvals: John Vandenberg: Looks good to me, approved XZise: Looks good to me, but someone else must approve jenkins-bot: Verified
diff --git a/pywikibot/site.py b/pywikibot/site.py index cfbd128..214f638 100644 --- a/pywikibot/site.py +++ b/pywikibot/site.py @@ -3897,6 +3897,33 @@ def getImagesFromAnHash(self, hash_found=None): return self.getFilesFromAnHash(hash_found)
+ def is_uploaddisabled(self): + """Return True if upload is disabled on site. + + If not called directly, it is cached by the first attempted + upload action. + + """ + if hasattr(self, '_uploaddisabled'): + return self._uploaddisabled + else: + # attempt a fake upload; on enabled sites will fail for: + # missingparam: One of the parameters + # filekey, file, url, statuskey is required + # TODO: is there another way? + try: + dummy = pywikibot.FilePage(self, title='dummy') + token = self.token(dummy, 'edit') + req = api.Request(site=self, action="upload", + token=token, throttle=False) + req.submit() + except api.APIError as error: + if error.code == u'uploaddisabled': + self._uploaddisabled = True + else: + self._uploaddisabled = False + return self._uploaddisabled + @deprecate_arg('imagepage', 'filepage') def upload(self, filepage, source_filename=None, source_url=None, comment=None, text=None, watch=False, ignore_warnings=False, @@ -3923,6 +3950,7 @@ and the chunk size is positive but lower than the file size. @type chunk_size: int """ + upload_warnings = { # map API warning codes to user error messages # %(msg)s will be replaced by message string from API responsse @@ -3980,8 +4008,14 @@ req.mime_params['chunk'] = (chunk, None, {'filename': req.params['filename']}) if file_key: req['filekey'] = file_key - # TODO: Proper error and warning handling - data = req.submit()['upload'] + try: + data = req.submit()['upload'] + self._uploaddisabled = False + except api.APIError as error: + # TODO: catch and process foreseeable errors + if error.code == u'uploaddisabled': + self._uploaddisabled = True + raise error if 'warnings' in data: result = data break @@ -4016,11 +4050,15 @@ req["ignorewarnings"] = "" try: result = req.submit() - except api.APIError: + self._uploaddisabled = False + except api.APIError as error: # TODO: catch and process foreseeable errors - raise + if error.code == u'uploaddisabled': + self._uploaddisabled = True + raise error result = result["upload"] - pywikibot.debug(result, _logger) + pywikibot.debug(result, _logger) + if "warnings" in result: warning = list(result["warnings"].keys())[0] message = result["warnings"][warning] diff --git a/scripts/upload.py b/scripts/upload.py index 5ab1607..2b6436e 100755 --- a/scripts/upload.py +++ b/scripts/upload.py @@ -270,7 +270,12 @@ else: pywikibot.output(u"Upload aborted.") return - + except pywikibot.data.api.APIError as error: + if error.code == u'uploaddisabled': + pywikibot.error("Upload error: Local file uploads are disabled on %s." + % site) + else: + pywikibot.error("Upload error: ", exc_info=True) except Exception: pywikibot.error("Upload error: ", exc_info=True)
diff --git a/tests/site_tests.py b/tests/site_tests.py index 125b6aa..df636c2 100644 --- a/tests/site_tests.py +++ b/tests/site_tests.py @@ -16,7 +16,7 @@
import pywikibot from pywikibot.exceptions import Error, NoPage -from tests.utils import PywikibotTestCase, unittest +from tests.utils import SiteTestCase, PywikibotTestCase, unittest
if sys.version_info[0] > 2: basestring = (str, ) @@ -1179,6 +1179,16 @@ self.assertEqual(ll.site.family.name, 'wikipedia')
+class TestUploadEnabledSite(SiteTestCase): + + def test_is_uploaddisabled(self): + site = pywikibot.Site('commons', 'commons') + self.assertFalse(site.is_uploaddisabled()) + + site = pywikibot.Site('wikidata', 'wikidata') + self.assertTrue(site.is_uploaddisabled()) + + if __name__ == '__main__': try: unittest.main()