Skip to content

Commit

Permalink
Merge branch 'release/1.9.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
dotchetter committed Jan 4, 2024
2 parents b92a12a + 4f542ff commit 6e19b65
Show file tree
Hide file tree
Showing 17 changed files with 200 additions and 21 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/heroku_ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
steps:
# Check-out your repository.
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v3


### ⬇ IMPORTANT PART ⬇ ###
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -129,3 +129,4 @@ dmypy.json
.pyre/

.idea/
/jarvis/logs/
5 changes: 3 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#Create a ubuntu base image with python 3 installed.
FROM python:3.10
FROM python:3.11

#Set the working directory
WORKDIR /
Expand All @@ -15,5 +15,6 @@ RUN pip3 install -r requirements.txt
#Expose the required port for MongoDB Atlas
EXPOSE 42487

#Run Jarvis with Pyttman CLI
# Run migrations and start Jarvis
CMD pyttman runfile jarvis jarvis/migrations/migrate.py upgrade
CMD pyttman runclient jarvis
2 changes: 1 addition & 1 deletion Procfile
Original file line number Diff line number Diff line change
@@ -1 +1 @@
worker: pyttman runclient jarvis
worker: pyttman runfile jarvis jarvis/migrations/migrate.py upgrade && pyttman runclient jarvis
File renamed without changes.
23 changes: 17 additions & 6 deletions jarvis/abilities/finance/ability.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ def register_debt(cls, message: Message) -> str:
author_is_borrower = message.entities["author_is_borrower"]
author_is_lender = message.entities["author_is_lender"]
amount = message.entities["amount"]
comment = message.entities["comment"]

if author_is_lender:
# author_is_lender supersedes author_is_borrower
Expand All @@ -175,7 +176,10 @@ def register_debt(cls, message: Message) -> str:
"Försök igen :slight_smile:"

# Create the debt entry
Debt.objects.create(borrower=borrower, lender=lender, amount=amount)
Debt.objects.create(borrower=borrower,
lender=lender,
amount=amount,
comment=comment)
total_debt_balance = Debt.objects.filter(
borrower=borrower, lender=lender
).sum("amount")
Expand Down Expand Up @@ -203,8 +207,11 @@ def get_debts(cls, message: Message) -> ReplyStream[str]:
"""
reply_stream = ReplyStream()
debts_by_lender: dict[User, int] = {}
borrower_name = extract_username(message, "borrower_name")
borrower: User = User.objects.from_username_or_alias(borrower_name)
if message.entities["author_is_borrower"]:
borrower = User.objects.from_message(message)
else:
borrower_name = extract_username(message, "borrower_name")
borrower: User = User.objects.from_username_or_alias(borrower_name)
debt_sum = Debt.objects.filter(borrower=borrower).sum("amount")

if borrower is None:
Expand All @@ -226,9 +233,13 @@ def get_debts(cls, message: Message) -> ReplyStream[str]:
except KeyError:
debts_by_lender[debt.lender] = debt.amount

for lender, _sum in debts_by_lender.items():
debt = Debt(lender=lender, borrower=borrower, amount=_sum)
reply_stream.put(debt)
if message.entities["individual"]:
for debt in Debt.objects.filter(borrower=borrower):
reply_stream.put(debt)
else:
for lender, _sum in debts_by_lender.items():
debt = Debt(lender=lender, borrower=borrower, amount=_sum)
reply_stream.put(debt)

return reply_stream

Expand Down
9 changes: 7 additions & 2 deletions jarvis/abilities/finance/intents.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ class AddDebt(Intent):
other_person = TextEntityField(valid_strings=SharedFinancesCalculator
.enrolled_usernames)
amount = IntEntityField()
comment = TextEntityField(span=10, prefixes=("för", "till"))

def respond(self, message: Message) -> Reply | ReplyStream:
if message.entities["amount"] is None:
Expand All @@ -148,11 +149,15 @@ class GetDebts(Intent):
Returns the sum of the debts registered for a borrower to
a particular lender.
"""
lead = ("visa", "lista", "show", "get", "hämta")
trail = ("skuld", "skulder", "debts", "lån", "lånat", "lånade")
lead = ("visa", "lista", "show", "get", "hämta", "hur")
trail = ("skuld", "skulder", "debts", "lån", "lånat", "lånade", "skyldig")

