diff --git a/Part_4/Yonathan/Dockerfile b/Part_4/Yonathan/Dockerfile new file mode 100644 index 0000000..b9e89db --- /dev/null +++ b/Part_4/Yonathan/Dockerfile @@ -0,0 +1,13 @@ +# Choosing an image for you container. +FROM python:3.11.0 +# Setting your working directory +WORKDIR /app +# This command would copy EVERY FILE from your project folder into your container, so be careful. +COPY . /app +# Installing needed packages and dependencies.** +RUN pip install -r requirements.txt +# This command basically executes your main file with Python. +CMD ["python", "main.py"] +# Setting a port for your app communications with Telegram servers. + +EXPOSE 80/tcp \ No newline at end of file diff --git a/Part_4/Yonathan/Readme.md b/Part_4/Yonathan/Readme.md new file mode 100644 index 0000000..8ab5ea6 --- /dev/null +++ b/Part_4/Yonathan/Readme.md @@ -0,0 +1,8 @@ +# Implementation of this example bot is deployed and it is found by the telegram handle [@A2SV_Remote_Part_4_Example_bot](https://t.me/A2SV_Remote_Part_4_Example_bot) + +⚠ It is not deployed, but you can run the code on codespaces or localy and use the bot +# Done by: Blen +# Bot Commands implemented: `/add_user` +# : `/all_users` +# : `/get_user_by_id` +# diff --git a/Part_4/Yonathan/__init__.py b/Part_4/Yonathan/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/Part_4/Yonathan/bot/__init__.py b/Part_4/Yonathan/bot/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/Part_4/Yonathan/bot/bot_instance.py b/Part_4/Yonathan/bot/bot_instance.py new file mode 100644 index 0000000..dd34dc4 --- /dev/null +++ b/Part_4/Yonathan/bot/bot_instance.py @@ -0,0 +1,20 @@ +import os +from aiogram import Bot, types + +from config import TOKEN_API +# Use the commented code below if you store the token api in .env +# from dotenv import load_dotenv +# load_dotenv() + +# For hosting on pythonanywhere use the following commented code +# from aiogram.client.session.aiohttp import AiohttpSession +# bot = Bot( +# token=TOKEN_API, +# parse_mode='HTML', +# session=AiohttpSession(proxy='http://proxy.server:3128') +# ) + +bot = Bot( + token=TOKEN_API, + parse_mode='HTML' +) \ No newline at end of file diff --git a/Part_4/Yonathan/bot/callbacks/__init__.py b/Part_4/Yonathan/bot/callbacks/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/Part_4/Yonathan/bot/callbacks/callback.py b/Part_4/Yonathan/bot/callbacks/callback.py new file mode 100644 index 0000000..363e6c5 --- /dev/null +++ b/Part_4/Yonathan/bot/callbacks/callback.py @@ -0,0 +1,15 @@ +from aiogram.filters import Command +from aiogram import Router, types +from aiogram.utils.keyboard import InlineKeyboardBuilder + + +callback_router = Router() + + +@callback_router.callback_query(lambda c: c.data.startswith("action_1")) +async def process_callback_respond_to_action1(callback_query: types.CallbackQuery): + await callback_query.message.answer(f"you picked {callback_query.data}") + +@callback_router.callback_query(lambda c: c.data.startswith("action_2")) +async def process_callback_respond_to_action1(callback_query: types.CallbackQuery): + await callback_query.message.answer(f"you picked {callback_query.data}") diff --git a/Part_4/Yonathan/bot/handlers/__init__.py b/Part_4/Yonathan/bot/handlers/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/Part_4/Yonathan/bot/handlers/message_handlers.py b/Part_4/Yonathan/bot/handlers/message_handlers.py new file mode 100644 index 0000000..bee76d8 --- /dev/null +++ b/Part_4/Yonathan/bot/handlers/message_handlers.py @@ -0,0 +1,47 @@ +from aiogram.filters import Command +from aiogram import Router, types, F +from aiogram.utils.keyboard import InlineKeyboardBuilder +from datetime import datetime + +from ..keyboards import keyboard +from database.services.user_services import get_users, get_user_by_id, create_user + +message_router = Router() + +@message_router.message(Command('all_users')) +async def all_users(message: types.Message): + try: + users = await get_users() + await message.answer(f"{users}") + except Exception as e: + await message.answer(f"Some error occurred: {e}") + +@message_router.message(Command('add_user')) +async def add_users(message: types.Message): + try: + print("Adding user...") + users = await create_user(int(message.chat.id), name = message.chat.full_name, date= datetime.now()) + print("done") + await message.answer(f"{users}") + except Exception as e: + await message.answer(f"Some error occurred:\n {e}") + +@message_router.message(Command('get_user_by_id')) +async def get_by_id(message: types.Message): + try: + await message.answer("What is the id of the user you are looking for?") + except: + await message.answer("Some error occurred") + +@message_router.message() +async def retrive_user_by_id(message: types.Message): + try: + print("searching user...") + user = await get_user_by_id(int(message.text)) + print("searching complete...") + await message.answer(f"{user}") + except Exception as e: + await message.answer(f"Some error occurred {e}") + + +# Same way you can update and delete users \ No newline at end of file diff --git a/Part_4/Yonathan/bot/keyboards/__init__.py b/Part_4/Yonathan/bot/keyboards/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/Part_4/Yonathan/bot/keyboards/keyboard.py b/Part_4/Yonathan/bot/keyboards/keyboard.py new file mode 100644 index 0000000..381e495 --- /dev/null +++ b/Part_4/Yonathan/bot/keyboards/keyboard.py @@ -0,0 +1,4 @@ + +from aiogram.types import ReplyKeyboardMarkup, InlineKeyboardMarkup, KeyboardButton, InlineKeyboardButton + + diff --git a/Part_4/Yonathan/config.py b/Part_4/Yonathan/config.py new file mode 100644 index 0000000..52c54c0 --- /dev/null +++ b/Part_4/Yonathan/config.py @@ -0,0 +1,2 @@ +TOKEN_API="6712112472:AAFQOvBA5T6-FTD4Cz2XmjFy14NVyPRiY8I" +MONGO_URL="mongodb+srv://A2SVian:zq0STDlLqS2pq8ox@data-cluster.oiwdwnw.mongodb.net/?retryWrites=true&w=majority" \ No newline at end of file diff --git a/Part_4/Yonathan/database/__init__.py b/Part_4/Yonathan/database/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/Part_4/Yonathan/database/loader.py b/Part_4/Yonathan/database/loader.py new file mode 100644 index 0000000..37aea4f --- /dev/null +++ b/Part_4/Yonathan/database/loader.py @@ -0,0 +1,10 @@ +from aiogram import Bot, Dispatcher +import motor.motor_asyncio +from aiogram.fsm.storage.memory import MemoryStorage + +from config import MONGO_URL + + + +cluster = motor.motor_asyncio.AsyncIOMotorClient(MONGO_URL) +collection = cluster.Blen.myCollection diff --git a/Part_4/Yonathan/database/models/__init__.py b/Part_4/Yonathan/database/models/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/Part_4/Yonathan/database/models/user_model.py b/Part_4/Yonathan/database/models/user_model.py new file mode 100644 index 0000000..05ac4c2 --- /dev/null +++ b/Part_4/Yonathan/database/models/user_model.py @@ -0,0 +1,16 @@ +from pydantic import BaseModel + +from ..loader import collection +from datetime import datetime + + +class User(BaseModel): + _id: int + name: str + date: datetime + bio: str + phone_number: str + + + +users_collection = collection.user \ No newline at end of file diff --git a/Part_4/Yonathan/database/services/__init__.py b/Part_4/Yonathan/database/services/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/Part_4/Yonathan/database/services/user_services.py b/Part_4/Yonathan/database/services/user_services.py new file mode 100644 index 0000000..9cea4cf --- /dev/null +++ b/Part_4/Yonathan/database/services/user_services.py @@ -0,0 +1,21 @@ +from ..models.user_model import User, users_collection + + +async def get_users() -> list[User]: + users = users_collection.find() + return [User(**u) async for u in users] + + +async def get_user_by_id(id: int) -> User or None: + user = await users_collection.find_one({'_id': id}) + return User(**user) if user else None + + +async def create_user(id: int, **kwargs) -> User: + user = await users_collection.insert_one({'_id': id, **kwargs}) + return await get_user_by_id(user.inserted_id) + + +async def update_user(id: int, **kwargs) -> User: + user = await users_collection.find_one_and_update({'_id': id}, {'$set': kwargs}, return_document=True) + return User(**user) diff --git a/Part_4/Yonathan/main.py b/Part_4/Yonathan/main.py new file mode 100644 index 0000000..5a604cf --- /dev/null +++ b/Part_4/Yonathan/main.py @@ -0,0 +1,37 @@ +import asyncio + +from aiogram import Dispatcher + +from bot.bot_instance import bot +from bot.handlers.message_handlers import message_router +from bot.callbacks.callback import callback_router + + +def register_routers(dp: Dispatcher) -> None: + """Registers routers""" + + dp.include_router(message_router) + + # callback routers + dp.include_router(callback_router) + + + + + +async def main() -> None: + """The main function which will execute our event loop and start polling.""" + try: + dp = Dispatcher() + + print('Bot Starting....') + register_routers(dp) + print("Polling ....") + + await dp.start_polling(bot) + except: + print("Some error occurred") + + +if __name__ == "__main__": + asyncio.run(main()) \ No newline at end of file diff --git a/Part_4/Yonathan/requirements.txt b/Part_4/Yonathan/requirements.txt new file mode 100644 index 0000000..5b79c5f Binary files /dev/null and b/Part_4/Yonathan/requirements.txt differ diff --git a/Part_4/Yonathan/utils/__init__.py b/Part_4/Yonathan/utils/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/Part_4/Yonathan/utils/state.py b/Part_4/Yonathan/utils/state.py new file mode 100644 index 0000000..dc33d67 --- /dev/null +++ b/Part_4/Yonathan/utils/state.py @@ -0,0 +1,8 @@ +from aiogram.fsm.state import StatesGroup, State + +class Form(StatesGroup): + name = State() + phone_number = State() + role = State() + photo = State() + bio = State() \ No newline at end of file