Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add code to handle automatic imports + new formats #13

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,15 @@ I've modified the quote_to_image file so that it first checks to see if an image

It just does this check in the images directory, not the metadata directory. If you want to force the regeneration of a specific image for any reason (e.g. you fixed a typo), just delete that image from the "images" directory, no need to touch the metadata directory, and it'll regenerate both.

# Adding a quote

Run `./insert_quote.py` to add a quote to the CSV/JSON/YAML files.

Sample command:
```
$ ./insert_quote.py --time '01:00' --time_human '1 am' --source 'The Best Example Book' --author 'Ian M Banks' "This is a test. Isn't it fun! \"Go forth and have fun\"" --csv
```

# Custom Image Sizes
The image generator now supports custom and pre-configured alternative image sizes. The default size will remain the old Kindle size (600 x 800) but you now have the option to run the script with command line arguments to choose from preconfigured sizes or set your own.

Expand Down
210 changes: 210 additions & 0 deletions insert_quote.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
#!/usr/bin/env python3
import argparse
import csv
import json
import time
import yaml


def main(time_arg, time_human, source, author, quote, csv_fmt, yaml_fmt, json_fmt):
"""Redirect based on format.

The main function accepts all the parsed arguments and redirects based on
the format. This can be trimmed when there's only one format in the future.

Args:
time_arg: Time in 24h format as a string
time_human: Human-readable time format as string. Eg: Midnight.
source: The name of the literary work for the quote.
author: The author of the literary work.
quote: The text of the quote.
csv_fmt: True if the output format is CSV.
yaml_fmt: True if the output format is YAML.
json_fmt: True if the output format is JSON.

Returns:
None
"""
time_obj = time.strptime(time_arg, "%H:%M")
if csv_fmt:
csv_append(time_obj, time_human, source, author, quote)
if yaml_fmt:
yaml_append(time_obj, time_human, source, author, quote)
if json_fmt:
json_append(time_obj, time_human, source, author, quote)


def yaml_append(time_obj, time_human, source, author, quote):
"""Append to YAML.

Appends to the YAML source file in the correct position based on time.

Args:
time_obj: Time in a time object
time_human: Human-readable time format as string. Eg: Midnight.
source: The name of the literary work for the quote.
author: The author of the literary work.
quote: The text of the quote.
csv_fmt: True if the output format is CSV.
yaml_fmt: True if the output format is YAML.
json_fmt: True if the output format is JSON.

Returns:
None

Raises:
InvalidTimeException: The time was format could not be parsed.
"""
content = []
with open("litclock.yaml") as f:
content = yaml.safe_load(f)
for i, line in enumerate(content):
if time.strptime(line["time"], "%H:%M") > time_obj:
print(f"Inserting before {line}")
content[i - 1 : i - 1] = [
{
"time": time.strftime("%H:%M", time_obj),
"time_name": time_human,
"source": source,
"author": author,
"quote": quote,
}
]
break
with open("litclock.yaml", "w") as f:
f.write(yaml.dump(content))


class CustomDialect(csv.excel):
delimiter = "|"


def csv_append(time_obj, time_human, source, author, quote):
"""Append to CSV.

Appends to the CSV source file in the correct position based on time.

Args:
time_obj: Time in a time object.
time_human: Human-readable time format as string. Eg: Midnight.
source: The name of the literary work for the quote.
author: The author of the literary work.
quote: The text of the quote.
csv_fmt: True if the output format is CSV.
yaml_fmt: True if the output format is YAML.
json_fmt: True if the output format is JSON.

Returns:
None

Raises:
InvalidTimeException: The time was format could not be parsed.
"""
content = []
with open("litclock_annotated_improved.csv") as f:
r = csv.reader(f, dialect=CustomDialect)
inserted = False
for i, line in enumerate(r):
if time.strptime(line[0], "%H:%M") > time_obj and not inserted:
print(f"Inserting before {line}")
content.append(
[
time.strftime("%H:%M", time_obj),
time_human,
quote,
source,
author,
]
)
inserted = True
else:
content.append(line)
with open("litclock_annotated_improved.csv.bak", "w") as f:
w = csv.writer(f, dialect=CustomDialect)
w.writerows(content)


def json_append(time_obj, time_human, source, author, quote):
"""Append to JSON.

Appends to the JSON source file in the correct position based on time.

Args:
time_obj: Time in a time object.
time_human: Human-readable time format as string. Eg: Midnight.
source: The name of the literary work for the quote.
author: The author of the literary work.
quote: The text of the quote.
csv_fmt: True if the output format is CSV.
yaml_fmt: True if the output format is YAML.
json_fmt: True if the output format is JSON.

Returns:
None

Raises:
InvalidTimeException: The time was format could not be parsed.
"""
content = []
with open("litclock.json") as f:
content = json.load(f)
for i, line in enumerate(content):
if time.strptime(line["time"], "%H:%M") > time_obj:
print(f"Inserting before {line}")
content[i - 1 : i - 1] = [
{
"time": time.strftime("%H:%M", time_obj),
"time_name": time_human,
"source": source,
"author": author,
"quote": quote,
}
]
break
with open("litclock.json", "w") as f:
json.dump(content, f, indent=True)


if __name__ == "__main__":
parser = argparse.ArgumentParser(
prog="InsertQuote",
description="Add a quote to the correct position in the data",
)
parser.add_argument("--time", required=True, help="Time in 24h format as a string")
parser.add_argument(
"--time_human",
required=True,
help="Human-readable time format as string. Eg: Midnight.",
)
parser.add_argument(
"--source",
required=True,
help="The name of the literary work for the quote.",
)
parser.add_argument("--author", required=True, help="The text of the quote.")

# This is a special group to pick formats and the mutual exclusion makes
# sure that one and only one is selected.
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument(
"--csv", action="store_true", help="True if the output format is CSV."
)
group.add_argument(
"--yaml", action="store_true", help="True if the output format is YAML."
)
group.add_argument(
"--json", action="store_true", help="True if the output format is JSON."
)

parser.add_argument("quote")
args = parser.parse_args()
main(
time_arg=args.time,
time_human=args.time_human,
source=args.source,
author=args.author,
quote=args.quote,
csv_fmt=args.csv,
yaml_fmt=args.yaml,
json_fmt=args.json,
)
Loading