2025-10-14: Manual update, main structure done

This commit is contained in:
Moussouni, Yaël
2025-10-14 10:21:09 +02:00
parent 7baa9137bf
commit 6171b6aa15
12 changed files with 523 additions and 39 deletions

101
.gitignore vendored
View File

@@ -1,10 +1,97 @@
.DS_Store
*.tmp
*.log
tmp/
log/
venv/
.venv/
# Specific files
cfg/filters
*.secret
db/
# Os generated files
## Linux
.Trash-*
## MacOS
.DS_Store
.AppleDouble
.LSOverride
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
._*
## Windows
Thumbs.db
Thumbs.db:encryptable
ehthumbs.db
ehthumbs_vista.db
Desktop.ini
desktop.ini
$RECYCLE.BIN/
# temporary or log(s) files and directories
*.tmp
*.log
*.logs
tmp/
log/
logs/
# Python
venv/
.venv/
__pycache__/
# LaTeX
Build/
build/
*.acn
*.acr
*.alg
*.aux
*.bak
*.bbl
*.bcf
*.blg
*.brf
*.bst
*.dvi
*.fdb_latexmk
*.fls
*.glg
*.glo
*.gls
*.idx
*.ilg
*.ind
*.ist
*.lof
*.log
*.lol
*.lot
*.maf
*.mtc
*.mtc1
*.nav
*.nlo
*.nls
*.out
*.pyg
*.run.xml
*.snm
*.synctex.gz
*.tex.backup
*.tex~
*.thm
*.toc
*.vrb
*.xdy
*.xml
*blx.bib
.bak
.mtc

View File

@@ -32,7 +32,7 @@ mkdir -p -v cfg/filters
mkdir -p -v db
touch db/read.bib
touch db/unread.bib
touch db/library.bib
touch db/local.bib
chmod u+x *.sh
echo "=== Done ==="

View File

