From b2660850e6ca7874e0496ddcee83bd193aaed83f Mon Sep 17 00:00:00 2001 From: Jeff Date: Wed, 12 Oct 2022 22:43:41 -0300 Subject: [PATCH] Starting struct db config/Repositories --- .gitignore | 1 + config/__init__.py | 0 config/mongo_connector.py | 8 ++ domain/__init__.py | 0 domain/user.py | 38 +++++++++ rastreio/db.py | 167 +++++++++++++++---------------------- rastreiobot.py | 5 +- tests/test_api_correios.py | 2 +- tests/test_rastreiobot.py | 2 +- webhook.py | 2 +- 10 files changed, 120 insertions(+), 105 deletions(-) create mode 100644 config/__init__.py create mode 100644 config/mongo_connector.py create mode 100644 domain/__init__.py create mode 100644 domain/user.py diff --git a/.gitignore b/.gitignore index ddc2987..fc244a5 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ __pycache__ rastreiobotenv/* *.log bot.log.* +venv \ No newline at end of file diff --git a/config/__init__.py b/config/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/config/mongo_connector.py b/config/mongo_connector.py new file mode 100644 index 0000000..39c85fb --- /dev/null +++ b/config/mongo_connector.py @@ -0,0 +1,8 @@ +from pymongo import MongoClient + + +class MongoConnector: + + def get_context(self): + return MongoClient().rastreiobot + \ No newline at end of file diff --git a/domain/__init__.py b/domain/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/domain/user.py b/domain/user.py new file mode 100644 index 0000000..0158055 --- /dev/null +++ b/domain/user.py @@ -0,0 +1,38 @@ +from config.mongo_connector import MongoConnector + + +class User: + + def __init__(self): + self.db = MongoConnector.get_context() + + @staticmethod + def update(self, telegram_id, upsert=False, **kwargs): + """Update an User in the database + + Args: + telegram_id (str): Telegram User ID. It's casts to string to keep + compatibility with current data. + upsert (bool): Create if the user doesn't exist + + Kwargs: + All keyword arguments will be sent as fields and its values to + update the user data. The following example will update the user, + which ID is 123, with `lang` field equals to `"pt_BR"`. + + + >>> User.update(123, lang="pt_BR") + + Returns: + An dict with User data. + """ + + telegram_id = str(telegram_id) + kwargs["id"] = telegram_id # Don't miss `id` if creating a new User + + return self.db.users.update( + {"id": telegram_id}, + {"$set": kwargs}, + upsert=upsert, + ) + \ No newline at end of file diff --git a/rastreio/db.py b/rastreio/db.py index 08a9b0e..4876e36 100644 --- a/rastreio/db.py +++ b/rastreio/db.py @@ -1,122 +1,89 @@ from time import time -from pymongo import ASCENDING, MongoClient - - -client = MongoClient() -db = client.rastreiobot - - -def metric_increase_package_counter(): - return db.metrics.update_one( - {"metric": "total_packages"}, - {"$inc": {"value": 1}}, - upsert=True, - ) - - -def all_packages(): - return db.rastreiobot.find() - - -def search_package(code): - return db.rastreiobot.find_one({"code": code}) - - -def search_packages_per_user(user_id): - user_id = str(user_id) - return db.rastreiobot.find({"users": user_id}).sort(user_id, ASCENDING) - - -def package_status(code): - return db.rastreiobot.find_one({"code": code})["stat"] - - -def package_has_user(code, user_id): - return db.rastreiobot.find_one({ - "code": code.upper(), - "users": user_id, - }) - +from pymongo import ASCENDING +from config.mongo_connector import MongoConnector + +class PackagesRepository: + + def __init__(self): + self.db = MongoConnector.get_context() + + def metric_increase_package_counter(self): + return self.db.metrics.update_one( + {"metric": "total_packages"}, + {"$inc": {"value": 1}}, + upsert=True, + ) -def add_package(code, users, stat): - users = users if isinstance(users, (list, tuple)) else [users] - package = db.rastreiobot.insert_one({ - "code": code.upper(), - "users": users, - "stat": stat, - "time": time(), - }) - metric_increase_package_counter() - return package + def all_packages(self): + return self.db.rastreiobot.find() -def add_user_to_package(code, user): - return db.rastreiobot.update_one( - {"code": code.upper()}, - {"$push": {"users": user}}, - ) + def search_package(self, code): + return self.db.rastreiobot.find_one({"code": code}) -def update_package(code, **kwargs): - code = str(code).upper() - return db.rastreiobot.update_one( - {"code": code}, - {"$set": kwargs}, - ) + def search_packages_per_user(self, user_id): + user_id = str(user_id) + return self.db.rastreiobot.find({"users": user_id}).sort(user_id, ASCENDING) -def remove_user_from_package(code, user_id): - print(code) - print(user_id) - package = search_package(code) - print(package) - users = package["users"] - users.remove(str(user_id)) - return update_package(code, users=users) + def package_status(self, code): + return self.db.rastreiobot.find_one({"code": code})["stat"] -def set_package_description(code, user_id, description=None): - user_id = str(user_id) - code = str(code).upper() - description = description or code - return db.rastreiobot.update_one( - {"code": code}, - {"$set": {user_id: description}}, - ) + def package_has_user(self, code, user_id): + return self.db.rastreiobot.find_one({ + "code": code.upper(), + "users": user_id, + }) -def delete_package(code): - return db.rastreiobot.delete_one({"code": code}) + def add_package(self, code, users, stat): + users = users if isinstance(users, (list, tuple)) else [users] + package = self.db.rastreiobot.insert_one({ + "code": code.upper(), + "users": users, + "stat": stat, + "time": time(), + }) + self.metric_increase_package_counter() + return package -class User: + def add_user_to_package(self, code, user): + return self.db.rastreiobot.update_one( + {"code": code.upper()}, + {"$push": {"users": user}}, + ) - @staticmethod - def update(telegram_id, upsert=False, **kwargs): - """Update an User in the database - Args: - telegram_id (str): Telegram User ID. It's casts to string to keep - compatibility with current data. - upsert (bool): Create if the user doesn't exist + def update_package(self, code, **kwargs): + code = str(code).upper() + return self.db.rastreiobot.update_one( + {"code": code}, + {"$set": kwargs}, + ) - Kwargs: - All keyword arguments will be sent as fields and its values to - update the user data. The following example will update the user, - which ID is 123, with `lang` field equals to `"pt_BR"`. + def remove_user_from_package(self, code, user_id): + print(code) + print(user_id) + package = self.search_package(code) + print(package) + users = package["users"] + users.remove(str(user_id)) + return self.update_package(code, users=users) - >>> User.update(123, lang="pt_BR") - Returns: - An dict with User data. - """ + def set_package_description(self, code, user_id, description=None): + user_id = str(user_id) + code = str(code).upper() + description = description or code + return self.db.rastreiobot.update_one( + {"code": code}, + {"$set": {user_id: description}}, + ) - telegram_id = str(telegram_id) - kwargs["id"] = telegram_id # Don't miss `id` if creating a new User - return db.users.update( - {"id": telegram_id}, - {"$set": kwargs}, - upsert=upsert, - ) + def delete_package(self, code): + return self.db.rastreiobot.delete_one({"code": code}) diff --git a/rastreiobot.py b/rastreiobot.py index 127a9bf..57adb49 100644 --- a/rastreiobot.py +++ b/rastreiobot.py @@ -16,7 +16,8 @@ import utils.msgs as msgs import utils.status as status -from rastreio import db +from rastreio.db import PackagesRepository + config = configparser.ConfigParser() config.read('bot.conf') @@ -56,7 +57,7 @@ def count_packages(): ''' Count total packages and packages per status ''' - cursor = db.all_packages() + cursor = PackagesRepository.all_packages() pkg_status = defaultdict(int) for elem in cursor: if len(elem['code']) > 13: diff --git a/tests/test_api_correios.py b/tests/test_api_correios.py index 2c8f215..caea07c 100644 --- a/tests/test_api_correios.py +++ b/tests/test_api_correios.py @@ -58,7 +58,7 @@ def test_parse_multiple_codes_output(mocked_parse): ]) -@patch("apis.apicorreios.db.update_package") +@patch("apis.apicorreios.db.PackagesRepository.update_package") def test_parse_package_in_transit(mocked_update_package): with open("tests/data/correios-package-in-transit.json") as file: returned_package = json.load(file) diff --git a/tests/test_rastreiobot.py b/tests/test_rastreiobot.py index c9722ac..f655fe2 100644 --- a/tests/test_rastreiobot.py +++ b/tests/test_rastreiobot.py @@ -38,7 +38,7 @@ def all_packages(): def test_count_packages(mocker, all_packages): - mocked = mocker.patch('rastreio.db.all_packages') + mocked = mocker.patch('rastreio.db.PackagesRepository.all_packages') mocked.return_value = all_packages assert dict(count_packages()) == { diff --git a/webhook.py b/webhook.py index a4b8acf..d104322 100644 --- a/webhook.py +++ b/webhook.py @@ -5,7 +5,7 @@ import sqlite3 import requests from flask import abort, request -from rastreio.db import User +from domain.user import User config = configparser.ConfigParser() config.sections()