From c9acbedb1377175acc8fe630c7eeddeee50d562e Mon Sep 17 00:00:00 2001 From: Oleg Silkin Date: Wed, 15 May 2019 19:17:06 -0400 Subject: [PATCH] Initial commit --- scripts.sql | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++++ server.py | 98 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 220 insertions(+) create mode 100644 scripts.sql create mode 100644 server.py diff --git a/scripts.sql b/scripts.sql new file mode 100644 index 0000000..3e7b40e --- /dev/null +++ b/scripts.sql @@ -0,0 +1,122 @@ +ATTACH DATABASE 'comments.db' AS Comments; + +PRAGMA FOREIGN_KEYS = ON; + +SELECT * FROM CLAIM WHERE LbryClaimId LIKE '1ed866252f80e48f2496acec72a69a5ad85497AC'; + +SELECT * FROM CLAIM; + +DROP TABLE CLAIM; +CREATE TABLE IF NOT EXISTS CLAIM ( + ClaimIndex INTEGER NOT NULL, + LbryClaimId TEXT NOT NULL, + Time_added INTEGER NOT NULL DEFAULT (strftime('%s', 'now')), + CONSTRAINT CLAIM_PK PRIMARY KEY (ClaimIndex) + ON CONFLICT ROLLBACK, + CONSTRAINT LBRY_CLAIMID_CK UNIQUE (LbryClaimId) + ON CONFLICT IGNORE, + CONSTRAINT LBRY_CLAIM_ID CHECK (length(LbryClaimId) = 40) +); +INSERT INTO CLAIM(LbryClaimId) +VALUES ('1ed866252f80e48f2496acec72a69a5ad85497ac'), + ('3128b0f0e9b4b18e33fc8e2a586a66da40f617c4'), + ('ce09230acc7b0037ddc9a1ac01f03baab8a23b1b'); +-- ('0c37b593d4d7e9a00e1bd69f305d0241eac3f4ad'); + +SELECT * FROM COMMENT; +DROP TABLE COMMENT; +CREATE TABLE IF NOT EXISTS COMMENT ( + CommentId INTEGER NOT NULL PRIMARY KEY , + ClaimIndex INTEGER NOT NULL, + ChannelName TEXT NOT NULL, + ParentId INTEGER DEFAULT NULL, + Timestamp INTEGER NOT NULL DEFAULT (strftime('%s', 'now')), + Comment TEXT NOT NULL, + CONSTRAINT COMMENT_CLAIM_FK + FOREIGN KEY (ClaimIndex) REFERENCES CLAIM(ClaimIndex) + ON UPDATE CASCADE ON DELETE CASCADE, + CONSTRAINT COMMENT_PARENT_FK + FOREIGN KEY (ParentId) REFERENCES COMMENT(CommentId) + ON UPDATE CASCADE ON DELETE SET NULL, + CONSTRAINT COMMENT_LEN CHECK(1 < length(Comment) AND length(Comment) <= 2000), + CONSTRAINT CHANNEL_NAME_LEN CHECK ( 0 < length(ChannelName) AND length(ChannelName) <= 120), + CONSTRAINT COMMENT_SK UNIQUE (ChannelName, Comment, ParentId) + ON CONFLICT IGNORE +); + + + +INSERT INTO COMMENT(ClaimIndex, ChannelName, ParentId, Comment) +SELECT 2 , 'Flatness Flatness LA', 1, 'sick bike tricks' +FROM CLAIM AS C +WHERE C.ClaimIndex = ClaimIndex AND EXISTS ( + SELECT * FROM Comments.COMMENT AS P + WHERE P.CommentId = P.ParentId +); + +-- first three should fail +INSERT INTO CLAIM(LbryClaimId) +VALUES ('1ed866252f80e48f2496acec72a69a5ad85497ac'), + ('3128b0f0e9b4b18e33fc8e2a586a66da40f617c4'), + ('ce09230acc7b0037ddc9a1ac01f03baab8a23b1b'), + ('0c37b593d4d7e9a00e1bd69f305d0241eac3f4ad'); + + +-- gets the top level comments for a given claim id +SELECT * FROM COMMENT AS C, CLAIM AS D +WHERE C.ParentId IS NULL + AND C.ClaimIndex = D.ClaimIndex + AND D.LbryClaimId LIKE 'some shit here'; + +SELECT SQLITE_VERSION(); + + + +SELECT * FROM CLAIM; +INSERT INTO COMMENT(ClaimIndex, ChannelName, Comment) +SELECT + C.ClaimIndex, 'doge loard', 'nice ass' +FROM CLAIM AS C WHERE C.LbryClaimId = '1ed866252f80e48f2496acec72a69a5ad85497ac'; + +SELECT C.ChannelId, C.Comment, C.Timestamp, D.LbryClaimId, D.Time_added +FROM COMMENT AS C NATURAL JOIN CLAIM AS D; + + INSERT INTO backups(creation_time, totalcomments, totalclaims, size_kb) + VALUES (]] .. time .. ", " .. com_count .. ", " .. claim_count .. + + SELECT last_insert_rowid(); + +SELECT _rowid_ FROM CLAIM UNION ALL +SELECT _rowid_ FROM COMMENT; + +INSERT INTO claims (lbry_perm_uri, Time_added) VALUES ('" .. + accouts:escape(claim_uri) .. "', " .. get_unix_time() .. ");" + + "UPDATE claims SET upvotes = " .. votes .. + " WHERE lbry_perm_uri = '" .. data.lbry_perm_uri .. "';" + + + "UPDATE claims SET downvotes = " .. votes .. + " WHERE lbry_perm_uri = '" .. data.lbry_perm_uri .. "';" + + "SELECT lbry_perm_uri FROM claims WHERE ClaimId = " .. + + "SELECT * FROM comments WHERE parent_com IS NULL AND ClaimId = " .. + + "INSERT INTO comments (ClaimId, poster_name, post_time," .. + " message) VALUES (" .. ClaimId .. ", '" .. poster_name .. + "', " .. post_time .. ", '" .. message .. "');" + +INSERT INTO comments (ClaimId, poster_name, " .. + "parent_com, post_time, message) VALUES (" .. ClaimId .. + ", '" .. poster_name .. "', " .. parent_id .. ", " .. + post_time .. ", '" .. message .. "');" + + "SELECT * FROM comments WHERE CommentId = '" .. comment_id .. "';" + "SELECT * FROM comments WHERE parent_com = '" .. comment_id .. "';" + +UPDATE comments SET upvotes = " .. votes .. + " WHERE CommentId = '" .. comment_id .. "';" + +UPDATE comments SET downvotes = " .. votes .. + " WHERE CommentId = '" .. comment_id .. "';" \ No newline at end of file diff --git a/server.py b/server.py new file mode 100644 index 0000000..680ffc6 --- /dev/null +++ b/server.py @@ -0,0 +1,98 @@ +import typing +import random +import asyncio +from aiohttp import web + + +class FakedCommentServer: + def __init__(self, port=2903): + self.port = port + self.app = web.Application(debug=True) + self.app.add_routes([web.post('/api', self.api)]) + self.runner = None + self.server = None + + def get_claim_comments(self, uri: str, better_keys: bool) -> typing.Union[dict, list, None]: + return [self.get_comment(i) for i in range(75)] + + def get_comment(self, comment_id: int, parent_id: int = None) -> dict: + return { + 'comment_id': comment_id, + 'parent_id': parent_id, + 'author': f'Person{comment_id}', + 'message': f'comment {comment_id}', + 'claim_id': random.randint(1, 2**16), + 'time_posted': random.randint(2**16, 2**32 - 1), + 'upvotes': random.randint(0, 9999), 'downvotes': random.randint(0, 9999) + } + + def comment(self, uri: str, poster: str, message: str) -> typing.Union[int, dict, None]: + if not uri.startswith('lbry://'): + return {'error': self.ERRORS['INVALID_URI']} + return random.randint(1, 9999) + + def reply(self, parent_id: int, poster: str, message: str) -> dict: + if 2 <= len(message) <= 2000 and 2 <= len(poster) <= 127 and parent_id > 0: + return random.randint(parent_id + 1, 2**32 - 1) + return {'error': self.ERRORS['INVALID_PARAMS']} + + def get_comment_data(self, comm_index: int, better_keys: bool = False) -> typing.Union[dict, None]: + return self.get_comment(comm_index) + + def get_comment_replies(self, comm_index: int) -> typing.Union[list, None]: + return [random.randint(comm_index, comm_index+250) for _ in range(75)] + + methods = { + 'get_claim_comments': get_claim_comments, + 'get_comment_data': get_comment_data, + 'get_comment_replies': get_comment_replies, + 'comment': comment, + 'reply': reply + } + + def process_json(self, body) -> dict: + response = {'jsonrpc': '2.0', 'id': body['id']} + if body['method'] in self.methods: + params = body.get('params', {}) + result = self.methods[body['method']](self, **params) + if type(result) is dict and 'error' in result: + response['error'] = result['error'] + else: + response['result'] = result + else: + response['error'] = self.ERRORS['UNKNOWN'] + return response + + async def _start(self): + self.runner = web.AppRunner(self.app) + await self.runner.setup() + self.server = web.TCPSite(self.runner, 'localhost', self.port) + await self.server.start() + + async def _stop(self): + await self.runner.cleanup() + + async def run(self, max_timeout=3600): + try: + await self._start() + await asyncio.sleep(max_timeout) + except asyncio.CancelledError: + pass + finally: + await self._stop() + + async def api(self, request): + body = await request.json() + if type(body) is list or type(body) is dict: + if type(body) is list: + response = [self.process_json(part) for part in body] + else: + response = self.process_json(body) + return web.json_response(response) + else: + return web.json_response({'error': self.ERRORS['UNKNOWN']}) + + +if __name__ == '__main__': + app = FakedCommentServer() + asyncio.run(app.run())