Last active
February 27, 2018 05:51
-
-
Save wumb0/d8e40c7491fd46eaaa570b23557944d8 to your computer and use it in GitHub Desktop.
helps index stuff for exams... if they don't give you an index, or the one they provide is bad. tweak as you see fit.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from sqlalchemy import create_engine, Column, Integer, String, func | |
from sqlalchemy.orm import sessionmaker | |
from sqlalchemy.ext.declarative import declarative_base | |
from reportlab.lib.pagesizes import letter | |
from reportlab.lib.units import cm | |
from reportlab.pdfgen import canvas | |
from reportlab.pdfbase.pdfmetrics import stringWidth | |
import sys | |
try: | |
raw_input = input | |
except: pass | |
Base = declarative_base() | |
class IndexEntry(Base): | |
__tablename__ = "entries" | |
id = Column(Integer, primary_key=True) | |
name = Column(String, index=True) | |
page = Column(Integer) | |
book = Column(Integer) | |
def createAndGetSession(dbpath): | |
engine = create_engine("sqlite:///" + dbpath) | |
Base.metadata.bind = engine | |
Base.metadata.create_all() | |
return sessionmaker(bind=engine)() | |
def get_entry(session, book): | |
topic = raw_input("Topic: ") | |
if not book: | |
book = raw_input("Book: ") | |
page = raw_input("Page: ") | |
i = IndexEntry(name=topic, page=int(page), book=int(book)) | |
session.add(i) | |
session.commit() | |
print("Added " + topic) | |
if __name__ == '__main__': | |
if len(sys.argv) < 3: | |
print("Usage: {} [add|show|export] database [outputname.pdf|bookno]".format(sys.argv[0])) | |
sys.exit(1) | |
session = createAndGetSession(sys.argv[2]) | |
if sys.argv[1] == "add": | |
if len(sys.argv) < 4: | |
book = None | |
else: | |
book = sys.argv[3] | |
while True: | |
try: | |
get_entry(session, book) | |
except KeyboardInterrupt: | |
break | |
elif sys.argv[1] == "show": | |
entries = session.query(IndexEntry).order_by(func.lower(IndexEntry.name)).all() | |
for i in entries: | |
print("{}\t\t\t{}-{}".format(i.name, i.book, i.page)) | |
elif sys.argv[1] == "export": | |
if len(sys.argv) < 4: | |
print("No output file name... using index.pdf") | |
output = "index.pdf" | |
else: | |
output = sys.argv[3] | |
cv = canvas.Canvas(output, pagesize=letter) | |
title = sys.argv[2] | |
width, height = letter | |
cv.setFont("Helvetica-Bold", 20) | |
cv.drawString((width-stringWidth(title, "Helvetica-Bold", 20))/2.0, height-30, title) | |
entries = list(session.query(IndexEntry).order_by(func.lower(IndexEntry.name)).all()) | |
current_letter = "\0" | |
additive = 0 | |
prev = "" | |
line = [] | |
row = 0 | |
cv.setLineWidth(.1) | |
cv.setFont("Helvetica", 10) | |
cv.setStrokeColorRGB(.85,.85,.85) | |
for i,entry in enumerate(entries): | |
ypos = height-15*row-additive-25 | |
if (prev != entry.name or i == len(entries)-1) and i != 0: | |
if i == len(entries)-1 and prev == entry.name: | |
# edge case on last entry name being the same as the second | |
# to last | |
line.append("{}:{}".format(entry.book, entry.page)) | |
cv.drawString(25, ypos, prev) | |
cv.drawRightString(width-25, ypos, ",".join(line)) | |
cv.line(width-25, ypos-2, 25, ypos-2) | |
row += 1 | |
del line[:] | |
if height-15*row-additive-25 <= 75: | |
cv.showPage() | |
cv.setStrokeColorRGB(.85,.85,.85) | |
cv.setFont("Helvetica", 10) | |
cv.setLineWidth(.1) | |
row = 0 | |
additive = 5 | |
line.append("{}:{}".format(entry.book, entry.page)) | |
if ord(entry.name[0].upper()) > ord(current_letter): | |
# if this is a new first letter, print the letter | |
cv.setFont("Helvetica-Bold", 12) | |
cv.setLineWidth(.5) | |
cv.setStrokeColorRGB(0,0,0) | |
cv.drawString(25, ypos-20, entry.name[0].upper()) | |
cv.line(width-25, ypos-22, 25, ypos-22) | |
if additive == 0: | |
# edge case for first entry | |
additive = 15 | |
additive += 25 | |
current_letter = entry.name[0].upper() | |
cv.setFont("Helvetica", 10) | |
cv.setStrokeColorRGB(.85,.85,.85) | |
cv.setLineWidth(.1) | |
ypos = height-15*row-additive-25 | |
if i == len(entries)-1: | |
# edge case on last entry being a new letter | |
cv.drawString(25, ypos, entry.name) | |
cv.drawRightString(width-25, ypos, ",".join(line)) | |
cv.line(width-25, ypos-2, 25, ypos-2) | |
prev = entry.name | |
cv.showPage() | |
cv.save() | |
else: | |
print("Usage: {} [add|show|export] database [outputname.pdf|bookno]".format(sys.argv[0])) | |
sys.exit(1) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment