def upload(self, file=None, filename=None, description='', ignore=False, file_size=None, url=None, filekey=None, comment=None): """Upload a file to the site. Note that one of `file`, `filekey` and `url` must be specified, but not more than one. For normal uploads, you specify `file`. Args: file (str): File object or stream to upload. filename (str): Destination filename, don't include namespace prefix like 'File:' description (str): Wikitext for the file description page. ignore (bool): True to upload despite any warnings. file_size (int): Deprecated in mwclient 0.7 url (str): URL to fetch the file from. filekey (str): Key that identifies a previous upload that was stashed temporarily. comment (str): Upload comment. Also used as the initial page text for new files if `description` is not specified. Example: >>> client.upload(open('somefile', 'rb'), filename='somefile.jpg', description='Some description') Returns: JSON result from the API. Raises: errors.InsufficientPermission requests.exceptions.HTTPError """ if file_size is not None: # Note that DeprecationWarning is hidden by default since Python 2.7 warnings.warn('file_size is deprecated since mwclient 0.7', DeprecationWarning) if filename is None: raise TypeError('filename must be specified') if len([x for x in [file, filekey, url] if x is not None]) != 1: raise TypeError( "exactly one of 'file', 'filekey' and 'url' must be specified") image = self.Images[filename] if not image.can('upload'): raise errors.InsufficientPermission(filename) if comment is None: comment = description text = None else: comment = comment text = description if file is not None: if not hasattr(file, 'read'): file = open(file, 'rb') content_size = file.seek(0, 2) file.seek(0) if self.version[:2] >= (1, 20) and content_size > self.chunk_size: return self.chunk_upload(file, filename, ignore, comment, text) predata = { 'action': 'upload', 'format': 'json', 'filename': filename, 'comment': comment, 'text': text, 'token': image.get_token('edit'), } if ignore: predata['ignorewarnings'] = 'true' if url: predata['url'] = url # sessionkey was renamed to filekey in MediaWiki 1.18 # https://phabricator.wikimedia.org/rMW5f13517e36b45342f228f3de4298bb0fe186995d if self.version[:2] < (1, 18): predata['sessionkey'] = filekey else: predata['filekey'] = filekey postdata = predata files = None if file is not None: # Workaround for https://github.com/mwclient/mwclient/issues/65 # ---------------------------------------------------------------- # Since the filename in Content-Disposition is not interpreted, # we can send some ascii-only dummy name rather than the real # filename, which might contain non-ascii. files = {'file': ('fake-filename', file)} sleeper = self.sleepers.make() while True: data = self.raw_call('api', postdata, files) info = json.loads(data) if not info: info = {} if self.handle_api_result(info, kwargs=predata, sleeper=sleeper): response = info.get('upload', {}) break if file is not None: file.close() return response
def upload(self, file=None, filename=None, description='', ignore=False, file_size=None, url=None, filekey=None, comment=None): """ Uploads a file to the site. Returns JSON result from the API. Can raise `errors.InsufficientPermission` and `requests.exceptions.HTTPError`. : Parameters : - file : File object or stream to upload. - filename : Destination filename, don't include namespace prefix like 'File:' - description : Wikitext for the file description page. - ignore : True to upload despite any warnings. - file_size : Deprecated in mwclient 0.7 - url : URL to fetch the file from. - filekey : Key that identifies a previous upload that was stashed temporarily. - comment : Upload comment. Also used as the initial page text for new files if `description` is not specified. Note that one of `file`, `filekey` and `url` must be specified, but not more than one. For normal uploads, you specify `file`. Example: >>> client.upload(open('somefile', 'rb'), filename='somefile.jpg', description='Some description') """ if file_size is not None: # Note that DeprecationWarning is hidden by default since Python 2.7 warnings.warn( 'file_size is deprecated since mwclient 0.7', DeprecationWarning ) file_size = None if filename is None: raise TypeError('filename must be specified') if len([x for x in [file, filekey, url] if x is not None]) != 1: raise TypeError("exactly one of 'file', 'filekey' and 'url' must be specified") image = self.Images[filename] if not image.can('upload'): raise errors.InsufficientPermission(filename) predata = {} if comment is None: predata['comment'] = description else: predata['comment'] = comment predata['text'] = description if ignore: predata['ignorewarnings'] = 'true' predata['token'] = image.get_token('edit') predata['action'] = 'upload' predata['format'] = 'json' predata['filename'] = filename if url: predata['url'] = url # Renamed from sessionkey to filekey # https://git.wikimedia.org/commit/mediawiki%2Fcore.git/5f13517e if self.version[:2] < (1, 18): predata['sessionkey'] = filekey else: predata['filekey'] = filekey postdata = predata files = None if file is not None: # Workaround for https://github.com/mwclient/mwclient/issues/65 # ---------------------------------------------------------------- # Since the filename in Content-Disposition is not interpreted, # we can send some ascii-only dummy name rather than the real # filename, which might contain non-ascii. file = ('fake-filename', file) # End of workaround # ---------------------------------------------------------------- files = {'file': file} sleeper = self.sleepers.make() while True: data = self.raw_call('api', postdata, files) info = json.loads(data) if not info: info = {} if self.handle_api_result(info, kwargs=predata, sleeper=sleeper): return info.get('upload', {})