Basically a fork from https://github.com/blochberger/sokman but with the intention of adding a visual interface as well
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
154 lines
4.3 KiB
154 lines
4.3 KiB
import html
|
|
import io
|
|
import string
|
|
import csv
|
|
|
|
from dataclasses import dataclass, field
|
|
from datetime import datetime
|
|
from pathlib import Path
|
|
from typing import Any, Dict, List, Optional, Set, Tuple, Union
|
|
|
|
import requests
|
|
|
|
from django.db import transaction
|
|
from django.core.management.base import BaseCommand, CommandParser, CommandError
|
|
|
|
from sok.models import (
|
|
Author,
|
|
Publication,
|
|
PublicationAuthor,
|
|
PublicationSource,
|
|
PublicationTag,
|
|
SearchTerm,
|
|
Source,
|
|
Tag,
|
|
)
|
|
|
|
|
|
|
|
# TODO: anpassen für WoS?
|
|
PUBLICATIONS = {
|
|
'article',
|
|
'inproceedings',
|
|
'proceedings',
|
|
'book',
|
|
'incollection',
|
|
'phdthesis',
|
|
'mastersthesis',
|
|
'www',
|
|
'person',
|
|
'data',
|
|
}
|
|
|
|
CITE_KEY_PREFIX = 'Z:'
|
|
|
|
|
|
class Command(BaseCommand):
|
|
|
|
def log_success(self, msg: str):
|
|
self.stdout.write(self.style.SUCCESS(msg))
|
|
|
|
def log_info(self, msg: str, nl: bool = True):
|
|
self.stdout.write(self.style.HTTP_INFO(msg), ending='\n' if nl else '')
|
|
self.stdout.flush()
|
|
|
|
# BaseCommand
|
|
|
|
def add_arguments(self, parser: CommandParser):
|
|
parser.add_argument('--search-term', default='Not specified')
|
|
parser.add_argument('--source', default='Zotero')
|
|
parser.add_argument('zfile')
|
|
|
|
@transaction.atomic
|
|
def handle(self, *args, **options):
|
|
source, created = Source.objects.get_or_create(name=options['source'])
|
|
|
|
search_term: Optional[SearchTerm] = None
|
|
if name := options['search_term']:
|
|
search_term, created = SearchTerm.objects.get_or_create(name=name)
|
|
if created:
|
|
self.log_success(f"Created search term: {search_term}")
|
|
|
|
publications: List[Publication] = []
|
|
|
|
zotero_file = options['zfile']
|
|
with open(zotero_file, 'r') as csvfile:
|
|
reader = csv.DictReader(csvfile)
|
|
for publ in reader:
|
|
|
|
authors: List[Author] = []
|
|
for name in set(publ['Author'].split('; ')):
|
|
author, created = Author.objects.get_or_create(name=name)
|
|
if created:
|
|
self.log_success(f"Added author: {author}")
|
|
else:
|
|
self.log_info(f"Author '{author}' already known")
|
|
authors.append(author)
|
|
|
|
tags: List[Tag] = []
|
|
for t in set(publ['Manual Tags'].split('; ')).union(publ['Automatic Tags'].split('; ')):
|
|
if t == '': continue
|
|
tag, created = Tag.objects.get_or_create(name=t)
|
|
if created:
|
|
self.log_success(f"Added tag: {tag}")
|
|
else:
|
|
self.log_info(f"Tag '{tag}' already exists")
|
|
tags.append(tag)
|
|
|
|
pages = (None, None)
|
|
if '-' in publ['Pages']:
|
|
pages = publ['Pages'].split('-')
|
|
|
|
# Add publication to database
|
|
publication, created = Publication.objects.get_or_create(
|
|
cite_key=publ['Key'],
|
|
title=publ['Title'],
|
|
year=publ['Publication Year'],
|
|
# TODO: peer_reviewed=result.is_peer_reviewed,
|
|
first_page=pages[0],
|
|
last_page=pages[1],
|
|
doi=publ['DOI'] or None,
|
|
abstract=publ['Abstract Note'] or None,
|
|
)
|
|
if created:
|
|
self.log_success(f"Added publication: {publication}")
|
|
else:
|
|
self.log_info(f"Publication '{publication}' already known")
|
|
publications.append(publication)
|
|
|
|
# Assign authors
|
|
for position, author in enumerate(authors):
|
|
publication_author, created = PublicationAuthor.objects.get_or_create(
|
|
author=author,
|
|
publication=publication,
|
|
position=position,
|
|
)
|
|
if created:
|
|
self.log_success(f"Assigned author '{author}' to publication '{publication}' at position {position}")
|
|
else:
|
|
self.log_info(f"Author '{author}' already assigned to publication '{publication}' at position '{position}'")
|
|
|
|
# Assign tags
|
|
for position, tag in enumerate(tags):
|
|
publication_tag, created = PublicationTag.objects.get_or_create(
|
|
tag=tag,
|
|
publication=publication,
|
|
)
|
|
if created:
|
|
self.log_success(f"Assigned tag '{tag}' to publication '{publication}'")
|
|
else:
|
|
self.log_info(f"Tag '{tag}' already assigned to publication '{publication}'")
|
|
|
|
# Assign sources
|
|
if search_term is not None:
|
|
for publication in publications:
|
|
print(publication, search_term, source)
|
|
publication_source, created = PublicationSource.objects.get_or_create(
|
|
source=source,
|
|
publication=publication,
|
|
search_term=search_term,
|
|
)
|
|
if created:
|
|
self.log_success(f"Assigned source '{source}' to publication '{publication}' with search term '{search_term}'")
|
|
else:
|
|
self.log_info(f"Source '{source}' already assigned to publication '{publication}' with search term '{search_term}'")
|
|
|