import os, sys
import tg, pylons
import subprocess
from webob.exc import HTTPNotFound
from bazbase import conversion, translators, structure
from bazki import getting, auth
from bazki.translators import url
from gameki import restricted, util
def foreach_markup(list_expr, color=None, ancestor=None, group=None,
owned=None, let='', propname=u'product', order_by=None):
if let is True:
varness = "o,ownr"
let = "owner=ownr"
else:
varness = "o"
# <><><>
markup = "<>\n"
markup += " <>\n" % (propname, let)
markup += "<>\n\n"
return markup
def markup_for_user(u, color=None, ancestor=None, group=None,
mode=None, display="", no_headers=False):
"""display should be a baz_eval expression."""
loopover = None
if mode != 'full' and mode is not None:
if structure.get_prop(mode).flavor == 'references':
if not u.has_propval(mode):
return ''
loopover = mode
propname = u'product'
else:
propname = mode
else:
propname = u'product'
markup = '<>\n' % (u.ename)
if not no_headers:
markup += '<>\n' % (u.ename, display)
if (u.has_propval(propname)
and (ancestor is None or ancestor.is_ancestor_of(u))
and group is None and color is None):
markup += '<>\n\n' % (u.ename, propname)
rg_element = u.ename
exclude_base = 'exclude!'
if loopover is not None:
markup += u'<>\n' % (u.ename, loopover)
rg_element = u'e'
exclude_base = 'exclude'
markup += foreach_markup(
"recursive_get(%s, 'stuff', '%s', %s, folded=False)" % (rg_element,
exclude_base,
u.ename),
color, ancestor, group, owned=True, let=True,
propname=propname)
# For stuff that's not owned, don't set owner at all, so all
# instances of the same item must be identical and get cached in the
# same slot.
markup += foreach_markup(
"recursive_get(%s, 'stuff', '%s', folded=False)" % (rg_element,
exclude_base),
color, ancestor, group, owned=False, propname=propname)
if (propname == u'product' and
(color is not None
or (ancestor is not None and ancestor.get_parent() is None)
or (ancestor is None and group is None))):
markup += "<>\n"
markup += " <>\n" % u.ename
markup += "<>\n\n"
if mode == 'fullq': # !!!
markup += '<>\n'
markup += foreach_markup(
"recursive_get(%s, 'stuff', 'invert', folded=False)" % (u.ename),
color, ancestor, group, owned=True, let="owner=%s" % u.ename,
propname=propname)
markup += foreach_markup(
"recursive_get(%s, 'stuff', 'invert', folded=False)" % (u.ename),
color, ancestor, group, owned=False, propname=propname)
markup += '<>\n'
if loopover is not None:
markup += '<>\n'
if not no_headers:
markup += '<>\n'
markup += '<>\n'
return markup
def print_stuff(user, name=None, mode=None, type='.pdf', no_headers=False):
if name is None or name == 'all':
name = u'Object'
packet_group = structure.get_element(u'PacketGroup')
if name[0].isupper():
ancestor = structure.get_element(name)
if packet_group.is_ancestor_of(ancestor):
group = ancestor
ancestor = None
display = "%s.name" % group.ename
else:
group = None
if ancestor.get_parent() is None:
display = '"Packet"'
elif ancestor.get_prop('group'):
display = '%s.group.name' % ancestor.ename
else:
display = '%s.type' % ancestor.ename
color = None
else:
color = name
ancestor = None
group = None
display = '"%s"' % color.capitalize()
if mode is not None:
if not restricted.is_omniscient():
raise restricted.omniscient_only()
if type == 'default':
type = getting.DEFAULT_DEFAULT
if user == 'compendium':
if not restricted.is_omniscient():
raise restricted.omniscient_only()
if mode is None:
mode = u'product'
markup = foreach_markup(
ancestor.ename if ancestor is not None else "Owner",
color, group=group, propname=mode, order_by=u'name')
elif user == 'production':
if not restricted.is_omniscient():
raise restricted.omniscient_only()
users = structure.get_element(u'Character').get_descendants()
users.sort(key=lambda u: conversion.render(u, u'name'))
places = structure.get_element(u'Place').get_descendants()
places.sort(key=lambda p: conversion.render(p, u'name'))
users += places
markup = ""
for u in users:
# TODO(xavid): combine with getting this for key above
if conversion.render(u, u'name'):
markup += markup_for_user(
u, color, ancestor, group, mode=mode or 'full',
display=display, no_headers=no_headers)
else:
if (not restricted.is_omniscient()
and user != restricted.logged_in_username()):
raise restricted.not_you()
owner = util.get_user(user)
markup = markup_for_user(owner, color, ancestor, group,
mode=mode, display=display,
no_headers=no_headers)
if mode is None:
pdfurl = url('/print/%s/%s.pdf' % (user, name))
else:
pdfurl = url('/print/%s/%s/%s.pdf' % (user, name, mode))
global_metadata = {'title': u'Gameki Printing',
'pdfurl': pdfurl}
#print >>sys.stderr, markup
if type == '.raw':
ret = markup
ctype = 'text/plain'
else:
try:
flags = ''
if no_headers:
flags += 'h'
ret = conversion.convert_markup(markup, type,
global_metadata,
cacheable_as='/print/%s/%s/%s/%s'
% (user, name, mode, flags))
except conversion.ConversionFailedException,e:
raise HTTPNotFound(e)
ctype, enc = translators.guess_type(name+type)
if not isinstance(ret,str):
# TG doesn't like buffers or unicode.
ret = str(ret)
return ret, ctype
class Printer(tg.TGController):
@tg.expose(template="mako:gameki.templates.printing")
def _default(self, user=None, name=None, mode=None, type=None,
print_as=None, print_mode=None, no_headers=False):
if user is None:
if not pylons.request.url.endswith('/'):
tg.redirect(pylons.request.url+'/')
return {}
if type is not None:
pass
elif name is None:
user, type = getting.filename_split(user)
elif mode is None:
name, type = getting.filename_split(name)
name = name.replace('_', ' ')
name = unicode(name, 'utf-8')
else:
mode, type = getting.filename_split(mode)
if not name:
name = None
if not mode:
mode = None
ret, ctype = print_stuff(user, name, mode, type, no_headers=no_headers)
if ctype:
try:
pylons.response.headers['Content-type'] = ctype + '; charset=utf-8'
except TypeError:
pass
return ret
# Printing to lpr translator
def lpr(im):
printer = im.metadata()['filters']['P']
username = im.metadata()['filters']['U']
mode = im.metadata()['filters']['Z']
command_line = ['lpr', '-P%s' % printer, '-U%s' % username]
if mode == 'duplex':
command_line.append('-o')
command_line.append('sides=two-sided-long-edge')
elif mode == 'fronts':
command_line.append('-o')
command_line.append('page-set=odd')
elif mode == 'backs':
command_line.append('-o')
command_line.append('page-set=even')
else:
assert False, mode
# This is either a .pdf produced by LaTeX and thus already on disk
# or data loaded from cache, which will be in memory.
if im.data is None:
command_line.append(im.asPath())
indata = ''
else:
indata = im.asData()
p = subprocess.Popen(command_line,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = p.communicate(indata)
im.setData('lpr returned: %s\n' % p.returncode + out + err, 'lpr')
im.deps.makeUncacheable()
translators.TRANSLATORS.setdefault('lpr', {})['.pdf'] = lpr