import os
from datetime import datetime, timedelta, date
import nbib
import random
from pathlib import Path
import string
__all__ = [
'get_timestamp', 'parse_timestamp_from_str', 'is_newer',
'get_nbibfile', 'get_save_location', 'get_files_newer_than',
'get_newest_file', 'get_pub_ref'
]
[docs]
def get_timestamp() -> str:
"""
Returns standardized timestamp.
:returns: standardized timestamp for current day as a string.
"""
return datetime.now().strftime('%Y-%m-%d')
[docs]
def parse_timestamp_from_str(stamp_text:str) -> date:
"""
Parses standardized time stamp from string.
:param stamp_text: str with the timestamp
:returns: Datetime for the timestamp
"""
return datetime.strptime(stamp_text,'%Y-%m-%d').date()
[docs]
def is_newer(reference:str, new_date:str) -> bool:
"""
Checks whether new_date is newer than reference
:param reference: reference timestamp string
:param new_date: new_date timestamp string
:returns: True, if new_date is more recent than reference.
"""
reference_date: date = parse_timestamp_from_str(reference)
new_date_date: date = parse_timestamp_from_str(new_date)
return (new_date_date>reference_date)
[docs]
def get_nbibfile(databasename:str) -> str:
"""
Fetches the nbib reference file for the given database. Does not check, if the file exists.
:param databasename: name of the database
:returns: path to the nbib file for that database.
"""
nbibpath: str = os.path.join(
os.path.dirname(os.path.realpath(__file__)),
'nbibs',
f'{databasename.lower()}.nbib')
return nbibpath
[docs]
def get_save_location(databasename) -> str:
"""
Finds the appropriate location to save a database file
:param databasename: Name of the database
:returns: path to the database directory, where files should be written.
"""
base_location: str = os.path.join(
os.path.dirname(os.path.realpath(__file__)),
'data'
)
dir_name: str = os.path.join(base_location, databasename)
if not os.path.isdir(dir_name):
os.makedirs(dir_name)
return dir_name
[docs]
def get_files_newer_than(directory:str, date_str:str, days:int, namefilter:str=None) -> list:
"""
Gets files newer than a given date in a dictionary, only going back a given number of days. Uses os.path.getmtime to establish file dates.
:param directory: where to search
:param date: base date for the search, e.g. today
:param days: how many days move the cutoff date to the past from the date parameter
:param namefilter: only return files, which have this string in their name
:returns: list of files newer than date-days, that optionally contain namefilter in their name.
"""
if not os.path.isdir(directory):
return ''
# Convert the date string to a datetime object
date:datetime = datetime.strptime(date_str, '%Y-%m-%d')
# Calculate the cutoff date
cutoff_date = date - timedelta(days=days)
newer_files: list = []
# Iterate over the files in the directory
for filename in os.listdir(directory):
# Check if the file should be checked, if namefilter is set:
if namefilter:
if not namefilter in filename:
continue
file_path:str = os.path.join(directory, filename)
# Get the modification time of the file
mod_time = datetime.fromtimestamp(os.path.getmtime(file_path))
# If the modification time is after the cutoff date, add the file to the list
if mod_time > cutoff_date:
newer_files.append(filename)
return newer_files
[docs]
def get_newest_file(directory:str, namefilter:str = None) -> str:
"""
Finds the latest modified file in a directory
:param directory: where to search
:param namefilter: only consider files with this in their name
:returns: name of the newest file, not the full path. If no files are found, returns a randomized string.
"""
if not os.path.isdir(directory):
return ''
existing_files = set(os.listdir(directory))
newest_file = ''.join(random.choices(string.ascii_letters + string.digits, k=3))
while newest_file in existing_files:
newest_file += ''.join(random.choices(string.ascii_letters + string.digits, k=3))
newest_time = datetime.min
for filename in os.listdir(directory):
# Check if the file should be checked, if namefilter is set:
if namefilter:
if not namefilter in filename:
continue
file_path:str = os.path.join(directory, filename)
# Get the modification time of the file
mod_time = datetime.fromtimestamp(os.path.getmtime(file_path))
if mod_time > newest_time:
newest_file = filename
newest_time = mod_time
return newest_file
[docs]
def get_pub_ref(databasename:str) -> list:
"""Fetches reference information for the given database
:param databasename: which database to get information for
:returns: list of reference information containing:
- short description
- long description
- PMID
"""
nbibdata: list = nbib.read_file(get_nbibfile(databasename))[0]
pubyear: str = nbibdata['publication_date'].split(maxsplit=1)[0]
try:
authors: list = [a['author_abbreviated'] for a in nbibdata['authors']]
except KeyError:
authors = [nbibdata['corporate_author']]
ref: str = f'{nbibdata["journal_abbreviated"]}.{nbibdata["publication_date"]}:{nbibdata["doi"]}'
title: str = nbibdata['title']
pmid: str = str(nbibdata['pubmed_id'])
if len(authors) < 3:
short: str = f'({" and ".join(authors)}, {pubyear})'
elif len(authors)==1:
short = f'({authors[0]} ({pubyear})'
else:
short = f'({authors[0]} et al., {pubyear})'
long: str = f'{", ".join(authors)}. {title} {ref}'
return [short, long, pmid]