Skip to content

Commit

Permalink
Implemented JSON database and Add Commands (#16)
Browse files Browse the repository at this point in the history
* Implemented JSON database

closes #1

* Add commands

- show
- add
- remove

closes #2
closes #3
  • Loading branch information
vmagueta authored Jul 1, 2024
1 parent e598115 commit b986909
Show file tree
Hide file tree
Showing 22 changed files with 600 additions and 39 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ jobs:
- name: Install Project
run: pip install '.[test]'
- name: Run tests
run: pytest -v --junitxml=test-result.xml
run: pytest -v --forked --junitxml=test-result.xml
- name: Publish Test Results
uses: EnricoMi/[email protected]
if: always()
Expand Down
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ lint:


test:
@.venv/bin/pytest -s
@.venv/bin/pytest -s --forked


watch:
# @.venv/bin/ptw
@ls **/*.py | entr pytest
@ls **/*.py | entr pytest --forked


clean: ## Clean unused files.
Expand Down
28 changes: 28 additions & 0 deletions assets/database.example.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"people": {
"[email protected]": {
"role": "Salesman",
"dept": "Sales",
"active": true,
"name": "Joe Doe"
}
},
"balance": {
"[email protected]": 500
},
"movement": {
"[email protected]":[
{
"date": "",
"value": 0,
"actor": "system"
}
]
},
"user": {
"[email protected]": {
"password": "sdjfbsdjhfbsjhd",
"is_admin": false
}
}
}
128 changes: 128 additions & 0 deletions assets/database.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
{
"people": {
"[email protected]": {
"name": "Jim Halpert",
"dept": "Sales",
"role": "Salesman"
},
"[email protected]": {
"name": "Dwight Schrute",
"dept": "Sales",
"role": "Manager"
},
"[email protected]": {
"name": "Gabe Lewis",
"dept": "C-Level",
"role": "CEO"
}
},
"balance": {
"[email protected]": 810,
"[email protected]": 410,
"[email protected]": 100
},
"movement": {
"[email protected]": [
{
"date": "2024-06-30T13:17:00.085814",
"actor": "system",
"value": 500
},
{
"date": "2024-07-01T09:38:03.015041",
"actor": "solermvictor",
"value": 30
},
{
"date": "2024-07-01T09:38:15.965008",
"actor": "solermvictor",
"value": 332
},
{
"date": "2024-07-01T09:43:45.392936",
"actor": "solermvictor",
"value": -62
},
{
"date": "2024-07-01T09:45:45.790470",
"actor": "solermvictor",
"value": 62
},
{
"date": "2024-07-01T09:45:52.961517",
"actor": "solermvictor",
"value": -62
},
{
"date": "2024-07-01T09:47:39.710349",
"actor": "solermvictor",
"value": 5
},
{
"date": "2024-07-01T09:47:47.852407",
"actor": "solermvictor",
"value": 5
}
],
"[email protected]": [
{
"date": "2024-06-30T13:17:00.086117",
"actor": "system",
"value": 100
},
{
"date": "2024-07-01T09:38:03.015054",
"actor": "solermvictor",
"value": 30
},
{
"date": "2024-07-01T09:38:15.965025",
"actor": "solermvictor",
"value": 332
},
{
"date": "2024-07-01T09:43:45.392949",
"actor": "solermvictor",
"value": -62
},
{
"date": "2024-07-01T09:45:45.790483",
"actor": "solermvictor",
"value": 62
},
{
"date": "2024-07-01T09:45:52.961531",
"actor": "solermvictor",
"value": -62
},
{
"date": "2024-07-01T09:47:39.710364",
"actor": "solermvictor",
"value": 5
},
{
"date": "2024-07-01T09:47:47.852421",
"actor": "solermvictor",
"value": 5
}
],
"[email protected]": [
{
"date": "2024-06-30T13:17:00.086294",
"actor": "system",
"value": 100
}
]
},
"users": {
"[email protected]": {
"password": "81sNc0oJ"
},
"[email protected]": {
"password": "HcQZ0aGz"
},
"[email protected]": {
"password": "SR2jr3iG"
}
}
}
2 changes: 1 addition & 1 deletion assets/people.csv
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
Jim Halpert, Sales, Salesman, [email protected]
Dwight Schrute, Sales, Manager, [email protected]
Gabe Lewis, Directory, Manager, [email protected]
Gabe Lewis, C-Level, CEO, [email protected]
34 changes: 34 additions & 0 deletions conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import pytest
from unittest.mock import patch


