Skip to content
This repository was archived by the owner on May 16, 2019. It is now read-only.

Commit 96aba83

Browse files
committed
Fix merge conflict in restapi.py
2 parents 258a5e6 + 9a32e94 commit 96aba83

File tree

10 files changed

+118
-61
lines changed

10 files changed

+118
-61
lines changed

api/restapi.py

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -266,9 +266,9 @@ def get_node(node):
266266
@authenticated
267267
def get_followers(self, request):
268268
def parse_followers(followers):
269-
if followers is not None:
269+
if followers[0] is not None:
270270
response = {"followers": []}
271-
for f in followers.followers:
271+
for f in followers[0].followers:
272272
follower_json = {
273273
"guid": f.guid.encode("hex"),
274274
"handle": f.metadata.handle,
@@ -278,28 +278,33 @@ def parse_followers(followers):
278278
"nsfw": f.metadata.nsfw
279279
}
280280
response["followers"].append(follower_json)
281+
if followers[1] is not None:
282+
response["count"] = followers[1]
281283
request.setHeader('content-type', "application/json")
282284
request.write(json.dumps(sanitize_html(response), indent=4))
283285
request.finish()
284286
else:
285287
request.write(json.dumps({}))
286288
request.finish()
289+
start = 0
290+
if "start" in request.args:
291+
start = int(request.args["start"][0])
287292
if "guid" in request.args:
288293
def get_node(node):
289294
if node is not None:
290-
self.mserver.get_followers(node).addCallback(parse_followers)
295+
self.mserver.get_followers(node, start).addCallback(parse_followers)
291296
else:
292297
request.write(json.dumps({}))
293298
request.finish()
294299
self.kserver.resolve(unhexlify(request.args["guid"][0])).addCallback(get_node)
295300
else:
296-
ser = self.db.follow.get_followers()
297-
if ser is not None:
301+
ser = self.db.follow.get_followers(start)
302+
if ser[0] is not None:
298303
f = objects.Followers()
299-
f.ParseFromString(ser)
300-
parse_followers(f)
304+
f.ParseFromString(ser[0])
305+
parse_followers((f, ser[1]))
301306
else:
302-
parse_followers(None)
307+
parse_followers((None, 0))
303308
return server.NOT_DONE_YET
304309

305310
@GET('^/api/v1/get_following')

config.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from ConfigParser import ConfigParser
1313
from urlparse import urlparse
1414

15-
PROTOCOL_VERSION = 1
15+
PROTOCOL_VERSION = 2
1616
CONFIG_FILE = join(os.getcwd(), 'ob.cfg')
1717

1818
# FIXME probably a better way to do this. This curretly checks two levels deep.

db/datastore.py

Lines changed: 30 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from protos import objects
1111
from protos.objects import Listings, Followers, Following
1212
from os.path import join
13-
from db.migrations import migration1, migration2
13+
from db.migrations import migration1, migration2, migration3
1414

1515

1616
class Database(object):
@@ -116,7 +116,7 @@ def _create_database(database_path):
116116
conn = lite.connect(database_path)
117117
cursor = conn.cursor()
118118

119-
cursor.execute('''PRAGMA user_version = 2''')
119+
cursor.execute('''PRAGMA user_version = 3''')
120120
cursor.execute('''CREATE TABLE hashmap(hash TEXT PRIMARY KEY, filepath TEXT)''')
121121

122122
cursor.execute('''CREATE TABLE profile(id INTEGER PRIMARY KEY, serializedUserInfo BLOB, tempHandle TEXT)''')
@@ -125,7 +125,8 @@ def _create_database(database_path):
125125

126126
cursor.execute('''CREATE TABLE keys(type TEXT PRIMARY KEY, privkey BLOB, pubkey BLOB)''')
127127

128-
cursor.execute('''CREATE TABLE followers(id INTEGER PRIMARY KEY, serializedFollowers BLOB)''')
128+
cursor.execute('''CREATE TABLE followers(guid TEXT UNIQUE, serializedFollower TEXT)''')
129+
cursor.execute('''CREATE INDEX index_followers ON followers(serializedFollower);''')
129130

