Skip to content
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

chore: Release v1.13.0 #6853

Merged
merged 22 commits into from
Feb 20, 2020
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
66d6086
chore: Release v1.12.0 (#6813)
iamareebjamal Feb 2, 2020
e4da2a7
chore(deps): update pycryptodome requirement from ~=3.9.4 to ~=3.9.6 …
dependabot-preview[bot] Feb 4, 2020
d910699
chore(deps): update sentry-sdk[flask] requirement from ~=0.13 t… (#6819)
dependabot-preview[bot] Feb 5, 2020
42c409b
fix: Invoice emails errors fixed and integration test (#6804)
mrsaicharan1 Feb 6, 2020
c42e031
chore: Pin werkzeug version (#6824)
iamareebjamal Feb 8, 2020
eb10779
fix: Removed inaccessible link & added user request info (#6821)
mrsaicharan1 Feb 8, 2020
505eefe
fix: Use new werkzeug imports (#6825)
iamareebjamal Feb 8, 2020
c2632b8
chore(deps): update python-dotenv requirement from ~=0.10.5 to… (#6822)
dependabot-preview[bot] Feb 8, 2020
294991f
fix: Error in deleting user with marketer role (#6831)
kushthedude Feb 9, 2020
216d99e
chore(deps): update humanize requirement from ~=0.5.1 to ~=1.0.0 (#6835)
dependabot-preview[bot] Feb 11, 2020
934aac6
chore(deps): update flask-login requirement from ~=0.4 to ~=0.5 (#6836)
dependabot-preview[bot] Feb 11, 2020
5c069b2
chore: Add pytype (#6839)
iamareebjamal Feb 14, 2020
c61797b
chore: Add pytest CI (#6840)
iamareebjamal Feb 14, 2020
94852c1
fix: Use circle CI cache properly (#6841)
iamareebjamal Feb 14, 2020
be87f63
chore(deps): update werkzeug requirement from ~=0.16.1 to ~=1.0… (#6834)
dependabot-preview[bot] Feb 14, 2020
01da891
chore: bump flask-admin to 1.5.5 (#6843)
kushthedude Feb 15, 2020
50f1991
chore: Use weak etags (#6844)
iamareebjamal Feb 16, 2020
774113a
chore: Update to redis 3.4.1
iamareebjamal Feb 16, 2020
31c3a3c
chore(deps-dev): update pre-commit requirement from ~=2.0.1 to… (#6849)
dependabot-preview[bot] Feb 19, 2020
c480da1
chore(deps): update requests[security] requirement from ~=2.22 to ~=2…
dependabot-preview[bot] Feb 19, 2020
ee271ba
fix: Cron entries of period tasks (#6850)
iamareebjamal Feb 20, 2020
25e6a09
chore: Prepare for v1.13.0 (#6854)
iamareebjamal Feb 20, 2020
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
94 changes: 80 additions & 14 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -1,28 +1,21 @@
version: 2
jobs:
build:
dependencies:
docker:
- image: circleci/python:3.7.4-node
environment:
APP_CONFIG: config.TestingConfig
DATABASE_URL: postgresql://postgres@localhost/test
TEST_DATABASE_URL: postgresql://postgres@localhost/test
# Services
- image: circleci/postgres:11.5-alpine-ram
environment:
POSTGRES_USER: postgres
POSTGRES_DB: test
- image: circleci/redis:5.0.6-alpine

working_directory: ~/code

steps:
- checkout

- run:
command: cat requirements/*.txt > requirements/combined.txt

# Download and cache dependencies
- restore_cache:
keys:
- v1.3-dependencies-{{ checksum "requirements/tests.txt" }}-{{ checksum "package.json" }}
- v1.3-dependencies-{{ checksum "requirements/combined.txt" }}-{{ checksum "package.json" }}
# fallback to using the latest cache if no exact match is found
- v1.3-dependencies-

Expand All @@ -32,7 +25,7 @@ jobs:
python3 -m venv venv
. venv/bin/activate
pip install --exists-action w -r requirements/tests.txt

- run:
name: Install Node Dependencies
command: yarn
Expand All @@ -43,7 +36,36 @@ jobs:
- ./node_modules
- ~/.cache/yarn
- ~/.yarn/bin
key: v1.3-dependencies-{{ checksum "requirements/tests.txt" }}-{{ checksum "package.json" }}
key: v1.3-dependencies-{{ checksum "requirements/combined.txt" }}-{{ checksum "package.json" }}

dredd:
docker:
- image: circleci/python:3.7.4-node
environment:
APP_CONFIG: config.TestingConfig
DATABASE_URL: postgresql://postgres@localhost/test
TEST_DATABASE_URL: postgresql://postgres@localhost/test
# Services
- image: circleci/postgres:11.5-alpine-ram
environment:
POSTGRES_USER: postgres
POSTGRES_DB: test
- image: circleci/redis:5.0.6-alpine

working_directory: ~/code

steps:
- checkout

- run:
command: cat requirements/*.txt > requirements/combined.txt

# Download and cache dependencies
- restore_cache:
keys:
- v1.3-dependencies-{{ checksum "requirements/combined.txt" }}-{{ checksum "package.json" }}
# fallback to using the latest cache if no exact match is found
- v1.3-dependencies-

- run:
name: Create API blueprint
Expand All @@ -52,3 +74,47 @@ jobs:
- run:
name: Test API Doc
command: . venv/bin/activate && npx dredd

pytype:
docker:
- image: circleci/python:3.7.4-node

working_directory: ~/code

steps:
- checkout

- run:
command: cat requirements/*.txt > requirements/combined.txt

# Download and cache dependencies
- restore_cache:
keys:
- v1.3-dependencies-{{ checksum "requirements/combined.txt" }}-{{ checksum "package.json" }}
# fallback to using the latest cache if no exact match is found
- v1.3-dependencies-

- restore_cache:
keys:
- v1-pytype

- run:
name: Test pytype
command: . venv/bin/activate && pytype

- save_cache:
paths:
- ./.pytype
key: v1-pytype

workflows:
version: 2
build-and-test:
jobs:
- dependencies
- dredd:
requires:
- dependencies
- pytype:
requires:
- dependencies
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,4 @@ generated/
docker-compose.override.yml
celerybeat-schedule.*
.coverage
.pytype
Empty file added app/api/__init__.py
Empty file.
Empty file added app/api/admin_sales/__init__.py
Empty file.
2 changes: 1 addition & 1 deletion app/api/attendees.py
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ def before_update_object(self, obj, data, kwargs):
checkout_times = (
obj.checkout_times.split(',') if obj.checkout_times else []
)
checkout_times.append(str(datetime.utcnow()))
checkout_times.append(str(datetime.datetime.utcnow()))
data['checkout_times'] = ','.join(checkout_times)

if 'attendee_notes' in data:
Expand Down
Empty file added app/api/custom/__init__.py
Empty file.
Empty file added app/api/data_layers/__init__.py
Empty file.
Empty file.
Empty file added app/api/helpers/__init__.py
Empty file.
5 changes: 3 additions & 2 deletions app/api/helpers/import_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from flask import current_app as app
from flask import request
from flask_jwt_extended import current_user
from werkzeug import secure_filename
from werkzeug.utils import secure_filename

from app.api.helpers.db import save_to_db
from app.api.helpers.errors import NotFoundError, ServerError
Expand Down Expand Up @@ -369,6 +369,7 @@ def import_event_json(task_handle, zip_path, creator_id):
except Exception as e:
raise make_error('event', er=e)
# create other services
item = [] # TODO: Remove workaround for pytype
try:
service_ids = {}
for item in IMPORT_SERIES:
Expand All @@ -384,7 +385,7 @@ def import_event_json(task_handle, zip_path, creator_id):
except IOError:
db.session.delete(new_event)
db.session.commit()
raise NotFoundError('File %s missing in event zip' % item[0])
raise NotFoundError('file', 'File %s missing in event zip' % item[0])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

except ValueError:
db.session.delete(new_event)
db.session.commit()
Expand Down
2 changes: 1 addition & 1 deletion app/api/helpers/jwt.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from flask import _app_ctx_stack as ctx_stack
from flask import _app_ctx_stack as ctx_stack # pytype: disable=import-error
from flask_jwt_extended.config import config
from flask_jwt_extended.exceptions import JWTExtendedException, UserLoadError
from flask_jwt_extended.view_decorators import _decode_jwt_from_request, _load_user
Expand Down
4 changes: 2 additions & 2 deletions app/api/helpers/mail.py
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,6 @@ def send_email_to_attendees(order, purchaser_id, attachments=None):
frontend_url=get_settings()['frontend_url'],
),
html=MAILS[TICKET_PURCHASED]['message'].format(
pdf_url=holder.pdf_url,
event_name=order.event.name,
frontend_url=get_settings()['frontend_url'],
),
Expand All @@ -351,7 +350,8 @@ def send_email_to_attendees(order, purchaser_id, attachments=None):
event_name=order.event.name, invoice_id=order.invoice_number
),
html=MAILS[TICKET_PURCHASED_ATTENDEE]['message'].format(
pdf_url=holder.pdf_url, event_name=order.event.name
my_tickets_url=get_settings()['frontend_url'] + '/my-tickets',
event_name=order.event.name,
),
attachments=attachments,
)
Expand Down
11 changes: 7 additions & 4 deletions app/api/helpers/permission_manager.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from typing import Union
from flask import request
from flask_jwt_extended import current_user, verify_jwt_in_request
from sqlalchemy.orm.exc import NoResultFound
Expand Down Expand Up @@ -357,7 +358,7 @@ def create_event(view, view_args, view_kwargs, *args, **kwargs):
}


def is_multiple(data):
def is_multiple(data: Union[str, list]) -> bool:
if type(data) is list:
return True
if type(data) is str:
Expand Down Expand Up @@ -465,8 +466,10 @@ def permission_manager(view, view_args, view_kwargs, *args, **kwargs):
if not is_multiple(model):
model = [model]

if is_multiple(fetch_key_url):
fetch_key_url = fetch_key_url.split(",")
if type(fetch_key_url) == str and is_multiple(fetch_key_url):
fetch_key_url = fetch_key_url.split( # pytype: disable=attribute-error
","
)

found = False
for index, mod in enumerate(model):
Expand All @@ -477,7 +480,7 @@ def permission_manager(view, view_args, view_kwargs, *args, **kwargs):
if not view_kwargs.get(f_url):
continue
try:
data = mod.query.filter(
data = mod.query.filter( # pytype: disable=attribute-error
getattr(mod, fetch_key_model) == view_kwargs[f_url]
).one()
except NoResultFound:
Expand Down
43 changes: 30 additions & 13 deletions app/api/helpers/scheduled_jobs.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import pytz
from dateutil.relativedelta import relativedelta
from sqlalchemy.orm.exc import NoResultFound
from flask_rest_jsonapi.exceptions import ObjectNotFound
from flask import render_template
from flask_celeryext import RequestContextTask

Expand Down Expand Up @@ -249,22 +251,27 @@ def send_monthly_event_invoice():
user = event.owner
admin_info = get_settings()
currency = event.payment_currency
ticket_fee_object = (
db.session.query(TicketFees).filter_by(currency=currency).one()
)
try:
ticket_fee_object = (
db.session.query(TicketFees).filter_by(currency=currency).one()
)
except NoResultFound:
raise ObjectNotFound(
{'source': ''}, 'Ticket Fee not set for {}'.format(currency)
)
ticket_fee_percentage = ticket_fee_object.service_fee
ticket_fee_maximum = ticket_fee_object.maximum_fee
orders = Order.query.filter_by(event=event).all()
gross_revenue = event.calc_monthly_revenue()
ticket_fees = event.tickets_sold * (ticket_fee_percentage / 100)
if ticket_fees > ticket_fee_maximum:
ticket_fees = ticket_fee_maximum
net_revenue = gross_revenue - ticket_fees
invoice_amount = gross_revenue * (ticket_fee_percentage / 100)
if invoice_amount > ticket_fee_maximum:
invoice_amount = ticket_fee_maximum
net_revenue = gross_revenue - invoice_amount
payment_details = {
'tickets_sold': event.tickets_sold,
'gross_revenue': gross_revenue,
'net_revenue': net_revenue,
'amount_payable': ticket_fees,
'amount_payable': invoice_amount,
}
# save invoice as pdf
pdf = create_save_pdf(
Expand All @@ -286,7 +293,7 @@ def send_monthly_event_invoice():
# save event_invoice info to DB

event_invoice = EventInvoice(
amount=net_revenue, invoice_pdf_url=pdf, event_id=event.id
amount=invoice_amount, invoice_pdf_url=pdf, event_id=event.id
)
save_to_db(event_invoice)

Expand All @@ -295,17 +302,27 @@ def send_monthly_event_invoice():
def setup_scheduled_task(sender, **kwargs):
from celery.schedules import crontab

sender.add_periodic_task(crontab(hour='*/5', minute=30), send_after_event_mail)
sender.add_periodic_task(crontab(minute=0, hour=0), send_event_fee_notification)
# Every day at 5:30
sender.add_periodic_task(crontab(hour=5, minute=30), send_after_event_mail)
# Every 1st day of month at 0:00
sender.add_periodic_task(
crontab(minute=0, hour=0, day_of_month=1), send_event_fee_notification
)
# Every 1st day of month at 0:00
sender.add_periodic_task(
crontab(minute=0, hour=0, day_of_month=1), send_event_fee_notification_followup
)
# Every day at 5:30
sender.add_periodic_task(
crontab(hour='*/5', minute=30), change_session_state_on_event_completion
crontab(hour=5, minute=30), change_session_state_on_event_completion
)
# Every 45 minutes
sender.add_periodic_task(crontab(minute='*/45'), expire_pending_tickets)
# Every 1st day of month at 0:00
sender.add_periodic_task(
crontab(minute=0, hour=0, day_of_month=1), send_monthly_event_invoice
)
sender.add_periodic_task(crontab(minute=0, hour='*/5'), event_invoices_mark_due)
# Every day at 5:00
sender.add_periodic_task(crontab(minute=0, hour=5), event_invoices_mark_due)
# Every 5 minutes
sender.add_periodic_task(crontab(minute='*/5'), delete_ticket_holders_no_order_id)
4 changes: 3 additions & 1 deletion app/api/helpers/system_mails.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,9 @@
'message': (
u"Hi, this is a confirmation mail of your tickets for the event {event_name}"
u"<br/>Your order has been processed successfully."
+ u"<br/> <a href='{pdf_url}'>Click here</a> to view/download your ticket."
+ u"<br/> Your tickets & invoice have been enclosed."
u"<br><br>You can also download your tickets in <b>My Tickets</b> section."
u"<br/>Login to manage the orders at <a href='{mytickets_url}' target='_blank'>{mytickets_url}</a> </em>"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line too long (117 > 90 characters)

u"<br><br><em>Looking forward to seeing you at the event."
),
},
Expand Down
Loading