Revision: 7558
Author: russblau
Date: 2009-10-28 20:14:24 +0000 (Wed, 28 Oct 2009)
Log Message:
-----------
First implementation of API uploading, and port of scripts/upload.py
Modified Paths:
--------------
branches/rewrite/pywikibot/data/api.py
branches/rewrite/pywikibot/exceptions.py
branches/rewrite/pywikibot/site.py
branches/rewrite/scripts/upload.py
Modified: branches/rewrite/pywikibot/data/api.py
===================================================================
--- branches/rewrite/pywikibot/data/api.py 2009-10-28 18:12:26 UTC (rev 7557)
+++ branches/rewrite/pywikibot/data/api.py 2009-10-28 20:14:24 UTC (rev 7558)
@@ -16,6 +16,7 @@
except ImportError:
import simplejson as json
import logging
+import mimetypes
import re
import traceback
import time
@@ -61,14 +62,20 @@
Attributes of this object (except for the special parameters listed
below) get passed as commands to api.php, and can be get or set using
the dict interface. All attributes must be strings (or unicode). Use
- an empty string for parameters that don't require a value (e.g.,
- "action=query&...&redirects").
+ an empty string for parameters that don't require a value. For example,
+ Request(action="query", titles="Foo bar", prop="info",
redirects="")
+ corresponds to the API request
+ "api.php?action=query&titles=Foo%20bar&prop=info&redirects"
This is the lowest-level interface to the API, and can be used for any
request that a particular site's API supports. See the API documentation
(
http://www.mediawiki.org/wiki/API) and site-specific settings for
details on what parameters are accepted for each request type.
+ Uploading files is a special case: to upload, the parameter "mime" must
+ be true, and the parameter "file" must be set equal to a valid
+ filename on the local computer, _not_ to the content of the file.
+
Returns a dict containing the JSON data returned by the wiki. Normally,
one of the dict keys will be equal to the value of the 'action'
parameter. Errors are caught and raise an APIError exception.
@@ -95,6 +102,7 @@
@param site: The Site to which the request will be submitted. If not
supplied, uses the user's configured default Site.
+ @param mime: If true, send in "multipart/form-data" format (default False)
@param max_retries: (optional) Maximum number of times to retry after
errors, defaults to 25
@param retry_wait: (optional) Minimum time to wait after an error,
@@ -108,6 +116,7 @@
self.site = kwargs.pop("site")
except KeyError:
self.site = pywikibot.Site()
+ self.mime = kwargs.pop("mime", False)
self.max_retries = kwargs.pop("max_retries", 25)
self.retry_wait = kwargs.pop("retry_wait", 5)
self.params = {}
@@ -199,7 +208,6 @@
"protect", "block", "unblock"
)
self.site.throttle(write=write)
- mime = False # debugging
uri = self.site.scriptpath() + "/api.php"
try:
ssl = False
@@ -208,15 +216,32 @@
ssl = True
elif config.use_SSL_always:
ssl = True
- if mime:
- global container
+ if self.mime:
# construct a MIME message containing all API key/values
container = MIMEMultipart(_subtype='form-data')
for key in self.params:
- submsg = MIMENonMultipart("text", "plain")
- submsg.add_header("Content-disposition",
"form-data",
- name=key)
- submsg.set_payload(self.params[key])
+ # key "file" requires special treatment in a multipart
+ # message
+ if key == "file":
+ local_filename = self.params[key]
+ filetype = mimetypes.guess_type(local_filename)[0] \
+ or 'application/octet-stream'
+ file_content = file(local_filename, "rb").read()
+ submsg = MIMENonMultipart(*filetype.split("/"))
+ submsg.add_header("Content-disposition",
+ "form-data", name=key,
+ filename=local_filename)
+ submsg.set_payload(file_content)
+ else:
+ try:
+ self.params[key].encode("ascii")
+ keytype = ("text", "plain")
+ except UnicodeError:
+ keytype = ("application",
"octet-stream")
+ submsg = MIMENonMultipart(*keytype)
+ submsg.add_header("Content-disposition",
"form-data",
+ name=key)
+ submsg.set_payload(self.params[key])
container.attach(submsg)
# strip the headers to get the HTTP message body
body = container.as_string()
Modified: branches/rewrite/pywikibot/exceptions.py
===================================================================
--- branches/rewrite/pywikibot/exceptions.py 2009-10-28 18:12:26 UTC (rev 7557)
+++ branches/rewrite/pywikibot/exceptions.py 2009-10-28 20:14:24 UTC (rev 7558)
@@ -116,3 +116,6 @@
class CaptchaError(Error):
"""Captcha is asked and config.solve_captcha ==
False."""
+class UploadWarning(Error):
+ """Upload failed with a warning message (passed as the
argument)."""
+
Modified: branches/rewrite/pywikibot/site.py
===================================================================
--- branches/rewrite/pywikibot/site.py 2009-10-28 18:12:26 UTC (rev 7557)
+++ branches/rewrite/pywikibot/site.py 2009-10-28 20:14:24 UTC (rev 7558)
@@ -2545,7 +2545,107 @@
return [image.title(withNamespace=False)
for image in self.allimages(sha1=hash_found)]
+ def upload(self, imagepage, source_filename=None, source_url=None,
+ comment=None, watch=False, ignore_warnings=False):
+ """Upload a file to the wiki.
+ Either source_filename or source_url, but not both, must be provided.
+
+ @param imagepage: an ImagePage object from which the wiki-name of the
+ file will be obtained.
+ @param source_filename: path to the file to be uploaded
+ @param source_url: URL of the file to be uploaded
+ @param comment: Edit summary; if this is not provided, then
+ imagepage.text will be used. An empty summary is not permitted.
+ @param watch: If true, add imagepage to the bot user's watchlist
+ @param ignore_warnings: if true, ignore API warnings and force
+ upload (for example, to overwrite an existing file); default False
+
+ """
+ upload_warnings = {
+ # map API warning codes to user error messages
+ # %(msg)s will be replaced by message string from API responsse
+ 'duplicate-archive':
+ "The file is a duplicate of a deleted file %(msg)s.",
+ 'was-deleted':
+ "The file %(msg)s was previously deleted.",
+ 'emptyfile':
+ "File %(msg)s is empty.",
+ 'exists':
+ "File %(msg)s already exists.",
+ 'duplicate':
+ "Uploaded file is a duplicate of %(msg)s.",
+ 'badfilename':
+ "Target filename is invalid.",
+ 'filetype-unwanted-type':
+ "File %(msg)s type is unwatched type.",
+ }
+
+ # check for required user right
+ if "upload" not in self.userinfo["rights"]:
+ raise pywikibot.Error(
+ "User '%s' does not have upload rights on site %s."
+ % (self.user(), self))
+ # check for required parameters
+ if (source_filename and source_url)\
+ or (source_filename is None and source_url is None):
+ raise ValueError(
+"APISite.upload: must provide either source_filename or source_url, not both."
+ )
+ if comment is None:
+ comment = imagepage.text
+ if not comment:
+ raise ValueError(
+"APISite.upload: cannot upload file without a summary/description."
+ )
+ token = self.token(imagepage, "edit")
+ if source_filename:
+ # upload local file
+ # make sure file actually exists
+ if not os.path.isfile(source_filename):
+ raise ValueError("File '%s' does not exist."
+ % source_filename)
+ filesize = os.path.getsize(source_filename)
+ # TODO: if file size exceeds some threshold (to be determined),
+ # upload by chunks
+ req = api.Request(site=self, action="upload", token=token,
+ filename=imagepage.title(withNamespace=False),
+ file=source_filename, comment=comment,
+ mime=True)
+ else:
+ # upload by URL
+ if "upload_by_url" not in self.userinfo["rights"]:
+ raise pywikibot.Error(
+ "User '%s' is not authorized to upload by URL on site
%s."
+ % (self.user(), self))
+ req = api.Request(site=self, action="upload", token=token,
+ filename=imagepage.title(withNamespace=False),
+ url=source_url, comment=comment)
+ if watch:
+ req["watch"] = ""
+ if ignore_warnings:
+ req["ignorewarnings"] = ""
+ try:
+ result = req.submit()
+ except api.APIError, err:
+ # TODO: catch and process foreseeable errors
+ raise
+ result = result["upload"]
+ pywikibot.output(result, level=pywikibot.DEBUG)
+ if "warnings" in result:
+ warning = result["warnings"].keys()[0]
+ message = result["warnings"][warning]
+ raise pywikibot.UploadWarning(upload_warnings[warning]
+ % {'msg': message})
+ else:
+ pywikibot.output(u"Upload: unrecognized response: %s"
+ % result["result"])
+ if result["result"] == "Success":
+ pywikibot.output(u"Upload successful.")
+ imagepage._imageinfo = result["imageinfo"]
+ return
+
+
#### METHODS NOT IMPLEMENTED YET ####
class NotImplementedYet:
Modified: branches/rewrite/scripts/upload.py
===================================================================
--- branches/rewrite/scripts/upload.py 2009-10-28 18:12:26 UTC (rev 7557)
+++ branches/rewrite/scripts/upload.py 2009-10-28 20:14:24 UTC (rev 7558)
@@ -6,15 +6,16 @@
-keep Keep the filename as is
-filename Target filename
- -noverify Do not ask for verification of the upload description if one is given
+ -noverify Do not ask for verification of the upload description if one
+ is given
-If any other arguments are given, the first is the URL or filename
-to upload, and the rest is a proposed description to go with the
-upload. If none of these are given, the user is asked for the
-file or URL to upload. The bot will then upload the image to the wiki.
+If any other arguments are given, the first is the URL or filename to
+upload, and the rest is a proposed description to go with the upload. If
+none of these are given, the user is asked for the file or URL to upload.
+The bot will then upload the image to the wiki.
-The script will ask for the location of an image, if not given as a parameter,
-and for a description.
+The script will ask for the location of an image, if not given as a
+parameter, and for a description.
"""
#
# (C) Rob W.W. Hooft, Andre Engels 2003-2004
@@ -23,58 +24,26 @@
#
__version__='$Id$'
+
import os, sys, time
-import urllib, mimetypes
-import wikipedia, config, query
+import urllib
+import urlparse
+import tempfile
+import pywikibot
+from pywikibot import config
-def post_multipart(site, address, fields, files, cookies):
- """
- Post fields and files to an http host as multipart/form-data.
- fields is a sequence of (name, value) elements for regular form fields.
- files is a sequence of (name, filename, value) elements for data to be uploaded as
files
- Return the server's response page.
- """
- contentType, body = encode_multipart_formdata(fields, files)
- return site.postData(address, body, contentType = contentType, cookies = cookies)
-def encode_multipart_formdata(fields, files):
- """
- fields is a sequence of (name, value) elements for regular form fields.
- files is a sequence of (name, filename, value) elements for data to be uploaded as
files
- Return (content_type, body) ready for httplib.HTTP instance
- """
- boundary = '----------ThIs_Is_tHe_bouNdaRY_$'
- lines = []
- for (key, value) in fields:
- lines.append('--' + boundary)
- lines.append('Content-Disposition: form-data; name="%s"' %
key)
- lines.append('')
- lines.append(value)
- for (key, filename, value) in files:
- lines.append('--' + boundary)
- lines.append('Content-Disposition: form-data; name="%s";
filename="%s"' % (key, filename))
- lines.append('Content-Type: %s' % get_content_type(filename))
- lines.append('')
- lines.append(value)
- lines.append('--' + boundary + '--')
- lines.append('')
- body = '\r\n'.join(lines)
- content_type = 'multipart/form-data; boundary=%s' % boundary
- return content_type, body
-
-def get_content_type(filename):
- return mimetypes.guess_type(filename)[0] or 'application/octet-stream'
-
-
class UploadRobot:
- def __init__(self, url, urlEncoding = None, description = u'', useFilename =
None, keepFilename = False,
- verifyDescription = True, ignoreWarning = False, targetSite = None,
uploadByUrl = False):
+ def __init__(self, url, urlEncoding=None, description=u'',
+ useFilename=None, keepFilename=False,
+ verifyDescription=True, ignoreWarning=False,
+ targetSite=None, uploadByUrl=False):
"""
ignoreWarning - Set this to True if you want to upload even if another
file would be overwritten or another mistake would be
risked.
+
"""
- self._retrieved = False
self.url = url
self.urlEncoding = urlEncoding
self.description = description
@@ -83,321 +52,203 @@
self.verifyDescription = verifyDescription
self.ignoreWarning = ignoreWarning
if config.upload_to_commons:
- self.targetSite = targetSite or wikipedia.getSite('commons',
'commons')
+ self.targetSite = targetSite or pywikibot.Site('commons',
'commons')
else:
- self.targetSite = targetSite or wikipedia.getSite()
+ self.targetSite = targetSite or pywikibot.Site()
self.targetSite.forceLogin()
self.uploadByUrl = uploadByUrl
def urlOK(self):
- '''
- Returns true iff the URL references an online site or an
- existing local file.
- '''
- return self.url != '' and ('://' in self.url or
os.path.exists(self.url))
+ "Return true iff self.url looks like an URL or an existing local
file."
+ return "://" in self.url or os.path.exists(self.url)
def read_file_content(self):
- if not self._retrieved or self.uploadByUrl:
- # Get file contents
- wikipedia.output(u'Reading file %s' % self.url)
- if '://' in self.url:
- resume = False
- dt = 15
+ """Return name of temp file in which remote file is
saved."""
+ pywikibot.output(u'Reading file %s' % self.url)
+ resume = False
+ dt = 15
+ uo = urllib.URLopener()
+ retrieved = False
- while not self._retrieved:
- uo = wikipedia.MyURLopener()
- if resume:
- wikipedia.output(u"Resume download...")
- uo.addheader('Range', 'bytes=%s-' % rlen)
+ while not retrieved:
+ if resume:
+ pywikibot.output(u"Resume download...")
+ uo.addheader('Range', 'bytes=%s-' % rlen)
- file = uo.open(self.url)
+ infile = uo.open(self.url)
- if 'text/html' in
file.info().getheader('Content-Type'):
- print "Couldn't download the image: the requested URL
was not found on this server."
- return
+ if 'text/html' in infile.info().getheader('Content-Type'):
+ print \
+"Couldn't download the image: the requested URL was not found on server."
+ return
- content_len = file.info().getheader('Content-Length')
- accept_ranges = file.info().getheader('Accept-Ranges') ==
'bytes'
+ content_len = infile.info().getheader('Content-Length')
+ accept_ranges = infile.info().getheader('Accept-Ranges') ==
'bytes'
- if resume:
- self._contents += file.read()
- else:
- self._contents = file.read()
+ if resume:
+ _contents += infile.read()
+ else:
+ _contents = infile.read()
- file.close()
- self._retrieved = True
+ infile.close()
+ retrieved = True
- if content_len:
- rlen = len(self._contents)
- content_len = int(content_len)
- if rlen < content_len:
- self._retrieved = False
- wikipedia.output(u"Connection closed at byte %s (%s
left)" % (rlen, content_len))
- if accept_ranges and rlen > 0:
- resume = True
- wikipedia.output(u"Sleeping for %d seconds..." %
dt)
- time.sleep(dt)
- if dt <= 60:
- dt += 15
- elif dt < 360:
- dt += 60
- else:
- if wikipedia.verbose:
- wikipedia.output(u"WARNING: No check length to retrieved
data is possible.")
+ if content_len:
+ rlen = len(_contents)
+ content_len = int(content_len)
+ if rlen < content_len:
+ retrieved = False
+ pywikibot.output(
+ u"Connection closed at byte %s (%s left)"
+ % (rlen, content_len))
+ if accept_ranges and rlen > 0:
+ resume = True
+ pywikibot.output(u"Sleeping for %d seconds..." % dt)
+ time.sleep(dt)
+ if dt <= 60:
+ dt += 15
+ elif dt < 360:
+ dt += 60
else:
- # Opening local files with MyURLopener would be possible, but we
- # don't do it because it only accepts ASCII characters in the
- # filename.
- file = open(self.url,"rb")
- self._contents = file.read()
- file.close()
-
+ pywikibot.output(
+ u"WARNING: No check length to retrieved data is
possible.",
+ level=pywikibot.VERBOSE)
+ handle, tempname = tempfile.mkstemp()
+ t = os.fdopen(handle, "wb")
+ t.write(_contents)
+ t.close()
+ return tempname
+
def process_filename(self):
+ """Return base filename portion of self.url"""
# Isolate the pure name
filename = self.url
-
- if '/' in filename:
- filename = filename.split('/')[-1]
-
- if '\\' in filename:
- filename = filename.split('\\')[-1]
-
- if self.urlEncoding:
- filename = urllib.unquote(filename.decode(self.urlEncoding))
-
+ # Filename may be either a local file path or a URL
+ if "://" in filename:
+ # extract the path portion of the URL
+ filename = urlparse.urlparse(filename).path
+ filename = os.path.basename(filename)
+
if self.useFilename:
filename = self.useFilename
if not self.keepFilename:
- wikipedia.output(u"The filename on the target wiki will default to:
%s" % filename)
- # ask newfn until it's valid
- ok = False
+ pywikibot.output(
+ u"The filename on the target wiki will default to: %s"
+ % filename)
# FIXME: these 2 belong somewhere else, presumably in family
forbidden = '/' # to be extended
- allowed_formats = (u'gif', u'jpg', u'jpeg',
u'mid', u'midi', u'ogg', u'png', u'svg',
u'xcf', u'djvu')
- while not ok:
- ok = True
- newfn = wikipedia.input(u'Enter a better name, or press enter to
accept:')
+ allowed_formats = (u'gif', u'jpg', u'jpeg',
u'mid', u'midi',
+ u'ogg', u'png', u'svg',
u'xcf', u'djvu')
+ # ask until it's valid
+ while True:
+ newfn = pywikibot.input(
+ u'Enter a better name, or press enter to accept:')
if newfn == "":
newfn = filename
+ break
ext = os.path.splitext(newfn)[1].lower().strip('.')
- for c in forbidden:
- if c in newfn:
- print "Invalid character: %s. Please try again" % c
- ok = False
- if ext not in allowed_formats and ok:
- choice = wikipedia.inputChoice(u"File format is not one of [%s],
but %s. Continue?" % (u' '.join(allowed_formats), ext), ['yes',
'no'], ['y', 'N'], 'N')
+ # are any chars in forbidden also in newfn?
+ invalid = set(forbidden) & set(newfn)
+ if invalid:
+ c = "".join(invalid)
+ print "Invalid character(s): %s. Please try again" % c
+ continue
+ if ext not in allowed_formats:
+ choice = pywikibot.inputChoice(
+ u"File format is not one of [%s], but %s. Continue?"
+ % (u' '.join(allowed_formats), ext),
+ ['yes', 'no'], ['y', 'N'],
'N')
if choice == 'n':
- ok = False
+ continue
+ break
if newfn != '':
filename = newfn
- # MediaWiki doesn't allow spaces in the file name.
- # Replace them here to avoid an extra confirmation form
- filename = filename.replace(' ', '_')
# A proper description for the submission.
- wikipedia.output(u"The suggested description is:")
- wikipedia.output(self.description)
+ pywikibot.output(u"The suggested description is:")
+ pywikibot.output(self.description)
if self.verifyDescription:
- newDescription = u''
- choice = wikipedia.inputChoice(u'Do you want to change this
description?', ['Yes', 'No'], ['y', 'N'],
'n')
- if choice == 'y':
- import editarticle
- editor = editarticle.TextEditor()
- newDescription = editor.edit(self.description)
- # if user saved / didn't press Cancel
- if newDescription:
- self.description = newDescription
+ newDescription = u''
+ choice = pywikibot.inputChoice(
+ u'Do you want to change this description?',
+ ['Yes', 'No'], ['y', 'N'], 'n')
+ if choice == 'y':
+ import editarticle
+ editor = editarticle.TextEditor()
+ newDescription = editor.edit(self.description)
+ # if user saved / didn't press Cancel
+ if newDescription:
+ self.description = newDescription
return filename
-
+
def upload_image(self, debug=False):
- """Gets the image at URL self.url, and uploads it to the target
wiki.
- Returns the filename which was used to upload the image.
- If the upload fails, the user is asked whether to try again or not.
- If the user chooses not to retry, returns null.
+ """Upload the image at self.url to the target wiki.
+
+ Return the filename that was used to upload the image.
+ If the upload fails, ask the user whether to try again or not.
+ If the user chooses not to retry, return null.
+
"""
- try:
- if config.use_api and self.targetSite.versionnumber() >= 16:
- x = self.targetSite.api_address()
- del x
- else:
- raise NotImplementedError
- except NotImplementedError:
- return self._uploadImageOld(debug)
-
- if not hasattr(self,'_contents'):
- self.read_file_content()
-
filename = self.process_filename()
-
- params = {
- 'action': 'upload',
- 'token': self.targetSite.getToken(),
- 'comment': self.description,
- 'filename': filename,
- #'': '',
- }
- if self.uploadByUrl:
- params['url'] = self.url
- else:
- params['file'] = self._contents
-
- if self.ignoreWarning:
- params['ignorewarnings'] = 1
-
- wikipedia.output(u'Uploading file to %s via API....' % self.targetSite)
-
- data = query.GetData(params, self.targetSite)
-
- if wikipedia.verbose:
- wikipedia.output("%s" % data)
-
- if 'error' in data: # error occured
- errCode = data['error']['code']
- wikipedia.output("%s" % data)
- else:
- data = data['upload']
- if data['result'] == u'Warning': #upload success but return
warning.
- warn = data['warnings'].keys()[0]
- wikipedia.output("We got a warning message:", newline=False)
- warFn = data['warnings'][warn]
- if warn == 'duplicate-archive':
- wikipedia.output("The file is duplicate a deleted file %s."
% warFn)
- elif warn == 'was-deleted':
- wikipedia.output("This file was deleted for %s." % warFn)
- elif warn == 'emptyfile':
- wikipedia.output("File %s is an empty file." % warFn)
- elif warn == 'exists':
- wikipedia.output("File %s is exists." % warFn)
- elif warn == 'duplicate':
- wikipedia.output("Uploaded file is duplicate with %s." %
warFn)
- elif warn == 'badfilename':
- wikipedia.output("Target filename is invaild.")
- elif warn == 'filetype-unwanted-type':
- wikipedia.output("File %s type is unwatched type." %
warFn)
- answer = wikipedia.inputChoice(u"Do you want to ignore?",
['Yes', 'No'], ['y', 'N'], 'N')
- if answer == "y":
- self.ignoreWarning = 1
- self.keepFilename = True
- return self.upload_image(debug)
- else:
- wikipedia.output("Upload aborted.")
- return
-
- elif data['result'] == u'Success': #No any warning, upload
and online complete.
- wikipedia.output(u"Upload successful.")
- return filename #data['filename']
-
- def _uploadImageOld(self, debug=False):
- if not hasattr(self,'_contents'):
- self.read_file_content()
-
- filename = self.process_filename()
- # Convert the filename (currently Unicode) to the encoding used on the
- # target wiki
- encodedFilename = filename.encode(self.targetSite.encoding())
+ site = self.targetSite
+ imagepage = pywikibot.ImagePage(site, filename) # normalizes filename
+ imagepage.text = self.description
+ pywikibot.output(u'Uploading file to %s via API....' % site)
- formdata = {
- 'wpUploadDescription': self.description,
- 'wpUploadAffirm': '1',
- 'wpUpload': 'upload bestand',
- 'wpEditToken': self.targetSite.getToken(), # Get an edit token so we
can do the upload
- 'wpDestFile': filename, # Set the new filename
- }
- # This somehow doesn't work.
- if self.ignoreWarning:
- formdata["wpIgnoreWarning"] = "1"
-
- if self.uploadByUrl:
- formdata["wpUploadFileURL"] = self.url
- formdata["wpSourceType"] = 'Url'
-
- # try to encode the strings to the encoding used by the target site.
- # if that's not possible (e.g. because there are non-Latin-1 characters and
- # the home Wikipedia uses Latin-1), convert all non-ASCII characters to
- # HTML entities.
- for key in formdata:
- assert isinstance(key, basestring), "ERROR: %s is not a string but
%s" % (key, type(key))
- try:
- formdata[key] = formdata[key].encode(self.targetSite.encoding())
- except (UnicodeEncodeError, UnicodeDecodeError):
- formdata[key] =
wikipedia.UnicodeToAsciiHtml(formdata[key]).encode(self.targetSite.encoding())
-
- # don't upload if we're in debug mode
- if not debug:
- wikipedia.output(u'Uploading file to %s...' % self.targetSite)
-
+ try:
if self.uploadByUrl:
- # Just do a post with all the fields filled out
- response, returned_html =
self.targetSite.postForm(self.targetSite.upload_address(), formdata.items(), cookies =
self.targetSite.cookies())
+ site.upload(imagepage, source_url=self.url,
+ ignore_warnings=self.ignoreWarning)
else:
- response, returned_html = post_multipart(self.targetSite,
self.targetSite.upload_address(),
- formdata.items(), (('wpUploadFile',
encodedFilename, self._contents),),
- cookies = self.targetSite.cookies())
- # There are 2 ways MediaWiki can react on success: either it gives
- # a 200 with a success message, or it gives a 302 (redirection).
- # Do we know how the "success!" HTML page should look like?
- # ATTENTION: if you changed your Wikimedia Commons account not to show
- # an English interface, this detection will fail!
- success_msg = self.targetSite.mediawiki_message('successfulupload')
- if success_msg in returned_html or response.status == 302:
- wikipedia.output(u"Upload successful.")
- # The following is not a good idea, because the server also gives a 200 when
- # something went wrong.
- #if response.status in [200, 302]:
- # wikipedia.output(u"Upload successful.")
+ if "://" in self.url:
+ temp = self.read_file_content()
+ else:
+ temp = self.url
+ site.upload(imagepage, source_filename=temp,
+ ignore_warnings=self.ignoreWarning)
- elif response.status == 301:
- wikipedia.output(u"Following redirect...")
- address = response.getheader('Location')
- wikipedia.output(u"Changed upload address to %s. Please update
%s.py" % (address, self.targetSite.family.__module__))
- exec('self.targetSite.upload_address = lambda: %r' % address,
locals(), globals())
+ except pywikibot.UploadWarning, warn:
+ pywikibot.output(u"We got a warning message: ", newline=False)
+ pywikibot.output(str(warn))
+ answer = pywikibot.inputChoice(u"Do you want to ignore?",
+ ['Yes', 'No'], ['y',
'N'], 'N')
+ if answer == "y":
+ self.ignoreWarning = 1
+ self.keepFilename = True
return self.upload_image(debug)
else:
- try:
- # Try to find the error message within the HTML page.
- # If we can't find it, we just dump the entire HTML page.
- returned_html = returned_html[returned_html.index('<!-- start
content -->') + 22: returned_html.index('<!-- end content -->')]
- except:
- pass
- wikipedia.output(u'%s\n\n' % returned_html)
- wikipedia.output(u'%i %s' % (response.status, response.reason))
+ pywikibot.output(u"Upload aborted.")
+ return
+
+ except Exception, e:
+ pywikibot.logger.exception("Upload error: " + str(e))
- if self.targetSite.mediawiki_message('uploadwarning') in
returned_html:
- answer = wikipedia.inputChoice(u"You have recevied an upload
warning message. Ignore?", ['Yes', 'No'], ['y', 'N'],
'N')
- if answer == "y":
- self.ignoreWarning = 1
- self.keepFilename = True
- return self._uploadImageOld(debug)
- else:
- answer = wikipedia.inputChoice(u'Upload of %s probably failed.
Above you see the HTML page which was returned by MediaWiki. Try again?' % filename,
['Yes', 'No'], ['y', 'N'], 'N')
- if answer == "y":
- return self._uploadImageOld(debug)
- else:
- return
- return filename
+ else:
+ #No warning, upload complete.
+ pywikibot.output(u"Upload successful.")
+ return filename #data['filename']
def run(self):
while not self.urlOK():
if not self.url:
- wikipedia.output(u'No input filename given')
+ pywikibot.output(u'No input filename given')
else:
- wikipedia.output(u'Invalid input filename given. Try again.')
- self.url = wikipedia.input(u'File or URL where image is now:')
+ pywikibot.output(u'Invalid input filename given. Try again.')
+ self.url = pywikibot.input(u'File or URL where image is now:')
return self.upload_image()
-def main(args):
+
+def main(*args):
url = u''
description = []
keepFilename = False
useFilename = None
verifyDescription = True
- # call wikipedia.py function to process all global wikipedia args
+ # process all global bot args
# returns a list of non-global args, i.e. args for upload.py
- args = wikipedia.handleArgs()
-
- for arg in args:
+ for arg in pywikibot.handleArgs(*args):
if arg:
if arg.startswith('-keep'):
keepFilename = True
@@ -410,11 +261,13 @@
else:
description.append(arg)
description = u' '.join(description)
- bot = UploadRobot(url, description=description, useFilename=useFilename,
keepFilename=keepFilename, verifyDescription=verifyDescription)
+ bot = UploadRobot(url, description=description, useFilename=useFilename,
+ keepFilename=keepFilename,
+ verifyDescription=verifyDescription)
bot.run()
if __name__ == "__main__":
try:
- main(sys.argv[1:])
+ main()
finally:
- wikipedia.stopme()
+ pywikibot.stopme()