MARKER = """\
unit: Mark unit tests
integration: Mark integration tests
high: High priority
medium: Medium priority
low: Low priority
"""


def pytest_configure(config):
for line in MARKER.split("\n"):
config.addinivalue_line("markers", line)


@pytest.fixture(autouse=True)
def go_to_tmpdir(request): # injeção de dependencias
tmpdir = request.getfixturevalue("tmpdir")
with tmpdir.as_cwd():
yield # protocolo de generators


@pytest.fixture(autouse=True, scope="function")
def setup_testing_database(request):
"""For each test, create a database file on tmpdir
force database.py to use that filepath.
"""
tmpdir = request.getfixturevalue("tmpdir")
test_db = str(tmpdir.join("database.test.json"))
with patch("dundie.database.DATABASE_PATH", test_db):
yield
52 changes: 50 additions & 2 deletions dundie/cli.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import json
from importlib import metadata

import rich_click as click
Expand Down Expand Up @@ -35,13 +36,60 @@ def load(filepath):
- Loads to database
"""
table = Table(title="Dunder Mifflin Associates")
headers = ["name", "dept", "role", "e-mail"]
headers = ["name", "dept", "role", "created", "e-mail"]
for header in headers:
table.add_column(header, style="italic cyan1")

result = core.load(filepath)
for person in result:
table.add_row(*[field.strip() for field in person.split(",")])
table.add_row(*[str(value) for value in person.values()])

console = Console()
console.print(table)


@main.command()
@click.option("--dept", required=False)
@click.option("--email", required=False)
@click.option("--output", default=None)
def show(output, **query):
"""Shows information about users."""
result = core.read(**query)
if output:
with open(output, "w") as output_file:
output_file.write(json.dumps(result))

if not result:
print("Nothing to show")

table = Table(title="Dunder Mifflin Report")
for key in result[0]:
table.add_column(key.title(), style="italic cyan1")

for person in result:
table.add_row(*[str(value) for value in person.values()])

console = Console()
console.print(table)


@main.command()
@click.argument("value", type=click.INT, required=True)
@click.option("--dept", required=False)
@click.option("--email", required=False)
@click.pass_context
def add(ctx, value, **query):
"""Add points to the user or dept"""
core.add(value, **query)
ctx.invoke(show, **query)


@main.command()
@click.argument("value", type=click.INT, required=True)
@click.option("--dept", required=False)
@click.option("--email", required=False)
@click.pass_context
def remove(ctx, value, **query):
"""Remove points to the user or dept"""
core.add(-value, **query)
ctx.invoke(show, **query)
67 changes: 63 additions & 4 deletions dundie/core.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
"""Core module of dundie"""

import os
from csv import reader

from dundie.database import add_movement, add_person, commit, connect
from dundie.utils.log import get_logger

log = get_logger()
Expand All @@ -10,12 +14,67 @@ def load(filepath):
>>> len(load('assets/people.csv'))
2
>>> load('assets/people.csv')[0][0]
'J'
"""
try:
with open(filepath) as file_:
return [line.strip() for line in file_.readlines()]
csv_data = reader(open(filepath))
except FileNotFoundError as e:
log.error(str(e))
raise e

db = connect()
people = []
headers = ["name", "dept", "role", "e-mail"]
for line in csv_data:
person_data = dict(zip(headers, [item.strip() for item in line]))
pk = person_data.pop("e-mail")
person, created = add_person(db, pk, person_data)

return_data = person.copy()
return_data["created"] = created
return_data["email"] = pk
people.append(return_data)

commit(db)
return people


def read(**query):
"""Read data from db and filters using query
read(email="[email protected]")
"""
db = connect()
return_data = []
for pk, data in db["people"].items():

dept = query.get("dept")
if dept and dept != data["dept"]:
continue

# WALRUS / Assignment Expression - a partir do python 3.8
if (email := query.get("email")) and email != pk:
continue

return_data.append(
{
"email": pk,
"balance": db["balance"][pk],
"last_movement": db["movement"][pk][-1]["date"],
**data,
}
)

return return_data


def add(value, **query):
"""Add value to each record on query."""
people = read(**query)
if not people:
raise RuntimeError("Not Found")

db = connect()
user = os.getenv("USER")
for person in people:
add_movement(db, person["email"], value, user)
commit(db)
Loading

0 comments on commit b986909

Please sign in to comment.