/
app.py
139 lines (107 loc) · 3.82 KB
/
app.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# Python 2 Fix
from __future__ import division
import sys
import os.path
import datetime
from flask import make_response
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
# Import modules
from dataserv.run import app, db
from dataserv.Farmer import Farmer
# Helper functions
def secs_to_mins(seconds):
if seconds < 60:
return "{0} second(s)".format(int(seconds))
elif seconds < 3600:
return "{0} minute(s)".format(int(seconds/60))
else:
return "{0} hour(s)".format(int(seconds/3600))
def online_farmers():
# maximum number of minutes since the last check in for
# the farmer to be considered an online farmer
online_time = app.config["ONLINE_TIME"]
# find the time object online_time minutes in the past
current_time = datetime.datetime.utcnow()
time_ago = current_time - datetime.timedelta(minutes=online_time)
# give us all farmers that have been around for the past online_time
return db.session.query(Farmer).filter(Farmer.last_seen > time_ago).all()
# Routes
@app.route('/')
def index():
return "Hello World."
@app.route('/api/register/<btc_addr>', methods=["GET"])
def register(btc_addr):
# create Farmer object to represent user
user = Farmer(btc_addr)
# error template
error_msg = "Registration Failed: {0}"
# attempt to register the farmer/farming address
try:
user.register()
return make_response("User registered.", 200)
except ValueError:
msg = "Invalid Bitcoin address."
return make_response(error_msg.format(msg), 400)
except LookupError:
msg = "Address already is registered."
return make_response(error_msg.format(msg), 409)
@app.route('/api/ping/<btc_addr>', methods=["GET"])
def ping(btc_addr):
# create Farmer object to represent user
user = Farmer(btc_addr)
# error template
error_msg = "Ping Failed: {0}"
# attempt to ping the farmer/farming address
try:
user.ping()
return make_response("Ping accepted.", 200)
except ValueError:
msg = "Invalid Bitcoin address."
return make_response(error_msg.format(msg), 400)
except LookupError:
msg = "Farmer not found."
return make_response(error_msg.format(msg), 404)
@app.route('/api/online', methods=["GET"])
def online():
# this could be formatted a bit better, but we just want to publicly display
# that status of the farmers connected to the node
output = ""
current_time = datetime.datetime.utcnow()
for farmer in online_farmers():
last_seen = secs_to_mins((current_time - farmer.last_seen).seconds)
text = "{0} | Last Seen: {1} | Height: {2}<br/>"
output += text.format(farmer.btc_addr, last_seen, farmer.height)
return output
@app.route('/api/total', methods=["GET"])
def total():
total_shards = 0
# add up number of shards
for farmer in online_farmers():
total_shards += farmer.height
# return in TB the number
app.config["BYTE_SIZE"] = 1024*1024*128
result = total_shards * (app.config["BYTE_SIZE"] / (1024*1024*1024*1024)) # bytes / 1 TB
return "{0} TB".format(round(result,2))
@app.route('/api/height/<btc_addr>/<int:height>', methods=["GET"])
def set_height(btc_addr, height):
# create Farmer object to represent user
user = Farmer(btc_addr)
# attempt to set height
try:
user.set_height(height)
return make_response("Height accepted.", 200)
except ValueError:
msg = "Invalid Bitcoin address."
return make_response(msg, 400)
except LookupError:
msg = "Farmer not found."
return make_response(msg, 404)
if __name__ == '__main__': # pragma: no cover
# Create Database
db.create_all()
# Run the Flask app
app.run(
host="0.0.0.0",
port=int("5000"),
debug=True
)