generalized get_current_txouts
[p2pool.git] / p2pool / draw.py
1 import pygame
2 import time
3 import hashlib
4 import math
5 import StringIO
6 from PIL import Image
7
8 from p2pool.util.vector import v
9 from p2pool.bitcoin import data as bitcoin_data
10
11 @apply
12 class color(object):
13     def __getattr__(self, name):
14         res = pygame.Color(name)
15         setattr(self, name, res)
16         return res
17
18 def get_uniform(bound, *data):
19     x = int(hashlib.sha256(repr(data)).hexdigest(), 16)
20     return x % bound
21
22 def get_pos(share, t, d):
23     x = 5 + get_uniform(400 - 10, share.hash, "pos")
24     y = d.get_height() - (t - share.time_seen)*10
25     if y < -10000: y = -10000
26     if y > 10000: y = 10000
27     return v(x, y)
28
29 def get_color(data):
30     return [get_uniform(256, data, x) for x in "rgb"]
31
32 def perp_and_normalize_to((dx, dy), d):
33     m = math.sqrt(dx**2 + dy**2)
34     return v(-dy/m*d, dx/m*d)
35
36 def go(share, tracker, t, d):
37     #c = color.green if share.peer is None else color.red
38     c = get_color(share.new_script)
39     pos = get_pos(share, t, d)
40     pygame.draw.circle(d, c, pos.rounded, 5)
41     if share.previous_hash in tracker.shares:
42         previous_share = tracker.shares[share.previous_hash]
43         previous_pos = get_pos(previous_share, t, d)
44         vec_to_previous = previous_pos - pos
45         if vec_to_previous.mag() > 1:
46             pygame.draw.polygon(d, c, [
47                 (pos + perp_and_normalize_to(vec_to_previous, 5)).rounded,
48                 (pos + perp_and_normalize_to(vec_to_previous, -5)).rounded,
49                 previous_pos.rounded,
50             ])
51     if share.peer is None:
52         pygame.draw.circle(d, c, pos.rounded, 10, 2)
53     for child_hash in tracker.reverse_shares.get(share.hash, set()):
54         go(tracker.shares[child_hash], tracker, t, d)
55     d.blit(f.render(bitcoin_data.script2_to_human(share.new_script, tracker.net.PARENT), True, (255, 255, 255)), pos)
56
57 pygame.font.init()
58 f = pygame.font.SysFont("Monospace", 16)
59
60 def get(tracker, best):
61     d = pygame.Surface((600, 600), 32)
62     if tracker.get_height(best) >= 100:
63         t = time.time()
64         start = tracker.get_nth_parent_hash(best, 100)
65         d.fill((0, 0, 0))
66         go(tracker.shares[start], tracker, t, d)
67     f = StringIO.StringIO()
68     Image.fromstring("RGB", d.get_size(), pygame.image.tostring(d, "RGB")).save(f, "png")
69     return f.getvalue()