Skip to content

Feature/support categories #113

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
131 commits
Select commit Hold shift + click to select a range
8928b17
update ORM and added export for an event
IdanPelled Jan 12, 2021
79874a7
update ORM and added export for an event
IdanPelled Jan 12, 2021
bc53da7
Merge branch 'main' of https://github.com/PythonFreeCourse/calendar i…
IdanPelled Jan 12, 2021
8f4e690
Added in app shareable events
IdanPelled Jan 13, 2021
25d1b80
upstream merge
IdanPelled Jan 13, 2021
8fb1035
docs: add type annotation and fix folder structure
IdanPelled Jan 13, 2021
149b571
docs: add type annotation and fix folder structure
IdanPelled Jan 13, 2021
be96e5d
docs: fix documentation
IdanPelled Jan 14, 2021
41ed0c2
feat: get weather forecast for date and location
hadaskedar2020 Jan 15, 2021
0bb1c48
feat: get weather forecast for date and location
hadaskedar2020 Jan 15, 2021
9b2a861
add: tests
IdanPelled Jan 15, 2021
ee88405
set up commit
sagizaidor Jan 16, 2021
aa654ac
add: timezone support
IdanPelled Jan 16, 2021
5227c11
add: session management
IdanPelled Jan 16, 2021
56877c6
fix bug
IdanPelled Jan 16, 2021
eda3c31
split conftest file
IdanPelled Jan 16, 2021
c24830a
split conftest file
IdanPelled Jan 16, 2021
69f81e1
move "utils" folder into "internal" folder
IdanPelled Jan 17, 2021
1e3b912
working day view with jinja2 template
sagizaidor Jan 17, 2021
8de8f90
Merge branch 'main' of https://github.com/PythonFreeCourse/calendar i…
sagizaidor Jan 17, 2021
43c57ce
with tests for pytest
sagizaidor Jan 17, 2021
4cc2447
feat: get weather forecast - fixes according to requested changes.
hadaskedar2020 Jan 18, 2021
0dc1ae6
change file structure
IdanPelled Jan 18, 2021
249523f
feat: get weather forecast - fixes according to requested changes.
hadaskedar2020 Jan 18, 2021
b0a8cc4
first functioning day-view html, css and router
sagizaidor Jan 18, 2021
f61c9e4
feat: Basic responsive calender day view page
sagizaidor Jan 18, 2021
868ba44
Merge branch 'develop' into feature/shareable-event
IdanPelled Jan 18, 2021
7c2edd0
Merge branch 'develop' feature/shareable-event
IdanPelled Jan 19, 2021
3c32513
feat: Basic responsive calender day view page
sagizaidor Jan 19, 2021
41abd94
Merge branch 'develop' into style/dayview
sagizaidor Jan 19, 2021
1cbda2e
fix lint now for sure
sagizaidor Jan 19, 2021
7b7bfd4
Merge branch 'style/dayview' of https://github.com/sagizaidor/calenda…
sagizaidor Jan 19, 2021
15baa62
more lint
sagizaidor Jan 19, 2021
a6b0a27
feat: get weather forecast - fix requirements.txt
hadaskedar2020 Jan 19, 2021
3883d5e
feat: enable invited users to view events
IdanPelled Jan 19, 2021
e39c43d
Merge branch 'develop into feature/shareable-event
IdanPelled Jan 19, 2021
6add784
feat: flake8 changes
IdanPelled Jan 19, 2021
cccd7b7
fix: requirements bug
IdanPelled Jan 19, 2021
5faf0ba
fix: requirements bug
IdanPelled Jan 19, 2021
bdd4d8b
feat: flake8 changes
IdanPelled Jan 19, 2021
d629a25
add: tests
IdanPelled Jan 19, 2021
046162d
feat: flake8 changes
IdanPelled Jan 19, 2021
0bcbff8
add: tests
IdanPelled Jan 20, 2021
9462602
feat: flake8 changes
IdanPelled Jan 20, 2021
053b156
edit: file structure
IdanPelled Jan 20, 2021
7684719
edit: file structure
IdanPelled Jan 20, 2021
c7c2a99
feat: get weather forecast - fix changes & add cache support
hadaskedar2020 Jan 20, 2021
fa2fe19
feat: get weather forecast - fix changes & add cache support
hadaskedar2020 Jan 20, 2021
12b2881
feat: get weather forecast - fix changes & add cache support
hadaskedar2020 Jan 20, 2021
b998fc5
feat: get weather forecast - fix changes & add cache support
hadaskedar2020 Jan 20, 2021
8b97c29
feat: add route tests
IdanPelled Jan 20, 2021
f035f21
feat: get weather forecast - fix changes & add cache support
hadaskedar2020 Jan 20, 2021
5f8efc8
feat: get weather forecast - fix changes & add cache support
hadaskedar2020 Jan 20, 2021
ba09ff0
fix: test bug
IdanPelled Jan 21, 2021
44f30a0
Merge branch 'develop' into feature/shareable-event
IdanPelled Jan 21, 2021
3400fe9
remove: config.py
IdanPelled Jan 21, 2021
eb5b7dc
Add categories table
ivarshav Jan 20, 2021
2312caa
Add router for categories
ivarshav Jan 20, 2021
f1463a4
sagizaidor Jan 21, 2021
40628f8
after all notes and started use the orm
sagizaidor Jan 21, 2021
2f57ab6
Add tests + schema
ivarshav Jan 21, 2021
e4e2314
Remove debug
ivarshav Jan 21, 2021
101b659
Linter
ivarshav Jan 21, 2021
e0c75f5
fix: type annotation
IdanPelled Jan 22, 2021
6cb7e83
Merge branch 'develop' of https://github.com/PythonFreeCourse/calenda…
hadaskedar2020 Jan 22, 2021
32c106b
feat: get weather forecast - add API mocking
hadaskedar2020 Jan 22, 2021
4fdb671
feat: get weather forecast - add API mocking
hadaskedar2020 Jan 22, 2021
8807251
feat: get weather forecast - add API mocking
hadaskedar2020 Jan 22, 2021
046cc8d
feat: get weather forecast - add API mocking
hadaskedar2020 Jan 22, 2021
c1b3a12
fixed: changed "size" var in html and and more acuurate typing
sagizaidor Jan 22, 2021
8131ab7
deleted some testing lines
sagizaidor Jan 22, 2021
02f9cb0
Merge branch 'develop' into style/dayview
sagizaidor Jan 22, 2021
253993a
add requirements missing
sagizaidor Jan 22, 2021
813c764
Merge branch 'style/dayview' of https://github.com/sagizaidor/calenda…
sagizaidor Jan 22, 2021
697fcde
PR comments and linter
ivarshav Jan 22, 2021
9da2df3
Test coverage
ivarshav Jan 22, 2021
3ec5f37
add: minor changes
IdanPelled Jan 22, 2021
b9198d5
feat: flake8 changes
IdanPelled Jan 22, 2021
1a67dfb
@hadaskedar2020
hadaskedar2020 Jan 22, 2021
dffcae4
feat: get weather forecast - add API mocking
hadaskedar2020 Jan 22, 2021
93215a4
feat: weather forecast - add API mocking & improve coverage
hadaskedar2020 Jan 22, 2021
fd52f2f
feat: weather forecast - add API mocking & improve coverage
hadaskedar2020 Jan 22, 2021
4eecea1
feat: weather forecast - add API mocking & improve coverage
hadaskedar2020 Jan 22, 2021
91fa227
feat: weather forecast - add API mocking & improve coverage
hadaskedar2020 Jan 22, 2021
e88596c
feat: weather forecast - add API mocking & improve coverage
hadaskedar2020 Jan 22, 2021
42e6dea
fixed: statements of event select more accurate
sagizaidor Jan 23, 2021
b0f4cf6
new test and lint fix
sagizaidor Jan 23, 2021
ab45a02
Merge pull request #44 from IdanPelled/feature/shareable-event
yammesicka Jan 23, 2021
59584e0
Merge branch 'develop' into feature/weather_forecast
hadaskedar2020 Jan 23, 2021
f23cac8
added more contants abd more notes taken
sagizaidor Jan 23, 2021
a91c53f
feat: weather forecast - move feat to internal
hadaskedar2020 Jan 23, 2021
3abd828
Delete Scripts directory
sagizaidor Jan 23, 2021
40ca575
Merge branch 'develop' of https://github.com/PythonFreeCourse/calenda…
hadaskedar2020 Jan 23, 2021
80d2408
Merge branch 'develop' into style/dayview
sagizaidor Jan 23, 2021
ccf393d
Merge branch 'feature/weather_forecast' of https://github.com/hadaske…
hadaskedar2020 Jan 23, 2021
d706153
Merge pull request #62 from hadaskedar2020/feature/weather_forecast
yammesicka Jan 23, 2021
df189bb
update constants
sagizaidor Jan 24, 2021
e7ef9bd
Merge branch 'style/dayview' of https://github.com/sagizaidor/calenda…
sagizaidor Jan 24, 2021
266793b
more notes
sagizaidor Jan 24, 2021
7a64596
forgot white space
sagizaidor Jan 24, 2021
e39c61f
Add categories table
ivarshav Jan 20, 2021
87a7397
Add router for categories
ivarshav Jan 20, 2021
0f04896
Add tests + schema
ivarshav Jan 21, 2021
9b50de5
Linter
ivarshav Jan 21, 2021
e429cb6
PR comments and linter
ivarshav Jan 22, 2021
1547528
Test coverage
ivarshav Jan 22, 2021
4f01060
Merge remote-tracking branch 'origin/feature/supportCategories' into …
ivarshav Jan 24, 2021
64d9cba
Remove
ivarshav Jan 24, 2021
88f0d90
Missed line
ivarshav Jan 24, 2021
e0ae06b
Rename file
ivarshav Jan 24, 2021
606892a
Tests
ivarshav Jan 24, 2021
0b4570b
Merge pull request #93 from sagizaidor/style/dayview
yammesicka Jan 25, 2021
894be6d
Add categories table
ivarshav Jan 20, 2021
b90e882
Add router for categories
ivarshav Jan 20, 2021
c489569
Add tests + schema
ivarshav Jan 21, 2021
3fc5476
Remove debug
ivarshav Jan 21, 2021
6700546
Linter
ivarshav Jan 21, 2021
ec9c5f0
PR comments and linter
ivarshav Jan 22, 2021
663fb1f
Test coverage
ivarshav Jan 22, 2021
9066d83
Add categories table
ivarshav Jan 20, 2021
3c5c55a
Add router for categories
ivarshav Jan 20, 2021
65034da
Add tests + schema
ivarshav Jan 21, 2021
1a98f50
PR comments and linter
ivarshav Jan 22, 2021
0c2492f
Remove
ivarshav Jan 24, 2021
cf80aab
Missed line
ivarshav Jan 24, 2021
ab110a1
Rename file
ivarshav Jan 24, 2021
b61cbaa
Tests
ivarshav Jan 24, 2021
265cbbc
Merge remote-tracking branch 'origin/feature/supportCategories' into …
ivarshav Jan 25, 2021
5c90a83
Up to date
ivarshav Jan 25, 2021
8e4b569
Fix tests
ivarshav Jan 25, 2021
8ffa704
Flake8
ivarshav Jan 25, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
dev.db
test.db
config.py
.vscode/settings.json