130131
cursor.execute('''CREATE TABLE following(id INTEGER PRIMARY KEY, serializedFollowing BLOB)''')
131132

@@ -182,8 +183,12 @@ def _run_migrations(self):
182183
if version == 0:
183184
migration1.migrate(self.PATH)
184185
migration2.migrate(self.PATH)
186+
migration3.migrate(self.PATH)
185187
elif version == 1:
186188
migration2.migrate(self.PATH)
189+
migration3.migrate(self.PATH)
190+
elif version == 2:
191+
migration3.migrate(self.PATH)
187192

188193

189194
class HashMap(object):
@@ -466,47 +471,41 @@ def is_following(self, guid):
466471

467472
def set_follower(self, proto):
468473
conn = Database.connect_database(self.PATH)
474+
p = Followers.Follower()
475+
p.ParseFromString(proto)
469476
with conn:
470477
cursor = conn.cursor()
471-
f = Followers()
472-
ser = self.get_followers()
473-
if ser is not None:
474-
f.ParseFromString(ser)
475-
for follower in f.followers:
476-
if follower.guid == proto.guid:
477-
f.followers.remove(follower)
478-
f.followers.extend([proto])
479-
cursor.execute('''INSERT OR REPLACE INTO followers(id, serializedFollowers) VALUES (?,?)''',
480-
(1, f.SerializeToString()))
478+
cursor.execute('''INSERT OR REPLACE INTO followers(guid, serializedFollower) VALUES (?,?)''',
479+
(p.guid.encode("hex"), proto.encode("hex")))
481480
conn.commit()
482481
conn.close()
483482

484483
def delete_follower(self, guid):
485484
conn = Database.connect_database(self.PATH)
486485
with conn:
487486
cursor = conn.cursor()
488-
f = Followers()
489-
ser = self.get_followers()
490-
if ser is not None:
491-
f.ParseFromString(ser)
492-
for follower in f.followers:
493-
if follower.guid == guid:
494-
f.followers.remove(follower)
495-
cursor.execute('''INSERT OR REPLACE INTO followers(id, serializedFollowers) VALUES (?,?)''',
496-
(1, f.SerializeToString()))
487+
cursor.execute('''DELETE FROM followers WHERE guid=?''', (guid.encode("hex"), ))
497488
conn.commit()
498489
conn.close()
499490

500-
def get_followers(self):
491+
def get_followers(self, start=0):
501492
conn = Database.connect_database(self.PATH)
502493
cursor = conn.cursor()
503-
cursor.execute('''SELECT serializedFollowers FROM followers WHERE id=1''')
504-
proto = cursor.fetchone()
505-
conn.close()
506-
if not proto:
507-
return None
508-
else:
509-
return proto[0]
494+
495+
cursor.execute('''SELECT Count(*) FROM followers''')
496+
count = cursor.fetchone()[0]
497+
498+
f = Followers()
499+
if count > 0:
500+
smt = '''select serializedFollower from followers order by rowid desc limit 30 offset ''' + str(start)
501+
cursor.execute(smt)
502+
serialized_followers = cursor.fetchall()
503+
conn.close()
504+
for proto in serialized_followers:
505+
p = Followers.Follower()
506+
p.ParseFromString(proto[0].decode("hex"))
507+
f.followers.extend([p])
508+
return (f.SerializeToString(), count)
510509

511510

512511
class MessageStore(object):
@@ -591,7 +590,7 @@ def get_conversations(self):
591590
handle = ""
592591
if val[0] is not None:
593592
try:
594-
with open(join(DATA_FOLDER, 'cache', g[0]), "r") as filename:
593+
with open(join(DATA_FOLDER, 'cache', g[0] + ".profile"), "r") as filename:
595594
profile = filename.read()
596595
p = objects.Profile()
597596
p.ParseFromString(profile)

