large breaking update
This commit is contained in:
parent
76fc4719c2
commit
fc750a1e14
@ -1,5 +1,6 @@
|
|||||||
import csv
|
import csv
|
||||||
import os
|
import os
|
||||||
|
import tomllib
|
||||||
|
|
||||||
import flask_apscheduler
|
import flask_apscheduler
|
||||||
from flask import Flask
|
from flask import Flask
|
||||||
@ -7,31 +8,41 @@ from whoosh.fields import *
|
|||||||
from whoosh.index import create_in
|
from whoosh.index import create_in
|
||||||
from whoosh.qparser import QueryParser
|
from whoosh.qparser import QueryParser
|
||||||
|
|
||||||
from csvparser.csvparser import concatenate_csv_row, getfullpublication
|
from application.csvparser import CsvParser
|
||||||
|
|
||||||
SCRIPT_DIR = os.path.dirname(__file__)
|
SCRIPT_DIR = os.path.dirname(__file__)
|
||||||
DATA_DIR = os.path.abspath(os.path.join(SCRIPT_DIR, "data"))
|
DATA_DIR = os.path.abspath(os.path.join(SCRIPT_DIR, "data"))
|
||||||
|
|
||||||
|
|
||||||
def create_app():
|
def create_app():
|
||||||
|
settings = settings_from_file()
|
||||||
|
|
||||||
APP = Flask(__name__, static_folder="static")
|
APP = Flask(__name__, static_folder="static")
|
||||||
APP.config["SECRET_KEY"] = "ty4425hk54a21eee5719b9s9df7sdfklx"
|
APP.config["SECRET_KEY"] = "ty4425hk54a21eee5719b9s9df7sdfklx"
|
||||||
APP.config["UPLOAD_FOLDER"] = "tmpupload"
|
APP.config["UPLOAD_FOLDER"] = "tmpupload"
|
||||||
|
APP.config["LIBRARY_FILENAME"] = settings["libaryfilename"]
|
||||||
|
APP.config["IMAGE_FOLDER"] = "static/images"
|
||||||
scheduler = flask_apscheduler.APScheduler()
|
scheduler = flask_apscheduler.APScheduler()
|
||||||
scheduler.api_enabled = False
|
scheduler.api_enabled = False
|
||||||
scheduler.init_app(APP)
|
scheduler.init_app(APP)
|
||||||
scheduler.start()
|
scheduler.start()
|
||||||
index_books()
|
index_books(APP.config["LIBRARY_FILENAME"], APP.config["IMAGE_FOLDER"])
|
||||||
|
|
||||||
@scheduler.task("interval", id="update", minutes=10)
|
@scheduler.task("interval", id="update", minutes=10)
|
||||||
def update():
|
def update():
|
||||||
index_books()
|
index_books(APP.config["LIBRARY_FILENAME"], APP.config["IMAGE_FOLDER"])
|
||||||
|
|
||||||
return APP
|
return APP
|
||||||
|
|
||||||
|
|
||||||
def index_books():
|
def get_app():
|
||||||
filename = os.path.join(DATA_DIR, "varlib.csv")
|
APP = Flask(__name__, static_folder="static")
|
||||||
|
return APP
|
||||||
|
|
||||||
|
|
||||||
|
def index_books(filename: str, image_folder: str):
|
||||||
|
csvparser = CsvParser(filename, image_folder)
|
||||||
|
filename = os.path.join(DATA_DIR, csvparser.csv_file)
|
||||||
schema = Schema(
|
schema = Schema(
|
||||||
title=TEXT(stored=True), path=ID(stored=True), content=TEXT
|
title=TEXT(stored=True), path=ID(stored=True), content=TEXT
|
||||||
)
|
)
|
||||||
@ -40,6 +51,13 @@ def index_books():
|
|||||||
with open(filename, "r", encoding="utf_8_sig") as libcsv:
|
with open(filename, "r", encoding="utf_8_sig") as libcsv:
|
||||||
csv_as_dict = csv.DictReader(libcsv)
|
csv_as_dict = csv.DictReader(libcsv)
|
||||||
for row in csv_as_dict:
|
for row in csv_as_dict:
|
||||||
rowcontent = concatenate_csv_row(row)
|
rowcontent = csvparser.concatenate_csv_row(row)
|
||||||
writer.add_document(title=row["Id"], path="/a", content=rowcontent)
|
writer.add_document(title=row["Id"], path="/a", content=rowcontent)
|
||||||
writer.commit()
|
writer.commit()
|
||||||
|
|
||||||
|
|
||||||
|
def settings_from_file():
|
||||||
|
settings = {}
|
||||||
|
with open("settings.toml", "rb") as settings_file:
|
||||||
|
settings = tomllib.load(settings_file)
|
||||||
|
return settings
|
||||||
|
238
library/application/csvparser.py
Normal file
238
library/application/csvparser.py
Normal file
@ -0,0 +1,238 @@
|
|||||||
|
import csv
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
from tempfile import NamedTemporaryFile
|
||||||
|
|
||||||
|
SCRIPT_DIR = os.path.dirname(__file__)
|
||||||
|
DATA_DIR = os.path.abspath(os.path.join(SCRIPT_DIR, "../data"))
|
||||||
|
FIELDNAMES = [
|
||||||
|
"Id",
|
||||||
|
"Publication",
|
||||||
|
"Author",
|
||||||
|
"Year",
|
||||||
|
"Custodian",
|
||||||
|
"Fields",
|
||||||
|
"Type",
|
||||||
|
"Publishers",
|
||||||
|
"License",
|
||||||
|
"LicenseShort",
|
||||||
|
"Highlights",
|
||||||
|
"Comments",
|
||||||
|
"Currently borrowed by",
|
||||||
|
]
|
||||||
|
|
||||||
|
class CsvParser:
|
||||||
|
def __init__(self, csv_file, image_dir):
|
||||||
|
self.csv_file = csv_file
|
||||||
|
self.image_dir = image_dir
|
||||||
|
|
||||||
|
|
||||||
|
def _hasimage(self, id):
|
||||||
|
"""does this Id from the csv have an image uploaded"""
|
||||||
|
image_jpg = os.path.join(self.image_dir, "image-{0}.jpg".format(id))
|
||||||
|
if os.path.exists(image_jpg):
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def parsecsv(self):
|
||||||
|
"""Test function to inspect csv file as dict"""
|
||||||
|
libcsv = open(os.path.join(DATA_DIR, self.csv_file), "r")
|
||||||
|
with libcsv:
|
||||||
|
csv_as_dict = csv.DictReader(libcsv)
|
||||||
|
return csv_as_dict
|
||||||
|
|
||||||
|
|
||||||
|
def getpublications(self):
|
||||||
|
"""get an overview of all publications for the main page"""
|
||||||
|
libcsv = open(os.path.join(DATA_DIR, self.csv_file), "r")
|
||||||
|
with libcsv:
|
||||||
|
csv_as_dict = csv.DictReader(libcsv)
|
||||||
|
publications = {}
|
||||||
|
for row in csv_as_dict:
|
||||||
|
year = row["Year"]
|
||||||
|
if not year:
|
||||||
|
year = "Unknown"
|
||||||
|
|
||||||
|
pubinfo = {
|
||||||
|
"Title": row["Publication"],
|
||||||
|
"Author": row["Author"],
|
||||||
|
"Type": row["Type"].lower().title(),
|
||||||
|
"Year": year,
|
||||||
|
"License": row["License"].lower().title(),
|
||||||
|
"Image": self._hasimage(row["Id"]),
|
||||||
|
}
|
||||||
|
publications[row["Id"]] = pubinfo
|
||||||
|
return publications
|
||||||
|
|
||||||
|
|
||||||
|
def gettypes(self):
|
||||||
|
"""for the dynamic menu get the unique types of publicatons"""
|
||||||
|
libcsv = open(os.path.join(DATA_DIR, self.csv_file), "r")
|
||||||
|
with libcsv:
|
||||||
|
csv_as_dict = csv.DictReader(libcsv)
|
||||||
|
listoftypes = []
|
||||||
|
for row in csv_as_dict:
|
||||||
|
lowertype = row["Type"].lower().title()
|
||||||
|
if lowertype not in listoftypes:
|
||||||
|
listoftypes.append(lowertype)
|
||||||
|
return listoftypes
|
||||||
|
|
||||||
|
|
||||||
|
def getyears(self):
|
||||||
|
"""for the dynamic menu get the unique years for publicatons"""
|
||||||
|
libcsv = open(os.path.join(DATA_DIR, self.csv_file), "r")
|
||||||
|
with libcsv:
|
||||||
|
csv_as_dict = csv.DictReader(libcsv)
|
||||||
|
listofyears = []
|
||||||
|
for row in csv_as_dict:
|
||||||
|
uniqueyear = row["Year"]
|
||||||
|
if not uniqueyear:
|
||||||
|
uniqueyear = "Unknown"
|
||||||
|
if uniqueyear not in listofyears:
|
||||||
|
listofyears.append(uniqueyear)
|
||||||
|
listofyears.sort()
|
||||||
|
return listofyears
|
||||||
|
|
||||||
|
|
||||||
|
def getlicenses(self):
|
||||||
|
"""for the dynamic menu get the unique liscenses for publicatons"""
|
||||||
|
libcsv = open(os.path.join(DATA_DIR, self.csv_file), "r")
|
||||||
|
with libcsv:
|
||||||
|
csv_as_dict = csv.DictReader(libcsv)
|
||||||
|
listoflicenses = []
|
||||||
|
for row in csv_as_dict:
|
||||||
|
license = row["License"].lower().title()
|
||||||
|
if not license:
|
||||||
|
license = "No License Mentioned"
|
||||||
|
if license not in listoflicenses:
|
||||||
|
listoflicenses.append(license)
|
||||||
|
return listoflicenses
|
||||||
|
|
||||||
|
|
||||||
|
def getfieldsofinterest(self):
|
||||||
|
"""for the R&R page get the fields of interest from the publicatons"""
|
||||||
|
libcsv = open(os.path.join(DATA_DIR, self.csv_file), "r")
|
||||||
|
with libcsv:
|
||||||
|
csv_as_dict = csv.DictReader(libcsv)
|
||||||
|
fieldsofinterest = {}
|
||||||
|
for row in csv_as_dict:
|
||||||
|
fields = row["Fields"].split(",")
|
||||||
|
fieldsofinterest[row["Id"]] = fields
|
||||||
|
return fieldsofinterest
|
||||||
|
|
||||||
|
|
||||||
|
def getpublicationfromcsvrow(self, row):
|
||||||
|
"""get entire publication info from a csv row"""
|
||||||
|
year = row["Year"]
|
||||||
|
if not year:
|
||||||
|
year = "Unknown"
|
||||||
|
|
||||||
|
license = row["License"]
|
||||||
|
if not license:
|
||||||
|
license = "No license mentioned"
|
||||||
|
|
||||||
|
borrowed = row["Currently borrowed by"]
|
||||||
|
if not borrowed:
|
||||||
|
borrowed = "No one"
|
||||||
|
|
||||||
|
pubinfo = {
|
||||||
|
"Title": row["Publication"],
|
||||||
|
"Author": row["Author"],
|
||||||
|
"Year": year,
|
||||||
|
"Custodian": row["Custodian"],
|
||||||
|
"Fields": row["Fields"],
|
||||||
|
"Type": row["Type"],
|
||||||
|
"Publishers": row["Publishers"],
|
||||||
|
"License": license,
|
||||||
|
"Highlights": row["Highlights"],
|
||||||
|
"Comments": row["Comments"],
|
||||||
|
"Borrowed": borrowed,
|
||||||
|
"Image": self._hasimage(self, row["Id"]),
|
||||||
|
}
|
||||||
|
return pubinfo
|
||||||
|
|
||||||
|
|
||||||
|
def getfullpublication(self, pubid):
|
||||||
|
"""For the single book view, most complete overview"""
|
||||||
|
libcsv = open(os.path.join(DATA_DIR, self.csv_file), "r")
|
||||||
|
pubinfo = {}
|
||||||
|
with libcsv:
|
||||||
|
csv_as_dict = csv.DictReader(libcsv)
|
||||||
|
for row in csv_as_dict:
|
||||||
|
if pubid == row["Id"]:
|
||||||
|
pubinfo = getpublicationfromcsvrow(row)
|
||||||
|
|
||||||
|
# print(pubinfo)
|
||||||
|
return pubinfo
|
||||||
|
|
||||||
|
|
||||||
|
def generatenewpublicationid(self):
|
||||||
|
"""When uploading a book generate a new unique ID"""
|
||||||
|
libcsv = open(os.path.join(DATA_DIR, self.csv_file), "r")
|
||||||
|
allidsincsv = []
|
||||||
|
with libcsv:
|
||||||
|
csv_as_dict = csv.DictReader(libcsv)
|
||||||
|
for row in csv_as_dict:
|
||||||
|
allidsincsv.append(int(row["Id"]))
|
||||||
|
return str(max(allidsincsv) + 1)
|
||||||
|
|
||||||
|
|
||||||
|
def writepublication(self, uploadform):
|
||||||
|
"""When uploading a publication writes entry to the csv"""
|
||||||
|
id = generatenewpublicationid()
|
||||||
|
with open(
|
||||||
|
os.path.join(DATA_DIR, "varlib.csv"), "a", newline=""
|
||||||
|
) as csvfile:
|
||||||
|
csv_as_writer = csv.DictWriter(csvfile, FIELDNAMES=FIELDNAMES)
|
||||||
|
csv_as_writer.writerow(
|
||||||
|
{
|
||||||
|
"Id": id,
|
||||||
|
"Publication": uploadform.uploadpublication.data,
|
||||||
|
"Author": uploadform.author.data,
|
||||||
|
"Year": uploadform.year.data,
|
||||||
|
"Custodian": uploadform.custodian.data,
|
||||||
|
"Fields": uploadform.fields.data,
|
||||||
|
"Type": uploadform.type.data,
|
||||||
|
"Publishers": uploadform.publishers.data,
|
||||||
|
"License": uploadform.license.data,
|
||||||
|
"LicenseShort": uploadform.licenseshort.data,
|
||||||
|
"Highlights": uploadform.highlights.data,
|
||||||
|
"Comments": uploadform.comments.data,
|
||||||
|
"Currently borrowed by": uploadform.borrowed.data,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
print("succesfully written book to csv")
|
||||||
|
return id
|
||||||
|
|
||||||
|
|
||||||
|
def editborrowedby(self, pubid, borrower):
|
||||||
|
"""Edits the borrowed by field for a publication entry in csv"""
|
||||||
|
tempfile = NamedTemporaryFile("w+t", newline="", delete=False)
|
||||||
|
filename = os.path.join(DATA_DIR, "varlib.csv")
|
||||||
|
with open(filename, "r", newline="") as libcsv, tempfile:
|
||||||
|
csv_as_dict = csv.DictReader(libcsv)
|
||||||
|
csv_as_writer = csv.DictWriter(tempfile, FIELDNAMES=FIELDNAMES)
|
||||||
|
# use the reader to read where, then writer to write the new row.
|
||||||
|
csv_as_writer.writeheader()
|
||||||
|
for row in csv_as_dict:
|
||||||
|
if pubid == row["Id"]:
|
||||||
|
print("publication changes borrower")
|
||||||
|
print(row["Publication"])
|
||||||
|
row["Currently borrowed by"] = borrower
|
||||||
|
csv_as_writer.writerow(row)
|
||||||
|
|
||||||
|
shutil.move(tempfile.name, filename)
|
||||||
|
|
||||||
|
|
||||||
|
def concatenate_csv_row(self, row):
|
||||||
|
rowcontent = []
|
||||||
|
rowcontent.append(row["Publication"])
|
||||||
|
rowcontent.append(row["Author"])
|
||||||
|
rowcontent.append(row["Fields"])
|
||||||
|
rowcontent.append(row["Type"])
|
||||||
|
rowcontent.append(row["Publishers"])
|
||||||
|
rowcontent.append(row["Highlights"])
|
||||||
|
rowcontent.append(row["Comments"])
|
||||||
|
return " ".join(rowcontent)
|
@ -1,236 +0,0 @@
|
|||||||
"""This parses the varlib.csv but only in a way
|
|
||||||
that is actually useful for the site"""
|
|
||||||
import csv
|
|
||||||
import os
|
|
||||||
import shutil
|
|
||||||
from tempfile import NamedTemporaryFile
|
|
||||||
|
|
||||||
script_dir = os.path.dirname(__file__)
|
|
||||||
data_dir = os.path.abspath(os.path.join(script_dir, "../data"))
|
|
||||||
image_dir = os.path.abspath(os.path.join(script_dir, "../static/images"))
|
|
||||||
fieldnames = [
|
|
||||||
"Id",
|
|
||||||
"Publication",
|
|
||||||
"Author",
|
|
||||||
"Year",
|
|
||||||
"Custodian",
|
|
||||||
"Fields",
|
|
||||||
"Type",
|
|
||||||
"Publishers",
|
|
||||||
"License",
|
|
||||||
"LicenseShort",
|
|
||||||
"Highlights",
|
|
||||||
"Comments",
|
|
||||||
"Currently borrowed by",
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
def parsecsv():
|
|
||||||
"""Test function to inspect csv file as dict"""
|
|
||||||
libcsv = open(os.path.join(data_dir, "varlib.csv"), "r")
|
|
||||||
with libcsv:
|
|
||||||
csv_as_dict = csv.DictReader(libcsv)
|
|
||||||
return csv_as_dict
|
|
||||||
|
|
||||||
|
|
||||||
def getpublications():
|
|
||||||
"""get an overview of all publications for the main page"""
|
|
||||||
libcsv = open(os.path.join(data_dir, "varlib.csv"), "r")
|
|
||||||
with libcsv:
|
|
||||||
csv_as_dict = csv.DictReader(libcsv)
|
|
||||||
publications = {}
|
|
||||||
for row in csv_as_dict:
|
|
||||||
year = row["Year"]
|
|
||||||
if not year:
|
|
||||||
year = "Unknown"
|
|
||||||
|
|
||||||
pubinfo = {
|
|
||||||
"Title": row["Publication"],
|
|
||||||
"Author": row["Author"],
|
|
||||||
"Type": row["Type"].lower().title(),
|
|
||||||
"Year": year,
|
|
||||||
"License": row["LicenseShort"].lower().title(),
|
|
||||||
"Image": hasimage(row["Id"]),
|
|
||||||
}
|
|
||||||
publications[row["Id"]] = pubinfo
|
|
||||||
return publications
|
|
||||||
|
|
||||||
|
|
||||||
def hasimage(id):
|
|
||||||
"""does this Id from the csv have an image uploaded"""
|
|
||||||
image_jpg = os.path.join(image_dir, "image-{0}.jpg".format(id))
|
|
||||||
if os.path.exists(image_jpg):
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def gettypes():
|
|
||||||
"""for the dynamic menu get the unique types of publicatons"""
|
|
||||||
libcsv = open(os.path.join(data_dir, "varlib.csv"), "r")
|
|
||||||
with libcsv:
|
|
||||||
csv_as_dict = csv.DictReader(libcsv)
|
|
||||||
listoftypes = []
|
|
||||||
for row in csv_as_dict:
|
|
||||||
lowertype = row["Type"].lower().title()
|
|
||||||
if lowertype not in listoftypes:
|
|
||||||
listoftypes.append(lowertype)
|
|
||||||
return listoftypes
|
|
||||||
|
|
||||||
|
|
||||||
def getyears():
|
|
||||||
"""for the dynamic menu get the unique years for publicatons"""
|
|
||||||
libcsv = open(os.path.join(data_dir, "varlib.csv"), "r")
|
|
||||||
with libcsv:
|
|
||||||
csv_as_dict = csv.DictReader(libcsv)
|
|
||||||
listofyears = []
|
|
||||||
for row in csv_as_dict:
|
|
||||||
uniqueyear = row["Year"]
|
|
||||||
if not uniqueyear:
|
|
||||||
uniqueyear = "Unknown"
|
|
||||||
if uniqueyear not in listofyears:
|
|
||||||
listofyears.append(uniqueyear)
|
|
||||||
listofyears.sort()
|
|
||||||
return listofyears
|
|
||||||
|
|
||||||
|
|
||||||
def getlicenses():
|
|
||||||
"""for the dynamic menu get the unique liscenses for publicatons"""
|
|
||||||
libcsv = open(os.path.join(data_dir, "varlib.csv"), "r")
|
|
||||||
with libcsv:
|
|
||||||
csv_as_dict = csv.DictReader(libcsv)
|
|
||||||
listoflicenses = []
|
|
||||||
for row in csv_as_dict:
|
|
||||||
license = row["LicenseShort"].lower().title()
|
|
||||||
if not license:
|
|
||||||
license = "No License Mentioned"
|
|
||||||
if license not in listoflicenses:
|
|
||||||
listoflicenses.append(license)
|
|
||||||
return listoflicenses
|
|
||||||
|
|
||||||
|
|
||||||
def getfieldsofinterest():
|
|
||||||
"""for the R&R page get the fields of interest from the publicatons"""
|
|
||||||
libcsv = open(os.path.join(data_dir, "varlib.csv"), "r")
|
|
||||||
with libcsv:
|
|
||||||
csv_as_dict = csv.DictReader(libcsv)
|
|
||||||
fieldsofinterest = {}
|
|
||||||
for row in csv_as_dict:
|
|
||||||
fields = row["Fields"].split(",")
|
|
||||||
fieldsofinterest[row["Id"]] = fields
|
|
||||||
return fieldsofinterest
|
|
||||||
|
|
||||||
|
|
||||||
def getpublicationfromcsvrow(row):
|
|
||||||
"""get entire publication info from a csv row"""
|
|
||||||
year = row["Year"]
|
|
||||||
if not year:
|
|
||||||
year = "Unknown"
|
|
||||||
|
|
||||||
license = row["License"]
|
|
||||||
if not license:
|
|
||||||
license = "No license mentioned"
|
|
||||||
|
|
||||||
borrowed = row["Currently borrowed by"]
|
|
||||||
if not borrowed:
|
|
||||||
borrowed = "No one"
|
|
||||||
|
|
||||||
pubinfo = {
|
|
||||||
"Title": row["Publication"],
|
|
||||||
"Author": row["Author"],
|
|
||||||
"Year": year,
|
|
||||||
"Custodian": row["Custodian"],
|
|
||||||
"Fields": row["Fields"],
|
|
||||||
"Type": row["Type"],
|
|
||||||
"Publishers": row["Publishers"],
|
|
||||||
"License": license,
|
|
||||||
"Highlights": row["Highlights"],
|
|
||||||
"Comments": row["Comments"],
|
|
||||||
"Borrowed": borrowed,
|
|
||||||
"Image": hasimage(row["Id"]),
|
|
||||||
}
|
|
||||||
return pubinfo
|
|
||||||
|
|
||||||
|
|
||||||
def getfullpublication(pubid):
|
|
||||||
"""For the single book view, most complete overview"""
|
|
||||||
libcsv = open(os.path.join(data_dir, "varlib.csv"), "r")
|
|
||||||
pubinfo = {}
|
|
||||||
with libcsv:
|
|
||||||
csv_as_dict = csv.DictReader(libcsv)
|
|
||||||
for row in csv_as_dict:
|
|
||||||
if pubid == row["Id"]:
|
|
||||||
pubinfo = getpublicationfromcsvrow(row)
|
|
||||||
|
|
||||||
# print(pubinfo)
|
|
||||||
return pubinfo
|
|
||||||
|
|
||||||
|
|
||||||
def generatenewpublicationid():
|
|
||||||
"""When uploading a book generate a new unique ID"""
|
|
||||||
libcsv = open(os.path.join(data_dir, "varlib.csv"), "r")
|
|
||||||
allidsincsv = []
|
|
||||||
with libcsv:
|
|
||||||
csv_as_dict = csv.DictReader(libcsv)
|
|
||||||
for row in csv_as_dict:
|
|
||||||
allidsincsv.append(int(row["Id"]))
|
|
||||||
return str(max(allidsincsv) + 1)
|
|
||||||
|
|
||||||
|
|
||||||
def writepublication(uploadform):
|
|
||||||
"""When uploading a publication writes entry to the csv"""
|
|
||||||
id = generatenewpublicationid()
|
|
||||||
with open(
|
|
||||||
os.path.join(data_dir, "varlib.csv"), "a", newline=""
|
|
||||||
) as csvfile:
|
|
||||||
csv_as_writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
|
|
||||||
csv_as_writer.writerow(
|
|
||||||
{
|
|
||||||
"Id": id,
|
|
||||||
"Publication": uploadform.uploadpublication.data,
|
|
||||||
"Author": uploadform.author.data,
|
|
||||||
"Year": uploadform.year.data,
|
|
||||||
"Custodian": uploadform.custodian.data,
|
|
||||||
"Fields": uploadform.fields.data,
|
|
||||||
"Type": uploadform.type.data,
|
|
||||||
"Publishers": uploadform.publishers.data,
|
|
||||||
"License": uploadform.license.data,
|
|
||||||
"LicenseShort": uploadform.licenseshort.data,
|
|
||||||
"Highlights": uploadform.highlights.data,
|
|
||||||
"Comments": uploadform.comments.data,
|
|
||||||
"Currently borrowed by": uploadform.borrowed.data,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
print("succesfully written book to csv")
|
|
||||||
return id
|
|
||||||
|
|
||||||
|
|
||||||
def editborrowedby(pubid, borrower):
|
|
||||||
"""Edits the borrowed by field for a publication entry in csv"""
|
|
||||||
tempfile = NamedTemporaryFile("w+t", newline="", delete=False)
|
|
||||||
filename = os.path.join(data_dir, "varlib.csv")
|
|
||||||
with open(filename, "r", newline="") as libcsv, tempfile:
|
|
||||||
csv_as_dict = csv.DictReader(libcsv)
|
|
||||||
csv_as_writer = csv.DictWriter(tempfile, fieldnames=fieldnames)
|
|
||||||
# use the reader to read where, then writer to write the new row.
|
|
||||||
csv_as_writer.writeheader()
|
|
||||||
for row in csv_as_dict:
|
|
||||||
if pubid == row["Id"]:
|
|
||||||
print("publication changes borrower")
|
|
||||||
print(row["Publication"])
|
|
||||||
row["Currently borrowed by"] = borrower
|
|
||||||
csv_as_writer.writerow(row)
|
|
||||||
|
|
||||||
shutil.move(tempfile.name, filename)
|
|
||||||
|
|
||||||
|
|
||||||
def concatenate_csv_row(row):
|
|
||||||
rowcontent = []
|
|
||||||
rowcontent.append(row["Publication"])
|
|
||||||
rowcontent.append(row["Author"])
|
|
||||||
rowcontent.append(row["Fields"])
|
|
||||||
rowcontent.append(row["Type"])
|
|
||||||
rowcontent.append(row["Publishers"])
|
|
||||||
rowcontent.append(row["Highlights"])
|
|
||||||
rowcontent.append(row["Comments"])
|
|
||||||
return " ".join(rowcontent)
|
|
@ -1,66 +0,0 @@
|
|||||||
Id,Publication,Author,Year,Custodian,Fields,Type,Publishers,License,LicenseShort,Highlights,Comments,Currently borrowed by
|
|
||||||
1,The Economics of Anarchism,Anarcho,2012,Varia,"Economics, Anarchism",Zine,theanarchistlibrary.org,Anti-copyright,Anti-copyright,"The labourer retains, even after he has recieved his wages, a natural right in the thing he has produced",,No one
|
|
||||||
2,Identity Politics - An Anthology,The Anarchist Library,,Varia,Identity politics,Zine,Paper Jam Collective,No license mentioned,No license mentioned,,Varia,No one
|
|
||||||
3,The mythology of work,CrimeThinc.com,,Varia,"Work, Anticapitalism",Zine,CrimeThinc.com,No license mentioned,No license mentioned,,"A selection from 'Work', a 376-page analysis of contemporary capitalism",
|
|
||||||
4,Forget Shorter Showers - Why Personal Change Does Not Equal Political Change,Derrick Jensen,2009,Varia,Environmental justice,Zine,,No license mentioned,No license mentioned,Green consumerism isn't enough.,,
|
|
||||||
5,Choreo-Graphic-Hypothesis,"<meta-author=""Joana Chicau"";>",2018,Varia,"Live Coding, Choreography",Paperback,Self published: Joana Chicau,Free Art License 1.3,Free Art License,"Theatrical actions are not necessary to the performance, Avoid if at all possible",,
|
|
||||||
6,Point of no Return,,2013,Varia,Anarchism in the West,Zine,,No license mentioned,No license mentioned,,Stories about becoming an anarchist in the West in the 80s,
|
|
||||||
7,Waar slapen de kroegtijgers van Oud Charlois,Jacco Weener,,Varia,"Oud Charlois, Drawing",Paperback,Self-published,No license mentioned,No license mentioned,,,
|
|
||||||
8,Dubbeldruk Play with me,"Editorial team: Karin de Jong, Giulia de Giovanelli, Floor van Luijk",2019,Varia,"Copyright, Publishing, Printing",Parazine,Printroom,Free art license,Free art license,,"Confusing licenses mentioned in the about text on the back of the publication, FAL, Copy-left and copy right all mentioned",
|
|
||||||
9,To Boldly Go: a starters guide to hand made and diy films,Film Werkplaats Worm Rotterdam,2008,Varia,"Experimental film, Analog film, DIY, Hand-made",Paperback,Knust (Nijmegen),'No license mentioned,No license mentioned,,,
|
|
||||||
10,Anarchism: Basic concepts and ideas,Peter Storm,2018,Varia,"Anarchism, Dutch Theory",Zine,Ravotr Editions in collaboration with Paper Jam,Feel free to use and copy this text as you see fit. Mentioning source and author would be greatly appreciated.,No license mentioned,,Revised text of a transcribed lecture Storm gave in Rotterdam.,
|
|
||||||
11,Queering Anarchism,"Deric Shannon, Abbey Willis",,Varia,"Anarchism, Queer Theory",Zine,Paper Jam Collective,No license mentioned,No license mentioned,,,
|
|
||||||
12,Abolish restaurants,Prole.info,2010,Varia,"Labour, Food industry",Paperback,Pm Press,Copyright 2010,Copyright,Drawing on a range of anti-capitalist ideas as well as a heaping plate of personal experience,,CCL
|
|
||||||
13,"Elk Woord Een Vonk: Verboden Teksten, verwerpelijke vervolging: de zaak Joke Kaviaar",Steungroep 13 September,2014,Varia (or Luke?),"Joke Kaviaar, Immigration, Activism, Forbidden Texts, Incarceration",Softcover,Self-published,Copyleft,Copyleft,,https://13-september.nl,
|
|
||||||
14,A NO BORDERS manifesto,Ill Will Editions,2015,Varia,Migrant justice,Zine,Self-published,No license mentioned,No license mentioned,,,
|
|
||||||
16,Futur Musique,De fanfare voor vooruit strevende volksmuziek,2018,Varia,"Musical Instruments, DIY",Zine,Self-published,No license mentioned,No license mentioned,Copied instructions on building one's own musical instruments,,
|
|
||||||
17,Franchir le cap,Quentin Juhel,2019,Varia,Convivial computation,Zine,Self-publsihed,Creative commons CC-BY-SA,Creative commons,,,
|
|
||||||
18,Consensus: Decision Making,Seeds For Change UK,2010,Varia,"Decision making, Consensus",Zine,Self-published,No license mentioned,No license mentioned,Short guide ,,
|
|
||||||
19,"Waar ook op gestemd wordt, wij laten ons niet regeren",Anarchistische Groep Nijmegen,2014,Varia,Democracy,Zine,Self-published,No license mentioned,No license mentioned,,,
|
|
||||||
20,The NGO sector: the trojan horse of capitalism,Crn Blok,,Varia,"Anti-capitalism, NGO",Zine,Self-published,Copyleft,Copyleft,,,
|
|
||||||
21,Messing Around With Packet Radio,"Roel Roscam Abbing, Dennis De Bel",,Varia,"Packet radio, DIY, radio, wireless",Zine,Self-published,Public domain,Public domain,,,
|
|
||||||
22,Organising Socially: affinity groups & decision making,Seeds for change,,Varia,"Consensus, Decision making, Affinity groups",Zine,Paper Jam Collective,No license mentioned,No license mentioned,,,
|
|
||||||
23,The Moral of the Xerox,"Florian Cramer, Clara Lobregat Balaguer",2017,Varia,"Piracy, Cultural Appropriation",Zine,Self-published,No license mentioned,No license mentioned,"Printed in diocese of Cologne, Germany on the joyous occasion of the Pluriversale VII: Stealing from the west for the critical parishioners of Akademie der Kunste der Welt",,
|
|
||||||
24,Non-Western Anarchisms,Jason Adams,,Varia,Non-Western Anarchisms,Zine,Zaba Books,No license mentioned,No license mentioned,"The purpose of this paper is to help anarchist/anti-authoritarian movements active today to reconceptualise the history and theory of first-wave anarchism on the global level, and to reconsider its relevance to the continuing anarchist project.",,
|
|
||||||
33,The immaterial labor union #7: immersive advertisement,Lídia Pereira and Δεριζαματζορ Προμπλεμ ιναυστραλια,,Varia,"labour, Advertisement, immersion, social media",Zine,Self-published,Zine is published under Gnu free documentation license 1.3 unless otherwise specified ,GNU Free Documentation License,,,
|
|
||||||
34,The immateriality labor union #10: immateriality,Lídia Pereira and Δεριζαματζορ Προμπλεμ ιναυστραλια,2017,Varia,"Labour, Immateriality",Zine,Self-published,GNU Free Documentation License,GNU Free Documentation License,,Varia,No one
|
|
||||||
35,The immaterial labor union. Special Issue #1: Homebrew Server Club,Homebrew Server Club,2017,Varia,"Self-Hosting, Servers, DIY",Zine,Self-published,CC-BY-SA,Creative commons,,,
|
|
||||||
36,Pervasive labour union. Special issue #2: The Entreprecariat,Silvio Lorusso,2017,Varia,"Entreprecariat, Labour, Precarity",Zine,Self-published,No license mentioned,No license mentioned,,Between April and May 2017 the Zine's name changed from Immaterial Labor Union to Pervasive Labour Union,
|
|
||||||
37,'Pervasive labour union #13: Fed Up,Lídia Pereira,2019,Varia,"Labour, DIY, federation",Zine,Self-published,"GNU Free Documentation License 1.3, CC-0, Copyright (C) 2019, Julia Janssen, Peer Production License",GNU Free Documentation License,,,
|
|
||||||
38,Each Page a Function,Raphaël Bastide,2019,Varia,"Automation, Drawing, Web to Print",Paperback,LeMegot editions,No license mentioned,No license mentioned,,,
|
|
||||||
39,In Beweging: Magazine van de Anarchistische Groep Nijmegen,Anarchistische Groep Nijmegen ,2018,Varia,"Anarchism, 1st of May, Nijmegen",Zine,Self-published,No license mentioned,No license mentioned,,Anarchistische Bieb de Zwarte Uil. library in Nijmegen open on saturday from 12:00 till 17:30,
|
|
||||||
40,Deep pockets #2 Shadowbook: Writing through the digital 2014-2018,Miriam Rasch,2018,Varia,"Language, digital, communication",Paperback,Institute of Network Cultures,CC BY-NC-SA 4.0,Creative Commons,,,
|
|
||||||
41,The Techno Galactic Software Observatory Reader,Constant,2018,Varia,"Software Studies, Software Curious People, Observation",Paperback,Self- published,No license mentioned,No license mentioned,,Reader for Techno Galactic Software Observatory work session,
|
|
||||||
42,Upsetting Settings,Piet Zwart Institute,2019,Varia,"Catalogue, Experimental publishing",Softcover,XPUB,Copyleft,Copyleft,,Dissertations from the Piet Zwart Institute 2017-2019,
|
|
||||||
43,I Have Witnessed First Time Experiences ,Connie Butler,2016,Varia,Fine Art,Softcover,Piet Zwart institute MFA,Copyright 2016,Copyright,,,
|
|
||||||
44,The Age of Aquariums: old horoscopes for the new year,Brenda Bosma,2013,Varia,Horoscope,Paperback,Subbacultcha!,No license mentioned,No license mentioned,,,
|
|
||||||
45,The Internet Measurement Handbook,,2018,Varia,"Internet, blackout, cyber-security",Paperback,Netblocks,CC,Creative Commons,,,
|
|
||||||
46,Issue #4 2019,Design Department Sandberg,2019,Varia ,Design theory,Paperback,Drukkerij RaddraaierSSP,No license mentioned,No license mentioned,,Dissertations from the Design Museum,
|
|
||||||
47,O Bike and Friends,Dennis De Bel,,Varia,"Bike sharing, DIY",Zine,Self-published,No license mentioned,No license mentioned,,,
|
|
||||||
48,Algoliterary Encounters,Algolit,2017,Varia,"Natural text processing, machine learning, algorithms",Catalogue,Algolit,Free Art License,Free Art License,,,
|
|
||||||
49,Der Fall von Afrin,Unknown,,Varia,Turkish politics,Zine,Unknown,No license mentioned,No license mentioned,,,
|
|
||||||
50,Andy de Fiets: Letter to Robin Kinross ,"Paul Haworth, Sam de Groot",2010,Varia,Typography,Paperback,TRUE TRUE TRUE Amsterdam,"Copyright 2009,2010",Copyright,,,
|
|
||||||
51,Ora Elastică,ODD,2018,Varia,"Art, Indonesia, Romania, non-western art theory",Softcover,frACTalia,No license mentioned,No license mentioned,,,
|
|
||||||
52,4 x Through The Labyrinth,"O. Nicolai & J. Wenzel, translated by Sadie Plant",2012,Joana Chicau,Labyrinths,Softcover,Rollo Press,Copyright,Copyright,,,
|
|
||||||
53,Towards an Immersive Intelligence,Joseph Nechvatal,2009,Joana Chicau?,"Virtual reality, Computer Art",Paperback,Edgewise,Copyright,Copyright,,,
|
|
||||||
54,Xavan et Jaluka - The Death of the Authors 1946,Peter Westenberg,2018,Varia,Public domain,Zine,Constant Verlag,Copyleft,Copyleft,,,
|
|
||||||
55,Spreekt U Sint-Gillis? Parlez-vous Saint-Gillois?,,,Varia,"Bruxelles, Language, Sint-Gillis",Softcover,Constant Verlag,Copyleft,Copyleft,,,
|
|
||||||
56,Mondothèque: a radiated book,"André Castro , Sînziana Păltineanu , Dennis Pohl , Dick Reckard , Natacha Roussel , Femke Snelting , Alexia de Visscher",2016,Varia,"Archive, Otlet, Library science, Mondaneum, Google, Mons",Softcover,Constant,Copyleft,Copyleft,,,
|
|
||||||
57,"The Death of the Authors: 'James Joyce, Rabindranath Tagore & Their Return to Life in Four Seasons",A Constant Remix,2013,Varia,"James Joyce, Ulysses",Softcover,Constant,Public domain,Public domain,,'generated from Public domain sources,
|
|
||||||
58,Verbindingen/Jonctions 10 : Tracks in electr(on)ic fields,Constant,2009,Varia,"Art, activism, technological culture",Softcover,Constant,Copyleft,Copyleft,,,
|
|
||||||
59,Conversations,Constant,2014,Varia,"Software studies, Libre graphics",Softcover,Constant Verlag,Copyleft,Copyleft,,,
|
|
||||||
60,Networks of one's own #1: Etherbox,"Michael Murtaugh, An Mertens, Roel Roscam Abbing, Femke Snelting",2018,Varia,"Networks, Digital Infrastructures, DIY, DIWO, Executable publication, Experimental Publishing",Paperback,Constant Verlag,Copyleft,Copyleft,,,
|
|
||||||
61,Mots de la cage aux ours - woorden uit de berenkuil,Constant,2012,Varia,"words, language, Bruxelles",Softcover,Constant,Copyleft,Copyleft,,,
|
|
||||||
62,Snake rituals and switching circuits,Florian Cramer,2009,Danny,"mass communication, personal communication, new media",paperback,Piet Zwart Institute,Creative Commons Attribution-Share Alike 3.0,Creative Commons,The function of a medium is ultimately decided by its users and not by its creators,,
|
|
||||||
63,Magium issue 1: On Eating in isolation,Alice Strete,2020,Varia,"food, sharing, personal stories, consumption",zine,Self Published,Free Art License,Free Art License,,,No one
|
|
||||||
64,Networks of One's Own 2: three takes on taking care,"Varia, Constant and Colm O’Neill",2019,Varia,"Software, internet, taking care, homebrew",paperback,Varia,Copyleft,Copyleft,Networks Of One’s Own is a periodic para-nodal publication that is itself collectively within a network.,,No one
|
|
||||||
65,My Hard-Drive Died Along With My Heart ,Thomas Walsklaar,2016,Varia,"Hard-drives, Data, Loss, Trust, Technology, collection, materiality, obsolescence, preservation, progress, writing ",paperback,Self Published, No License Mentioned,No License Mentioned,,"We always seem to be looking for a new technical solution for knowledge and information storage. We hope there is one magical, final solution, one that will solve every issu But easy solutions create their own problems. The perceived view of the stable nature of digital information differs from reality. There are many points of failure, like old physical formats, lost or non functional machines, companies that go bankrupt, file formats with no support in the future, or changing user licenses. It seems that the more technical the technology gets, the more problems it creates.",No one
|
|
||||||
67,"Low power to the people: Pirates, protest. and politics in FM radio activism",Christina Dunbar-Hester,2014,Danny,"Radio, Activism, FM, Wireless, Legal, Policies, Piracy, Politics",hardcover,MIT press,Copyright,Copyright,The internet didn't drop down from the sky--it was created by the military and we need to take it back,,No one
|
|
||||||
68,Pretty fly for a wi-fi,Roel Roscam Abbing,2014,Varia,"Wireless, Wifi, internet, DIY, antennas ",paperback,Self Published, GNU Free Documentation License 1.3,GNU Free Documentation License,,appreciate the DIY etched beauty of Object #4,Danny
|
|
||||||
69,TX Pirate radio dispatches from eighties London ,Stephen Hebditch,2017,Danny,"Radio, Activism, FM, AM, Wireless, Piracy, Politics, Zine culture",paperback,Tx Publications,Copyright,Copyright,,,Danny
|
|
||||||
70,The impossibility of interface,Matthew Fuller,2006,Varia,"Interface, Software, Software culture, Media design, ",paperback,HRO,No License Mentioned,No License Mentioned,,"Such contextualisation, in turn, suggests ways of developing digital media with an awareness of its social ramifications.",
|
|
||||||
71,Let's use free speech to praise pirate radio ,Andrew Bushard,2014,Danny,"Radio, Poetry, Piracy",paperback, Free Press Media Press Inc,No License Mentioned,No License Mentioned,At the risk of sounding melodramatic I want to consider pirate radio as innately noble,"25 Poems, 26 Pages Pirate radio represents magical rebellion. Pirate radio signifies creative protest. Pirate radio can change the world.",
|
|
||||||
72,Cursusboek voor het N-examen,VERON vereniging experimenteel onderzoek nederland,2012,Varia,"Radio, Broadcasting, Exams, equipment, Radio amateurs",Paperback,Stichting servicebureau VERON,Copyright,Copyright,,,No one
|
|
||||||
73,Freax the brief history of the computer demoscene,Tamás Polgár,2008,Danny,"Demoscene, Coding, Software art, Amiga, Home Computers, Music",paperback,CSW Verlag digitalkultur,Copyright,Copyright,,Very thorough first hand account of the demoscene until the end of the amiga era. The book hints towards freax volume 2 but this book was never made.,Luke
|
|
||||||
74,Tasks of the Contingent Librarian,Simon Browne,2020,Varia,Contingent Librarianship,Box of cards,de Appel,Copyleft,Copyleft,,,
|
|
||||||
75,Handmade Electronic Music,Nicolas Collins,2009,Danny,"Music, DIY, Hacking, Hardware, How-To",Paperback,Routledge,Copyright,Copyright,,,No one
|
|
|
@ -58,22 +58,6 @@ class PublicationForm(FlaskForm):
|
|||||||
)
|
)
|
||||||
publishers = StringField("Publishers:")
|
publishers = StringField("Publishers:")
|
||||||
license = StringField("License:")
|
license = StringField("License:")
|
||||||
licenseshort = RadioField(
|
|
||||||
"Select the closest license type:",
|
|
||||||
choices=[
|
|
||||||
("Anti-copyright", "Anti-copyright"),
|
|
||||||
("No License Mentioned", "No License Mentioned"),
|
|
||||||
("Free Art License", "Free Art License"),
|
|
||||||
("Copyright", "Copyright"),
|
|
||||||
("Copyleft", "Copyleft"),
|
|
||||||
("Creative Commons", "Creative Commons"),
|
|
||||||
("Public Domain", "Public Domain"),
|
|
||||||
(
|
|
||||||
"GNU Free Documentation License",
|
|
||||||
"GNU Free Documentation License",
|
|
||||||
),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
highlights = StringField("Highlights from the publication:")
|
highlights = StringField("Highlights from the publication:")
|
||||||
comments = StringField("Comments on the publication:")
|
comments = StringField("Comments on the publication:")
|
||||||
borrowed = StringField("Currently borrowed by:")
|
borrowed = StringField("Currently borrowed by:")
|
@ -15,12 +15,11 @@ from requests import get
|
|||||||
from werkzeug.utils import secure_filename
|
from werkzeug.utils import secure_filename
|
||||||
|
|
||||||
from app import create_app
|
from app import create_app
|
||||||
from borrowform import BorrowForm
|
from forms.borrowform import BorrowForm
|
||||||
from csvparser.csvparser import (editborrowedby, getfullpublication,
|
from forms.uploadform import PublicationForm
|
||||||
getlicenses, getpublications, gettypes,
|
|
||||||
getyears, writepublication)
|
from application.csvparser import CsvParser
|
||||||
from search import search
|
from search import search
|
||||||
from uploadform import PublicationForm
|
|
||||||
|
|
||||||
APP = create_app()
|
APP = create_app()
|
||||||
csrf = CSRFProtect()
|
csrf = CSRFProtect()
|
||||||
@ -31,10 +30,11 @@ csrf.init_app(APP)
|
|||||||
def index():
|
def index():
|
||||||
"""Main route, shows all the books and you can filter them
|
"""Main route, shows all the books and you can filter them
|
||||||
based on year, license, type"""
|
based on year, license, type"""
|
||||||
pubtypes = gettypes()
|
csvparser = CsvParser(APP.config["LIBRARY_FILENAME"], APP.config["IMAGE_FOLDER"])
|
||||||
pubyears = getyears()
|
pubtypes = csvparser.gettypes()
|
||||||
publicenses = getlicenses()
|
pubyears = csvparser.getyears()
|
||||||
publicatons = getpublications()
|
publicenses = csvparser.getlicenses()
|
||||||
|
publicatons = csvparser.getpublications()
|
||||||
template = render_template(
|
template = render_template(
|
||||||
"index.html",
|
"index.html",
|
||||||
publications=publicatons,
|
publications=publicatons,
|
||||||
@ -49,16 +49,16 @@ def index():
|
|||||||
def upload():
|
def upload():
|
||||||
"""Upload route, a page to upload a book to the csv"""
|
"""Upload route, a page to upload a book to the csv"""
|
||||||
uploadform = PublicationForm()
|
uploadform = PublicationForm()
|
||||||
|
csvparser = CsvParser(APP.config["libaryfilename"], APP.config[""])
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
if uploadform.validate_on_submit() and checksecret(
|
if uploadform.validate_on_submit() and checksecret(
|
||||||
uploadform.secret.data
|
uploadform.secret.data
|
||||||
):
|
):
|
||||||
id = writepublication(uploadform)
|
id = csvparser.writepublication(uploadform)
|
||||||
saveimage(uploadform.image.data, id)
|
saveimage(uploadform.image.data, id)
|
||||||
return redirect(str(id), code=303)
|
return redirect(str(id), code=303)
|
||||||
else:
|
else:
|
||||||
return render_template("upload.html", uploadform=uploadform)
|
return render_template("upload.html", uploadform=uploadform)
|
||||||
print("test")
|
|
||||||
return render_template("upload.html", uploadform=uploadform)
|
return render_template("upload.html", uploadform=uploadform)
|
||||||
|
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ from whoosh.fields import *
|
|||||||
from whoosh.index import open_dir
|
from whoosh.index import open_dir
|
||||||
from whoosh.qparser import QueryParser
|
from whoosh.qparser import QueryParser
|
||||||
|
|
||||||
from csvparser.csvparser import getfullpublication
|
from application.csvparser import CsvParser
|
||||||
|
|
||||||
SCRIPT_DIR = os.path.dirname(__file__)
|
SCRIPT_DIR = os.path.dirname(__file__)
|
||||||
DATA_DIR = os.path.abspath(os.path.join(SCRIPT_DIR, "data"))
|
DATA_DIR = os.path.abspath(os.path.join(SCRIPT_DIR, "data"))
|
||||||
|
@ -1,9 +1,3 @@
|
|||||||
[title]
|
title = "Your library title"
|
||||||
"Your library title"
|
libaryfilename = "newlib.csv"
|
||||||
|
readmethod = "download"
|
||||||
[libaryfilename]
|
|
||||||
"varlib.csv"
|
|
||||||
|
|
||||||
[readmethod]
|
|
||||||
"download"
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user