def retrieve(cls): """ Retrieve all non-hidden remote collections from Zotero. """ logger.info('retrieving collections...') zot = zotero.Zotero(settings.ZOTERO_USER_ID, settings.ZOTERO_LIBRARY_TYPE, settings.ZOTERO_API_KEY) collections = [collection for collection in zot.collections() if collection['data']['name'][0] != '_'] def save_collections(parent_key, collections): """ Saves parent and childcollections recursively as models. """ for collection in [c for c in collections if c['data']['parentCollection'] == parent_key]: key = collection['data']['key'] name = collection['data']['name'] parent = cls.objects.get(slug=parent_key) if parent_key else None local_collection, created = cls.objects.update_or_create( slug=key, defaults={'title': name, 'parent': parent}) logger.debug('Collection {} saved.'.format(name)) save_collections(key, collections) # Check for collections to delete logger.debug('cleaning up...') collection_keys = [collection['data']['key'] for collection in collections] for local_collection in cls.objects.all(): if local_collection.slug not in collection_keys: local_collection.delete() logger.debug('Collection {} deleted.'.format(local_collection.title)) save_collections(False, collections)
class CreateNewZotero: #creds.json- credentials used to access zotero group library that needs to be populated creds = json.loads(open('creds.json').read()) zot = zotero.Zotero(creds['libraryID'], creds['libraryType'], creds['apiKey']) #Function to create a zotero record def createItem(self, art): zoterorest = ZoteroRESTCalls() if art != None: template = self.zot.item_template(art.template) template['extra'] = art.id template['title'] = art.title template['url'] = art.url template['abstractNote'] = art.content template['tags'] = art.tags if art.template == 'journalArticle': template['issn'] = art.issn try: # log.debug('Trying to create:%s' % art) resp = self.zot.create_items([template]) # print resp postUrlSuf = '/'+self.creds['libraryType']+'s/'+self.creds['libraryID']+'/items?key='+self.creds['apiKey'] title = 'Original Blog URL:' + art.blogUrl result = zoterorest.createChildAttachment(postUrlSuf, resp[0]['key'], art.blogUrl, title) log.info("Created Zotero item with title %s" % art.title) # log.info("Child attachment result:%s" % result) except Exception, e: log.info("********ERROR, UNEXPECTED EXCEPTION********") log.info(e) log.info("*******************************************") traceback.print_exc() else:
def sync_articles(cls): """ Updates local articles from Zotero. NOT IN USE! ARTICLES ARE STILL SAVED LOCALLY. """ zot = zotero.Zotero(settings.ZOTERO_USER_ID, settings.ZOTERO_LIBRARY_TYPE, settings.ZOTERO_API_KEY) articles = zot.everything(zot.items(tag='Scholie', sort='date', direction='desc')) print(articles) # Get all articles for article in articles: title = article['data']['title'] key = article['key'] notes = [child['data']['note'] for child in zot.children(key) if child['data']['itemType'] == 'note'] try: html_text = next(iter(notes)) # Retrieve html formatted text from first note except StopIteration: logger.warning('Article {} is empty! Skipping...'.format(title)) continue # Skip empty articles obj, created = cls.objects.update_or_create(slug=key, defaults={'title': title, 'text': html_text}) return obj # Clean up deleted articles. for local_article in cls.objects.all(): if local_article.slug not in [article['key'] for article in articles]: local_article.delete() children = zot.children(local_article.slug) return children
def __init__(self): self.api_key = ZOT_api_key self.library_id = ZOT_library_id self.library_type = ZOT_library_type self.zot = zotero.Zotero(self.library_id, self.library_type, self.api_key)
def get_zot(): with open(Path(zotero_api_key_file_path).expanduser(), "r") as inf: library_id = inf.readline().strip() api_key = inf.readline().strip() library_type = "user" zot = zotero.Zotero(library_id, library_type, api_key) return zot
def do(self): from pyzotero import zotero collections = ZoteroCollection.objects.all() for collection in collections: api = collection.api zotero_id = collection.zotero_id zot = zotero.Zotero(zotero_id, "group", api) #list = zot.top(limit=5) list = zot.everything(zot.top()) for each in list: try: info = ZoteroItem.objects.get(key=each["data"].get("key")) info.data = each["data"] info.save() except: title = each["data"].get("title") info = ZoteroItem.objects.create( title=title if title else "No title", key=each["data"].get("key"), data=each["data"], collection=collection, ) if collection.uid == 3: info.import_to_library()
def update_zotero(refs, libid, colid, apikey): zot = zotero.Zotero(libid, 'group', apikey) subcols = {} zotcols = zot.collections_sub(colid) for c in zotcols: subcols[ c['data']['name'] ] = c['data']['key'] #print(subcols) def zotero_get_collection_id(colname): if colname not in subcols: newcols = zot.create_collections([{'name':colname, 'parentCollection':colid}]) newcol = newcols['successful']['0'] subcols[ newcol['data']['name']] = newcol['data']['key'] return(subcols[colname]) items = [] for ref in refs: subcolid = zotero_get_collection_id(ref['objet']) item = ref2zot(ref, [colid,subcolid]) #items.append(item) print("Adding item "+ref['ID'], end='... ') addeditems = zot.create_items([item]) print("DONE") if addeditems['failed'] == {} else print("FAILED")
def apply_category_tags(ctx, tag, input): """Apply category tags to items matching tags listed in INPUT. INPUT should contain a list of tags, separated by newlines. INPUT can be a filename or `-` to read from stdin. References matching any of the tags in that list will be tagged in the Zotero library with the additional tag specified with `--tag`. For example, INPUT could contain a list of Asian country names, in which case all library items tagged with one of those country names could additionally be given the tag "ASIA": python zma.py [OPTIONS] --tag ASIA asian-countries.txt """ zot = zotero.Zotero(ctx.obj['library_id'], ctx.obj['library_type'], ctx.obj['key']) subtags = input.read().splitlines() s = ' || '.join([t for t in subtags if t.strip() != '']) items = zot.everything(zot.items(tag=s)) for item in items: # skip if the item already has this tag; otherwise update if not any(t['tag'] == tag for t in item['data']['tags']): click.echo('UPDATING {}'.format(item['data'].get('title'))) zot.add_tags(item, tag)
def get(self): zot = zotero.Zotero(settings.ZOTERO_USER_ID, settings.ZOTERO_LIBRARY_TYPE, settings.ZOTERO_API_KEY) if self.format == 'note': html = zot.item(self.key)['data']['note'] path = f'{settings.TMP_DIR}/{self.key}.pdf' HTML(string=html).write_pdf(path) logger.debug(f'Conversion to pdf successfull: {self.key}') with open(path, 'rb') as file: response = HttpResponse(file.read(), content_type=f'application/pdf') elif self.format == 'file': try: file = zot.file(self.key) except zotero_errors.ResourceNotFound: logger.exception(f'Zotero: File at {self.key} is missing!') return False response = HttpResponse( file, content_type=f'application/{self.type.slug}') response['Content-Disposition'] = f'attachment; \ filename={slugify(self.item.product.zotitem.title)}.pdf' return response
def dump_db(api_key): """ Just dump out the entire database :param api_key: for our Zotero database :return: None """ zot = zotero.Zotero(LIBRARY_ID, LIBRARY_TYPE, api_key) # gab *all the stuff items = zot.everything(zot.top()) # print each item's item type and ID for i, item in enumerate(items): if 'note' in item['data']['itemType']: pass # print('Skipping note') else: if 'title' in item['data']: print(len(item['data']['tags']), item['meta']['createdByUser']['username'], ':', item['data']['title'].replace('\n', ' ')) elif 'case' in item['data']['itemType']: # Special case for, erm, court cases print(len(item['data']['tags']), item['meta']['createdByUser']['username'], ':', item['data']['caseName'].replace('\n', ' ')) else: # Some items do not have a title, so just dump out all the data print(len(item['data']['tags']), item['meta']['createdByUser']['username'], ':', item['data'])
def _zotero_api_result(self): api = zotero.Zotero(self.library_id, self.library_type) results = api.item(self.item_id, format='json') formatted = api.item(self.item_id, content='bib') results['formatted'] = formatted return results
def get_or_create_zotero_collection(username): if not hasattr(settings, 'ZOTERO_IDENTITY'): logger.warn('no settings.ZOTERO_IDENTITY found') return try: zot = zotero.Zotero(settings.ZOTERO_IDENTITY, 'user', settings.ZOTERO_API_KEY) colls = zot.all_collections() except: logger.exception( 'unable to get zotero collections, zotero id: %s, zotero key: %s' % (settings.ZOTERO_IDENTITY, settings.ZOTERO_API_KEY)) return False, None, None # get collection by username (let's trust django username :D) for coll in colls: if coll['data']['name'] == username: return False, coll, zot # create collection collreq = zot.create_collection([{'name': username}]) coll = json.loads(collreq) if 'successful' in coll: # print coll['successful'] return True, coll['successful']['0'], zot logger.warn('unable to create collection, got %s' % collreq) return False, None, zot
def init_zotero(): return zotero.Zotero( library_id=current_app.config['KERKO_ZOTERO_LIBRARY_ID'], library_type=current_app.config['KERKO_ZOTERO_LIBRARY_TYPE'], api_key=current_app.config['KERKO_ZOTERO_API_KEY'], locale=current_app.config['KERKO_ZOTERO_LOCALE'] )
def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) zot = zotero.Zotero(settings.ZOTERO_USER_ID, settings.ZOTERO_LIBRARY_TYPE, settings.ZOTERO_API_KEY) context['api_object'] = zot.item(self.object.slug) return context
def get_zotero_connection(): api_key, library_id, library_type = get_zotero_variables() zot = zotero.Zotero(library_id=library_id, library_type=library_type, api_key=api_key) return zot
def _get_untagged_items(collections, api_key): """ :param collections: dictionary of collections :param api_key: for accessing our Zotero database :return: list of items that need tagging """ untagged_items = [] zot = zotero.Zotero(LIBRARY_ID, LIBRARY_TYPE, api_key) # gab *all* the stuff items = zot.everything(zot.top()) # grind through everything, only keeping the items that belong to the CFR collection that have *NO* tags for i, item in enumerate(items): # TODO pass in collections name instead of hard-coding 'CFR' if collections['CFR']['zoteroKey'] in item['data'][ 'collections'] and item['data']['tags'] == []: untagged_items.append({ 'title': item['data'].setdefault('title', 'no title') }) #, 'abstract' : item['data']['abstractNote']}) return untagged_items
def __init__(self, options): self._options = options self._user_id = self._get_setting('ZOTERO_USER') self._api_access_key = self._get_setting('ZOTERO_API_ACCESS_KEY') self._check_api_key() self._zotero_client = zotero.Zotero(self._user_id, 'user', self._api_access_key)
def print_bibliography(ctx, print_tag, output): """Print an html bibliography for a given collection, with tags listed beneath each entry. Tags can be filtered by providing tag prefixes through `--print-tag`. OUTPUT can be a filename or `-` to print to stdout. Example: python zma.py --library-type group --library-id 2183860 / --collection-id 27MV6NK5 print-bibliography / --print-tag "#THEME:" --print-tag "+" zotero.html """ zot = zotero.Zotero(ctx.obj['library_id'], ctx.obj['library_type'], ctx.obj['key']) t = zot.everything( zot.collection_items_top(ctx.obj['collection_id'], include='bib,data', style='mla', linkwrap='1')) # sort by bibliography; lowercase entries to make the sort case-insensitive t = sorted(t, key=lambda i: i['bib'].lower()) for i in t: if print_tag: tags = _filter_tags([k['tag'] for k in i['data']['tags']], print_tag) else: tags = i['data']['tags'] output.write(i['bib']) output.write('<blockquote>') output.write(', '.join(tags)) output.write('</blockquote>')
def find_missing_tags(ctx, match, local, remote, tags_list): """Compare a list of tags to those in the library. Prints lists of tags to two plain text files, by default "missing-user- tags.txt" (tags that are in the Zotero library but not in the user-supplied file) and "missing-zotero-tags.txt" (tags that are in the user-supplied file but not in the Zotero library). This function is intended to be used where there is an established codebook, and you wish to check whether (1) there are any unused tags in the codebook, and (2) there are any tags in the Zotero library that aren't documented in the codebook. If the tags in the codebook have a common prefix, results from the Zotero library can be filtered using the `--tag- filter` argument. """ local_tags = tags_list.read().splitlines() zot = zotero.Zotero(ctx.obj['library_id'], ctx.obj['library_type'], ctx.obj['key']) remote_tags = zot.everything( zot.tags(q=ctx.obj['tag_filter'], qmode='startsWith')) local_only = [l for l in local_tags if not l in remote_tags] remote_only = [r for r in remote_tags if not r in local_tags] with open(remote, 'w') as out: out.write('\n'.join(sorted(local_only))) with open(local, 'w') as out: out.write('\n'.join(sorted(remote_only)))
def __init__(self, config: ZoteroxyConfig): self.config = config self._metadata_cache = Cache(duration=config.settings.cache_duration) self._file_cache = FileCache( duration=config.settings.cache_file_duration, directory=config.settings.cache_directory) self.library = zotero.Zotero(config.library.id, config.library.type, config.zotero.api_key)
def main(): zot = zotero.Zotero(settings.zoteroUserId, 'user', settings.zoteroAPIKey) #items = zot.top(limit=5) # items = zot.publications() # we've retrieved the latest five top-level items in our library # we can print each item's item type and ID for item in items: print('Item: %s | Key: %s' % (item['data']['itemType'], item['data']['key']))
def clean_tags2(): api_key = 'fBDBqRPwW9O3mYyNLiksBKZy' base_url = 'https://api.zotero.org' library_id = '1279414' library_type = 'user' from pyzotero import zotero zot = zotero.Zotero(library_id, library_type, api_key) for chunk in ut.ProgChunks(bad_tags, 50): zot.delete_tags(*chunk)
def zotero_collection_from_items(items, collection_name, **connection): zot = zotero.Zotero(**connection) collection = zot.create_collections([{ 'name': collection_name }])["success"]["0"] print("Adding to collection %s..." % collection_name) li = len(items) for i, it in enumerate(items): zot.addto_collection(collection, zot.item(it)) print("%i/%i" % (i + 1, li)) return
def __init__(self, apikey, userlibrary_id, usercollection_name, workmode): self.__log = LogFile('ZoteroSync').log self.__zot = zotero.Zotero(userlibrary_id, "user", apikey) self.__collID = ZoteroLibs.findCollectionID(self.__zot, usercollection_name) self.__modes = workmode self.collateMaps()
def fetch_bibtex(zot_key): """ fetches the bibtex dict of the passed in key """ result = {} zot = zotero.Zotero(library_id, library_type, api_key) try: result['bibtex'] = zot.item(zot_key, format='bibtex').entries_dict result['error'] = None except Exception as e: result['bibtex'] = None result['error'] = "{}".format(e) return result
def _get_library(self, library_id): """ If library id specified, fetch the group library from Zotero. Otherwise, use the user's personal library. """ if library_id and library_id != 'personal': if not self._library_client: self._library_client = zotero.Zotero(str(library_id), 'group', self.account.oauth_key) return self._library_client else: return self.client
def main(): import argparse import os parser = argparse.ArgumentParser( description="Create a collection from items added to a Word .docx file" " via the Word Zotero Integration") parser.add_argument('file', help="The .docx file path.") parser.add_argument("collection", help="Name of new collection to create.") parser.add_argument( "--api-key", help="A Zotero API key with write permissions. " "Create here (after login): https://www.zotero.org/settings/keys/new") parser.add_argument( "--library-id", default="infer", help="The library ID if different to " "the one used to add the items (See top of table here 'Your userID " "for use in API calls': https://www.zotero.org/settings/keys).") parser.add_argument("--library-type", default="user") parser.add_argument( "-n", "--dry-run", action="store_true", default=False, help= "Only retrieve items from file and try opening Zotero API connection.") args = parser.parse_args() apikeyfile = os.path.expanduser("~/.zotero_api_key") if os.path.exists(apikeyfile): with open(apikeyfile) as f: args.api_key = f.read().strip() print('Using Zotero API key in %s' % apikeyfile) elif not args.api_key: print("You need to either parse --api-key or put one into %s" % apikeyfile) return items = items_from_docx(args.file) connection = { d: getattr(args, d) for d in ['library_id', 'library_type', 'api_key'] } if len(items) > 0: if connection['library_id'] == "infer": lid = [i['library_id'] for i in items][0] connection['library_id'] = lid if args.dry_run: zot = zotero.Zotero(**connection) else: zotero_collection_from_items([i['id'] for i in items], args.collection, **connection)
def get_tags(ctx, output): """Print a list of tags in the library that match the input prefix. Tags are filtered to include or exclude those that match the prefix strings given. Each match is checked at the beginning of the string (left-to-right). OUTPUT can be a filename or `-` to print to stdout. """ zot = zotero.Zotero(ctx.obj['library_id'], ctx.obj['library_type'], ctx.obj['key']) t = zot.everything(zot.tags(q=ctx.obj['tag_filter'], qmode='startsWith')) output.write('\n'.join(sorted(t)))
def grab(): grab_button.config(state=DISABLED) progress_indicator.set("In progress...") root.update() library_id = libraryid_w.get() zot_api_key = zot_api_key_w.get() hyp_username = hyp_username_w.get() hyp_api_key = hyp_api_key_w.get() zot = zotero.Zotero(library_id, 'user', zot_api_key) num2grab = number_to_grab_w.get() items = zot.top(limit=num2grab) progress_indicator.set("Zotero library downloaded") root.update() for entry_i in enumerate(items): progress_indicator.set("Processing notes...({} of {})".format( entry_i[0] + 1, len(items))) root.update() entry = entry_i[1] entry_children = zot.children(entry['key']) notes = [ note for note in entry_children if note['data']['itemType'] == 'note' ] tags = extract_note_tags(notes) entry_annotations = json.loads( h_annot.api.search(hyp_api_key, url=entry['data']['url'], user=hyp_username))["rows"] note_imports = [] for annotation in entry_annotations: if annotation["id"] in tags: continue else: template = zot.item_template("note") template['tags'] = (annotation['tags'].copy() + [{ "tag": annotation["id"], "type": 1 }] + [{ "tag": "hyp-annotation", "type": 1 }]) template['note'] = format_converted_note(annotation) note_imports.append(template) #TODO: Fix this so it doesn't break if you have more than 50 annotations on a document zot.create_items(note_imports, entry["key"]) progress_indicator.set("Done!") grab_button.config(state=NORMAL)
def get_zotero_data(): z = zotero.Zotero(library_id, library_type, api_key) isawbib_json = z.everything(z.top(sort="dateModified")) # cit = z.add_parameters(content='bib', style='https://www.zotero.org/styles/transactions-of-the-american-philological-association', sort="dateModified") cit = z.add_parameters(content='bib', style='mla', sort="dateModified") isawbib_cit = z.everything(z.top()) # More elegant way to write this? for i, item in enumerate(isawbib_cit): isawbib_json[i]['data']['citation'] = item items = isawbib_json count = len(items) items = _sort_zotero_date(items) return items, count