diff --git a/src/metriki/__init__.py b/src/metriki/__init__.py index bc4711d..e69de29 100644 --- a/src/metriki/__init__.py +++ b/src/metriki/__init__.py @@ -1,57 +0,0 @@ -from nio import AsyncClient, RoomMessageText -import random - -class BooeehBot: - - def generate_boeh(self): - boeh = "b" - for _ in range(random.randint(1, 10)): - boeh += "o" - for _ in range(random.randint(1, 5)): - boeh += "e" - for _ in range(random.randint(1, 3)): - boeh += "e" - return boeh - - def __init__(self, url, username, password): - self.url = url - self.username = username - self.password = password - self.client = AsyncClient(url, username) - - async def login(self): - try: - response = await self.client.login(self.password) - print(f"Logged in. Serving {self.username}.") - return response - except Exception as e: - print(f"Login error: {e}") - return None - - async def handle_message(self, room, event): - specific_user_id = "@joewilliams007:matrix.org" - - if isinstance(event, RoomMessageText): - if event.sender == specific_user_id: - response_text = self.generate_boeh() - try: - await self.client.room_send( - room.room_id, - message_type="m.room.message", - content={"msgtype": "m.text", "body": response_text}, - ) - print(f"Response to {event.sender}: " + response_text) - except Exception as e: - print(f"Failed to send message: {e}") - - async def start(self): - login_response = await self.login() - if not login_response: - return - - self.client.add_event_callback(self.handle_message, RoomMessageText) - - await self.client.sync_forever(timeout=30000) - - async def stop(self): - await self.client.close() diff --git a/src/metriki/app.py b/src/metriki/app.py index e69de29..27b710e 100644 --- a/src/metriki/app.py +++ b/src/metriki/app.py @@ -0,0 +1,146 @@ +from app.app import Application as BaseApplication +from aiohttp import web +import aiohttp +import json +import uuid +from datetime import datetime + +class BaseView(web.View): + + @property + def ip(self): + return self.request.headers.get("X-Forwarded-For",self.request.remote) + def uid(self): + return str(uuid.uuid4()) + + @property + def app(self): + return self.request.app + + @property + def db(self): + return self.app.db + + def set(self,key, value,**kwargs): + record = dict( + ip=self.ip, + key=key, + value=json.dumps(value,default=str), + created=datetime.now() + ) + record.update(kwargs) + self.db['session'].upsert(dict( + key=key, + value=json.dumps(value,default=str), + ip=self.ip, + created=datetime.now() + ),['session_id','key']) + return record + + def get(self,key,default=None): + try: + return json.loads(self.db['session'].find_one(dict(session_id=self.session_id,key=key))['value']) + except: + return default + + def insert(self, table, data): + data['session_id'] = self.session_id + data['created'] = datetime.now() + return self.db[table].insert(data) + + def find(self,table,data=None): + if not data: + data = {} + data['session_id'] = self.session_id + return [dict(d) for d in self.db[table].find(**data)] + +class EventView(BaseView): + + document_fields = ['html','title','html','domain','href'] + + event_fields = ['target','event','tag','scroll_height','scroll_left','scroll_top','client_width','client_height','page_x','page_y','screen_x','screen_y','client_x','client_y','target_x','target_y'] + + def is_document_record(self, data): + return self.data.get('html') and True or False + + def get_record(self, data): + + try: + record = {} + for field in self.document_fields: + if field in data: + record[field] = data[field] + if len(record.keys()) == len(document_fields): + return record + except KeyError: + pass + + try: + record = {} + for field in self.event_fields: + if field in data: + record[field] = data[field] + if len(record.keys()) == len(event_fields): + return record + except: + pass + + return None + + async def get(self): + ws = web.WebSocketResponse() + await ws.prepare(request) + + html = None + visit_id = self.uid() + print(f"Socket connected from {self.ip}.") + + async for msg in ws: + if msg.type == web.WSMsgType.TEXT: + # Echo the received message back to the client + try: + data = data.json() + except: + continue + + data = self.get_record(data) + if self.is_document_record(data): + html = data.get('html') + record = dict( + html=html, + visit_id=visit_id, + domain=data.get('domain'), + href=data.get('href'), + title=data.get('title') + ) + self.insert('visit', record) + self.app.view_count += 1 + else: + data['visit_id'] = visit_id + self.insert('event', record) + self.app.event_count += 1 + + print(self.app.view_count, self.app.event_count) + + elif msg.type == web.WSMsgType.ERROR: + print(f'Socket closed: {ws.exception()}') + + print("Socket cracefully closed.") + return ws + +class Application(BaseApplication): + + async def __init__(self, db_path, *args, **kwargs): + self.view_count = 0 + self.event_count = 0 + await super().__init__(db_path=db_path, *args, **kwargs) + self.router.add_get("/", self.index_handler) + self.router.add_view("/event", EventView) + + async def index_handler(self, request): + return web.Response( + text="\n".join(["Under the spreading chestnut tree" + "I sold you, and you sold me" + "There lie they, and here lie we," + "Under the spreading chestnut tree." + ]),content_type='text/plain')