trelby_export/src/locationreport.py

141 lines
4.1 KiB
Python

import misc
import pdf
import pml
import screenplay
import util
import functools
import operator
class LocationReport:
# sr = SceneReport
def __init__(self, sr):
self.sp = sr.sp
# key = scene name, value = LocationInfo. note that multiple keys
# can point to the same LocationInfo.
locations = {}
# like locations, but this one stores per-scene information
self.scenes = {}
# make grouped scenes point to the same LocationInfos.
for sceneList in self.sp.locations.locations:
li = LocationInfo(self.sp)
for scene in sceneList:
locations[scene] = li
# merge scene information for locations and store scene
# information
for si in sr.scenes:
locations.setdefault(si.name, LocationInfo(self.sp)).addScene(si)
self.scenes.setdefault(si.name, LocationInfo(self.sp)).\
addScene(si)
# remove empty LocationInfos, sort them and store to a list
tmp = []
for li in locations.values():
if (len(li.scenes) > 0) and (li not in tmp):
tmp.append(li)
def cmpfunc(a, b):
return (a > b) - (a < b)
def sortFunc(o1, o2):
ret = cmpfunc(o2.lines, o1.lines)
if ret != 0:
return ret
else:
return cmpfunc(o1.scenes[0], o2.scenes[0])
tmp = sorted(tmp, key=functools.cmp_to_key(sortFunc))
self.locations = tmp
# information about what to include (and yes, the comma is needed
# to unpack the list)
self.INF_SPEAKERS, = list(range(1))
self.inf = []
for s in ["Speakers"]:
self.inf.append(misc.CheckBoxItem(s))
def generate(self):
tf = pml.TextFormatter(self.sp.cfg.paperWidth,
self.sp.cfg.paperHeight, 15.0, 12)
scriptLines = sum([li.lines for li in self.locations])
for li in self.locations:
tf.addSpace(5.0)
# list of (scenename, lines_in_scene) tuples, which we sort in
# DESC(lines_in_scene) ASC(scenename) order.
tmp = [(scene, self.scenes[scene].lines) for scene in li.scenes]
tmp.sort(key = operator.itemgetter(0))
tmp.sort(key = operator.itemgetter(1), reverse=True)
for scene, lines in tmp:
if len(tmp) > 1:
pct = " (%d%%)" % util.pct(lines, li.lines)
else:
pct = ""
tf.addText("%s%s" % (scene, pct), style = pml.BOLD)
tf.addSpace(1.0)
tf.addWrappedText("Lines: %d (%d%% action, %d%% of script),"
" Scenes: %d, Pages: %d (%s)" % (li.lines,
util.pct(li.actionLines, li.lines),
util.pct(li.lines, scriptLines), li.sceneCount,
len(li.pages), li.pages), " ")
if self.inf[self.INF_SPEAKERS].selected:
tf.addSpace(2.5)
for it in util.sortDict(li.chars):
tf.addText(" %3d %s" % (it[1], it[0]))
return pdf.generate(tf.doc)
# information about one location
class LocationInfo:
def __init__(self, sp):
# number of scenes
self.sceneCount = 0
# scene names, e.g. ["INT. MOTEL ROOM - NIGHT", "EXT. MOTEL -
# NIGHT"]
self.scenes = []
# total lines, excluding scene lines
self.lines = 0
# action lines
self.actionLines = 0
# page numbers
self.pages = screenplay.PageList(sp.getPageNumbers())
# key = character name (upper cased), value = number of dialogue
# lines
self.chars = {}
# add a scene. si = SceneInfo
def addScene(self, si):
if si.name not in self.scenes:
self.scenes.append(si.name)
self.sceneCount += 1
self.lines += si.lines
self.actionLines += si.actionLines
self.pages += si.pages
for name, dlines in si.chars.items():
self.chars[name] = self.chars.get(name, 0) + dlines