Install black.
This commit is contained in:
2850
utils/books.json
Normal file
2850
utils/books.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,2 +1,2 @@
|
||||
# save this file as 'config.py' and then, fill it with you api key
|
||||
GOODREADS_PUBLIC_API_KEY = 'write here your goodreads public API key'
|
||||
GOODREADS_PUBLIC_API_KEY = "write here your goodreads public API key"
|
||||
|
||||
@@ -8,46 +8,53 @@ from config import GOODREADS_PUBLIC_API_KEY
|
||||
|
||||
def get_details(book_object):
|
||||
|
||||
url = "http://www.goodreads.com/book/title.xml?key={}&title={}".format(GOODREADS_PUBLIC_API_KEY,
|
||||
urllib.parse.quote_plus(book_object['title']))
|
||||
url = "http://www.goodreads.com/book/title.xml?key={}&title={}".format(
|
||||
GOODREADS_PUBLIC_API_KEY, urllib.parse.quote_plus(book_object["title"])
|
||||
)
|
||||
|
||||
try:
|
||||
tree = ET.ElementTree(file=urllib.request.urlopen(url))
|
||||
root = tree.getroot()
|
||||
book = root.find('book')
|
||||
book_object['year'] = book.find('publication_year').text or ''
|
||||
book_object['lang'] = book.find('language_code').text
|
||||
book_object['rating'] = book.find('average_rating').text
|
||||
book_object['pages'] = book.find('num_pages').text
|
||||
book_object['image_url'] = book.find('image_url').text
|
||||
book = root.find("book")
|
||||
book_object["year"] = book.find("publication_year").text or ""
|
||||
book_object["lang"] = book.find("language_code").text
|
||||
book_object["rating"] = book.find("average_rating").text
|
||||
book_object["pages"] = book.find("num_pages").text
|
||||
book_object["image_url"] = book.find("image_url").text
|
||||
except urllib.error.HTTPError as e:
|
||||
print('Error getting book details from GoodReads for book: {}. \nGot error: '.format(book_object['title']))
|
||||
print(str(e.getcode()) + ' ' + e.msg)
|
||||
print(
|
||||
"Error getting book details from GoodReads for book: {}. \nGot error: ".format(
|
||||
book_object["title"]
|
||||
)
|
||||
)
|
||||
print(str(e.getcode()) + " " + e.msg)
|
||||
|
||||
|
||||
def get_goodread_info(library, force):
|
||||
import sys
|
||||
print('')
|
||||
print('Getting GoodReads data...')
|
||||
|
||||
print("")
|
||||
print("Getting GoodReads data...")
|
||||
|
||||
processed = 0
|
||||
total_book_count = 0
|
||||
for key in library:
|
||||
total_book_count += len(library[key])
|
||||
|
||||
|
||||
for category in library:
|
||||
book_list = library[category]
|
||||
for book in book_list:
|
||||
# do not call the api again if we already have the infomation
|
||||
if not force and 'rating' in book and book['rating']:
|
||||
if not force and "rating" in book and book["rating"]:
|
||||
processed += 1
|
||||
continue
|
||||
get_details(book)
|
||||
processed += 1
|
||||
|
||||
print('{}/{} records processed.'.format(processed, total_book_count), end="\b")
|
||||
sys.stdout.write('\r')
|
||||
print(
|
||||
"{}/{} records processed.".format(processed, total_book_count), end="\b"
|
||||
)
|
||||
sys.stdout.write("\r")
|
||||
sys.stdout.flush() # <- makes python print it anyway
|
||||
|
||||
# need to wait a second between the requests, to not abuse the API
|
||||
|
||||
@@ -7,65 +7,62 @@ import simplejson
|
||||
# ARGUMENT HANDLING
|
||||
try:
|
||||
import argparse
|
||||
parser = argparse.ArgumentParser(description='Process file.')
|
||||
|
||||
parser = argparse.ArgumentParser(description="Process file.")
|
||||
parser.add_argument("--in_file", help="File to process, defaults to ./../README.MD")
|
||||
parser.add_argument(
|
||||
'--in_file',
|
||||
help='File to process, defaults to ./../README.MD')
|
||||
parser.add_argument(
|
||||
'--out_file',
|
||||
help='File to save to, defaults to ./../README-NEW.MD')
|
||||
parser.add_argument(
|
||||
'--input_file_type',
|
||||
choices=['old', 'new'],
|
||||
help='old if links are displayed in a list, new if in a table')
|
||||
parser.add_argument(
|
||||
'--sort_by',
|
||||
choices = ['rating', 'title', 'author', 'year'],
|
||||
help='defaults to rating')
|
||||
parser.add_argument(
|
||||
'--force',
|
||||
dest='force',
|
||||
action='store_true',
|
||||
default=False
|
||||
"--out_file", help="File to save to, defaults to ./../README-NEW.MD"
|
||||
)
|
||||
parser.add_argument(
|
||||
'--store-json',
|
||||
dest='store_json',
|
||||
action='store_true',
|
||||
default=False
|
||||
"--input_file_type",
|
||||
choices=["old", "new"],
|
||||
help="old if links are displayed in a list, new if in a table",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--sort_by",
|
||||
choices=["rating", "title", "author", "year"],
|
||||
help="defaults to rating",
|
||||
)
|
||||
parser.add_argument("--force", dest="force", action="store_true", default=False)
|
||||
parser.add_argument(
|
||||
"--store-json", dest="store_json", action="store_true", default=False
|
||||
)
|
||||
flags = parser.parse_args()
|
||||
except ImportError:
|
||||
flags = None
|
||||
|
||||
|
||||
def sort(library, key_to_sort_on, reverse = False):
|
||||
def sort(library, key_to_sort_on, reverse=False):
|
||||
new_library = {}
|
||||
for key in library:
|
||||
books = library[key]
|
||||
new_library[key] = sorted(books, key=lambda k: k[key_to_sort_on], reverse=reverse)
|
||||
new_library[key] = sorted(
|
||||
books, key=lambda k: k[key_to_sort_on], reverse=reverse
|
||||
)
|
||||
return new_library
|
||||
|
||||
|
||||
def format_library(library):
|
||||
formated_library = []
|
||||
for category in library:
|
||||
for book in library[category]:
|
||||
book["category"] = category[len("## "):]
|
||||
book["category"] = category[len("## ") :]
|
||||
formated_library.append(book)
|
||||
return formated_library
|
||||
|
||||
|
||||
def main():
|
||||
from read_file import load
|
||||
from gooodreads import get_goodread_info
|
||||
from write_file import render
|
||||
|
||||
in_file = flags.in_file or './../README.md'
|
||||
out_file = flags.out_file or './../README-new.md'
|
||||
input_file_type = flags.input_file_type or 'new'
|
||||
sort_by = flags.sort_by or 'rating'
|
||||
in_file = flags.in_file or "./../README.md"
|
||||
out_file = flags.out_file or "./../README-new.md"
|
||||
input_file_type = flags.input_file_type or "new"
|
||||
sort_by = flags.sort_by or "rating"
|
||||
force = flags.force
|
||||
store_json = flags.store_json
|
||||
reverse = True if sort_by == 'rating' else False
|
||||
reverse = True if sort_by == "rating" else False
|
||||
|
||||
library = load(in_file, input_file_type)
|
||||
get_goodread_info(library, force)
|
||||
@@ -74,5 +71,7 @@ def main():
|
||||
if store_json:
|
||||
with open("out.json", "w") as f:
|
||||
f.write(simplejson.dumps(format_library(library), indent=4, sort_keys=True))
|
||||
if __name__ == '__main__':
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
8
utils/pyvenv.cfg
Normal file
8
utils/pyvenv.cfg
Normal file
@@ -0,0 +1,8 @@
|
||||
home = /usr
|
||||
implementation = CPython
|
||||
version_info = 3.8.2.final.0
|
||||
virtualenv = 20.0.20
|
||||
include-system-site-packages = false
|
||||
base-prefix = /usr
|
||||
base-exec-prefix = /usr
|
||||
base-executable = /usr/bin/python3
|
||||
@@ -8,24 +8,24 @@ def read_file_content(file):
|
||||
# old (list)
|
||||
def parse_book_string(book_string):
|
||||
book = {}
|
||||
book['title'] = book_string.split('[')[1].split(']')[0]
|
||||
book['url'] = book_string.split(']')[1].split('(')[1].split(')')[0]
|
||||
book['author'] = book_string.split(' by ')[-1]
|
||||
book['rating'] = ''
|
||||
book['year'] = ''
|
||||
book["title"] = book_string.split("[")[1].split("]")[0]
|
||||
book["url"] = book_string.split("]")[1].split("(")[1].split(")")[0]
|
||||
book["author"] = book_string.split(" by ")[-1]
|
||||
book["rating"] = ""
|
||||
book["year"] = ""
|
||||
return book
|
||||
|
||||
|
||||
# new (table)
|
||||
def parse_book_string_new(book_string):
|
||||
book = {}
|
||||
book_split = book_string.split('|')
|
||||
book_split = book_string.split("|")
|
||||
# print(book_split)
|
||||
book['title'] = book_split[1].strip()
|
||||
book['author'] = book_split[2].strip()
|
||||
book['url'] = book_split[3].strip().split('[')[1].split('(')[1].split(')')[0]
|
||||
book['rating'] = book_split[3].strip().split('[')[1].split(']')[0]
|
||||
book['year'] = book_split[4].strip()
|
||||
book["title"] = book_split[1].strip()
|
||||
book["author"] = book_split[2].strip()
|
||||
book["url"] = book_split[3].strip().split("[")[1].split("(")[1].split(")")[0]
|
||||
book["rating"] = book_split[3].strip().split("[")[1].split("]")[0]
|
||||
book["year"] = book_split[4].strip()
|
||||
return book
|
||||
|
||||
|
||||
@@ -33,8 +33,8 @@ def load(file, file_type):
|
||||
file = read_file_content(file)
|
||||
|
||||
# we start one line after tilte # Books
|
||||
line_to_start = file.index('# Books') + 1
|
||||
current_title = ''
|
||||
line_to_start = file.index("# Books") + 1
|
||||
current_title = ""
|
||||
books_under_current_title = []
|
||||
library = {}
|
||||
|
||||
@@ -42,7 +42,7 @@ def load(file, file_type):
|
||||
line = file[i]
|
||||
|
||||
# we have a title
|
||||
if line.startswith('##'):
|
||||
if line.startswith("##"):
|
||||
if len(current_title) == 0:
|
||||
current_title = line
|
||||
else:
|
||||
@@ -52,12 +52,16 @@ def load(file, file_type):
|
||||
continue
|
||||
|
||||
# we have a book
|
||||
if file_type == 'old':
|
||||
if line.startswith('*'):
|
||||
if file_type == "old":
|
||||
if line.startswith("*"):
|
||||
book = parse_book_string(line)
|
||||
books_under_current_title.append(book)
|
||||
else:
|
||||
if line.startswith('|') and not line.startswith('| Name') and not line.startswith('|---'):
|
||||
if (
|
||||
line.startswith("|")
|
||||
and not line.startswith("| Name")
|
||||
and not line.startswith("|---")
|
||||
):
|
||||
book = parse_book_string_new(line)
|
||||
books_under_current_title.append(book)
|
||||
|
||||
|
||||
8
utils/requirements.txt
Normal file
8
utils/requirements.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
appdirs==1.4.4
|
||||
attrs==20.1.0
|
||||
black==19.10b0
|
||||
click==7.1.2
|
||||
pathspec==0.8.0
|
||||
regex==2020.7.14
|
||||
toml==0.10.1
|
||||
typed-ast==1.4.1
|
||||
7
utils/update_json_files.py
Normal file
7
utils/update_json_files.py
Normal file
@@ -0,0 +1,7 @@
|
||||
import json
|
||||
|
||||
from read_file import load
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
library = load("../README.md", "new")
|
||||
@@ -4,14 +4,12 @@ import os
|
||||
|
||||
def render_book_line(book_object):
|
||||
book = book_object
|
||||
book['rating'] = '?' if not 'rating' in book else book['rating']
|
||||
book['url'] = '' if not 'url' in book else book['url']
|
||||
book['year'] = '' if not 'year' in book else book['year']
|
||||
return '| {} | {} | [{}]({}) | {} | \n'.format(book['title'],
|
||||
book['author'],
|
||||
book['rating'],
|
||||
book['url'],
|
||||
book['year'])
|
||||
book["rating"] = "?" if not "rating" in book else book["rating"]
|
||||
book["url"] = "" if not "url" in book else book["url"]
|
||||
book["year"] = "" if not "year" in book else book["year"]
|
||||
return "| {} | {} | [{}]({}) | {} | \n".format(
|
||||
book["title"], book["author"], book["rating"], book["url"], book["year"]
|
||||
)
|
||||
|
||||
|
||||
# TODO: refine this logic
|
||||
@@ -21,32 +19,37 @@ def render(in_file, out_file, library):
|
||||
savig the new file to tmp_file location, the copying it to out-file and deleting tmp_file
|
||||
this is done to prevent issues if the in and the out file are the same
|
||||
"""
|
||||
tmp_file = './.tmp-file.md'
|
||||
open(tmp_file, 'a').close()
|
||||
tmp_file = "./.tmp-file.md"
|
||||
open(tmp_file, "a").close()
|
||||
books_not_reached = True
|
||||
with open(tmp_file, 'w') as out_file_tmp:
|
||||
with open(tmp_file, "w") as out_file_tmp:
|
||||
with open(in_file) as original_file:
|
||||
for line in original_file:
|
||||
|
||||
if line.strip() in library:
|
||||
if not books_not_reached: out_file_tmp.write('\n')
|
||||
if not books_not_reached:
|
||||
out_file_tmp.write("\n")
|
||||
books_not_reached = False
|
||||
|
||||
# render chapter and start of the table
|
||||
out_file_tmp.write(line)
|
||||
if len(library[line.strip()]) > 0:
|
||||
out_file_tmp.write('| Name | Author | Goodreads Rating | Year Published | \n')
|
||||
out_file_tmp.write('|------|--------|------------------|----------------| \n')
|
||||
out_file_tmp.write(
|
||||
"| Name | Author | Goodreads Rating | Year Published | \n"
|
||||
)
|
||||
out_file_tmp.write(
|
||||
"|------|--------|------------------|----------------| \n"
|
||||
)
|
||||
# render books
|
||||
for book in library[line.strip()]:
|
||||
out_file_tmp.write(render_book_line(book))
|
||||
elif books_not_reached:
|
||||
out_file_tmp.write(line)
|
||||
elif line.startswith('## License'):
|
||||
out_file_tmp.write('\n')
|
||||
out_file_tmp.write('\n')
|
||||
elif line.startswith("## License"):
|
||||
out_file_tmp.write("\n")
|
||||
out_file_tmp.write("\n")
|
||||
out_file_tmp.write(line)
|
||||
books_not_reached = True
|
||||
|
||||
copyfile(tmp_file, out_file)
|
||||
os.remove(tmp_file)
|
||||
os.remove(tmp_file)
|
||||
|
||||
Reference in New Issue
Block a user