db/migrations/migration2.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,5 @@ def migrate(database_path):
2121
# update version
2222
cursor.execute('''PRAGMA user_version = 2''')
2323
conn.commit()
24+
2425
conn.close()

db/migrations/migration3.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import sqlite3
2+
from protos import objects
3+
4+
5+
def migrate(database_path):
6+
print "migrating to db version 3"
7+
conn = sqlite3.connect(database_path)
8+
conn.text_factory = str
9+
cursor = conn.cursor()
10+
# read followers from db
11+
cursor.execute('''SELECT serializedFollowers FROM followers WHERE id=1''')
12+
followers = cursor.fetchone()
13+
14+
# delete follower table
15+
cursor.execute('''DROP TABLE followers''')
16+
17+
# create new table
18+
cursor.execute('''CREATE TABLE followers(guid TEXT UNIQUE, serializedFollower TEXT)''')
19+
cursor.execute('''CREATE INDEX index_followers ON followers(serializedFollower);''')
20+
21+
# write followers back into db
22+
23+
if followers is not None:
24+
f = objects.Followers()
25+
f.ParseFromString(followers[0])
26+
for follower in f.followers:
27+
cursor.execute('''INSERT INTO followers(guid, serializedFollower) VALUES (?,?)''',
28+
(follower.guid.encode("hex"), follower.SerializeToString().encode("hex"),))
29+
30+
# update version
31+
cursor.execute('''PRAGMA user_version = 3''')
32+
conn.commit()
33+
conn.close()

db/tests/test_datastore.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -163,13 +163,13 @@ def test_follow_unfollow(self):
163163
self.assertFalse(self.fd.is_following(self.u.guid))
164164

165165
def test_deleteFollower(self):
166-
self.fd.set_follower(self.f)
167-
self.fd.set_follower(self.f)
166+
self.fd.set_follower(self.f.SerializeToString())
167+
self.fd.set_follower(self.f.SerializeToString())
168168
f = self.fd.get_followers()
169169
self.assertIsNotNone(f)
170170
self.fd.delete_follower(self.f.guid)
171171
f = self.fd.get_followers()
172-
self.assertEqual(f, '')
172+
self.assertEqual(f[0], '')
173173

174174
def test_MassageStore(self):
175175
msgs = self.ms.get_messages(self.u.guid, 'CHAT')

market/network.py

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ def get_result(result):
195195
self.get_image(node_to_ask, p.avatar_hash)
196196
if not os.path.isfile(os.path.join(DATA_FOLDER, 'cache', p.header_hash.encode("hex"))):
197197
self.get_image(node_to_ask, p.header_hash)
198-
self.cache(result[1][0], node_to_ask.id.encode("hex"))
198+
self.cache(result[1][0], node_to_ask.id.encode("hex") + ".profile")
199199
return p
200200
except Exception:
201201
return None
@@ -373,7 +373,7 @@ def save_to_db(result):
373373
self.log.info("sending unfollow request to %s" % node_to_unfollow)
374374
return d.addCallback(save_to_db)
375375

