-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathspectrumd
executable file
·219 lines (174 loc) · 7.32 KB
/
spectrumd
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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
spectrum.payswarm.com
Wireless devices such as mobile phones, laptops, and routers use
radio spectrum to communicate with one another. This spectrum is
often statically allocated and fairly fixed in the way it is
deployed. This static allocation usually leads to unfortunate
quality of service issues in heavily utilized areas such as
conference halls, city centers, or mass-transport terminals.
One approach to addressing the quality of service problem is to
allow radios to purchase additional or alternative bandwidth
channels using a dynamic spectrum marketplace.
A dynamic spectrum marketplace is space in which wireless
spectrum can be allocated, purchased, and sold. The goal of
these sorts of marketplaces is to ensure efficient usage of
spectrum usage through the use of market forces to sell spectrum
to the highest bidder.
This website is a demonstration of a dynamic spectrum marketplace.
It uses the PaySwarm open standards to express identity, licenses,
digital contracts, and blocks of spectrum for sale. All purchases
for the spectrum are performed using the PaySwarm standard as well.
:copyright: (c) 2013 by Digital Bazaar
:license: BSD, see LICENSE for more details.
"""
import os.path, json, time
from sqlite3 import dbapi2 as sqlite3
from flask import Flask, request, session, g, redirect, url_for, abort, \
jsonify, render_template, flash, _app_ctx_stack, make_response
# configuration
DATABASE_TEMPLATE = os.path.join(os.path.dirname(__file__), 'schema.sql')
DATABASE = os.path.join(os.path.dirname(__file__), 'spectrum.db')
ASSET_TEMPLATE = os.path.join(os.path.dirname(__file__), 'asset.jsonld')
LISTING_TEMPLATE = os.path.join(os.path.dirname(__file__), 'listing.jsonld')
DEBUG = True
IDENTITY = 'https://dev.payswarm.com/i/spectrum-market'
ACCOUNT = 'https://dev.payswarm.com/i/spectrum-market/accounts/auctions'
# Spectrum marketplace application
app = Flask(__name__)
app.config.from_object(__name__)
app.config.from_envvar('SPECTRUMD_SETTINGS', silent=True)
import datetime
def w3cdatetime(i):
""" Output datetime in RFC 3339 format that is also valid ISO 8601
timestamp representation"""
year, month, day, hour, minute, second, wday, jday, dst = time.gmtime(i)
o = str(year)
if (month, day, hour, minute, second) == (1, 1, 0, 0, 0): return o
o = o + '-%2.2d' % month
if (day, hour, minute, second) == (1, 0, 0, 0): return o
o = o + '-%2.2d' % day
if (hour, minute, second) == (0, 0, 0): return o
o = o + 'T%2.2d:%2.2d' % (hour, minute)
if second != 0:
o = o + ':%2.2d' % second
o = o + 'Z'
return o
def request_wants_jsonld():
best = request.accept_mimetypes \
.best_match(['application/ld+json', 'text/html'])
return best == 'application/ld+json' and \
request.accept_mimetypes[best] > \
request.accept_mimetypes['text/html']
def init_db():
"""Creates the database tables."""
with app.app_context():
db = get_db()
with app.open_resource(DATABASE_TEMPLATE, mode='r') as f:
db.cursor().executescript(f.read())
db.commit()
def get_db():
"""Opens a new database connection if there is none yet for the
current application context.
"""
top = _app_ctx_stack.top
if not hasattr(top, 'sqlite_db'):
sqlite_db = sqlite3.connect(app.config['DATABASE'])
sqlite_db.row_factory = sqlite3.Row
top.sqlite_db = sqlite_db
return top.sqlite_db
@app.teardown_appcontext
def close_db_connection(exception):
"""Closes the database again at the end of the request."""
top = _app_ctx_stack.top
if hasattr(top, 'sqlite_db'):
top.sqlite_db.close()
@app.route('/')
def show_homepage():
return render_template('index.html')
@app.route('/docs/')
def show_docs():
return render_template('docs.html')
@app.route('/offers/', methods=['GET'])
def show_offers():
db = get_db()
offers = []
if(request_wants_jsonld()):
# return content-negotiated JSON-LD response
for row in db.execute('SELECT offer FROM offers ORDER BY id'):
offers.append(json.loads(row[0]))
return json.dumps(offers, indent=2)
else:
# return HTML if JSON-LD was not requested
for row in db.execute('SELECT id, offer FROM offers ORDER BY id'):
offers.append({'id': row[0], 'data': json.loads(row[1])})
return render_template('offers.html', offers=offers)
@app.route('/offers/<offer_id>', methods=['GET'])
def show_offer(offer_id):
db = get_db()
cur = db.execute('SELECT offer FROM offers WHERE id=?',
(offer_id))
headers = {
# 'Content-Type': 'application/ld+json'
'Content-Type': 'text/plain'
}
offer = cur.fetchone()[0]
return (offer, 200, headers)
@app.route('/offers/', methods=['POST'])
def create_request():
db = get_db()
cur = db.execute('INSERT INTO offers VALUES (?, ?)',
(None, '{}'))
db.commit()
offer_id = cur.lastrowid
assetUrl = 'http://localhost:5000/offers/' + str(offer_id)
assetFile = open(ASSET_TEMPLATE, 'r')
asset = json.loads(assetFile.read())
listingRestrictions = asset['listingRestrictions']
payee = listingRestrictions['payee'][0]
# set spectrum parameters
asset['spectrum'] = json.loads(request.data)
asset['id'] = assetUrl + '#asset'
asset['assetProvider'] = IDENTITY
asset['title'] = "Spectrum - %1.3f Mhz centered at %1.3f Mhz, %1.3f dBm" % \
(int(asset['spectrum']['occupiedBandwidth'])/1000000,
int(asset['spectrum']['centerFrequency'])/1000000,
float(asset['spectrum']['transmitPower']))
payee['id'] = assetUrl + '#payee'
payee['destination'] = ACCOUNT
listingRestrictions['validFrom'] = w3cdatetime(time.time())
listingRestrictions['validUntil'] = w3cdatetime(time.time() + 60*60*24)
listingUrl = 'http://localhost:5000/offers/' + str(offer_id)
listingFile = open(LISTING_TEMPLATE, 'r')
listing = json.loads(listingFile.read())
listing['id'] = listingUrl + '#listing'
listing['asset'] = assetUrl + '#asset'
listing['vendor'] = IDENTITY
listing['validFrom'] = w3cdatetime(time.time())
listing['validUntil'] = w3cdatetime(time.time() + 60*60*24)
listingPayee = listing['payee'][0]
listingPayee['id'] = listingUrl + '#listing-payee-1'
listingPayee['comment'] = \
"Spectrum payment for %1.3f Mhz centered at %1.3f Mhz, %1.3f dBm" % \
(int(asset['spectrum']['occupiedBandwidth'])/1000000,
int(asset['spectrum']['centerFrequency'])/1000000,
float(asset['spectrum']['transmitPower']))
listingPayee['payeeRate'] = '0.05'
listingPayee['destination'] = ACCOUNT
assetAndListing = {
'@context': [
'https://w3id.org/payswarm/v1', 'https://w3id.org/spectrum/v1'],
'@graph': [asset, listing]
}
cur = db.execute('UPDATE offers SET offer=? WHERE id=?',
(json.dumps(assetAndListing, indent=2), offer_id))
db.commit()
return render_template('offer_created.html', offer_id=offer_id), 201
@app.route('/contracts/')
def show_contracts():
return render_template('contracts.html')
if __name__ == '__main__':
if(not os.path.exists(DATABASE)):
init_db()
app.run()