mirror of
https://github.com/Steffo99/greed.git
synced 2024-11-30 17:44:18 +00:00
Import from Steffo99/pizzabot
This commit is contained in:
commit
c66fcd5939
5 changed files with 231 additions and 0 deletions
103
.gitignore
vendored
Normal file
103
.gitignore
vendored
Normal file
|
@ -0,0 +1,103 @@
|
|||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
env/
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
.hypothesis/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
local_settings.py
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
target/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# pyenv
|
||||
.python-version
|
||||
|
||||
# celery beat schedule file
|
||||
celerybeat-schedule
|
||||
|
||||
# SageMath parsed files
|
||||
*.sage.py
|
||||
|
||||
# dotenv
|
||||
.env
|
||||
|
||||
# virtualenv
|
||||
.venv
|
||||
venv/
|
||||
ENV/
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
.spyproject
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
# mkdocs documentation
|
||||
/site
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
|
||||
.idea
|
5
README.md
Normal file
5
README.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
# pizzabot
|
||||
Un bot di Telegram per ordinazioni di una pizzeria
|
||||
|
||||
## Variabili di ambiente richieste
|
||||
- `telegram_api_key`: l'API key del bot pizzeria
|
10
bot.py
Normal file
10
bot.py
Normal file
|
@ -0,0 +1,10 @@
|
|||
from telegram.ext import Updater
|
||||
import logging
|
||||
import os
|
||||
|
||||
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
|
||||
|
||||
if __name__ == "__main__":
|
||||
bot = Updater(os.environ("telegram_api_key"))
|
||||
bot.start_polling()
|
||||
bot.idle()
|
94
database.py
Normal file
94
database.py
Normal file
|
@ -0,0 +1,94 @@
|
|||
from sqlalchemy.ext.declarative import declarative_base
|
||||
from sqlalchemy.orm import sessionmaker, relationship, composite
|
||||
from sqlalchemy import Column, BigInteger, Integer, String, Numeric, DateTime, ForeignKey, Float, create_engine
|
||||
from dbcomposites import Coordinates
|
||||
|
||||
# Init the sqlalchemy engine
|
||||
engine = create_engine("postgres://steffo:HIDDENPASSWORD@royal.steffo.eu:5432/pizzadev")
|
||||
Base = declarative_base(bind=engine)
|
||||
Session = sessionmaker(bind=engine)
|
||||
|
||||
# Create a new default session
|
||||
session = Session()
|
||||
|
||||
|
||||
class TelegramUser(Base):
|
||||
"""Basic Telegram user data"""
|
||||
__tablename__ = "tusers"
|
||||
|
||||
tid = Column(BigInteger, primary_key=True)
|
||||
tusername = Column(String)
|
||||
tfirstname = Column(String, nullable=False)
|
||||
tlastname = Column(String)
|
||||
|
||||
def __str__(self):
|
||||
if self.tusername is not None:
|
||||
return f"@{self.tusername}"
|
||||
elif self.tlastname is not None:
|
||||
return f"{self.tfirstname} {self.tlastname}"
|
||||
else:
|
||||
return f"{self.tfirstname}"
|
||||
|
||||
def __repr__(self):
|
||||
return f"<User #{self.tid}>"
|
||||
|
||||
|
||||
class Pizza(Base):
|
||||
"""Data for a pizza type"""
|
||||
__tablename__ = "pizza"
|
||||
|
||||
id = Column(Integer, primary_key=True)
|
||||
name = Column(String, nullable=False, unique=True)
|
||||
details = Column(String)
|
||||
price = Column(Numeric, scale=2, nullable=False)
|
||||
|
||||
def __str__(self, full=False):
|
||||
if full:
|
||||
return f"{self.name} [{self.price}]\n{self.details}"
|
||||
return f"{self.name} [{self.price}]"
|
||||
|
||||
def __repr__(self):
|
||||
return f"<Pizza #{self.id}>"
|
||||
|
||||
|
||||
class PizzaSelection(Base):
|
||||
"""Data for a single pizza placed in a order"""
|
||||
__tablename__ = "pizzaselection"
|
||||
|
||||
order_id = Column(Integer, ForeignKey("orders.id"), primary_key=True)
|
||||
pizza_id = Column(Integer, ForeignKey("pizza.id"), primary_key=True)
|
||||
pizza = relationship("Pizza")
|
||||
|
||||
notes = Column(String)
|
||||
|
||||
def __repr__(self):
|
||||
return "<PizzaSelection of Pizza #{self.pizza_id} in Order #{self.order_id}>"
|
||||
|
||||
|
||||
class Order(Base):
|
||||
"""Data for a pizza order"""
|
||||
__tablename__ = "orders"
|
||||
|
||||
id = Column(Integer, primary_key=True)
|
||||
creation_time = Column(DateTime, nullable=False)
|
||||
requested_time = Column(DateTime)
|
||||
delivery_time = Column(DateTime)
|
||||
completed_time = Column(DateTime)
|
||||
notes = Column(String)
|
||||
|
||||
delivery_long = Column(Float, nullable=False)
|
||||
delivery_lat = Column(Float, nullable=False)
|
||||
delivery_location = composite(Coordinates, delivery_long, delivery_lat)
|
||||
|
||||
user_id = Column(Integer, ForeignKey("tusers.id"))
|
||||
user = relationship("TelegramUser")
|
||||
|
||||
pizzas = relationship("PizzaSelection")
|
||||
|
||||
def __repr__(self):
|
||||
return f"<Order #{self.id}>"
|
||||
|
||||
|
||||
# If run as script, create all the tables in the db
|
||||
if __name__ == "__main__":
|
||||
Base.metadata.create_all(bind=engine)
|
19
dbcomposites.py
Normal file
19
dbcomposites.py
Normal file
|
@ -0,0 +1,19 @@
|
|||
# Custom composite types
|
||||
# All types must contain the __composite_values__ method
|
||||
|
||||
class Coordinates(object):
|
||||
"""Geographic coordinates"""
|
||||
def __init__(self, longitude, latitude):
|
||||
self.longitude = longitude
|
||||
self.latitude = latitude
|
||||
|
||||
def __repr__(self):
|
||||
return f"Coordinates(longitude={self.longitude}, latitude={self.latitude})"
|
||||
|
||||
def __eq__(self, other):
|
||||
return isinstance(other, Coordinates) \
|
||||
and self.longitude == other.longitude \
|
||||
and self.latitude == other.latitude
|
||||
|
||||
def __composite_values__(self):
|
||||
return self.longitude, self.latitude
|
Loading…
Reference in a new issue