To start off you'll need to import the WizrdTree.py module.
import WizardTree as wt
This contains the methods needed to crawl CYOA style comment chains on reddit. If a story starts as a comment you can crawl it using CrawlComment
, by providing either the url or the comment id. For example,
story = wt.CrawlComment(url = "https://www.reddit.com/r/talesfromtechsupport/comments/3xyesc/project_management_seems_a_lot_like_cooking_a/cy8z5uv")
or, you could achieve the same result using:
story = wt.CrawlComment(comment_id = "cy8z5uv")
If a story starts of as a submission (which is usually the case on /r/YouEnterADungeon and /r/playzorkwithme) you should use CrawlSubmission(url, submission_id)
instead, providing either the url or the submission id.
Once you've crawled the story, you can export it as JSON using the Export
method and import it again using the Import
method. See below for examples.
As of now there are two ways to read a story, one is by using the 'HTML conversion' example listed below. The other is by using the HTML viewer (available online here).
Thanks to /u/XiuathoTheWizard and everyone else who contributed to his original story, for inspiring this project and bringing the great folks at /r/TalesFromTechSupport a tale that won't soon be forgotten.
For more info see the Github repository
Code by /u/XkF21WNJ.
In [ ]:
import WizardTree as wt
story = wt.CrawlComment(comment_id = "cy8z5uv")
wt.Export(story, "Output/WizardTree.json")
In [13]:
import WizardTree as wt
story = wt.Import("Output/WizardTree.json")
In [14]:
print "Title: " + story['title']
print "Author: " + story['author']
print "Url: " + story['url']
print "Contains %d events, with %d possible endings" % (
len(story['events']),
len([1 for event in story['events'].values() if len(event['actions']) == 0]))
In [16]:
%matplotlib inline
#Imports
import WizardTree as wt
import networkx as nx
import matplotlib.pyplot as plt
#Build graph
G = nx.DiGraph()
for event_id in story['events']:
event = story['events'][event_id]
for action_id in event['actions']:
action = story['actions'][action_id]
G.add_edge(event_id, action['consequence'])
#Plot
shells = {}
pos = {}
for node in nx.dfs_preorder_nodes(G):
depth = len(nx.ancestors(G, node))
if depth in shells:
shells[depth].append(node)
else:
shells[depth] = [node]
pos[node] = [len(shells[depth]), -depth]
plt.figure(figsize=(8,20))
nx.draw(G, pos=pos, with_labels=False)
plt.show()
In [17]:
#Imports
from html import HTML
#Definitions
def Truncate(text):
return text[:60] + (text[60:] and '..')
def ParseEvent(story, body, event_id, index):
event = story['events'][event_id]
div = body.div(klass = 'event')
div.a('', name = event_id)
links = div.div(klass = 'link-container')
if event['parent'] != None:
links.a('Go to Previous',
href = '#'+event['parent'],
klass = 'left-link')
else:
links.a('Go to Index', href = '#index', klass = 'left-link')
links.a('Go to Original', href = event['url'], klass = 'right-link')
div.text(event['description'], escape=False)
for action_id in event['actions']:
ParseAction(story, body, action_id, div.ul(), index)
def ParseAction(story, body, action_id, ul, index):
action = story['actions'][action_id]
href = '#'+action['consequence']
indli = index.li()
indli.a(action['description'], href = href, klass='action', style = 'display: block;', escape=False)
li = ul.li(klass = 'action')
a = li.a(href = href,
style = "display: block;",
title = '/u/'+ action['actor'])
a.span(action['description'], escape=False)
ParseEvent(story, body, action['consequence'], index)
def ParseStory(story):
#Styling
css = """
body {
font-family: arial, sans-serif;
width: 40em;
margin-left:auto;
margin-right:auto;
}
p {
text-align: justiy;
-moz-hyphens: auto;
hyphens: auto;
}
.event {
margin-bottom: 1000ex;
}
.event > p {
font-family: Georgia, serif;
font-size: larger;
line-height: 1.5em;
}
.action p {
margin-top: 0.25em;
margin-bottom: 0.25em;
}
.action {
font-family: consolas, monospace;
margin: 0 0 2ex 0;
}
.link-container {
font-family: consolas, monospace;
display: flex;
}
.left-link{
width: 40ex;
}
.right-link{
flex-grow: 1;
text-align: right;
}
"""
#Build HTML file
doc = HTML()
doc.text("<!DOCTYPE html>", escape=False)
html = doc.html()
header = html.head()
header.meta(charset = "UTF-8")
header.title(story['title'])
header.style(css, escape = False)
body = html.body()
index = HTML().ul()
#Parse tree
ParseEvent(story, body, story['start'], index)
#Add index
body.a('', name = 'index')
body.h1('Index')
body.div(index, escape = False)
#Add credits
body.a('', name = 'credits')
body.h1('Credits')
body.p("A special thanks to " + story['author'] + " for creating the story")
body.p("Also thanks to all the commenters appearing in the story:")
users_ul = body.ul()
for actor in story['actors']: users_ul.li("/u/"+actor)
body.p("Powered by python, coded by /u/XkF21WNJ.")
return doc
doc = ParseStory(story)
#Export to file
with open("Output/WizardTree.html", 'w') as f:
f.write(unicode(doc).encode('utf-8'))
In [ ]: