12 import twisted
.internet
.reactor
13 import twisted
.web
.resource
14 import twisted
.web
.server
16 import entangled_network
18 class ObserverResource(twisted
.web
.resource
.Resource
):
28 self
.delay_log_file
= open('delays.log', 'w')
29 def produce_graph(self
, rss
):
30 f
= open('graph/graph%03d.dot' % self
.graph_counter
, 'w')
31 f
.write(self
.tree_pic_dot(self
.trees
[rss
]))
33 self
.graph_counter
+= 1
34 def node_pic(self
, node
, tree
):
36 name
= self
.names
[node
]
40 if node
in tree
['child_left']: left_node
= tree
['child_left'][node
]
41 if node
in tree
['child_right']: right_node
= tree
['child_right'][node
]
42 left_pic
= self
.node_pic(left_node
, tree
)
43 right_pic
= self
.node_pic(right_node
, tree
)
44 lefts
= left_pic
.split('\n')
45 retu
+= '-' + lefts
[0] + '\n'
46 for line
in lefts
[1:]:
47 retu
+= ' |' + line
+ '\n'
49 rights
= right_pic
.split('\n')
50 retu
+= ' -' + rights
[0] + '\n'
51 for line
in rights
[1:]:
52 retu
+= ' ' + line
+ '\n'
58 def node_dot(self
, node
, tree
):
60 if node
in tree
['child_left'] and tree
['child_left'][node
]:
61 left_node
= tree
['child_left'][node
]
62 retu
+= self
.names
[node
] + ' -> ' + self
.names
[left_node
] + ';\n'
63 retu
+= self
.node_dot(left_node
, tree
)
64 if node
in tree
['child_right'] and tree
['child_right'][node
]:
65 right_node
= tree
['child_right'][node
]
66 retu
+= self
.names
[node
] + ' -> ' + self
.names
[right_node
] + ';\n'
67 retu
+= self
.node_dot(right_node
, tree
)
69 def tree_pic_dot(self
, tree
):
71 retu
= 'digraph p2prfd {\n'
72 retu
+= self
.names
[root
] + ';\n'
73 retu
+= self
.node_dot(root
, tree
)
77 def tree_pic(self
, tree
):
79 return self
.node_pic(root
, tree
)
81 def add_name(self
, node
):
82 if node
and not (node
in self
.names
):
84 self
.names
[node
] = '%02d' % self
.last_name
86 def render_GET(self
, request
):
87 queries
= request
.args
88 request
.responseHeaders
.setRawHeaders('content-type', ['text/plain'])
89 print 'queries = %s' % repr(queries
)
91 if 'action' in queries
: action
= queries
['action'][0]
92 if action
== 'new_root':
93 feed_url
= queries
['rss'][0]
94 root
= eval(queries
['root'][0])
96 if feed_url
in self
.trees
:
99 self
.trees
[feed_url
] = {'root': None, 'child_left': {}, 'child_right': {}}
100 self
.trees
[feed_url
]['root'] = root
101 self
.produce_graph(feed_url
)
103 elif action
== 'adopt_child':
104 parent
= eval(queries
['parent'][0]);
105 child
= eval(queries
['child'][0]);
106 feed_url
= queries
['rss'][0]
107 loc
= queries
['loc'][0]
108 self
.add_name(parent
)
111 self
.trees
[feed_url
]['child_left'][parent
] = child
114 self
.trees
[feed_url
]['child_right'][parent
] = child
116 self
.produce_graph(feed_url
)
118 elif action
== 'update_received':
119 print 'publish_id =', queries
['publish_id'][0]
120 print 'timestamp =', queries
['timestamp'][0]
121 publish_id
= queries
['publish_id'][0]
122 timestamp
= queries
['timestamp'][0]
123 if publish_id
not in self
.publish_time
:
124 self
.publish_time
[publish_id
] = float(timestamp
)
126 update_delay
= float(timestamp
) - self
.publish_time
[publish_id
]
127 self
.average_delay
= (self
.average_delay
*self
.delay_count
+ update_delay
) / (self
.delay_count
+1)
128 self
.delay_count
= self
.delay_count
+1
129 print 'update_delay = %.2f' % update_delay
130 print 'average_delay = %.5f' % self
.average_delay
131 level
= int(queries
['level'][0])
132 node
= eval(queries
['node'][0])
133 name
= self
.names
[node
]
134 self
.delay_log_file
.write('update delay = %.2f (node %s, level %d)\n' % (update_delay
, name
, level
))
135 self
.delay_log_file
.write('average delay = %.5f\n' % self
.average_delay
)
139 if 'rss' in queries
: rss
= queries
['rss'][0]
141 if rss
in self
.trees
:
142 if 'type' in queries
:
143 return self
.tree_pic_dot(self
.trees
[rss
])
145 return self
.tree_pic(self
.trees
[rss
])
146 else: return 'tree for %s not found' % rss
151 rsrc
= ObserverResource()
152 site
= twisted
.web
.server
.Site(rsrc
)
153 twisted
.internet
.reactor
.listenTCP(9501, site
)
154 twisted
.internet
.reactor
.run()