koeart initial
This commit is contained in:
parent
16b190d2bf
commit
848446f781
|
@ -0,0 +1,403 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
Convert questions for the famous Penta News Game Show from
|
||||
some yaml format to json.
|
||||
|
||||
It's just a helper to write the questions in a more human
|
||||
readeable format assuming yaml is more human readable
|
||||
|
||||
Note:
|
||||
- Media files are looked for relative to the questions file
|
||||
- Media files are expected relative to the generated json files
|
||||
|
||||
TODO:
|
||||
* Add own constructor to Question() / nice to have
|
||||
* Use import logging for debug logging
|
||||
"""
|
||||
|
||||
__author__ = "Frank Becker <fb@alien8.de>"
|
||||
__version__ = "0.0.2"
|
||||
__date__ = "Fri 18 Nov 2011 18:10:44 CET"
|
||||
__copyright__ = "Copyright (c) 2011 Frank Becker"
|
||||
__license__ = "Python"
|
||||
|
||||
import os
|
||||
import sys
|
||||
import random
|
||||
import json
|
||||
from reportlab.lib.pagesizes import A5, LETTER, landscape, portrait
|
||||
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Image
|
||||
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
|
||||
from reportlab.lib.units import inch, cm
|
||||
from reportlab.platypus.flowables import PageBreak
|
||||
from optparse import OptionParser
|
||||
|
||||
try:
|
||||
import yaml
|
||||
except ImportError:
|
||||
print 'You need to install PyYAML first. E. g. "pip install pyyaml"'
|
||||
|
||||
|
||||
class Question(yaml.YAMLObject):
|
||||
"""Represents a question
|
||||
"""
|
||||
yaml_tag = u"!Question"
|
||||
web_root = "data"
|
||||
|
||||
# Generate random points in range of points_per_round
|
||||
gen_random_points = True
|
||||
points_per_round = {
|
||||
1: (1, 100),
|
||||
2: (100, 1000),
|
||||
3: (10000, 100000),
|
||||
4: (5, 42),
|
||||
5: (13, 80),
|
||||
}
|
||||
|
||||
# {round_no1: [tier1, tier2, ...], round_no2: [tier1, ...]}
|
||||
registered_questions = {}
|
||||
|
||||
def __init__(self, question=u"", tier=0, answers=[], game_round=0,
|
||||
media=("", "", ""), media_path="data", web_root="data"):
|
||||
"""docstring for __init__
|
||||
@question - the Question
|
||||
@rank - number of the question in the game
|
||||
@game_round - number of the round in the game
|
||||
@answers - list of answers, assumed are 4
|
||||
@media - (media show at question time, media shown at answer time,
|
||||
media shown at resolution time)
|
||||
@media_path - path to the media files
|
||||
"""
|
||||
self.question = question
|
||||
self.answers = answers
|
||||
self.tier = tier
|
||||
self.game_round = game_round
|
||||
self.media = media
|
||||
self.media_path = media_path
|
||||
self.web_root = web_root
|
||||
|
||||
def __type_by_extension(self, media_file):
|
||||
"""returns the media type looked up by it's extension
|
||||
FIXME (a8): maybe use file magic in the future
|
||||
|
||||
@media_file - path to the media file
|
||||
"""
|
||||
media_types = dict(
|
||||
video = ('webm'),
|
||||
image = ('png', 'jpg', 'gif'),
|
||||
)
|
||||
if not os.path.isfile(media_file):
|
||||
raise IOError("The file {0} does not exist.".format(media_file,))
|
||||
ext = media_file.rsplit('.', 1)[1]
|
||||
for k, v in media_types.items():
|
||||
if ext in v:
|
||||
return k
|
||||
raise KeyError("Media type for {0} not found".format(media_file,))
|
||||
|
||||
def __repr__(self):
|
||||
"""docstring for __repr__"""
|
||||
return "%s(%r)" % (self.__class__.__name__, self.question)
|
||||
|
||||
def _get_points(self, game_round, tier):
|
||||
"""returns the points by game_round/tier combo"""
|
||||
|
||||
points_fixed = {
|
||||
1: 100,
|
||||
2: 150,
|
||||
3: 225,
|
||||
4: 337,
|
||||
5: 506,
|
||||
6: 759,
|
||||
7: 1139,
|
||||
8: 1709,
|
||||
9: 2563,
|
||||
10: 3844,
|
||||
11: 5555,
|
||||
12: 7531,
|
||||
}
|
||||
|
||||
if not self.gen_random_points:
|
||||
return points_fixed.get(tier, 0)
|
||||
|
||||
range = self.points_per_round.get(game_round)
|
||||
points = random.randint(*range)
|
||||
return points
|
||||
|
||||
@property
|
||||
def as_dict(self):
|
||||
"""dump data suiteable for json conversion"""
|
||||
|
||||
data = {}
|
||||
data['text'] = self.question
|
||||
data['tier'] = self._get_points(int(self.game_round), int(self.tier))
|
||||
try:
|
||||
data['source'] = self.source
|
||||
except AttributeError:
|
||||
data['source'] = False
|
||||
print self.question
|
||||
print self.answers
|
||||
data['answers'] = [
|
||||
{'text': answer[False]} if answer.has_key(False) \
|
||||
else {'text': answer[True], 'right': True} \
|
||||
for answer in self.answers
|
||||
]
|
||||
if hasattr(self, 'media'):
|
||||
def gen_questions():
|
||||
q_data = {}
|
||||
for f in self.media['question']:
|
||||
q_data[self.__type_by_extension(
|
||||
os.path.sep.join(os.path.join([self.media_path, f]))
|
||||
)] = os.sep.join([self.web_root, f])
|
||||
return q_data
|
||||
def gen_explanation():
|
||||
"""Sorry, hacky. Quick fix required only 1st element is taken"""
|
||||
f = self.media['explanation'][0]
|
||||
k = self.__type_by_extension(os.path.sep.join(
|
||||
os.path.join([self.media_path, f])))
|
||||
v = [os.sep.join([self.web_root, expl]) \
|
||||
for expl in self.media['explanation']]
|
||||
if v:
|
||||
v = v[0]
|
||||
else:
|
||||
v = ""
|
||||
return {'explanation': {k: v}}
|
||||
#): os.sep.join([self.web_root, f])
|
||||
|
||||
#[os.sep.join([self.web_root, expl]) \
|
||||
# for expl in self.media['explanation']]}
|
||||
def k_not_found():
|
||||
raise KeyError("Media keyword not found")
|
||||
|
||||
for k in self.media.keys():
|
||||
m_data = dict(
|
||||
question = gen_questions,
|
||||
explanation= gen_explanation,
|
||||
k_not_found = "lambda x: pass",
|
||||
).get(k, 'k_not_found')()
|
||||
for key, value in m_data.items():
|
||||
data[key] = value
|
||||
return data
|
||||
|
||||
@property
|
||||
def as_pdf_dict(self):
|
||||
"""Return full data set. Includes comment field"""
|
||||
data = self.as_dict
|
||||
try:
|
||||
data['comment'] = self.comment
|
||||
except AttributeError:
|
||||
data['comment'] = ""
|
||||
|
||||
return data
|
||||
|
||||
|
||||
@classmethod
|
||||
def get_points(cls):
|
||||
"""docstring for get_points"""
|
||||
for key in sorted(cls.points.keys()):
|
||||
yield cls.points[key]
|
||||
|
||||
@staticmethod
|
||||
def register_question(obj):
|
||||
"""register object in class so no question with the
|
||||
same tier/round combo can exist"""
|
||||
if Question.registered_questions.has_key(obj.game_round) and \
|
||||
obj.tier in Question.registered_questions[obj.game_round]:
|
||||
raise IndexError("Slot for Question {0} is alredy taken".format(
|
||||
obj.question,))
|
||||
elif Question.registered_questions.has_key(obj.game_round):
|
||||
Question.registered_questions[obj.game_round].append(obj.tier)
|
||||
else:
|
||||
Question.registered_questions[obj.game_round] = [obj.tier]
|
||||
|
||||
|
||||
def init_parser():
|
||||
"""Read command line options
|
||||
|
||||
returns:
|
||||
options:dict -- config options
|
||||
"""
|
||||
parser = OptionParser()
|
||||
|
||||
parser.add_option(
|
||||
"-d",
|
||||
"--debug",
|
||||
dest="debug",
|
||||
help="Toggle debugging",
|
||||
action="store_true",
|
||||
default=False,
|
||||
)
|
||||
|
||||
parser.add_option(
|
||||
"-f",
|
||||
"--questions-file",
|
||||
dest="file",
|
||||
help=("Use this file instead of the default "
|
||||
"questions.yaml"),
|
||||
metavar="FILE",
|
||||
)
|
||||
|
||||
parser.add_option(
|
||||
"-p",
|
||||
"--generate-pdf",
|
||||
dest="pdf",
|
||||
help=("Generate the speaker PDF"),
|
||||
action="store_true",
|
||||
default=False,
|
||||
)
|
||||
|
||||
parser.add_option(
|
||||
"-v",
|
||||
"--version",
|
||||
dest="version",
|
||||
help="Show program version",
|
||||
action="store_true",
|
||||
default=False,
|
||||
)
|
||||
|
||||
options = parser.parse_args()[0]
|
||||
return options
|
||||
|
||||
def questions_per_round(questions, game_round=None):
|
||||
"""docstring for questions_per_round"""
|
||||
return [q for q in questions if q.game_round == game_round]
|
||||
|
||||
def write_json_file(questions):
|
||||
"""docstring for write_json_file"""
|
||||
game_round = questions[0].game_round
|
||||
file_name = 'round_{0}.json'.format(game_round)
|
||||
fh = open(file_name, 'w')
|
||||
fh.writelines(json.dumps([q.as_dict for q in questions], indent=2))
|
||||
|
||||
def gen_pdf(questions, game_rounds):
|
||||
"""generate speaker PDF"""
|
||||
|
||||
styles = getSampleStyleSheet()
|
||||
doc = SimpleDocTemplate("pngs-speaker.pdf")
|
||||
doc.pagesize = landscape(A5)
|
||||
style = styles["Normal"]
|
||||
page_elements = []
|
||||
for round in game_rounds:
|
||||
for num, question in enumerate(
|
||||
questions_per_round(questions, game_round=round)):
|
||||
q_data = question.as_pdf_dict
|
||||
page_elements.append(
|
||||
Paragraph("<em>Game Round</em>: {0}".format(round),
|
||||
style)
|
||||
)
|
||||
page_elements.append(Spacer(0, 0.1*cm))
|
||||
page_elements.append(
|
||||
Paragraph(
|
||||
"<font size=12><em>Question {0}:</em> <bold>{1}</bold>"
|
||||
"</font>".format(num + 1, q_data['text'].encode('utf-8')),
|
||||
style)
|
||||
)
|
||||
page_elements.append(Spacer(0, 0.2*cm))
|
||||
page_elements.append(
|
||||
Paragraph("<em>Comment</em>: {0}".format(q_data.get('comment').encode('utf-8')),
|
||||
style)
|
||||
)
|
||||
page_elements.append(Spacer(0, 0.2*cm))
|
||||
page_elements.append(
|
||||
Paragraph("<em>Answers</em>:",
|
||||
style)
|
||||
)
|
||||
page_elements.append(
|
||||
Paragraph("* " + "<br />* ".join([unicode(t['text']) for t in q_data['answers']]),
|
||||
style)
|
||||
)
|
||||
page_elements.append(
|
||||
Paragraph("<em>Points</em>: {0}".format(q_data.get('tier')),
|
||||
style)
|
||||
)
|
||||
page_elements.append(PageBreak())
|
||||
doc.build(page_elements)
|
||||
return
|
||||
|
||||
Story = [Spacer(0, 1*cm)]
|
||||
p = Paragraph("Blubber1", styles["Normal"])
|
||||
Story.append(p)
|
||||
p = Paragraph("Blubber2", styles["Normal"])
|
||||
Story.append(p)
|
||||
Story.append(Spacer(10, 5*cm))
|
||||
p = Paragraph("Blubber3", styles["Normal"])
|
||||
Story.append(p)
|
||||
#doc.build(Story, onFirstPage=myFirstPage, onLaterPages=myLaterPages)
|
||||
doc.build(Story)
|
||||
|
||||
def gen_answers_html(questions, game_rounds):
|
||||
"""generate html"""
|
||||
fh = open("answers.html", 'w')
|
||||
html_header = """
|
||||
<html>
|
||||
<head>
|
||||
<title></title>
|
||||
</head>
|
||||
<body>
|
||||
"""
|
||||
html_footer = """
|
||||
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
#fh.write(html_header)
|
||||
fh.write('<ul>\n')
|
||||
for round in game_rounds:
|
||||
fh.write('<h2>Game Round {0}</h2>\n'.format(round))
|
||||
for num, question in enumerate(
|
||||
questions_per_round(questions, game_round=round)):
|
||||
fh.write('<li>')
|
||||
print question.question
|
||||
fh.write(u'Question {0}: {1}<br />'.format(num + 1, question.question))
|
||||
answers = ['<link href="{0}">Link {1}</link> '.format(s, n) \
|
||||
for n, s in enumerate(question.source.split())]
|
||||
#encode('utf-8')),
|
||||
fh.writelines(", ".join(answers))
|
||||
fh.write('</li>\n')
|
||||
fh.write('</ul>\n')
|
||||
#fh.write(html_footer)
|
||||
fh.close()
|
||||
|
||||
def main():
|
||||
"""docstring for main"""
|
||||
|
||||
options = init_parser()
|
||||
if options.version:
|
||||
print "Version: {0}".format(__version__,)
|
||||
sys.exit()
|
||||
|
||||
if options.file:
|
||||
questions_fh = open(options.file)
|
||||
else:
|
||||
questions_fh = open('questions.yaml')
|
||||
|
||||
questions = []
|
||||
for q in yaml.load_all(questions_fh.read()):
|
||||
#FIXME (fb@alien8.de) 11-11-18 23:16:34 use yaml constructor
|
||||
# yaml.add_constructor
|
||||
Question.register_question(q)
|
||||
if options.file:
|
||||
q.media_path = os.path.abspath(os.path.dirname(options.file))
|
||||
questions.append(q)
|
||||
if options.debug:
|
||||
print Question.registered_questions
|
||||
print [q.media for q in questions]
|
||||
|
||||
game_rounds = sorted(Question.registered_questions.keys())
|
||||
for r in game_rounds:
|
||||
write_json_file(questions_per_round(questions, game_round=r))
|
||||
if options.debug:
|
||||
print "Written file for game round: {0}".format(r)
|
||||
|
||||
if options.pdf:
|
||||
gen_pdf(questions, game_rounds)
|
||||
|
||||
#gen_answers_html(questions, game_rounds)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 fileencoding=utf-8 :
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 64 KiB |
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,156 @@
|
|||
#--- !Question
|
||||
##question: What is the question?
|
||||
##answers:
|
||||
## - Answer 1
|
||||
## - Answer 2
|
||||
## - Answer 3
|
||||
## - Answer 4
|
||||
##tier: 1
|
||||
##game_round: 1
|
||||
##media:
|
||||
## - aaa
|
||||
## - bbb
|
||||
#
|
||||
|
||||
--- !Question
|
||||
question: Was ist (vermutlich) kein Überwachungsprogramm der NSA?
|
||||
answers:
|
||||
- false: Tempora
|
||||
- false: Prism
|
||||
- false: XKeyscore
|
||||
- true: Mirror
|
||||
|
||||
--- !Question
|
||||
question: Wie alt ist die erste .com Adresse?
|
||||
- false: 23 Jahre
|
||||
- false: 25 Jahre
|
||||
- true: 27 Jahre
|
||||
- false: 28 Jahre
|
||||
# http://pentamedia.c3d2.de/submit/2010/03/18/25-years-anniversary-of-1st-com-address/
|
||||
|
||||
#'--- !Question
|
||||
#' question: Welches E-Mail Feature wurde im Jahr 2013 von deutschen E-Mail Providern standardmäßig unterstützt?
|
||||
#' - false: gpg
|
||||
#' - true: SSL (zwischen Servern)
|
||||
#' - false:
|
||||
#'
|
||||
|
||||
--- !Question
|
||||
question: Wieviel Jahre Gefängnis hat Bradley Manning bekommen?
|
||||
#alternativ: Wie viel Jahre Gefängnis gibt es für die Mörder in diesem Video?
|
||||
answers:
|
||||
- false: 5 Jahre
|
||||
- false: 13 Jahre
|
||||
- false: 27 Jahre
|
||||
- true: 35 Jahre
|
||||
#alternativ: - true: 0 Jahre
|
||||
|
||||
--- !Question
|
||||
question: Wie heißt der aktuelle Linux Kernel?
|
||||
answers:
|
||||
- true: Linux for Workgroups
|
||||
- false: Linux for Workstations
|
||||
- false: Linux for Desktops
|
||||
- false: Linux for Work
|
||||
|
||||
--- !Question
|
||||
question: Wie viele Stunden dürfen Menschen an Großbritanniens Grenzen ohne Anklage, Richtervorbehalt und Anwalt festgehalten?
|
||||
answers:
|
||||
- false: 5 Stunden
|
||||
- true: 9 Stunden
|
||||
- false: 1 Tag
|
||||
- false: gar nicht, da eine Demokratie
|
||||
|
||||
--- !Question
|
||||
question: Wie viele Daten werden in Deutschland monatlich von Amerikanern abgeschnorchelt?
|
||||
answers:
|
||||
- false: 100 Millionen
|
||||
- false: 300 Millionen
|
||||
- true: 500 Millionen
|
||||
- false: 700 Millionen
|
||||
|
||||
--- !Question
|
||||
question: Wie teuer ist der Staatstrojaner "FinFisher"?
|
||||
answers:
|
||||
- false: 100.000 €
|
||||
- true: 150.000 €
|
||||
- false: 200.000 €
|
||||
- false: 1 Million €
|
||||
|
||||
--- !Question
|
||||
question: Was ist sicher?
|
||||
answers:
|
||||
- false: Digitale Kommunikation
|
||||
- true:
|
||||
- false: Rente
|
||||
- false:
|
||||
|
||||
--- !Question
|
||||
question: In wie vielen Ländern hat Edward Snowden Asyl beantragt?
|
||||
answers:
|
||||
- false: 19
|
||||
- true: 21
|
||||
- false: 23
|
||||
- false: 25
|
||||
|
||||
--- !Question
|
||||
question: Wie viele Menschen waren 2013 auf der Freiheit statt Angst Demo?
|
||||
answers:
|
||||
- false: 10.000
|
||||
- false: 15.000
|
||||
- true: 20.000
|
||||
- false: 50.000
|
||||
|
||||
--- !Question
|
||||
question: Welche Dienste bietet der C3D2 (noch) nicht an?
|
||||
answers:
|
||||
- false: Kinderbetreuung
|
||||
- false: Jabber
|
||||
- false: Mail
|
||||
- true: Feed-Reader
|
||||
|
||||
#--- !Question
|
||||
#question: Wer ermöglicht Malware in der der GPL?
|
||||
# - true: Joomla
|
||||
# - false: RMS
|
||||
# - false:
|
||||
# http://blog.sucuri.net/2013/08/open-source-backdoor-copyrighted-under-gnu-gpl.html
|
||||
#
|
||||
|
||||
--- !Question
|
||||
question: Was ist ein Super-Grundrecht?
|
||||
answers:
|
||||
- false: Freiheit
|
||||
- false: Menschewürde
|
||||
- true: Sicherheit
|
||||
- false: Geheime Kommunikation
|
||||
|
||||
--- !Question
|
||||
question: Wie heißt die Alternative zur GEMA?
|
||||
answers:
|
||||
- false: Gehma!
|
||||
- true: C3S
|
||||
- false: C4S
|
||||
- false: C3
|
||||
|
||||
--- !Question
|
||||
question: Welches Programm war Bestandteil der Anklage (Computer Fraud) gegen Bradley Manning?
|
||||
answers:
|
||||
- false: ettercap
|
||||
- false: nmap
|
||||
- true: wget
|
||||
- false: Linux
|
||||
|
||||
--- !Question
|
||||
question: Wie groß ist das zuletzt releaste Insurance File von Wikileaks?
|
||||
answers:
|
||||
- false: 4 GB
|
||||
- false: 40 GB
|
||||
- true: 400 GB
|
||||
- false: 4 TB
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,5 @@
|
|||
This file is placed here by pip to indicate the source was put
|
||||
here by pip.
|
||||
|
||||
Once this package is successfully installed this source code will be
|
||||
deleted (unless you remove this file).
|
|
@ -0,0 +1,230 @@
|
|||
%PDF-1.3
|
||||
%“Œ‹ž ReportLab Generated PDF document http://www.reportlab.com
|
||||
1 0 obj
|
||||
<< /F1 2 0 R /F2 3 0 R >>
|
||||
endobj
|
||||
2 0 obj
|
||||
<< /BaseFont /Helvetica /Encoding /WinAnsiEncoding /Name /F1 /Subtype /Type1 /Type /Font >>
|
||||
endobj
|
||||
3 0 obj
|
||||
<< /BaseFont /Helvetica-Oblique /Encoding /WinAnsiEncoding /Name /F2 /Subtype /Type1 /Type /Font >>
|
||||
endobj
|
||||
4 0 obj
|
||||
<< /Contents 24 0 R /MediaBox [ 0 0 595.2756 420.9449 ] /Parent 23 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >>
|
||||
/Type /Page >>
|
||||
endobj
|
||||
5 0 obj
|
||||
<< /Contents 25 0 R /MediaBox [ 0 0 595.2756 420.9449 ] /Parent 23 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >>
|
||||
/Type /Page >>
|
||||
endobj
|
||||
6 0 obj
|
||||
<< /Contents 26 0 R /MediaBox [ 0 0 595.2756 420.9449 ] /Parent 23 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >>
|
||||
/Type /Page >>
|
||||
endobj
|
||||
7 0 obj
|
||||
<< /Contents 27 0 R /MediaBox [ 0 0 595.2756 420.9449 ] /Parent 23 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >>
|
||||
/Type /Page >>
|
||||
endobj
|
||||
8 0 obj
|
||||
<< /Contents 28 0 R /MediaBox [ 0 0 595.2756 420.9449 ] /Parent 23 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >>
|
||||
/Type /Page >>
|
||||
endobj
|
||||
9 0 obj
|
||||
<< /Contents 29 0 R /MediaBox [ 0 0 595.2756 420.9449 ] /Parent 23 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >>
|
||||
/Type /Page >>
|
||||
endobj
|
||||
10 0 obj
|
||||
<< /Contents 30 0 R /MediaBox [ 0 0 595.2756 420.9449 ] /Parent 23 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >>
|
||||
/Type /Page >>
|
||||
endobj
|
||||
11 0 obj
|
||||
<< /Contents 31 0 R /MediaBox [ 0 0 595.2756 420.9449 ] /Parent 23 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >>
|
||||
/Type /Page >>
|
||||
endobj
|
||||
12 0 obj
|
||||
<< /Contents 32 0 R /MediaBox [ 0 0 595.2756 420.9449 ] /Parent 23 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >>
|
||||
/Type /Page >>
|
||||
endobj
|
||||
13 0 obj
|
||||
<< /Contents 33 0 R /MediaBox [ 0 0 595.2756 420.9449 ] /Parent 23 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >>
|
||||
/Type /Page >>
|
||||
endobj
|
||||
14 0 obj
|
||||
<< /Contents 34 0 R /MediaBox [ 0 0 595.2756 420.9449 ] /Parent 23 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >>
|
||||
/Type /Page >>
|
||||
endobj
|
||||
15 0 obj
|
||||
<< /Contents 35 0 R /MediaBox [ 0 0 595.2756 420.9449 ] /Parent 23 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >>
|
||||
/Type /Page >>
|
||||
endobj
|
||||
16 0 obj
|
||||
<< /Contents 36 0 R /MediaBox [ 0 0 595.2756 420.9449 ] /Parent 23 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >>
|
||||
/Type /Page >>
|
||||
endobj
|
||||
17 0 obj
|
||||
<< /Contents 37 0 R /MediaBox [ 0 0 595.2756 420.9449 ] /Parent 23 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >>
|
||||
/Type /Page >>
|
||||
endobj
|
||||
18 0 obj
|
||||
<< /Contents 38 0 R /MediaBox [ 0 0 595.2756 420.9449 ] /Parent 23 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >>
|
||||
/Type /Page >>
|
||||
endobj
|
||||
19 0 obj
|
||||
<< /Contents 39 0 R /MediaBox [ 0 0 595.2756 420.9449 ] /Parent 23 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >>
|
||||
/Type /Page >>
|
||||
endobj
|
||||
20 0 obj
|
||||
<< /Contents 40 0 R /MediaBox [ 0 0 595.2756 420.9449 ] /Parent 23 0 R /Resources << /Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] >> /Rotate 0 /Trans << >>
|
||||
/Type /Page >>
|
||||
endobj
|
||||
21 0 obj
|
||||
<< /Outlines 41 0 R /PageMode /UseNone /Pages 23 0 R /Type /Catalog >>
|
||||
endobj
|
||||
22 0 obj
|
||||
<< /Author (\(anonymous\)) /CreationDate (D:20140910235918-01'00') /Creator (\(unspecified\)) /Keywords () /Producer (ReportLab PDF Library - www.reportlab.com) /Subject (\(unspecified\))
|
||||
/Title (\(anonymous\)) >>
|
||||
endobj
|
||||
23 0 obj
|
||||
<< /Count 17 /Kids [ 4 0 R 5 0 R 6 0 R 7 0 R 8 0 R 9 0 R 10 0 R 11 0 R 12 0 R 13 0 R
|
||||
14 0 R 15 0 R 16 0 R 17 0 R 18 0 R 19 0 R 20 0 R ] /Type /Pages >>
|
||||
endobj
|
||||
24 0 obj
|
||||
<< /Filter [ /ASCII85Decode /FlateDecode ] /Length 472 >>
|
||||
stream
|
||||
Gat=&d;FOi'R_q1+7:BFJ[LaPn7>HQ[j>XSb2RJr;ECL2>-d$mXkReM6X353iLY,:\YmDsbej&o(BBX)Y%JS*JLC]g\K4.[\<$L"pO3X&@Jp1\6f`un(E/;c)&iM=A@R?\0K6ZN@'oBVm&E$)&%#`K/8LYY61f>^ZOgaPf`$a4<cVW@'4DN`(aELDgK!;lePf]Ie/.rJCJcma74A7u)IjQC^fiG5W.osTQqa/;dPq=U30R%Q=E:u-HX]5jO`.:`-EprG)c!qBh]k,c>o!U-G?mS!0Q9/cKmsV)K%m/K@J3W85duBtB(eu(!HNT1qe'a$##4bW>@XWr=J]303ZSfS??6r'MrL&d!7n7*e<0oH.aD_1fc^ED=9Eo?c`8eM"[%Z)AHnH$Pd`>F]$lBDZW_86rLoB1?AULMneetiQ%IV8;i*K_p,4Ak[27FGcb%Xrs3LG9'N2F#KcANBKmrJ([d<Lr~>endstream
|
||||
endobj
|
||||
25 0 obj
|
||||
<< /Filter [ /ASCII85Decode /FlateDecode ] /Length 429 >>
|
||||
stream
|
||||
Gat=&9i&Vk&A=:s+5X78Xh3>BDRk<q%WVQKgaer4)S1q,#RS9&F[<iE6870$c+KJ=hTRMU1Pa`Z1'9uXm[lJK5a6ltY)d7Ja/Ibgk]Z_E2j!Mkk(^SlRMlR%1B,1%C,=$e0jFdMI;pugMA;Y$S.T)u=sl7bhY2%K`>O3\:t2h71]'"^Klf=f_@!bLjr`!J/`-+GIf#Sa<)tL#&;-`4S)[m_mp_82-F?U<DNQ?alhkXb=64HCV\KqC)N":6Qg66&h(9%sS*7F+rS<\obc6h*K"+Q/2(CrWqE>;eDH+^V&\W5a%saJ'Y$/`XkX[Hf#^C=.;-tBl.if(A\YZ%5hN;4/2*H47b$1T'OBH-!23%>Hd;GmqQT.l]ZtT^TRl,['.akgXCV;dRg!`)7SS[MaF8#WJ9lm/3p95[Q[OSkZ:LLKah>~>endstream
|
||||
endobj
|
||||
26 0 obj
|
||||
<< /Filter [ /ASCII85Decode /FlateDecode ] /Length 431 >>
|
||||
stream
|
||||
Gat=%>t`'h'R_(i5FfbTYU4)Na$aHqME'"#"^gsYD;6TddAEbE?Z-]E3`j@h,Qr/6\bDV@0*SV9](]>/k:)Fo-n%IZ!m5qOFGS,IgNi72kSH18&Hp$J3)=@NK5;J)WFU(HX"^og(arP;,46.dGh4`#0\2N3%ZnDRauP@2#Bc`Ik9NRcD@!T$Vj&k_gdVTgcqR_ddhhoKCK(U=k#rql2oZiX_rJs+<lQ7`&@iDW-?g,j;CmJf-!)f`hV?stTX$oI)('B)P]$r3`-4`.ddkE;8a@#4$HkJ3F.pm&29_69kF<fI2pC9c6200PKpGW8ZF,@VNah!<&WO4Y$KD?He'UFK=qkRu7uV99%,uD,g(NeHE(b0pDG`PjVl/k<':;3gB"D#&/>.*%$#6"BL*6pagZaq"Il7fu=(Q_83,XYKg\Cj<HJ!Q~>endstream
|
||||
endobj
|
||||
27 0 obj
|
||||
<< /Filter [ /ASCII85Decode /FlateDecode ] /Length 557 >>
|
||||
stream
|
||||
Gat=&?#S1G'Rd17s)9%&U]oLIBsJOS50<t;aro-(h;i`69:THQ6fckF0nX?Q:_c"5K?s5d\G("tIsC`)%Ib^bb;BM@aLC)I'I1B2qg:I#2P'?Xg1>m3S4.-3VuBD@r%n>AahMZo_klN/i,%=\iL!in50/KJ\a=M7!r:H?EhR#e!?SE7ZQON6^&qf+7%?%FKZ>Kj[7:aEYle4i\ZP1XXAc5jI'ND\C1au<(ADA)eiH-s#Zai#=_3MKOL;L]8O:oCR3?.8.ROt1T?_McgY&-lg:f`hN3apm=o.;h,#.dpM>_nX2@X@ZCA'AP+r/LGad7KsPd!;sU8+!^hoXO"*Jo8Z/tU=SO$q;Z8e\@<;)p%aOpkB^eX`>.,Lbm]gJ_Ak)We1]*EC[9ln4YD>WjiUI$@h1752fk[,(R$4!T5;/R-E@\A2$@1G"S5irf2,Vc=\N1P5uSG0,$hQ$2Hj9(iV\W+dE'S9]cFD+l;dg</0rC?bTlJ^3^e#kUQrIT*_pSLhHuT8rQI50j!7AN'n\UTJ+LIucC$Q$22%@^-cN@QJc7TF)D6~>endstream
|
||||
endobj
|
||||
28 0 obj
|
||||
<< /Filter [ /ASCII85Decode /FlateDecode ] /Length 391 >>
|
||||
stream
|
||||
Gat=ebtc,@'SZ9,]YdkrMgFi6TIh*-7bqGRd_rPu=#6_E`_mrLl(*jS$AB&89\Sb0qp(]ea=[,3QNEPO\@c=U6M_&?JOV]<D;+H,oR$L7)oW(M$50HSfAff4NIN=dhSN'U\QK85bq/FdHGe\?\I^lhCR\TPIK.=_P/.:f6g;rB(Okh(<?*]Vo&+DOa)-!,(@B4A]<W2f=k0CV(en1>^1MmC,M3pV"j>W\c0JepmCLHY64o"*\@tWd9VomkFbb71Rnkck8@9)"8UYaPAk[d,PT7E*9&_aUVVsIF;2D>9DP'h&&f!eH7n494e7R$+FDY)`B?^1/6?Se9`da];JIW9G!I7)NE8R`e])ad`h*CR1kbK^$IjaBTZ$"Y(N8lN*rSA@+WQ;+~>endstream
|
||||
endobj
|
||||
29 0 obj
|
||||
<< /Filter [ /ASCII85Decode /FlateDecode ] /Length 429 >>
|
||||
stream
|
||||
Gat=%;,>%_&:Q"c5MY;[@J3<)*A;#TiY#LHm130pA%Hf&.j=n=CJfj\6838Fk54T7qsFrFR"P*<'`b!3Y3usa6LkQ+>R&:YmZMJNXkU[q=H>ha:L'MHhrIn^Uu>)qP?ZZH1K025P0[=MSgjnV.LHL*Ei[bmOM'rACkskMZr#2WOpcVtKIM*W$+7WeQEZ*,[Y;c9k\jgdXfQYG.MrR5@lD>Xa%XBGk,XJ@&A2&?H8!K\,M'0K0U572,(D?ga]bX6a>H'cK</K1<%>Y0E`/=K<%=GOX3L%B:8uQF`eaY=Vj%]1p;-ulbJLd@Xm)I#`/3f*kacZLi!k%,UHm?k=k/j#U?&[nT-&r"9=+ra0EAF9#f<iHZ:jK!.%46tRSOFP.,IHa5o^m(@2rK6N5PFl@IjFAc-&fFp5Iq,/IL=Z#Dnc!ec~>endstream
|
||||
endobj
|
||||
30 0 obj
|
||||
<< /Filter [ /ASCII85Decode /FlateDecode ] /Length 457 >>
|
||||
stream
|
||||
Gat='>u/<k'R_@f5Fb4hEOM]PK,::,qLFFd,0tsK@)=s0]9)gR/bNVr7gQ!X*pu2cSC;gh%d"Q$s%*E"a11>SE.N6@/d$rTJD7S?H`Pcn(H.6!C9aEVA]N?rPUkcY9Wg;F$j4Nr^tFI#q,PYc\5O:(.5,gaLA:F?c9iLUE$'t,??58E/R]4pS29,XGI'tDfkjr@gR%^$CKQb)Bs&%k.q9XL^aLK[Q(AT-KdnHk91W=OKo39Ag/?7Y:k<8[&rU'^-6\@(gL.`+eEA>SHE9eT4LSTn3\C$ar'%T%jYkNqnXMA_Aj`nFEd072(:I2ce>-'*^-'sfd>7oR=_E527+ABF-Vj%Uc^Zl)1U<d9+r5hT%hCX77of7N7p"EGWA(53''ui7/,Cj?G=7o3d`pHN?IE0$caF,tm>D=1o#Z8@p5j'6(QR3[s)6.lSnbml)79.N0@XbZ1+DMh~>endstream
|
||||
endobj
|
||||
31 0 obj
|
||||
<< /Filter [ /ASCII85Decode /FlateDecode ] /Length 477 >>
|
||||
stream
|
||||
Gat=&_,A-(&A9m;5O<VE*,6*I:qScD_?FO>3hEk"Z:LccYXr7#HUC1O<-3)BkooN_HZ++$J[e)G2pDA@'"AoXTF?tecmXhq)8TTVYJ&M&FO0?mct\]I)b"%6iuqJn^Q_u?mM/2dMZG+c/`KRr%)J%g#S5)#Gls4r%m*PnY(6AHV!0HYrZ2r`32DcmDd5_&<2.F<k]&4uQtp/.)keOq=(O)3$(toIYf//!,&FL1kq[<jNL?'X]8%sFN=t@T@E]akJ;r#L$B+lBD/Ff9qQmHb6Alid0;+XL/0m/`K@bVGc+7m37ATg%h^iZ3kaCc#X#rmd._GI3;,"i%LNZE<C<%WHAtkmH>;tX7'/=O]ZP@sKV%qH+$q,i2gh$b&6#XH^E7XN=IVVZFnc]LT0BNb9WqB9S6[WEGg-IV"*l9Km#qc_p2o:MQ\oL$U//X;P:g,HpT(6)ejStFV=$iA@+G!NeTjE'NJm[lV~>endstream
|
||||
endobj
|
||||
32 0 obj
|
||||
<< /Filter [ /ASCII85Decode /FlateDecode ] /Length 524 >>
|
||||
stream
|
||||
Gat='_2ctu&A;015J1K/6&=?Q-@8%/J-.<FQU^!$`m`G!fO2=ni9QeU&M4HmWlS&3A7j\F1N+J!o+C6DoYBc2cef$7M0]V.A-M6;]WJ)qn'd-gS\$:)TBB?W'G]5q&=85<86jmsKH%po&G^jAVrM"*hQ*7;a_e//K)3Xm>tUMj6_mNN<MI-%f*S]51Ege,LrWB_iXe8<Q(Q-\J'5F\;M`=q<7_@\.;+C]._p]Cc-I+.B/OsdZI"=-Gq>GE2s[DiI!N.$O_7+F=9!/'<okKNiEY9M^*aji6Tq><<\dl1`8V@tAU]GAW9BKUHh--97<A8akI`o('dM-WKW+`2@d!U((t32\YnV/hd]1uB/s&d7"ppgVdU$(bOt8e[f8X9Uf3<E@6[n42="U]7W.029X]K:*a2M(VZO)b%DO4HpA[V(i4KQG?SgV5MBun>'Aak7X:#%O]2XOR$nL:XWQu^7E2i..b^LYk4gHJh^R,KW@eTD1,DnJ7q6M^Yih)T!*fJQXIQke)l05GY5^]~>endstream
|
||||
endobj
|
||||
33 0 obj
|
||||
<< /Filter [ /ASCII85Decode /FlateDecode ] /Length 411 >>
|
||||
stream
|
||||
Gat=e>u/<k'Sc'Jp^ciT,\Hal$gY;W$kt?#&Qut.JVl=f_fZ@7?Z2nc6REtD2GHuna8;AJ!jdg?\]fRL`RQPk37:;nk_D^L\4PGWf63(d@O$FH@"')MZ-@8@RmoW-Ci8AbN,:-V@_5gfX^V`X[)aL6nk-)<O?S0:\IbqLE_gDi8P\)*&E^hW@b_8K]e$7uLKJZ>`IDr'.qqV@CJ3-Wa]sp_\L_,H;D"MO;.@/a)QO4R#CADAX4\os@`h?V<uDXMS;l4iPh7J]h3cgGlf&A1.TXRNch$u*WNLLtr%M[Ohd(<NXhA?W@ut>ke7E,&-]%utUPPWh6sWZ:cQqdkZ^$5)T89i6RXs*-V1rXgUVYd98[opd0F3D\hbGN9I<.10T*/X's+L8Sl*C*i#bn1Gg8tnA_pRK~>endstream
|
||||
endobj
|
||||
34 0 obj
|
||||
<< /Filter [ /ASCII85Decode /FlateDecode ] /Length 364 >>
|
||||
stream
|
||||
Gat=d9hWAh&;KY)r.k#KH\aJaMqR_H.b[N+<W\j[]9S1D0H]]>GIra3M5@TGZ7n?^cbhHX*VSs%!:Ecj5;?9%DSS<]8/HME_r*<Zpnp#.:l:u8lbrJkP\]=:8ZoPl',GJOJ8%6+r2JR-R:h5m9@]<n/#;Xk3+"G/62XeFouNuE"0e/KRDa`u=ha.,6S03ia^;/]B:Cf_9(8qVnhh)nk'!6K%uY_qMC`pRD+eEq#&@F.d7W5d'PE<1VW<5H8PGa>F.WtC;:r/p/b>3h,SJ'Na%)'sp";-\m`K-SlfNR>--)Fr*("oRSV!,a4^u`VYouJiYng2lEOE23&gBC$-(")[\]W*=]F)TY``Ro1(N1P4;u~>endstream
|
||||
endobj
|
||||
35 0 obj
|
||||
<< /Filter [ /ASCII85Decode /FlateDecode ] /Length 492 >>
|
||||
stream
|
||||
Gat=e>u/<k'Sc'Jp^cO#M9`Q1Cu`O.nKW#i+H%T'NU7!Of$8.Hjk!]D!jWAhBsXVuj*fdT6\1Ulm5N,eXs,j?V*GndY<]Y9+U[0TC,S8E%D&S4HuNBN"Io^oa/2NL>q;?"bUS98MZG+3/Rjb^6gHAM&0=gtdh@PoQ8i*sl2n;cW,7Y!H[!9LG:4c]JnnL)YYDQ<MspFMIshbU/4uT]YjTMuX_GU-:6Q"$I@RsF*pY<%&W.Ps;'I\\4?t&%HDSbRk+]etI&`'XR#o(te4NTTYgaM&[Tjd%;6kS>_JDd\UQ/9+:jf!O?.DA>B1%nt--%.Qn78eim)N#g3/_3O6%K[OR)Spmck)W&EB#>^SfrE-P<Erqf.&TUb1^;83pQL#k>?/YUPmDEH_dF./7ti=iuJ_]5L];7TsP#@6Vf3-SZ-?1[_$9A=A@sG9X[=+7#S^*&8<WVg[UV.:"1Q56T/ZJs3^J(OC`hqi,W/E6F61aR`Y?@~>endstream
|
||||
endobj
|
||||
36 0 obj
|
||||
<< /Filter [ /ASCII85Decode /FlateDecode ] /Length 544 >>
|
||||
stream
|
||||
Gat=&d;IYl'R`L2+7:@B;ehf#KYC,a<Oun8e?4pYG2O^WM/?id+RSK=0m#+T[UO7kahHr0F0:Qa0NpU<k8N9"%[U*(>X2Ts:QlL`Haq>t]q>6Ehda\EN(,@dV!3PY@Yrh6+"$:'Ol;nA"E:g2@WApc#'Wrir33;+>X8;$PDbO=22HLARqr(_o6Q>k,;'^f")HDmFhihsN/hnC.9oKcU^U[*Q;L`*u:S,![;Ho4RM"P>-3J?l#(PuDH9&AH6:DbCAY^n%gg(JY-JN'd+kdm1@XC)N8.0;66\&_mP_Mh!\,DGYh1DgX:]Ou-a6Iuc7gX$cR(<,SegBL4)0G9(6G)3=Ug'h;?YTmET2:W@>"q=>U5p:BB73u6oud322Q[ON2PJ\luB7-0\pOjWk/l[\+bN,(`VDp$IQ1_^$5_Lm!N<_eqf[kLN0L3QbEXq`f6,G0S*<Nrm5lQ)gVRIhO@%:(%XBBY6(<4hl_Ff6,)<*7eW=86Y@eWd28%>J3n'!3YW;K(A(qu:1JX>6IgbkD!XAYJ#Y%<-1tHi~>endstream
|
||||
endobj
|
||||
37 0 obj
|
||||
<< /Filter [ /ASCII85Decode /FlateDecode ] /Length 445 >>
|
||||
stream
|
||||
Gat='>u/<k'R_@f5MX:NibZ5]D7l6E'HcfHWUY8<4&TXlG$Be&hGViP'*tI0e+B/Wcag_@"_%^Zlb!37$95Yl5T,@t./,`X0jKTRkH3L4TA2,P+<Z-WH#-t1AAdVT-6$1!$tGcb!@@&:`!s$QDj2"C&%Yfp$&Ic(S>1<2@.$SXSE.W5/R]FjPS3,3gF2"i\o!@CqdR<g9kl40W>4ngA'ApTG`i=>Q)Yt5]A%$$M-:aak6Nrjcp0566DCFjY#COd;M23:pf3=J3$"TNd%k=]3j\`'X^n9Q900uPq4XNc*;Q+gq!Xq[e8N\YHZ>a;!`dcc`'Hm*n\^HC3umpg#!LC3U<44>np!Z`m+)T>T;&\=g&iK+8EOtE9=T>VNESQ"N="3$X.,FDq\^TC95QB;c^NFj8nUfP_:hs6q>[SRCT4?-V:pD=Zt5rcq#Fo*nfe~>endstream
|
||||
endobj
|
||||
38 0 obj
|
||||
<< /Filter [ /ASCII85Decode /FlateDecode ] /Length 474 >>
|
||||
stream
|
||||
Gat='bAP0N&A07X%st*C9l6)K^nh,/\8WiBl90epidr1ca$SnRCJ<I_!?ipsZ/h>/)=JsfLgAMY'*0eGi9m!7AIt\'IF![^$r9a,n_%a*+)X#j:5='Whs]5:#MCm/f?)SNf3rKB0q`(3Mn#T=BYD=ciN4eSIKS!<:<l^?I:2ImC-0OogIK+3oI)$0$.i&6=6Qn@HL-P1qO/8N,qgP!pFBa6dt3-B@?&GU7i9H,\#1u:dj6?Oj9o'A@p-[=,7NtG:b0c"A,JNg2+Jg"bLRtUN&$bOlj9(HStZ?4JEI9uYuhioZ:'OaK-ldeCYTPHP4IS[GZZWkI%U%+O,&ETKjL2$W"<0G[E's]$AmC%dd@uC6!0g^3Z:Q&7]!;4`5m5K::MrLCSGZj0>=5Vj*$[Y1f`bh>f9Z?nk@"!2q,^bb%DpL8^?DuH"p811)7!5NYa:2s,ZEPi3KF[$%h*RcN_Y62t\Kg?i~>endstream
|
||||
endobj
|
||||
39 0 obj
|
||||
<< /Filter [ /ASCII85Decode /FlateDecode ] /Length 400 >>
|
||||
stream
|
||||
Gat=&_+k%d&A=:s%s(,Pf1pP-mW($qe-eRYT"M0ZBF3M7[Mt04D^ju:/k@[5HC-Y_hOBiU0Rkdh1Bh_Hi;<c[3J[iH&g\YiE%SYlf5:gXHd`D_Qpl:`jF/F@ILNuZr2^56,L==0fnPE=A"KB<>:>*&Y0-PHLuhYi[.FR<6V3dPa[ruO@@foDN!J<"MZ"H1g0tLqr3re"7Fk%96@Vi/$9^NhXt6X^$eA;c#BNHjIMfqbk#?rBS">TipJ(pMb%Xj8BkK(aZFi0,%'h9Q=MB,"SnBp,AB%\S.4SURi'WNLcD*58FH<2Ue``-UL8A1>Z,\q`q0pRJq^ICS;,@)O$n5o";/Co5;33Nd1lHZMnSp/FM,k!O?f1N0X8N"fghU'(Fun"5H!;&qSIb2Gd@(~>endstream
|
||||
endobj
|
||||
40 0 obj
|
||||
<< /Filter [ /ASCII85Decode /FlateDecode ] /Length 570 >>
|
||||
stream
|
||||
Gat=';/b/B&:R./5FhSg&Fs;jOecp"[:g5Sei%m0M]kU[Q8kB$'Qq0>(UFn2$m?rfG*Mml^<cOZ3(1,ufN/g'/;(F`*4UN8%9tXpf`J=^Id^@Qa8]W/"NKJXV,F1T'1.r'T.<cV'e1c5Q2hu6[A'mA!J@q_&FSi'jDQ1<^7u't_'Op,.2rK6g[Mj"(('"`&qRP+'rfhU40mot?/h]`gBO5#[=S*n0.^K80J+<h/JbaJq4lE#@g+["!G/4HrNlp&cI$mHWU1>#LP;b.p-eeQr&0khqU*dB#.\aa<3t:DY0iqs#9qFW]XaYd=r+WIgXN@6q$<p4JV?CN:[!^4C.'b%e(&NaYK!>[X,Y+=IQ-b9A'cpL/l)(<,SMM9PTK(%/GIOJD15hj#E8+rHrA?;@<'NO,Dt>Pp<bZ29o[n*PKm5D--&$daWW,%O:G^"a=/n!d,mX_XM2IG&86]A6h"+k(f9FhdN5Q*7N,2F@NL-;,u(AV113<s?1-VpOpT@>5K%@#gQ;e@2-mC#>(h#cgf9iU7&9AGm*t-BqYq$);JY=)rIuTra+"TthB+?M(Sq~>endstream
|
||||
endobj
|
||||
41 0 obj
|
||||
<< /Count 0 /Type /Outlines >>
|
||||
endobj
|
||||
xref
|
||||
0 42
|
||||
0000000000 65535 f
|
||||
0000000075 00000 n
|
||||
0000000119 00000 n
|
||||
0000000229 00000 n
|
||||
0000000347 00000 n
|
||||
0000000556 00000 n
|
||||
0000000765 00000 n
|
||||
0000000974 00000 n
|
||||
0000001183 00000 n
|
||||
0000001392 00000 n
|
||||
0000001601 00000 n
|
||||
0000001811 00000 n
|
||||
0000002021 00000 n
|
||||
0000002231 00000 n
|
||||
0000002441 00000 n
|
||||
0000002651 00000 n
|
||||
0000002861 00000 n
|
||||
0000003071 00000 n
|
||||
0000003281 00000 n
|
||||
0000003491 00000 n
|
||||
0000003701 00000 n
|
||||
0000003911 00000 n
|
||||
0000004001 00000 n
|
||||
0000004238 00000 n
|
||||
0000004413 00000 n
|
||||
0000004981 00000 n
|
||||
0000005506 00000 n
|
||||
0000006033 00000 n
|
||||
0000006686 00000 n
|
||||
0000007173 00000 n
|
||||
0000007698 00000 n
|
||||
0000008251 00000 n
|
||||
0000008824 00000 n
|
||||
0000009444 00000 n
|
||||
0000009951 00000 n
|
||||
0000010411 00000 n
|
||||
0000010999 00000 n
|
||||
0000011639 00000 n
|
||||
0000012180 00000 n
|
||||
0000012750 00000 n
|
||||
0000013246 00000 n
|
||||
0000013912 00000 n
|
||||
trailer
|
||||
<< /ID
|
||||
% ReportLab generated PDF document -- digest (http://www.reportlab.com)
|
||||
[(\230$X\275V\370W6V\245\353\035\230\3721\010) (\230$X\275V\370W6V\245\353\035\230\3721\010)]
|
||||
/Info 22 0 R /Root 21 0 R /Size 42 >>
|
||||
startxref
|
||||
13962
|
||||
%%EOF
|
|
@ -0,0 +1,205 @@
|
|||
!!python/object:__main__.Question
|
||||
question: Wie hat das FBI nach eigenen Angaben die Silkroad Seite hops genommen?
|
||||
answers:
|
||||
- false: Werbung geschaltet
|
||||
- false: die NSA um Hilfe gefragt
|
||||
- true: die Captcha Funktion angegriffen
|
||||
- false: Ross Ulbricht hat sich gestellt
|
||||
tier: 1
|
||||
game_round: 1
|
||||
media:
|
||||
question:
|
||||
- pix/question1.png
|
||||
- videos/big-buck-bunny_trailer.webm
|
||||
explanation:
|
||||
- videos/big-buck-bunny_trailer.webm
|
||||
- pix/question1.png
|
||||
comment: test
|
||||
|
||||
--- !Question
|
||||
question: Suzan G LeVine, die US-Botschafter in der Schweiz, schor ihren Amtseid auf
|
||||
answers:
|
||||
- false: einem iPad
|
||||
- false: der Bibel
|
||||
- false: der Schweizer Verfassung
|
||||
- true: einem Kindle
|
||||
tier: 2
|
||||
game_round: 1
|
||||
#media:
|
||||
# question:
|
||||
# - pix/question1.png
|
||||
# - videos/big-buck-bunny_trailer.webm
|
||||
# explanation:
|
||||
# - videos/big-buck-bunny_trailer.webm
|
||||
# - pix/question1.png
|
||||
|
||||
--- !Question
|
||||
question: Was muss in einer SMS stehen um ein WIKO Android Smartphone zum Reboot zu zwingen?
|
||||
answers:
|
||||
- false: reboot
|
||||
- true: \=
|
||||
- false: ; shutdown -r now \n
|
||||
- false: 6662342
|
||||
tier: 3
|
||||
game_round: 1
|
||||
#media:
|
||||
# question:
|
||||
# - pix/question1.png
|
||||
# - videos/big-buck-bunny_trailer.webm
|
||||
# explanation:
|
||||
# - videos/big-buck-bunny_trailer.webm
|
||||
# - pix/question1.png
|
||||
|
||||
--- !Question
|
||||
question: Was verloste die saechsische Polizei als Preis ihres WM-Tippspiels?
|
||||
answers:
|
||||
- false: eine Nacht in der Ausnuechterungszelle mit Fruehstueck
|
||||
- false: einen Kanister Pfefferspray
|
||||
- true: Fahrt mit dem Wasserwerfer
|
||||
- false: bei der naechsten Anti-Nazi Demo am 13. Februar ohne Platzverweis eine Sitzblockade machen zu duerfen
|
||||
tier: 4
|
||||
game_round: 1
|
||||
#media:
|
||||
# question:
|
||||
# - pix/question1.png
|
||||
# - videos/big-buck-bunny_trailer.webm
|
||||
# explanation:
|
||||
# - videos/big-buck-bunny_trailer.webm
|
||||
# - pix/question1.png
|
||||
|
||||
--- !Question
|
||||
question: Wie wiele Stille SMS wurden 2013 von der Berliner Polizei versendet?
|
||||
answers:
|
||||
- false: 73.000
|
||||
- false: 145.000
|
||||
- true: 250.000
|
||||
- false: 310.000
|
||||
tier: 5
|
||||
game_round: 1
|
||||
#media:
|
||||
#question:
|
||||
# - pix/question1.png
|
||||
# - videos/big-buck-bunny_trailer.webm
|
||||
#explanation:
|
||||
# - videos/big-buck-bunny_trailer.webm
|
||||
# - pix/question1.png
|
||||
|
||||
--- !Question
|
||||
question: Mit welchen Akronymen hadert Generalbundesanwalt Harald Range gelegentlich?
|
||||
answers:
|
||||
- false: CIA und AIC
|
||||
- false: BND und NPD
|
||||
- true: NSA und NASA
|
||||
- false: ISS und ISIS
|
||||
tier: 6
|
||||
game_round: 1
|
||||
|
||||
--- !Question
|
||||
question: Wie lange brauchte die Verwaltung der Stadt Dresden um die Datenbasis der Freifunk-Hotspots im Themenstadtplan zu aktualisieren?
|
||||
answers:
|
||||
- false: 24 Stunden
|
||||
- true: 48 Stunden
|
||||
- false: 2 Wochen
|
||||
- false: 2 Monate
|
||||
tier: 7
|
||||
game_round: 1
|
||||
|
||||
--- !Question
|
||||
question: Auf welche verschluesselung verweisen die Macher von TrueCrypt als "sichere" Alternative?
|
||||
answers:
|
||||
- false: FileVault (Apple)
|
||||
- false: SafeGuard (Sophos)
|
||||
- false: Luks (u. a. Debian)
|
||||
- true: BitLocker (Microsoft)
|
||||
tier: 8
|
||||
game_round: 1
|
||||
|
||||
--- !Question
|
||||
question: Was ist das besondere an dieser Schriftart?
|
||||
answers:
|
||||
- true: stammt vom Schild eines Obdachlosen
|
||||
- false: gewann den Nerdcore fuer hervorragende Typografie
|
||||
- false: naechste iOS Standardschrift
|
||||
- false: reduziert die Kreditwuerdigkeit, da er von einer Gambling-Seite installiert wird
|
||||
tier: 9
|
||||
game_round: 1
|
||||
|
||||
--- !Question
|
||||
question: Wer speichert wann du und was du spielst, zum Beispiel Spiele wie Angry Birds und WoW?
|
||||
answers:
|
||||
- false: GCHQ
|
||||
- false: C3D2
|
||||
- false: BND
|
||||
- true: NSA
|
||||
tier: 10
|
||||
game_round: 1
|
||||
|
||||
--- !Question
|
||||
question: Wieviele Gaeste waren auf dem 30c3?
|
||||
answers:
|
||||
- false: 1337
|
||||
- false: 8080
|
||||
- false: 4223
|
||||
- true: over 9000
|
||||
tier: 1
|
||||
game_round: 2
|
||||
|
||||
--- !Question
|
||||
question: Welche Hackergruppe speiste 2007 eine Atombombenexplosion in den Stream einer Webcam ein, welche gerade Live in einer TV-Sendung namens Panorama zu sehen war?
|
||||
answers:
|
||||
- false: Anonymous
|
||||
- false: LulzSec
|
||||
- false: ScriptKiddiz
|
||||
- true: Ztohoven
|
||||
tier: 2
|
||||
game_round: 2
|
||||
|
||||
--- !Question
|
||||
question: Welcher Inhalt wird fuer private Haushalte in Grossbritannien automatisch gefiltert und von wem?
|
||||
answers:
|
||||
- false: Flugblaetter theisistischer Sekten, von der Kirche
|
||||
- true: Pornografie, vom Interprovider
|
||||
- false: Streptokokken, vom Wasserwerk
|
||||
- false: Werbung fuer Fremdangebote, vom Mobilfunknetzbetreiber
|
||||
tier: 3
|
||||
game_round: 2
|
||||
|
||||
--- !Question
|
||||
question: Wie nennt die NSA Angriffe ueber fingierte Hardware wie USB-Geraete oder Monitorkabel?
|
||||
answers:
|
||||
- false: Tim Access Operations
|
||||
- false: Easy Access Operations
|
||||
- true: Tailored Access Operations
|
||||
- false: Suitable Access Operations
|
||||
tier: 4
|
||||
game_round: 2
|
||||
|
||||
--- !Question
|
||||
question: Auf welche Absicherungstechnik plant die Bundesregierung demnaechst zurueck zu greifen um ihre Dokumentenerzeugnisse zu sichern?
|
||||
answers:
|
||||
- false: Voynich-Chiffre
|
||||
- false: Enigma
|
||||
- true: Schreibmaschine
|
||||
- false: Stenographie
|
||||
tier: 5
|
||||
game_round: 2
|
||||
|
||||
--- !Question
|
||||
question: Als was stuft die NSA jeden TOR-Nutzer automatisch ein?
|
||||
answers:
|
||||
- true: Extremist
|
||||
- false: Terrorist
|
||||
- false: Torrorist
|
||||
- false: Zwiebelfreund
|
||||
tier: 6
|
||||
game_round: 2
|
||||
|
||||
--- !Question
|
||||
question: Als Gregor Gysi dem Bundestagspraesident Norbert Lammert erklärt, dass auch dieser von der NSA abgehoert wird, entgegnete dieser "Ja, aber im Unterschied zu Ihnen..."
|
||||
answers:
|
||||
- false: war ich nicht in der SED
|
||||
- true: trage ich es mit Fassung
|
||||
- false: verschluessel ich Mails mit 2048 Bit
|
||||
- false: ist die NSA Affaere fuer mich beendet.
|
||||
tier: 7
|
||||
game_round: 2
|
|
@ -0,0 +1,404 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
Convert questions for the famous Penta News Game Show from
|
||||
some yaml format to json.
|
||||
|
||||
It's just a helper to write the questions in a more human
|
||||
readeable format assuming yaml is more human readable
|
||||
|
||||
Note:
|
||||
- Media files are looked for relative to the questions file
|
||||
- Media files are expected relative to the generated json files
|
||||
|
||||
TODO:
|
||||
* Add own constructor to Question() / nice to have
|
||||
* Use import logging for debug logging
|
||||
"""
|
||||
|
||||
__author__ = "Frank Becker <fb@alien8.de>"
|
||||
__version__ = "0.0.2"
|
||||
__date__ = "Fri 18 Nov 2011 18:10:44 CET"
|
||||
__copyright__ = "Copyright (c) 2011 Frank Becker"
|
||||
__license__ = "Python"
|
||||
|
||||
import os
|
||||
import sys
|
||||
import random
|
||||
import json
|
||||
from reportlab.lib.pagesizes import A5, LETTER, landscape, portrait
|
||||
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Image
|
||||
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
|
||||
from reportlab.lib.units import inch, cm
|
||||
from reportlab.platypus.flowables import PageBreak
|
||||
from optparse import OptionParser
|
||||
|
||||
try:
|
||||
import yaml
|
||||
except ImportError:
|
||||
print 'You need to install PyYAML first. E. g. "pip install pyyaml"'
|
||||
|
||||
|
||||
class Question(yaml.YAMLObject):
|
||||
"""Represents a question
|
||||
"""
|
||||
yaml_tag = u"!Question"
|
||||
web_root = "data"
|
||||
|
||||
# Generate random points in range of points_per_round
|
||||
gen_random_points = True
|
||||
points_per_round = {
|
||||
1: (1, 100),
|
||||
2: (100, 1000),
|
||||
3: (10000, 100000),
|
||||
4: (5, 42),
|
||||
5: (13, 80),
|
||||
}
|
||||
|
||||
# {round_no1: [tier1, tier2, ...], round_no2: [tier1, ...]}
|
||||
registered_questions = {}
|
||||
|
||||
def __init__(self, question=u"", tier=0, answers=[], game_round=0,
|
||||
media=("", "", ""), media_path="data", web_root="data"):
|
||||
"""docstring for __init__
|
||||
@question - the Question
|
||||
@rank - number of the question in the game
|
||||
@game_round - number of the round in the game
|
||||
@answers - list of answers, assumed are 4
|
||||
@media - (media show at question time, media shown at answer time,
|
||||
media shown at resolution time)
|
||||
@media_path - path to the media files
|
||||
"""
|
||||
self.question = question
|
||||
self.answers = answers
|
||||
self.tier = tier
|
||||
self.game_round = game_round
|
||||
self.media = media
|
||||
self.media_path = media_path
|
||||
self.web_root = web_root
|
||||
|
||||
def __type_by_extension(self, media_file):
|
||||
"""returns the media type looked up by it's extension
|
||||
FIXME (a8): maybe use file magic in the future
|
||||
|
||||
@media_file - path to the media file
|
||||
"""
|
||||
media_types = dict(
|
||||
video = ('webm'),
|
||||
image = ('png', 'jpg', 'gif'),
|
||||
)
|
||||
if not os.path.isfile(media_file):
|
||||
raise IOError("The file {0} does not exist.".format(media_file,))
|
||||
ext = media_file.rsplit('.', 1)[1]
|
||||
for k, v in media_types.items():
|
||||
if ext in v:
|
||||
return k
|
||||
raise KeyError("Media type for {0} not found".format(media_file,))
|
||||
|
||||
def __repr__(self):
|
||||
"""docstring for __repr__"""
|
||||
return "%s(%r)" % (self.__class__.__name__, self.question)
|
||||
|
||||
def _get_points(self, game_round, tier):
|
||||
"""returns the points by game_round/tier combo"""
|
||||
|
||||
points_fixed = {
|
||||
1: 100,
|
||||
2: 150,
|
||||
3: 225,
|
||||
4: 337,
|
||||
5: 506,
|
||||
6: 759,
|
||||
7: 1139,
|
||||
8: 1709,
|
||||
9: 2563,
|
||||
10: 3844,
|
||||
11: 5555,
|
||||
12: 7531,
|
||||
}
|
||||
|
||||
if not self.gen_random_points:
|
||||
return points_fixed.get(tier, 0)
|
||||
|
||||
range = self.points_per_round.get(game_round)
|
||||
points = random.randint(*range)
|
||||
return points
|
||||
|
||||
@property
|
||||
def as_dict(self):
|
||||
"""dump data suiteable for json conversion"""
|
||||
|
||||
data = {}
|
||||
data['text'] = self.question
|
||||
data['tier'] = self._get_points(int(self.game_round), int(self.tier))
|
||||
try:
|
||||
data['source'] = self.source
|
||||
except AttributeError:
|
||||
data['source'] = False
|
||||
print self.question
|
||||
print self.answers
|
||||
data['answers'] = [
|
||||
{'text': answer[False]} if answer.has_key(False) \
|
||||
else {'text': answer[True], 'right': True} \
|
||||
for answer in self.answers
|
||||
]
|
||||
if hasattr(self, 'media'):
|
||||
def gen_questions():
|
||||
q_data = {}
|
||||
for f in self.media['question']:
|
||||
q_data[self.__type_by_extension(
|
||||
os.path.sep.join(os.path.join([self.media_path, f]))
|
||||
)] = os.sep.join([self.web_root, f])
|
||||
return q_data
|
||||
def gen_explanation():
|
||||
"""Sorry, hacky. Quick fix required only 1st element is taken"""
|
||||
f = self.media['explanation'][0]
|
||||
k = self.__type_by_extension(os.path.sep.join(
|
||||
os.path.join([self.media_path, f])))
|
||||
v = [os.sep.join([self.web_root, expl]) \
|
||||
for expl in self.media['explanation']]
|
||||
if v:
|
||||
v = v[0]
|
||||
else:
|
||||
v = ""
|
||||
return {'explanation': {k: v}}
|
||||
#): os.sep.join([self.web_root, f])
|
||||
|
||||
#[os.sep.join([self.web_root, expl]) \
|
||||
# for expl in self.media['explanation']]}
|
||||
def k_not_found():
|
||||
raise KeyError("Media keyword not found")
|
||||
|
||||
for k in self.media.keys():
|
||||
m_data = dict(
|
||||
question = gen_questions,
|
||||
explanation= gen_explanation,
|
||||
k_not_found = "lambda x: pass",
|
||||
).get(k, 'k_not_found')()
|
||||
for key, value in m_data.items():
|
||||
data[key] = value
|
||||
return data
|
||||
|
||||
@property
|
||||
def as_pdf_dict(self):
|
||||
"""Return full data set. Includes comment field"""
|
||||
data = self.as_dict
|
||||
try:
|
||||
data['comment'] = self.comment
|
||||
except AttributeError:
|
||||
data['comment'] = ""
|
||||
|
||||
return data
|
||||
|
||||
|
||||
@classmethod
|
||||
def get_points(cls):
|
||||
"""docstring for get_points"""
|
||||
for key in sorted(cls.points.keys()):
|
||||
yield cls.points[key]
|
||||
|
||||
@staticmethod
|
||||
def register_question(obj):
|
||||
"""register object in class so no question with the
|
||||
same tier/round combo can exist"""
|
||||
if Question.registered_questions.has_key(obj.game_round) and \
|
||||
obj.tier in Question.registered_questions[obj.game_round]:
|
||||
raise IndexError("Slot for Question {0} is alredy taken".format(
|
||||
obj.question,))
|
||||
elif Question.registered_questions.has_key(obj.game_round):
|
||||
Question.registered_questions[obj.game_round].append(obj.tier)
|
||||
else:
|
||||
Question.registered_questions[obj.game_round] = [obj.tier]
|
||||
|
||||
|
||||
def init_parser():
|
||||
"""Read command line options
|
||||
|
||||
returns:
|
||||
options:dict -- config options
|
||||
"""
|
||||
parser = OptionParser()
|
||||
|
||||
parser.add_option(
|
||||
"-d",
|
||||
"--debug",
|
||||
dest="debug",
|
||||
help="Toggle debugging",
|
||||
action="store_true",
|
||||
default=False,
|
||||
)
|
||||
|
||||
parser.add_option(
|
||||
"-f",
|
||||
"--questions-file",
|
||||
dest="file",
|
||||
help=("Use this file instead of the default "
|
||||
"questions.yaml"),
|
||||
metavar="FILE",
|
||||
default="questions.yaml"
|
||||
)
|
||||
|
||||
parser.add_option(
|
||||
"-p",
|
||||
"--generate-pdf",
|
||||
dest="pdf",
|
||||
help=("Generate the speaker PDF"),
|
||||
action="store_true",
|
||||
default=False,
|
||||
)
|
||||
|
||||
parser.add_option(
|
||||
"-v",
|
||||
"--version",
|
||||
dest="version",
|
||||
help="Show program version",
|
||||
action="store_true",
|
||||
default=False,
|
||||
)
|
||||
|
||||
options = parser.parse_args()[0]
|
||||
return options
|
||||
|
||||
def questions_per_round(questions, game_round=None):
|
||||
"""docstring for questions_per_round"""
|
||||
return [q for q in questions if q.game_round == game_round]
|
||||
|
||||
def write_json_file(questions):
|
||||
"""docstring for write_json_file"""
|
||||
game_round = questions[0].game_round
|
||||
file_name = 'round_{0}.json'.format(game_round)
|
||||
fh = open(file_name, 'w')
|
||||
fh.writelines(json.dumps([q.as_dict for q in questions], indent=2))
|
||||
|
||||
def gen_pdf(questions, game_rounds):
|
||||
"""generate speaker PDF"""
|
||||
|
||||
styles = getSampleStyleSheet()
|
||||
doc = SimpleDocTemplate("pngs-speaker.pdf")
|
||||
doc.pagesize = landscape(A5)
|
||||
style = styles["Normal"]
|
||||
page_elements = []
|
||||
for round in game_rounds:
|
||||
for num, question in enumerate(
|
||||
questions_per_round(questions, game_round=round)):
|
||||
q_data = question.as_pdf_dict
|
||||
page_elements.append(
|
||||
Paragraph("<em>Game Round</em>: {0}".format(round),
|
||||
style)
|
||||
)
|
||||
page_elements.append(Spacer(0, 0.1*cm))
|
||||
page_elements.append(
|
||||
Paragraph(
|
||||
"<font size=12><em>Question {0}:</em> <bold>{1}</bold>"
|
||||
"</font>".format(num + 1, q_data['text'].encode('utf-8')),
|
||||
style)
|
||||
)
|
||||
page_elements.append(Spacer(0, 0.2*cm))
|
||||
page_elements.append(
|
||||
Paragraph("<em>Comment</em>: {0}".format(q_data.get('comment').encode('utf-8')),
|
||||
style)
|
||||
)
|
||||
page_elements.append(Spacer(0, 0.2*cm))
|
||||
page_elements.append(
|
||||
Paragraph("<em>Answers</em>:",
|
||||
style)
|
||||
)
|
||||
page_elements.append(
|
||||
Paragraph("* " + "<br />* ".join([unicode(t['text']) for t in q_data['answers']]),
|
||||
style)
|
||||
)
|
||||
page_elements.append(
|
||||
Paragraph("<em>Points</em>: {0}".format(q_data.get('tier')),
|
||||
style)
|
||||
)
|
||||
page_elements.append(PageBreak())
|
||||
doc.build(page_elements)
|
||||
return
|
||||
|
||||
Story = [Spacer(0, 1*cm)]
|
||||
p = Paragraph("Blubber1", styles["Normal"])
|
||||
Story.append(p)
|
||||
p = Paragraph("Blubber2", styles["Normal"])
|
||||
Story.append(p)
|
||||
Story.append(Spacer(10, 5*cm))
|
||||
p = Paragraph("Blubber3", styles["Normal"])
|
||||
Story.append(p)
|
||||
#doc.build(Story, onFirstPage=myFirstPage, onLaterPages=myLaterPages)
|
||||
doc.build(Story)
|
||||
|
||||
def gen_answers_html(questions, game_rounds):
|
||||
"""generate html"""
|
||||
fh = open("answers.html", 'w')
|
||||
html_header = """
|
||||
<html>
|
||||
<head>
|
||||
<title></title>
|
||||
</head>
|
||||
<body>
|
||||
"""
|
||||
html_footer = """
|
||||
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
#fh.write(html_header)
|
||||
fh.write('<ul>\n')
|
||||
for round in game_rounds:
|
||||
fh.write('<h2>Game Round {0}</h2>\n'.format(round))
|
||||
for num, question in enumerate(
|
||||
questions_per_round(questions, game_round=round)):
|
||||
fh.write('<li>')
|
||||
print question.question
|
||||
fh.write(u'Question {0}: {1}<br />'.format(num + 1, question.question))
|
||||
answers = ['<link href="{0}">Link {1}</link> '.format(s, n) \
|
||||
for n, s in enumerate(question.source.split())]
|
||||
#encode('utf-8')),
|
||||
fh.writelines(", ".join(answers))
|
||||
fh.write('</li>\n')
|
||||
fh.write('</ul>\n')
|
||||
#fh.write(html_footer)
|
||||
fh.close()
|
||||
|
||||
def main():
|
||||
"""docstring for main"""
|
||||
|
||||
options = init_parser()
|
||||
if options.version:
|
||||
print "Version: {0}".format(__version__,)
|
||||
sys.exit()
|
||||
|
||||
if options.file:
|
||||
questions_fh = open(options.file)
|
||||
else:
|
||||
questions_fh = open('questions.yaml')
|
||||
|
||||
questions = []
|
||||
for q in yaml.load_all(questions_fh.read()):
|
||||
#FIXME (fb@alien8.de) 11-11-18 23:16:34 use yaml constructor
|
||||
# yaml.add_constructor
|
||||
Question.register_question(q)
|
||||
if options.file:
|
||||
q.media_path = os.path.abspath(os.path.dirname(options.file))
|
||||
questions.append(q)
|
||||
if options.debug:
|
||||
print Question.registered_questions
|
||||
print [q.media for q in questions]
|
||||
|
||||
game_rounds = sorted(Question.registered_questions.keys())
|
||||
for r in game_rounds:
|
||||
write_json_file(questions_per_round(questions, game_round=r))
|
||||
if options.debug:
|
||||
print "Written file for game round: {0}".format(r)
|
||||
|
||||
if options.pdf:
|
||||
gen_pdf(questions, game_rounds)
|
||||
|
||||
#gen_answers_html(questions, game_rounds)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 fileencoding=utf-8 :
|
||||
|
|
@ -0,0 +1,142 @@
|
|||
[
|
||||
{
|
||||
"tier": 186,
|
||||
"text": "Wieviele Gaeste waren auf dem 30c3?",
|
||||
"answers": [
|
||||
{
|
||||
"text": 1337
|
||||
},
|
||||
{
|
||||
"text": 8080
|
||||
},
|
||||
{
|
||||
"text": 4223
|
||||
},
|
||||
{
|
||||
"text": "over 9000",
|
||||
"right": true
|
||||
}
|
||||
],
|
||||
"source": false
|
||||
},
|
||||
{
|
||||
"tier": 953,
|
||||
"text": "Welche Hackergruppe speiste 2007 eine Atombombenexplosion in den Stream einer Webcam ein, welche gerade Live in einer TV-Sendung namens Panorama zu sehen war?",
|
||||
"answers": [
|
||||
{
|
||||
"text": "Anonymous"
|
||||
},
|
||||
{
|
||||
"text": "LulzSec"
|
||||
},
|
||||
{
|
||||
"text": "ScriptKiddiz"
|
||||
},
|
||||
{
|
||||
"text": "Ztohoven",
|
||||
"right": true
|
||||
}
|
||||
],
|
||||
"source": false
|
||||
},
|
||||
{
|
||||
"tier": 951,
|
||||
"text": "Welcher Inhalt wird fuer private Haushalte in Grossbritannien automatisch gefiltert und von wem?",
|
||||
"answers": [
|
||||
{
|
||||
"text": "Flugblaetter theisistischer Sekten, von der Kirche"
|
||||
},
|
||||
{
|
||||
"text": "Pornografie, vom Interprovider",
|
||||
"right": true
|
||||
},
|
||||
{
|
||||
"text": "Streptokokken, vom Wasserwerk"
|
||||
},
|
||||
{
|
||||
"text": "Werbung fuer Fremdangebote, vom Mobilfunknetzbetreiber"
|
||||
}
|
||||
],
|
||||
"source": false
|
||||
},
|
||||
{
|
||||
"tier": 996,
|
||||
"text": "Wie nennt die NSA Angriffe ueber fingierte Hardware wie USB-Geraete oder Monitorkabel?",
|
||||
"answers": [
|
||||
{
|
||||
"text": "Tim Access Operations"
|
||||
},
|
||||
{
|
||||
"text": "Easy Access Operations"
|
||||
},
|
||||
{
|
||||
"text": "Tailored Access Operations",
|
||||
"right": true
|
||||
},
|
||||
{
|
||||
"text": "Suitable Access Operations"
|
||||
}
|
||||
],
|
||||
"source": false
|
||||
},
|
||||
{
|
||||
"tier": 428,
|
||||
"text": "Auf welche Absicherungstechnik plant die Bundesregierung demnaechst zurueck zu greifen um ihre Dokumentenerzeugnisse zu sichern?",
|
||||
"answers": [
|
||||
{
|
||||
"text": "Voynich-Chiffre"
|
||||
},
|
||||
{
|
||||
"text": "Enigma"
|
||||
},
|
||||
{
|
||||
"text": "Schreibmaschine",
|
||||
"right": true
|
||||
},
|
||||
{
|
||||
"text": "Stenographie"
|
||||
}
|
||||
],
|
||||
"source": false
|
||||
},
|
||||
{
|
||||
"tier": 403,
|
||||
"text": "Als was stuft die NSA jeden TOR-Nutzer automatisch ein?",
|
||||
"answers": [
|
||||
{
|
||||
"text": "Extremist",
|
||||
"right": true
|
||||
},
|
||||
{
|
||||
"text": "Terrorist"
|
||||
},
|
||||
{
|
||||
"text": "Torrorist"
|
||||
},
|
||||
{
|
||||
"text": "Zwiebelfreund"
|
||||
}
|
||||
],
|
||||
"source": false
|
||||
},
|
||||
{
|
||||
"tier": 362,
|
||||
"text": "Als Gregor Gysi dem Bundestagspraesident Norbert Lammert erkl\u00e4rt, dass auch dieser von der NSA abgehoert wird, entgegnete dieser \"Ja, aber im Unterschied zu Ihnen...\"",
|
||||
"answers": [
|
||||
{
|
||||
"text": "war ich nicht in der SED"
|
||||
},
|
||||
{
|
||||
"text": "trage ich es mit Fassung",
|
||||
"right": true
|
||||
},
|
||||
{
|
||||
"text": "verschluessel ich Mails mit 2048 Bit"
|
||||
},
|
||||
{
|
||||
"text": "ist die NSA Affaere fuer mich beendet."
|
||||
}
|
||||
],
|
||||
"source": false
|
||||
}
|
||||
]
|
Loading…
Reference in New Issue