-
Notifications
You must be signed in to change notification settings - Fork 53
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
Second funnel app #254
Second funnel app #254
Conversation
funnel/__init__.py
Outdated
mail.init_app(app) | ||
|
||
lastuser.init_app(funnelapp) | ||
lastuser.init_app(app) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jace these lines above seems wrong. specially the db.app = <>
part. How to handle these?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
db.app
assignment is only required if there's a database operation outside a request context, to let the db object know which app to operate on. This can happen during init, if we're loading from db, or doing a background job. Workaround: enclose the database operation in with app.app_context():
(we've previously used with app.test_request_context():
, a somewhat heavier operation since it also constructs a dummy request).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok. And what about the others? Double assigning migrate
and calling init_app()
multiple times on db
, mail
and lastuser
doesn't seem right.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mail and Lastuser are fine. Migrate doesn't need to be on Funnelapp.
funnel/__init__.py
Outdated
@@ -12,6 +12,7 @@ | |||
from ._version import __version__ | |||
|
|||
|
|||
funnelapp = Flask(__name__, instance_relative_config=True) | |||
app = Flask(__name__, instance_relative_config=True) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Always put app
first and funnelapp
second, since funnelapp will be removed eventually.
funnel/__init__.py
Outdated
db.init_app(app) | ||
|
||
db.app = funnelapp | ||
db.app = app |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove both these lines.
funnel/__init__.py
Outdated
db.app = app | ||
|
||
migrate = Migrate(funnelapp, db) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove this. Migrate only needs to be on the main app.
funnel/__init__.py
Outdated
mail.init_app(app) | ||
|
||
lastuser.init_app(funnelapp) | ||
lastuser.init_app(app) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mail and Lastuser are fine. Migrate doesn't need to be on Funnelapp.
funnel/util.py
Outdated
@@ -4,8 +4,8 @@ | |||
from urlparse import urlparse | |||
import qrcode | |||
import qrcode.image.svg | |||
from flask import current_app |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Place this import above qrcode
since it's a more foundational library.
funnel/views/proposal.py
Outdated
@@ -379,7 +388,8 @@ def proposal_prev(profile, space, proposal): | |||
return redirect(space.url_for()) | |||
|
|||
|
|||
@app.route('/<space>/<proposal>/move', methods=['POST',], subdomain='<profile>') | |||
@app.route('/<profile>/<space>/<proposal>/move', methods=['POST',]) | |||
@funnelapp.route('/<space>/<proposal>/move', methods=['POST',], subdomain='<profile>') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
methods=['POST']
in both lines (for style consistency).
funnel/views/usergroup.py
Outdated
@funnelapp.route('/<space>/users/new', defaults={'group': None}, endpoint='usergroup_new', | ||
methods=['GET', 'POST'], subdomain='<profile>') | ||
@app.route('/<profile>/<space>/users/<group>/edit', methods=['GET', 'POST']) | ||
@funnelapp.route('/<space>/users/<group>/edit', methods=['GET', 'POST'], subdomain='<profile>') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Order them app
, app
, funnelapp
, funnelapp
.
manage.py
Outdated
@@ -2,7 +2,7 @@ | |||
|
|||
from coaster.manage import init_manager | |||
|
|||
from funnel import app, models | |||
from funnel import funnelapp, app, models |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
funnelapp
is not required here.
rqfunnelinit.py
Outdated
@@ -0,0 +1,14 @@ | |||
from urlparse import urlparse |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file is not required. The same RQ backend will power both apps.
runserver.py
Outdated
@@ -6,5 +6,5 @@ | |||
try: | |||
port = int(sys.argv[1]) | |||
except (IndexError, ValueError): | |||
port = 3000 | |||
port = 3001 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Keep the port here, change it for Funnel.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Partial review, will continue later today.
funnel/jobs/jobs.py
Outdated
|
||
|
||
def import_tickets(ticket_client_id): | ||
with app.test_request_context(): | ||
with current_app.test_request_context(): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change this back to app
. If you need a test_request_context
, then current_app
will be None
, so this construct will fail. Do this everywhere that test_request_context
or app_context
is used.
spaces_all = ProposalSpace.fetch_sorted().filter( | ||
ProposalSpace.profile == self, ProposalSpace.parent_space == None | ||
).all() | ||
return spaces_all |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be a relationship. Why is it a property?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure why it was defined as a property, I just organized it. Anyway, now when I try to define it as a relationship, there is a circular import issue. ProposalSpace
model requires Profile
for a relationship and vice versa.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can put the name in quotes. SQLAlchemy will do an eval
using the model namespace to pick the correct model. That means any valid Python expression will work inside the quotes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few more cosmetic changes.
funnel/views/index.py
Outdated
from ..models import Profile, ProposalSpace, Proposal | ||
from .space import space_data | ||
|
||
|
||
def index_jsonify(data): | ||
spaces_data = list() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's wrong with spaces_data = []
?
funnel/views/index.py
Outdated
space_dict = dict(space.current_access()) | ||
if space_dict: | ||
spaces_data.append(space_dict) | ||
return jsonify(spaces=spaces_data) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This whole thing could be:
return jsonify(spaces=[d for d in [dict(s.current_access()) for s in data['spaces']] if d])
funnel/views/index.py
Outdated
def index(): | ||
g.profile = None | ||
g.permissions = [] | ||
spaces = ProposalSpace.fetch_sorted().filter(ProposalSpace.profile != None).all() | ||
return render_template('index.html.jinja2', spaces=spaces) | ||
return dict(spaces=spaces) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return {'spaces': spaces}
funnel/views/index.py
Outdated
g.profile = None | ||
g.permissions = [] | ||
spaces = ProposalSpace.fetch_sorted().filter(ProposalSpace.profile != None).all() | ||
return dict(spaces=spaces) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As above.
@render_with({'text/html': 'funnelindex.html.jinja2', 'application/json': index_jsonify}) | ||
def funnelindex(): | ||
g.profile = None | ||
g.permissions = [] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This has to be current_auth.permissions
now. See Coaster's load_models
for how to set it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
g.permissions
is used in a lot of places on this repo. I'm not completely sure about the effects of change to current_auth.permissions
. can we do this part of another PR? or maybe the next PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
current_auth.permissions
is guaranteed to be an InspectableSet
. g.permissions
only promises to support the in
operator. It could be a list, tuple or set. This difference is crucial for the transition.
funnel/views/index.py
Outdated
spaces_data.append(space_dict) | ||
return jsonify( | ||
profile=dict(data['profile'].current_access()), | ||
spaces=spaces_data) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Simplify this as above.
funnel/views/space.py
Outdated
@@ -38,7 +38,8 @@ def space_data(space): | |||
|
|||
|
|||
# Test endpoint | |||
@app.route('/form', methods=['GET', 'POST'], subdomain='<profile>') | |||
@app.route('/<profile>/form', methods=['GET', 'POST']) | |||
@funnelapp.route('/form', methods=['GET', 'POST'], subdomain='<profile>') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove this endpoint. We added it to test Baseframe's form generator. It's not required anymore.
funnel/views/index.py
Outdated
g.permissions = [] | ||
spaces = ProposalSpace.fetch_sorted().filter(ProposalSpace.profile != None).all() | ||
# XXX: Can we just return index() ? | ||
return {'spaces': [d for d in [dict(s.current_access()) for s in spaces] if d]} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jace ^
funnel/models/profile.py
Outdated
parent_spaces_test = db.relationship('ProposalSpace', | ||
lazy='dynamic', | ||
primaryjoin="and_(ProposalSpace.profile_id == Profile.id, ProposalSpace.parent_space_id == None)" | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jace need some help with this one, parent_spaces
below is returned by the fetch_sorted()
classmethod which, along with sorting the results, does a state filter, which I can't do where without importing ProposalSpace
, which I can do as I removed the circular import issue from space.py, but want to check if it's possible without importing ProposalSpace
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That entire function could be a SQL expression, which means it could be a relationship.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's complicated in the SQL expression is the custom sorting that fetch_sorted()
does. Closest event is first, then second third are future events and then forth and so on are older events etc like that. can be done using sqlalchemy's hybrid_property
I think.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Leave this aside for now. I'll look at rewriting it as a relationship later.
funnel/views/index.py
Outdated
@render_with({'text/html': 'funnelindex.html.jinja2'}, json=True) | ||
def funnelindex(): | ||
g.profile = None | ||
g.permissions = [] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jace g.permissions
is widely used in this repo. I'm not too sure about the changes required to change them back to current_auth.permissions
. Can we handle this in a separate PR?
funnel/views/index.py
Outdated
g.permissions = [] | ||
spaces = ProposalSpace.fetch_sorted().filter(ProposalSpace.profile != None).all() | ||
# XXX: Can we just return index() ? | ||
return {'spaces': spaces} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jace can we just return index()
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You'll get the output of render_with
, unless you pass it _render=False
. https://coaster.readthedocs.io/en/latest/views/decorators.html#coaster.views.decorators.render_with
* replaced app with funnelapp and created new app instance * added route for new app to all views * replaced runtime use of app iwth current_app * renamed runfunnelserver.py to runfunnel.py * separated rqinit file for both applications * added app specific configuration * added comment for app specific config * fixed app order, removed unnecessary views from funnelapp and more fixes * renamed jsonify function name * moved model import inside function to avoid circular import * misc fixes * moving lastuser confix to app specific config files * added LASTUSER_COOKIE_DOMAIN to app specific config * fixed mui css issue with funnelapp * funnelindex page update with new UI * downloading CSV file instead of showing on tab * using content type text/csv * fixed placement of few hr tags * Call embedIframe only when preview video link is present. * misc fixes * reverted to index_jsonify function * removed unused function * using parent_spaces_test relationship to test * removed parent_spaces_test * Sync funnelindex with index. Change heading to bold on proposal page. * removed doubt
* Add static pages. * Second funnel app (#254) * replaced app with funnelapp and created new app instance * added route for new app to all views * replaced runtime use of app iwth current_app * renamed runfunnelserver.py to runfunnel.py * separated rqinit file for both applications * added app specific configuration * added comment for app specific config * fixed app order, removed unnecessary views from funnelapp and more fixes * renamed jsonify function name * moved model import inside function to avoid circular import * misc fixes * moving lastuser confix to app specific config files * added LASTUSER_COOKIE_DOMAIN to app specific config * fixed mui css issue with funnelapp * funnelindex page update with new UI * downloading CSV file instead of showing on tab * using content type text/csv * fixed placement of few hr tags * Call embedIframe only when preview video link is present. * misc fixes * reverted to index_jsonify function * removed unused function * using parent_spaces_test relationship to test * removed parent_spaces_test * Sync funnelindex with index. Change heading to bold on proposal page. * removed doubt * Update footer with hasgeek info. * Update hasgeek index page. * Update navbar in about page. * Update Flask Flat Pages in requirements.txt. * Fix columns of footer. * Minor css changes. * Add divider btw headings. * Add analytics and social media widgets. Add previous events section. * added flatpages config to app settings
* replaced app with funnelapp and created new app instance * added route for new app to all views * replaced runtime use of app iwth current_app * renamed runfunnelserver.py to runfunnel.py * separated rqinit file for both applications * added app specific configuration * added comment for app specific config * fixed app order, removed unnecessary views from funnelapp and more fixes * renamed jsonify function name * moved model import inside function to avoid circular import * misc fixes * moving lastuser confix to app specific config files * added LASTUSER_COOKIE_DOMAIN to app specific config * fixed mui css issue with funnelapp * funnelindex page update with new UI * downloading CSV file instead of showing on tab * using content type text/csv * fixed placement of few hr tags * Call embedIframe only when preview video link is present. * misc fixes * reverted to index_jsonify function * removed unused function * using parent_spaces_test relationship to test * removed parent_spaces_test * Sync funnelindex with index. Change heading to bold on proposal page. * removed doubt
* Add static pages. * Second funnel app (#254) * replaced app with funnelapp and created new app instance * added route for new app to all views * replaced runtime use of app iwth current_app * renamed runfunnelserver.py to runfunnel.py * separated rqinit file for both applications * added app specific configuration * added comment for app specific config * fixed app order, removed unnecessary views from funnelapp and more fixes * renamed jsonify function name * moved model import inside function to avoid circular import * misc fixes * moving lastuser confix to app specific config files * added LASTUSER_COOKIE_DOMAIN to app specific config * fixed mui css issue with funnelapp * funnelindex page update with new UI * downloading CSV file instead of showing on tab * using content type text/csv * fixed placement of few hr tags * Call embedIframe only when preview video link is present. * misc fixes * reverted to index_jsonify function * removed unused function * using parent_spaces_test relationship to test * removed parent_spaces_test * Sync funnelindex with index. Change heading to bold on proposal page. * removed doubt * Update footer with hasgeek info. * Update hasgeek index page. * Update navbar in about page. * Update Flask Flat Pages in requirements.txt. * Fix columns of footer. * Minor css changes. * Add divider btw headings. * Add analytics and social media widgets. Add previous events section. * added flatpages config to app settings
First part of completing #230.