141 lines
4.1 KiB
Python
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
|