Skip to content

Instantly share code, notes, and snippets.

@wumb0
Last active February 27, 2018 05:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wumb0/d8e40c7491fd46eaaa570b23557944d8 to your computer and use it in GitHub Desktop.
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.
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