376-
def get_followers(self, node_to_ask):
376+
def get_followers(self, node_to_ask, start=0):
377377
"""
378378
Query the given node for a list if its followers. The response will be a
379379
`Followers` protobuf object. We will verify the signature for each follower
@@ -388,8 +388,11 @@ def get_response(response):
388388
verify_key.verify(response[1][0], response[1][1])
389389
f.ParseFromString(response[1][0])
390390
except Exception:
391-
return None
391+
return (None, None)
392392
# Verify the signature and guid of each follower.
393+
count = None
394+
if len(response[1]) > 2:
395+
count = response[1][2]
393396
for follower in f.followers:
394397
try:
395398
v_key = nacl.signing.VerifyKey(follower.pubkey)
@@ -404,9 +407,14 @@ def get_response(response):
404407
raise Exception('Invalid follower')
405408
except Exception:
406409
f.followers.remove(follower)
407-
return f
410+
return (f, count)
408411

409-
d = self.protocol.callGetFollowers(node_to_ask)
412+
peer = (node_to_ask.ip, node_to_ask.port)
413+
if peer in self.protocol.multiplexer and \
414+
self.protocol.multiplexer[peer].handler.remote_node_version > 1:
415+
d = self.protocol.callGetFollowers(node_to_ask, start=start)
416+
else:
417+
d = self.protocol.callGetFollowers(node_to_ask)
410418
self.log.info("fetching followers from %s" % node_to_ask)
411419
return d.addCallback(get_response)
412420

@@ -1241,3 +1249,15 @@ def cache(file_to_save, filename):
12411249
"""
12421250
with open(os.path.join(DATA_FOLDER, "cache", filename), 'wb') as outfile:
12431251
outfile.write(file_to_save)
1252+
1253+
@staticmethod
1254+
def load_from_cache(filename):
1255+
"""
1256+
Loads a file from cache
1257+
"""
1258+
filepath = DATA_FOLDER + "cache/" + filename
1259+
if not os.path.exists(filepath):
1260+
return None
1261+
with open(filepath, "r") as filename:
1262+
f = filename.read()
1263+
return f

market/protocol.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -175,14 +175,14 @@ def rpc_unfollow(self, sender, signature):
175175
self.log.warning("failed to validate signature on unfollow request")
176176
return ["False"]
177177

178-
def rpc_get_followers(self, sender):
178+
def rpc_get_followers(self, sender, start=None):
179179
self.log.info("serving followers list to %s" % sender)
180180
self.router.addContact(sender)
181-
ser = self.db.follow.get_followers()
182-
if ser is None:
183-
return None
181+
if start is not None:
182+
ser = self.db.follow.get_followers(int(start))
184183
else:
185-
return [ser, self.signing_key.sign(ser)[:64]]
184+
ser = self.db.follow.get_followers()
185+
return [ser[0], self.signing_key.sign(ser[0])[:64], ser[1]]
186186

187187
def rpc_get_following(self, sender):
188188
self.log.info("serving following list to %s" % sender)
@@ -398,8 +398,11 @@ def callUnfollow(self, nodeToAsk, signature):
398398
d = self.unfollow(nodeToAsk, signature)
399399
return d.addCallback(self.handleCallResponse, nodeToAsk)
400400

401-
def callGetFollowers(self, nodeToAsk):
402-
d = self.get_followers(nodeToAsk)
401+
def callGetFollowers(self, nodeToAsk, start=None):
402+
if start is None:
403+
d = self.get_followers(nodeToAsk)
404+
else:
405+
d = self.get_followers(nodeToAsk, start)
403406
return d.addCallback(self.handleCallResponse, nodeToAsk)
404407

405408
def callGetFollowing(self, nodeToAsk):

net/rpcudp.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,6 @@ def receive_message(self, message, sender, connection, ban_score):
5050
connection.shutdown()
5151
return False
5252

53-
if message.protoVer < PROTOCOL_VERSION:
54-
self.log.warning("received message from %s with incompatible protocol version." %
55-
str(connection.dest_addr))
56-
connection.shutdown()
57-
return False
58-
5953
self.multiplexer.vendors[sender.id] = sender
6054

6155
msgID = message.messageID

net/wireprotocol.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ def __init__(self, processors, nat_type, relay_node, ban_score, *args, **kwargs)
6868
self.is_new_node = True
6969
self.on_connection_made()
7070
self.time_last_message = 0
71+
self.remote_node_version = 1
7172
self.ping_interval = 30 if nat_type != FULL_CONE else 300
7273

7374
def on_connection_made(self):
@@ -94,6 +95,7 @@ def receive_message(self, datagram):
9495
(m.sender.relayAddress.ip, m.sender.relayAddress.port),
9596
m.sender.natType,
9697
m.sender.vendor)
98+
self.remote_node_version = m.protoVer
9799
if self.time_last_message == 0:
98100
h = nacl.hash.sha512(m.sender.publicKey)
99101
pow_hash = h[40:]

0 commit comments

Comments
 (0)