author_is_borrower = BoolEntityField(message_contains=("jag", "i"))
borrower_name = TextEntityField(
valid_strings=SharedFinancesCalculator.enrolled_usernames)
individual = BoolEntityField(message_contains=("individuell",
"individuella",
"individuellt"))

def respond(self, message: Message) -> Reply | ReplyStream:
return self.ability.get_debts(message)
Expand Down
5 changes: 3 additions & 2 deletions jarvis/abilities/finance/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ class Debt(me.Document):
lender: User = me.ReferenceField(User, required=True)
amount: float = me.FloatField(default=0.0)
created: datetime = me.DateTimeField(default=lambda: datetime.now())
comment = me.StringField(required=False)

def __str__(self):
"""
Expand All @@ -157,8 +158,8 @@ def __str__(self):
lender = f":bust_in_silhouette: **" \
f"{self.lender.username.capitalize()}**\n"
amount = f":money_with_wings: **{self.amount}:-**\n"

return lender + amount + sep
comment = f":speech_left: **{self.comment}**\n" if self.comment else ""
return lender + amount + comment + sep


class AccountingEntry(me.Document):
Expand Down
6 changes: 3 additions & 3 deletions jarvis/abilities/recipes/intents.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class GetRecipes(Intent):
lead = ("sök", "visa", "hitta")
trail = ("recept",)

name = StringEntityField(prefixes=("med",), span=10)
name = StringEntityField(prefixes=("med", "på"), span=10)
from_vendor = StringEntityField(prefixes=("från",))

def respond(self, message: Message) -> Reply | ReplyStream:
Expand All @@ -46,10 +46,10 @@ def respond(self, message: Message) -> Reply | ReplyStream:
query = Recipe.objects.filter(url__contains=vendor)
if keyword:
keyword = keyword.lower()
query = query.filter(name__in=keyword.split())
query = query.filter(name__icontains=keyword)
if not (matching_recipes := query.all()):
return Reply("Jag hittade inga recept med det namnet.")
stream = ReplyStream()
for recipe in matching_recipes:
stream.put(Reply(recipe.url))
stream.put(Reply(recipe))
return stream
8 changes: 5 additions & 3 deletions jarvis/abilities/recipes/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,16 @@ class Recipe(me.Document):
created = me.DateTimeField(defalt=lambda: datetime.now())
user = me.ReferenceField("User", required=False)
url = me.StringField(required=True)
name = me.ListField(required=True)
name = me.StringField(required=True)
comment = me.StringField(required=False)

@property
def pretty(self):
name = " ".join(self.name)
output = f"**{name}**\n{self.url}"
output = f"**{self.name}**\n{self.url}"
if self.user is not None:
output += f"\nSkapad av {self.user.username}"
if self.comment:
output += f"\nKommentar:\n{self.comment}"
return output

def __str__(self):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from jarvis.abilities.recipes.models import Recipe

__doc__ = "Change the name field in Recipe to Text field instead of List field"


def upgrade():
for recipe in Recipe.objects.all():
if isinstance(recipe.name, list):
recipe.name = " ".join(recipe.name)
recipe.save()


def downgrade():
for recipe in Recipe.objects.all():
if isinstance(recipe.name, str):
recipe.name = recipe.name.split()
recipe.save()
20 changes: 20 additions & 0 deletions jarvis/migrations/00000002_add_comment_string_field_to_recipe.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from mongoengine import StringField
from jarvis.abilities.recipes.models import Recipe

__doc__ = " Assign a 'comment' field to the Recipe model."


def upgrade():
Recipe.comment = StringField(required=False)
for recipe in Recipe.objects.all():
if hasattr(recipe, "comment"):
continue
recipe.comment = ""
recipe.save()


def downgrade():
for recipe in Recipe.objects.all():
if hasattr(recipe, "comment"):
del recipe.comment
recipe.save()
24 changes: 24 additions & 0 deletions jarvis/migrations/00000003_add_comment_string_field_to_debt.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from mongoengine import StringField
from jarvis.abilities.finance.models import Debt

column_to_add = StringField(required=False)
column_name = "comment"

__doc__ = "Assign a 'comment' field to the Debt model."


def upgrade():
Debt.comment = column_to_add

for debt in Debt.objects.all():
if hasattr(debt, column_name):
continue
debt.comment = ""
debt.save()


def downgrade():
for debt in Debt.objects.all():
if hasattr(debt, column_name):
del debt.comment
debt.save()
89 changes: 89 additions & 0 deletions jarvis/migrations/migrate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import inspect
import re
import sys
from importlib import import_module
from pathlib import Path

from pyttman import app
from jarvis.models import MigrationVersion


if __name__ == "__main__":
# Set the path base dir to the current working directory
# so that the migrations module can be imported.

if (version_cursor := MigrationVersion.objects.first()) is None:
version_cursor = MigrationVersion.objects.create()

migrations_dir = Path(app.settings.APP_BASE_DIR) / "migrations"
if not migrations_dir.exists():
raise FileNotFoundError(f"Could not find migrations directory: "
f"{migrations_dir.as_posix()}")

sys.path.append(migrations_dir.as_posix())

args = set(sys.argv[1:])
if "current" in args:
# fill with zeros to 8 digits
print(f"{MigrationVersion.objects.first().version:08d}")
exit(0)

steps_limit = sys.argv[-1]
steps_limit = re.sub("[+-]", "", steps_limit)
if steps_limit.isdigit():
steps_limit = abs(int(steps_limit))
else:
steps_limit = None


current_version = file_version = version_cursor.version
upgrade = "upgrade" in args
downgrade = "downgrade" in args
performed_migrations = 0

if upgrade:
migration_files = migrations_dir.glob("*.py")
elif downgrade:
migration_files = reversed(list(migrations_dir.glob("*.py")))
else:
print("Please specify either 'upgrade' or 'downgrade' as an argument.")
exit(0)

print("Running migrations...")

for migration_file in migration_files:
if migration_file.name.startswith("00000000"):
continue
elif migration_file.name == "migrate.py":
continue

try:
file_version_str = migration_file.name.split("_")[0]
file_version = int(file_version_str)
except ValueError:
raise ValueError(f"Could not parse version from migration file: "
f"{migration_file.as_posix()}")

if upgrade and file_version > current_version:
method = "upgrade"
elif downgrade and file_version < current_version:
method = "downgrade"
else:
continue

migration_module = import_module(migration_file.stem)
func = getattr(migration_module, method)
print(f" >> Running {method} in migration {file_version_str}: "
f"'{inspect.getdoc(migration_module)}'")
func()
performed_migrations += 1
version_cursor.version = file_version
version_cursor.save()

if steps_limit is not None and performed_migrations >= steps_limit:
break

if performed_migrations == 0:
print("\nNo migrations to perform.")
else:
print(f"\nPerformed {performed_migrations} migrations.")
8 changes: 8 additions & 0 deletions jarvis/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@
from pyttman.core.containers import Message


class MigrationVersion(me.Document):
"""
This model is used to keep track of the current
migration version of the database.
"""
version = me.IntField(required=True, default=0)


class UserQuerySet(QuerySet):
"""
Custom metaclass for User queries
Expand Down
2 changes: 1 addition & 1 deletion jarvis/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
DB_NAME_PROD = os.getenv("MONGO_DB_NAME_PROD")
DB_NAME_DEV = os.getenv("MONGO_DB_NAME_DEV")
APPEND_LOG_FILES = True
USE_TEST_SERVER = False
USE_TEST_SERVER = os.getenv("USE_TEST_SERVER") == "True"

MIDDLEWARE = {

Expand Down
Binary file modified requirements.txt
Binary file not shown.

0 comments on commit 6e19b65

Please sign in to comment.