def uploadAttachedFilePatch(self, item, patchdata, fileinfo, algorithm='bsdiff'): """Upload a patch for an attached file already present on the server.""" #get upload authorization #post file or patch uaparams = { 'target': 'item', 'targetModifier': 'file', 'itemKey': item.get('itemKey') } reqUrl = self.apiRequestString(uaparams) uaPostData = urllib.urlencode(fileinfo) uploadAuthResponse = zrequest(reqUrl, 'POST', uaPostData, {'If-Match': item.get('md5')}) if uploadAuthResponse.status_code != 200: logging.info('upload new attached file - uploadAuthResponse: ') logging.info(uploadAuthResponse.status_code) logging.info(uploadAuthResponse.text) raise zotero.ZoteroApiError("Upload Authorization Failed") #patch upload upAuthOb = json.loads(uploadAuthResponse.text) if 'exists' in upAuthOb and upAuthOb['exists'] == 1: #file already exists with this hash return None upparams = { 'target': 'item', 'targetModifier': 'file', 'itemKey': item.get('itemKey'), 'upload': upAuthOb['uploadKey'], 'algorithm': algorithm } uploadUrl = self.apiRequestString(upparams) logging.info(upAuthOb) #uploadBody = bytearray(upAuthOb['prefix'].encode()) #uploadBody.extend(patchdata) #uploadBody.extend(bytearray(upAuthOb['suffix'].encode())) uploadBody = bytearray(patchdata) logging.info(uploadBody) logging.info(upAuthOb['contentType']) uploadResponse = zrequest(uploadUrl, 'PATCH', uploadBody, { 'Content-Type': upAuthOb['contentType'], 'If-Match': item.get('md5') }) if uploadResponse.status_code != 204: logging.info(uploadResponse.status_code) logging.info(uploadResponse.text) raise zotero.ZoteroApiError( "Error uploading or applying attachment file patch") return True
def uploadNewAttachedFile(self, item, filedata, fileinfo): """Create an attachment item as a child of the passed item and upload a file as the attachment. """ #get upload authorization #post file or patch uaparams = { 'target': 'item', 'targetModifier': 'file', 'itemKey': item.get('itemKey') } reqUrl = self.apiRequestString(uaparams) uaPostData = urllib.urlencode(fileinfo) uploadAuthResponse = zrequest(reqUrl, 'POST', uaPostData, {'If-None-Match': '*'}) if uploadAuthResponse.status_code != 200: logging.info('upload new attached file - uploadAuthResponse: ') logging.info(uploadAuthResponse.status_code) logging.info(uploadAuthResponse.text) raise zotero.ZoteroApiError("Upload Authorization Failed") #full upload upAuthOb = json.loads(uploadAuthResponse.text) if 'exists' in upAuthOb and upAuthOb['exists'] == 1: #file already exists with this hash return None #uploadBody = u'' + upAuthOb['prefix'] + filedata + upAuthOb['suffix'] uploadBody = bytearray(upAuthOb['prefix'].encode()) uploadBody.extend(filedata) uploadBody.extend(bytearray(upAuthOb['suffix'].encode())) uploadResponse = zrequest(upAuthOb['url'], 'POST', uploadBody, {'Content-Type': upAuthOb['contentType']}) if uploadResponse.status_code != 201: raise zotero.ZoteroApiError("Error uploading attachment file") ucparams = { 'target': 'item', 'targetModifier': 'file', 'itemKey': item.get('itemKey') } ucReqUrl = self.apiRequestString(ucparams) registerUploadBody = uaPostData = urllib.urlencode( {'upload': upAuthOb['uploadKey']}) ucResponse = zrequest( ucReqUrl, 'POST', registerUploadBody, { 'Content-Type': 'application/x-www-form-urlencoded', 'If-None-Match': '*' }) if ucResponse.status_code != 204: raise zotero.ZoteroApiError( "Error confirming upload to Zotero API - " + ucResponse.text) return True
def updateObjectsFromWriteResponse(objsArray, response): data = json.loads(response.text) if (response.status_code == 200): newLastModifiedVersion = response.headers["Last-Modified-Version"] if 'success' in data: for ind in data['success'].keys(): key = data['success'][ind] i = int(ind) obj = objsArray[i] objKey = obj.get('key') if objKey != '' and objKey != key: raise zotero.ZoteroApiError( "Item key mismatch in multi-write request") if objKey == '': obj.set('key', key) obj.set('version', newLastModifiedVersion) obj.synced = True obj.writeFailure = False if 'failed' in data: for ind in data['failed'].keys(): val = data['failed'][ind] i = int(ind) obj = objsArray[i] obj.writeFailure = val elif response.status_code == 204: objsArray[0].synced = True
def getCreatorFields(self, creatorType): """Get the list of creator fields and translations for a particular creator type.""" reqUrl = zotero.ZOTERO_URI + 'creatorFields' response = self._request(reqUrl, 'GET') if response.status_code != 200: raise zotero.ZoteroApiError("failed to fetch creatorFields") creatorFields = json.loads(response.getBody()) return creatorFields
def getCreatorTypes(self, itemType): """Get the list of possible creator types for a particular Zotero item type.""" reqUrl = zotero.ZOTERO_URI + 'itemTypeCreatorTypes?itemType=' + itemType response = self._request(reqUrl, 'GET') if response.status_code != 200: raise zotero.ZoteroApiError("failed to fetch creatorTypes") creatorTypes = json.loads(response.getBody()) return creatorTypes
def getItemFields(self, itemType): """Get the list of possible item fields for a particular Zotero item type.""" reqUrl = zotero.ZOTERO_URI + 'itemFields' response = self._request(reqUrl, 'GET') if response.status_code != 200: raise zotero.ZoteroApiError("failed to fetch itemFields") itemFields = json.loads(response.getBody()) return itemFields
def getItemTypes(self): """Get the list of possible Zotero item types.""" reqUrl = zotero.ZOTERO_URI + 'itemTypes' response = self._request(reqUrl, 'GET') if response.status_code != 200: raise zotero.ZoteroApiError("failed to fetch itemTypes") itemTypes = json.loads(response.getBody()) return itemTypes
def fetchItemKeys(self, params={}): """Fetch all item keys in the library, specified by params.""" logging.info('zotero.Library.fetchItemKeys') fetchedKeys = [] aparams = {'target': 'items', 'format': 'keys'} aparams.update(params) reqUrl = self.apiRequestString(aparams) response = self._request(reqUrl) if response.status_code != 200: raise zotero.ZoteroApiError("Error fetching item keys" + str(response.status_code)) body = response.text fetchedKeys = body.strip().split("\n") return fetchedKeys
def getTemplateItem(itemType, linkMode=None): """Return a template for a Zotero API item of a particular type.""" newItem = zotero.Item() aparams = {'target': 'itemTemplate', 'itemType': itemType} if linkMode != None: aparams['linkMode'] = linkMode reqUrl = apiRequestString(aparams) response = zrequest(reqUrl) if response.status_code != 200: raise zotero.ZoteroApiError("Error getting template item") itemTemplate = json.loads(response.text) newItem.initItemFromTemplate(itemTemplate) return newItem
def fetchTrashedItems(self, params={}): """Fetch a set of items marked for deletion.""" fetchedItems = [] aparams = {'target': 'trash', 'content': 'json'} aparams.update(params) reqUrl = self.apiRequestString(aparams) response = self._request(reqUrl) if response.status_code != 200: raise zotero.ZoteroApiError("Error fetching items" + str(response.status_code)) body = response.text feed = zotero.Feed(body) self._lastFeed = feed fetchedItems = self.items.addItemsFromFeed(feed) return fetchedItems
def fetchItem(self, itemKey, params={}): """Fetch a single item.""" aparams = {'target': 'item', 'content': 'json', 'itemKey': itemKey} aparams.update(params) reqUrl = self.apiRequestString(aparams) response = self._request(reqUrl, 'GET') if response.status_code != 200: raise zotero.ZoteroApiError("Error fetching items") body = response.text item = zotero.Item(body) if not item: return False self.items.addItem(item) return item
def fetchItems(self, params={}): """Fetch a set of items.""" fetchedItems = [] aparams = {'target': 'items', 'content': 'json', 'key': self._apiKey} aparams.update(params) reqUrl = self.apiRequestString(aparams) logging.info(reqUrl) response = self._request(reqUrl) if (response.status_code != 200): raise zotero.ZoteroApiError("Error fetching items. " + str(response.status_code)) body = response.text feed = zotero.Feed(body) self._lastFeed = feed fetchedItems = self.items.addItemsFromFeed(feed) return fetchedItems
def fetchItemBib(self, itemKey, style=None): """Fetch a bibliography entry for an item.""" #TODO:parse correctly and return just bib aparams = {'target': 'item', 'content': 'bib', 'itemKey': itemKey} if style != None: aparams['style'] = style reqUrl = self.apiRequestString(aparams) response = self._request(reqUrl, 'GET') if response.status_code != 200: raise zotero.ZoteroApiError("Error fetching items") body = response.text feed = zotero.Feed(body) if len(feed.entries) == 0: return False else: item = zotero.Item(feed.entries[0]) self.items.addItem(item) return item
def fetchItemExport(self, itemKey, format='rdf_bibliontology'): """ Fetch an export format of an item. """ formats = [ 'bibtex', 'bookmarks', 'coins', 'csljson', 'mods', 'refer', 'rdf_bibliontology', 'rdf_dc', 'rdf_zotero', 'ris', 'tei', 'wikipedia' ] logging.debug("requesting format %s for item %s" % (format, itemKey)) if format not in formats: logging.warning( "format '%s' is not in libZotero's list of known export formats" % format) aparams = {'target': 'item', 'itemKey': itemKey, 'format': format} reqUrl = self.apiRequestString(aparams) response = self._request(reqUrl, 'GET') if response.status_code != 200: raise zotero.ZoteroApiError( "Error fetching export format='%s' for itemKey='%s'" % (format, itemKey)) return response.text
def fetchCollections(self, params={}): """Fetch a set of collections.""" aparams = {'target': 'collections', 'content': 'json', 'limit': 100} aparams.update(params) reqUrl = self.apiRequestString(aparams) response = self._request(reqUrl) if response.status_code != 200: raise zotero.ZoteroApiError("Error fetching collections") feed = zotero.Feed(response.text) self._lastFeed = feed addedCollections = self.collections.addCollectionsFromFeed(feed) if 'next' in feed.links: nextUrl = feed.links['next']['href'] parsedNextUrl = urlparse.urlparse(nextUrl) parsedNextQuery = urlparse.parse_qs(parsedNextUrl.query) parsedNextQuery = self.apiQueryString( parsedNextQuery.update({'key': self._apiKey})) reqUrl = parsedNextUrl['scheme'] + '://' + parsedNextUrl[ 'host'] + parsedNextUrl['path'] + parsedNextQuery else: reqUrl = False return addedCollections