@@ -93,8 +93,8 @@ def ads_bibcode(bibcodes):
bibentry = feed.text
bibentry = bibentry[:-2]
bibentry += (",\n"
"\tarxtic_notes={},\n"
"\tarxtic_category={},\n"
"\tarxtic_comment={},\n"
"\tarxtic_library={},\n"
"\tarxtic_keywords={},\n"
"\tarxtic_score={-1},\n"
"\tarxtic_filename={},\n"

View File

@@ -102,8 +102,8 @@ def parse_bibtex(entries,
f"\teprint={{{eprint}}},\n"
f"\turl={{{url}}},\n"
f"\tabstract={{{abstract}}},\n"
"\tarxtic_notes={},\n"
"\tarxtic_category={},\n"
"\tarxtic_comment={},\n"
"\tarxtic_library={},\n"
"\tarxtic_keywords={},\n"
"\tarxtic_score={-1},\n"
"\tarxtic_filename={},\n"

View File

@@ -31,6 +31,7 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see www.gnu.org/licenses/.
"""
import os
import subprocess
from urllib.parse import urlencode, quote_plus
import requests as rq
@@ -59,9 +60,138 @@ ids = ["2510.06329", "2509.13163"]
bibcodes = ["2022A&A...658A.152V", "2021A&A...649A..97L"]
query = "first_author:\"Voggel, K\"year:(2022)"
utils.print_reference(arxiv_api.arxiv_today())
utils.print_title_author(arxiv_api.arxiv_id(ids))
print(ads_api.ads_bibcode_search(query, num=2))
utils.print_abstract(ads_api.ads_bibcode(bibcodes))
#test1 = local_api.update_local_pdf()
#local_api.bibtex_to_file(test1, "test1")
#test1 = local_api.file_to_bibtex("test1")
#test2 = bib.Library()
#
#utils.arxtic_comment("2022ApJ...941L..11F", test1)
#utils.arxtic_library_add("2022ApJ...941L..11F", test1, "test1")
#utils.arxtic_keywords_add("2022ApJ...941L..11F", test1, "kw1")
#utils.arxtic_score("2022ApJ...941L..11F", test1, "42")
#utils.arxtic_date_read("2022ApJ...941L..11F", test1)
#utils.export_abstract(test1, "test1")
if __name__ == "__main__":
q = False
s = True
libraries_names = [f.replace(".bib", "") for f in os.listdir(DB_DIR)
if not f[0] == "." and ".bib" in f]
libraries = {l: local_api.file_to_bibtex(l + ".bib")
for l in libraries_names}
while not q:
print(COLOUR_INPUT + "Select an action")
val = input("> " + COLOUR_DEFAULT)
args = val.split(" ")
nargs = len(args)
arg0 = args[0].lower()
try:
if arg0 in ["quit", "exit", "q"]:
if s == True:
q = True
else:
raise Exception(("Unsaved changes, "
"type \"save\" to update database or "
"type \"cancel\" to discard"))
elif arg0 in ["save", "write"]:
for i in range(len(libraries)):
lib_name = libraries_names[i]
lib = libraries[lib_name]
local_api.bibtex_to_file(lib, lib_name)
s = True
elif arg0 in ["cancel", "reset", "reload"]:
for i in range(len(libraries)):
lib_name = libraries_names[i]
libraries[lib_name] = local_api.file_to_bibtex(lib_name)
s = True
elif arg0 in ["local"]:
libraries["local"] = local_api.update_local_pdf(
library=libraries["local"])
elif arg0 in ["print"]:
if nargs == 2:
utils.print_abstract(libraries[args[1]])
elif nargs == 3:
if args[2] in ["abstract", "abs"]:
utils.print_abstract(libraries[args[1]])
if args[2] in ["title", "author", "authors"]:
utils.print_title_author(libraries[args[1]])
if args[2] in ["reference", "references", "ref", "refs"]:
utils.print_reference(libraries[args[1]])
else:
raise Exception("Not recognized")
elif arg0 in ["export"]:
if nargs == 1:
for i in range(len(libraries)):
lib_name = libraries_names[i]
lib = libraries[lib_name]
utils.export_abstract(lib, lib_name+".txt")
elif nargs == 2:
utils.export_abstract(libraries[args[1]], args[1]+".txt")
elif nargs == 3:
if args[2] in ["abstract", "abs"]:
utils.export_abstract(libraries[args[1]], args[1]+".txt")
if args[2] in ["title", "author", "authors"]:
utils.export_title_author(libraries[args[1]], args[1]+".txt")
if args[2] in ["reference", "references", "ref", "refs"]:
utils.export_reference(libraries[args[1]], args[1]+".txt")
else:
raise Exception("Not recognized")
elif arg0 in ["mv", "move"]:
if nargs == 4:
utils.mv(args[1], libraries[args[2]], libraries[args[3]])
s = False
else:
raise Exception("Not recognized")
elif arg0 in ["cp", "copy"]:
if nargs == 4:
utils.cp(args[1], libraries[args[2]], libraries[args[3]])
s = False
else:
raise Exception("Not recognized")
elif arg0 in ["rm", "remove", "del", "delete"]:
if nargs == 3:
utils.rm(args[1], libraries[args[2]])
s = False
else:
raise Exception("Not recognized")
elif arg0 in ["comment"]:
if nargs == 3:
utils.arxtic_comment(args[2], libraries[args[2]])
s = False
elif arg0 in ["read"]:
if nargs == 2:
utils.launch_reader(args[1], libraries["local"])
utils.arxtic_comment(args[1], libraries["local"])
s = False
elif nargs == 3:
utils.launch_reader(args[1], libraries[args[2]])
utils.arxtic_comment(args[1], libraries[args[2]])
s = False
else:
raise Exception("Not recognized")
else:
raise Exception("Not recognized")
except Exception as err:
msg = str(err)
print(COLOUR_ERROR + "Error! " + msg + COLOUR_DEFAULT)
utils.print_reference(local_api.update_local_pdf())

View File

@@ -76,7 +76,7 @@ def update_local_pdf(library=None, directory=PDF_DIR):
known_pdf = [block["arxtic_filename"] for block in blocks]
folder_pdf = [f for f in os.listdir(directory)
if not f[0] == "." and ".pdf" if f]
if not f[0] == "." and ".pdf" in f]
for pdf in folder_pdf:
fields = pdf.replace(".pdf", "").split("_")
@@ -92,6 +92,7 @@ def update_local_pdf(library=None, directory=PDF_DIR):
arxiv_id = "/".join(fields[2:])
arxiv_library = arxiv_api.arxiv_id(arxiv_id)
if len(arxiv_library.blocks) == 1:
arxiv_library.blocks[0]["arxtic_filename"] = pdf
library.add(arxiv_library.blocks)
else:
print(COLOUR_WARNING
@@ -113,6 +114,7 @@ def update_local_pdf(library=None, directory=PDF_DIR):
bibcodes = ads_api.ads_bibcode_search(query, num=2)
if len(bibcodes) == 1:
ads_library = ads_api.ads_bibcode(bibcodes)
ads_library.blocks[0]["arxtic_filename"] = pdf
library.add(ads_library.blocks)
else:
print(COLOUR_WARNING

View File

@@ -31,6 +31,7 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see www.gnu.org/licenses/.
"""
import os
import subprocess
from urllib.parse import urlencode, quote_plus
import requests as rq
@@ -38,6 +39,7 @@ import numpy as np
import textwrap as tw
import feedparser as fp
import bibtexparser as bib
import datetime as dt
FILTERS_DIR = os.environ.get("FILTERS_DIR")
DB_DIR = os.environ.get("DB_DIR")
@@ -50,27 +52,76 @@ COLOUR_INFO="\033[34m"
COLOUR_WARNING = "\033[93m"
COLOUR_ERROR = "\033[91m"
COLOUR_REF = "\033[34m"
COLOUR_TITLE = "\033[35m"
COLOUR_AUTHOR = "\033[32m"
COLOUR_ABS = "\033[36m"
COLOUR_ARXTIC = "\033[91m"
## General
def wrap(txt, length=80):
wrapped_txt = '\n'.join(tw.wrap(txt, length, break_long_words=False))
return wrapped_txt
## Prints
def print_abstract(library):
if not isinstance(library, bib.Library):
library = bib.Library(library)
for block in library.blocks:
if isinstance(block, bib.model.Block):
print(COLOUR_INFO, end="")
print(block.key, end="")
print(" [" + block["url"] + "]", end="")
print(COLOUR_DEFAULT)
print(COLOUR_DEFAULT + wrap(block["title"]) + COLOUR_DEFAULT)
print(COLOUR_OUTPUT
print("#"
+ COLOUR_REF
+ block.key + " [" + block["url"] + "]"
+ COLOUR_DEFAULT)
if block["arxtic_filename"] != "":
print(COLOUR_REF
+ "("
+ PDF_DIR
+ block["arxtic_filename"]
+ ")"
+ COLOUR_DEFAULT)
print("Title: "
+ COLOUR_TITLE
+ wrap(block["title"])
+ COLOUR_DEFAULT)
print("Author(s): "
+ COLOUR_AUTHOR
+ wrap(", ".join(block["author"].split(" and ")))
+ COLOUR_DEFAULT)
print(COLOUR_INPUT
print("Abstract: "
+ COLOUR_ABS
+ wrap(block["abstract"])
+ COLOUR_DEFAULT)
if block["arxtic_comment"] != "":
print("Comment: "
+ COLOUR_ARXTIC
+ wrap(block["arxtic_comment"])
+ COLOUR_DEFAULT)
if block["arxtic_library"] != "":
print("Library: "
+ COLOUR_ARXTIC
+ ", ".join(block["arxtic_library"].split(","))
+ COLOUR_DEFAULT)
if block["arxtic_keywords"] != "":
print("Keywords: "
+ COLOUR_ARXTIC
+ ", ".join(block["arxtic_library"].split(","))
+ COLOUR_DEFAULT)
if float(block["arxtic_score"]) >= 0:
print("Score: "
+ COLOUR_ARXTIC
+ block["arxtic_score"]
+ COLOUR_DEFAULT)
if block["arxtic_date_read"] != "":
print("Read date: "
+ COLOUR_ARXTIC
+ block["arxtic_date_read"]
+ COLOUR_DEFAULT)
print("")
print(80*"=")
print("")
return 0
@@ -79,15 +130,52 @@ def print_title_author(library):
library = bib.Library(library)
for block in library.blocks:
if isinstance(block, bib.model.Block):
print(COLOUR_INFO, end="")
print(block.key, end="")
print(" [" + block["url"] + "]", end="")
print(COLOUR_DEFAULT)
print(COLOUR_DEFAULT + wrap(block["title"]) + COLOUR_DEFAULT)
print(COLOUR_OUTPUT
print("#"
+ COLOUR_REF
+ block.key + " [" + block["url"] + "]"
+ COLOUR_DEFAULT)
if block["arxtic_filename"] != "":
print(COLOUR_REF
+ "("
+ PDF_DIR
+ block["arxtic_filename"]
+ ")"
+ COLOUR_DEFAULT)
print("Title: "
+ COLOUR_TITLE
+ wrap(block["title"])
+ COLOUR_DEFAULT)
print("Author(s): "
+ COLOUR_AUTHOR
+ wrap(", ".join(block["author"].split(" and ")))
+ COLOUR_DEFAULT)
if block["arxtic_comment"] != "":
print("Comment: "
+ COLOUR_ARXTIC
+ wrap(block["arxtic_comment"])
+ COLOUR_DEFAULT)
if block["arxtic_library"] != "":
print("Library: "
+ COLOUR_ARXTIC
+ ", ".join(block["arxtic_library"].split(","))
+ COLOUR_DEFAULT)
if block["arxtic_keywords"] != "":
print("Keywords: "
+ COLOUR_ARXTIC
+ ", ".join(block["arxtic_library"].split(","))
+ COLOUR_DEFAULT)
if float(block["arxtic_score"]) >= 0:
print("Score: "
+ COLOUR_ARXTIC
+ block["arxtic_score"]
+ COLOUR_DEFAULT)
if block["arxtic_date_read"] != "":
print("Read date: "
+ COLOUR_ARXTIC
+ block["arxtic_date_read"]
+ COLOUR_DEFAULT)
print("")
print(80*"=")
print("")
return 0
@@ -101,3 +189,180 @@ def print_reference(library):
print(" [" + block["url"] + "]", end="")
print(COLOUR_DEFAULT)
return 0
## Exports
def export_abstract(library, filename, directory=PDF_DIR):
if not isinstance(library, bib.Library):
library = bib.Library(library)
with open(directory + filename, "w+") as file:
for block in library.blocks:
if isinstance(block, bib.model.Block):
file.write("#" + block.key + " [" + block["url"] + "]\n")
file.write(wrap("Title: " + block["title"]) + "\n")
file.write(wrap("Author(s): "
+ ", ".join(block["author"].split(" and ")))
+ "\n")
file.write(wrap("Abstract: " + block["abstract"]) + "\n")
if block["arxtic_comment"] != "":
file.write(wrap("Comment: " + block["arxtic_comment"])
+ "\n")
if block["arxtic_library"] != "":
file.write("Library: "
+ ", ".join(block["arxtic_library"].split(","))
+ "\n")
if block["arxtic_keywords"] != "":
file.write("Keywords: "
+ ", ".join(block["arxtic_library"].split(","))
+ "\n")
if float(block["arxtic_score"]) >= 0:
file.write("Score: " + block["arxtic_score"] + "\n")
if block["arxtic_date_read"] != "":
file.write("Read date: " + block["arxtic_date_read"] + "\n")
file.write("\n" + 80*"=" + "\n")
file.write("\n")
return 0
def export_title_author(library, filename, directory=PDF_DIR):
if not isinstance(library, bib.Library):
library = bib.Library(library)
with open(directory + filename, "w+") as file:
for block in library.blocks:
if isinstance(block, bib.model.Block):
file.write("#" + block.key + " [" + block["url"] + "]\n")
file.write(wrap("Title: " + block["title"]) + "\n")
file.write(wrap("Author(s): "
+ ", ".join(block["author"].split(" and ")))
+ "\n")
if block["arxtic_comment"] != "":
file.write(wrap("Comment: " + block["arxtic_comment"])
+ "\n")
if block["arxtic_library"] != "":
file.write("Library: "
+ ", ".join(block["arxtic_library"].split(","))
+ "\n")
if block["arxtic_keywords"] != "":
file.write("Keywords: "
+ ", ".join(block["arxtic_library"].split(","))
+ "\n")
if float(block["arxtic_score"]) >= 0:
file.write("Score: " + block["arxtic_score"] + "\n")
if block["arxtic_date_read"] != "":
file.write("Read date: " + block["arxtic_date_read"] + "\n")
file.write("\n" + 80*"=" + "\n")
file.write("\n")
return 0
def export_reference(library, filename, directory=PDF_DIR):
if not isinstance(library, bib.Library):
library = bib.Library(library)
with open(directory + filename, "w+") as file:
for block in library.blocks:
if isinstance(block, bib.model.Block):
file.write("#" + block.key + " [" + block["url"] + "]\n")
return 0
## Manipulation
def find(key, library):
blocks = library.blocks
i = 0
while i < len(blocks):
block = blocks[i]
if isinstance(block, bib.model.Block):
if block.key == key:
return block
i += 1
return None
def mv(key, lib_from, lib_to):
block = find(key, lib_from)
lib_to.add(block)
lib_from.remove(block)
return lib_from, lib_to
def cp(key, lib_from, lib_to):
block = find(key, lib_from)
lib_to.add(block)
return lib_from, lib_to
def rm(key, library):
block = find(key, library)
library.remove(block)
return library
## ArXtic parameters
def arxtic_comment(key, library):
block = find(key, library)
comment = block["arxtic_comment"]
with open("comment.tmp", "w+") as file:
file.write(comment)
subprocess.run(["nvim", "comment.tmp"])
with open("comment.tmp", "r") as file:
comment = "".join(file.readlines())
subprocess.run(["rm", "comment.tmp"])
block["arxtic_comment"] = comment
return library
def arxtic_library_add(key, library, value):
block = find(key, library)
old_value = block["arxtic_library"]
new_value = old_value + "," + value
if new_value[0] == ",": new_value = new_value[1:]
if new_value[-1] == ",": new_value = new_value[:-1]
block["arxtic_library"] = new_value
return library
def arxtic_library_remove(key, library, value):
block = find(key, library)
old_value = block["arxtic_library"]
new_value = old_value.replace(value, "").replace(",,", ",")
if new_value[0] == ",": new_value = new_value[1:]
if new_value[-1] == ",": new_value = new_value[:-1]
block["arxtic_library"] = new_value
return library
def arxtic_keywords_add(key, library, value):
block = find(key, library)
old_value = block["arxtic_keywords"]
new_value = old_value + "," + value
if new_value[0] == ",": new_value = new_value[1:]
if new_value[-1] == ",": new_value = new_value[:-1]
block["arxtic_keywords"] = new_value
return library
def arxtic_keywords_remove(key, library, value):
block = find(key, library)
old_value = block["arxtic_keywords"]
new_value = old_value.replace(value, "").replace(",,", ",")
if new_value[0] == ",": new_value = new_value[1:]
if new_value[-1] == ",": new_value = new_value[:-1]
block["arxtic_keywords"] = new_value
return library
def arxtic_score(key, library, score):
block = find(key, library)
block["arxtic_score"] = score
return library
def arxtic_date_read(key, library, date=None):
block = find(key, library)
if date is None:
date = dt.datetime.now()
block["arxtic_date_read"] = date.strftime("%Y-%m-%d")
return library
def arxtic_filename(key, library, filename):
block = find(key, library)
block["arxtic_filename"] = filename
return library
## External reader
def launch_reader(key, library, directory=PDF_DIR):
block = find(key, library)
fname = block["arxtic_filename"]
subprocess.Popen(["/bin/flatpak", "run", "com.github.ahrm.sioyek", directory+fname],
stdout = subprocess.DEVNULL,
stderr = subprocess.DEVNULL)