# Byte-compiled / optimized / DLL files
__pycache__/
Expand Down Expand Up @@ -88,6 +89,9 @@ ipython_config.py
# pyenv
.python-version

# pycharm
.idea/

# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
Expand All @@ -113,6 +117,8 @@ venv/
ENV/
env.bak/
venv.bak/
Scripts/*
pyvenv.cfg

# Spyder project settings
.spyderproject
Expand All @@ -131,3 +137,5 @@ dmypy.json

# Pyre type checker
.pyre/

app/routers/stam
13 changes: 12 additions & 1 deletion app/config.py.example
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import os

from fastapi_mail import ConnectionConfig

# flake8: noqa

# general
DOMAIN = 'Our-Domain'

# DATABASE
DEVELOPMENT_DATABASE_STRING = "sqlite:///./dev.db"
Expand All @@ -12,10 +15,18 @@ MEDIA_DIRECTORY = 'media'
PICTURE_EXTENSION = '.png'
AVATAR_SIZE = (120, 120)

# API-KEYS
WEATHER_API_KEY = os.getenv('WEATHER_API_KEY')

# export
ICAL_VERSION = '2.0'
PRODUCT_ID = '-//Our product id//'

# email
email_conf = ConnectionConfig(
MAIL_USERNAME=os.getenv("MAIL_USERNAME") or "user",
MAIL_PASSWORD=os.getenv("MAIL_PASSWORD") or "password",
MAIL_FROM=os.getenv("MAIL_FROM") or "a@a.com",
MAIL_FROM=os.getenv("MAIL_FROM") or "a@a.com",
MAIL_PORT=587,
MAIL_SERVER="smtp.gmail.com",
MAIL_TLS=True,
Expand Down
4 changes: 2 additions & 2 deletions app/database/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import Session
from sqlalchemy.orm import sessionmaker

from app import config


SQLALCHEMY_DATABASE_URL = os.getenv(
"DATABASE_CONNECTION_STRING", config.DEVELOPMENT_DATABASE_STRING)

Expand All @@ -18,7 +18,7 @@
Base = declarative_base()


def get_db():
def get_db() -> Session:
db = SessionLocal()
try:
yield db
Expand Down
100 changes: 88 additions & 12 deletions app/database/models.py
Original file line number Diff line number Diff line change
@@ -1,34 +1,110 @@
from sqlalchemy import Boolean, Column, DateTime, ForeignKey, Integer, String
from sqlalchemy.orm import relationship
from datetime import datetime

from .database import Base
from sqlalchemy import Boolean, Column, DateTime, ForeignKey, Integer, \
String, UniqueConstraint
from sqlalchemy.orm import relationship, Session

from app.database.database import Base


class UserEvent(Base):
__tablename__ = "user_event"

id = Column(Integer, primary_key=True, index=True)
user_id = Column('user_id', Integer, ForeignKey('users.id'))
event_id = Column('event_id', Integer, ForeignKey('events.id'))

events = relationship("Event", back_populates="participants")
participants = relationship("User", back_populates="events")

def __repr__(self):
return f'<UserEvent ({self.participants}, {self.events})>'


class User(Base):
__tablename__ = "users"

id = Column(Integer, primary_key=True, index=True)
username = Column(String, unique=True)
email = Column(String, unique=True)
password = Column(String)
username = Column(String, unique=True, nullable=False)
email = Column(String, unique=True, nullable=False)
password = Column(String, nullable=False)
full_name = Column(String)
description = Column(String, default="Happy new user!")
avatar = Column(String, default="profile.png")
is_active = Column(Boolean, default=False)

is_active = Column(Boolean, default=True)
events = relationship("UserEvent", back_populates="participants")

events = relationship(
"Event", cascade="all, delete", back_populates="owner")
def __repr__(self):
return f'<User {self.id}>'


class Event(Base):
__tablename__ = "events"

id = Column(Integer, primary_key=True, index=True)
title = Column(String)
content = Column(String)
title = Column(String, nullable=False)
start = Column(DateTime, nullable=False)
end = Column(DateTime, nullable=False)
content = Column(String)
location = Column(String)
color = Column(String, nullable=True)

owner = relationship("User")
participants = relationship("UserEvent", back_populates="events")

owner_id = Column(Integer, ForeignKey("users.id"))
category_id = Column(Integer, ForeignKey("categories.id"))

def __repr__(self):
return f'<Event {self.id}>'


class Category(Base):
__tablename__ = "categories"

__table_args__ = (
UniqueConstraint('user_id', 'name', 'color'),
)
id = Column(Integer, primary_key=True, index=True)
name = Column(String, nullable=False)
color = Column(String, nullable=False)
user_id = Column(Integer, ForeignKey("users.id"), nullable=False)

@classmethod
def create(cls, db_session: Session, name: str, color: str, user_id: int):
try:
category = cls(name=name, color=color, user_id=user_id)
db_session.add(category)
db_session.flush()
db_session.commit()
db_session.refresh(category)
return category
except Exception as e:
raise e

def to_dict(self):
return {c.name: getattr(self, c.name) for c in self.__table__.columns}

def __repr__(self):
return f'<Category {self.id} {self.name} {self.color}>'


class Invitation(Base):
__tablename__ = "invitations"

id = Column(Integer, primary_key=True, index=True)
status = Column(String, nullable=False, default="unread")
recipient_id = Column(Integer, ForeignKey("users.id"))
event_id = Column(Integer, ForeignKey("events.id"))
creation = Column(DateTime, default=datetime.now)

recipient = relationship("User")
event = relationship("Event")

owner = relationship("User", back_populates="events")
def __repr__(self):
return (
f'<Invitation '
f'({self.event.owner}'
f'to {self.recipient})>'
)
52 changes: 33 additions & 19 deletions app/internal/agenda_events.py
Original file line number Diff line number Diff line change
@@ -1,32 +1,35 @@
from datetime import date, timedelta
from typing import List, Optional
from typing import List, Optional, Union, Iterator

from app.database.models import Event
from app.database.database import SessionLocal
import arrow
from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy.orm import Session

from app.database.models import Event
from app.routers.event import sort_by_date
from app.routers.user import get_all_user_events


def get_events_per_dates(
session: SessionLocal,
session: Session,
user_id: int,
start: Optional[date],
end: Optional[date]
) -> List[Event]:
"""Read from the db. Return a list of all the user events between
the relevant dates."""
) -> Union[Iterator[Event], list]:
"""Read from the db. Return a list of all
the user events between the relevant dates."""

if start > end:
return []
try:
events = (
session.query(Event).filter(Event.owner_id == user_id)
.filter(Event.start.between(start, end + timedelta(days=1)))
.order_by(Event.start).all()
)
except SQLAlchemyError:
return []
else:
return events

return (
filter_dates(
sort_by_date(
get_all_user_events(session, user_id)
),
start,
end,
)
)


def build_arrow_delta_granularity(diff: timedelta) -> List[str]:
Expand All @@ -51,5 +54,16 @@ def get_time_delta_string(start: date, end: date) -> str:
granularity = build_arrow_delta_granularity(diff)
duration_string = arrow_end.humanize(
arrow_start, only_distance=True, granularity=granularity
)
)
return duration_string


def filter_dates(
events: List[Event], start: Optional[date],
end: Optional[date]) -> Iterator[Event]:
"""filter events by a time frame."""

yield from (
event for event in events
if start <= event.start.date() <= end
)
Empty file added app/internal/event.py
Empty file.
22 changes: 22 additions & 0 deletions app/internal/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from sqlalchemy.orm import Session

from app.database.models import Base


def save(item, session: Session) -> bool:
"""Commits an instance to the db.
source: app.database.database.Base"""

if issubclass(item.__class__, Base):
session.add(item)
session.commit()
return True
return False


def create_model(session: Session, model_class, **kw):
"""Creates and saves a db model."""

instance = model_class(**kw)
save(instance, session)
return instance
Loading