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

Upgrade Flask related dependencies #507

Merged
merged 2 commits into from
Dec 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
22 changes: 8 additions & 14 deletions critiquebrainz/data/dump_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@
from time import gmtime, strftime

import click
import orjson
import sqlalchemy
from flask import current_app, jsonify
from flask.json import JSONEncoder
from flask.json.provider import JSONProvider
from psycopg2.sql import SQL, Identifier

from critiquebrainz import db
Expand Down Expand Up @@ -147,7 +148,7 @@ def json(location, rotate=False):
"""
create_path(location)

current_app.json_encoder = DumpJSONEncoder
current_app.json_encoder = OrJSONProvider

print("Creating new archives...")
with db.engine.begin() as connection:
Expand Down Expand Up @@ -541,16 +542,9 @@ def reset_sequence(table_names):
connection.close()


class DumpJSONEncoder(JSONEncoder):
"""Custom JSON encoder for database dumps."""
class OrJSONProvider(JSONProvider):
def dumps(self, obj, **kwargs):
return orjson.dumps(obj).decode()

def default(self, o): # pylint: disable=method-hidden
try:
if isinstance(o, datetime):
return o.isoformat()
iterable = iter(o)
except TypeError:
pass
else:
return list(iterable)
return JSONEncoder.default(self, o)
def loads(self, s, **kwargs):
return orjson.loads(s)
6 changes: 3 additions & 3 deletions critiquebrainz/frontend/babel.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@


def init_app(app, domain='messages'):
babel = Babel(app, default_domain=domain)

app.config['LANGUAGES'] = {}
for language in app.config['SUPPORTED_LANGUAGES']:
app.config['LANGUAGES'][language] = Locale.parse(language).language_name
Expand All @@ -21,7 +19,6 @@ def after_this_request(f):
g.after_request_callbacks.append(f)
return f

@babel.localeselector
def get_locale(): # pylint: disable=unused-variable
supported_languages = app.config['SUPPORTED_LANGUAGES']
language_arg = request.args.get('l')
Expand All @@ -38,3 +35,6 @@ def remember_language(response): # pylint: disable=unused-variable
return language_cookie

return request.accept_languages.best_match(supported_languages)

babel = Babel()
babel.init_app(app, default_domain=domain, locale_selector=get_locale)
21 changes: 9 additions & 12 deletions critiquebrainz/frontend/external/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@

See documentation in each module for information about usage.
"""
from flask import current_app, _app_ctx_stack

from flask import current_app, g
from critiquebrainz.frontend.external.entities import get_entity_by_id, get_multiple_entities


Expand Down Expand Up @@ -38,19 +37,16 @@ def init_app(self, app):

@property
def get_entity_by_id(self):
ctx = _app_ctx_stack.top
if ctx is not None:
if not hasattr(ctx, 'get_entity_by_id'):
ctx.get_entity_by_id = self.get_entity_by_id_method
return ctx.get_entity_by_id
if not hasattr(g, 'get_entity_by_id'):
g.get_entity_by_id = self.get_entity_by_id_method
return g.get_entity_by_id

@property
def get_multiple_entities(self):
ctx = _app_ctx_stack.top
if ctx is not None:
if not hasattr(ctx, 'get_multiple_entities'):
ctx.get_multiple_entities = self.get_multiple_entities_method
return ctx.get_multiple_entities
if not hasattr(g, 'get_multiple_entities'):
g.get_multiple_entities = self.get_multiple_entities_method
return g.get_multiple_entities



mbstore = MBDataAccess()
Expand All @@ -67,6 +63,7 @@ def development_get_multiple_entities(entities):
data[mbid] = get_dummy_item(mbid, entity_type)
return data


def development_get_entity_by_id(entity_id, entity_type):
"""Same as get_entity_by_id, but always returns a dummy item if the requested entity
isn't in the MusicBrainz database. Used in development with a sample database."""
Expand Down
4 changes: 2 additions & 2 deletions critiquebrainz/frontend/forms/review.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ def __init__(self, default_license_id='CC BY-SA 3.0', default_language='en', **k
kwargs.setdefault('language', default_language)
FlaskForm.__init__(self, **kwargs)

def validate(self):
if not super(ReviewEditForm, self).validate():
def validate(self, extra_validators=None):
if not super(ReviewEditForm, self).validate(extra_validators):
return False
if not self.text.data and not self.rating.data:
self.text.errors.append("You must provide some text or a rating to complete this review.")
Expand Down
2 changes: 1 addition & 1 deletion critiquebrainz/frontend/views/profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def edit():
"license_choice": form.license_choice.data,
})
flash.success(gettext("Profile updated."))
return redirect(url_for('user.reviews', user_ref= current_user.user_ref))
return redirect(url_for('user.reviews', user_ref=current_user.user_ref))

form.display_name.data = current_user.display_name
form.email.data = current_user.email
Expand Down
7 changes: 7 additions & 0 deletions critiquebrainz/frontend/views/test/test_comment.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,13 +96,20 @@ def test_create(self):

# blocked user should not be allowed to comment
db_users.block(self.commenter.id)
# because the g global persists for entire duration of the test, we need to manually logout/login
# the user again for the current_user to be refreshed. in production, this would happen automatically
# as the current_user is loaded at the start of each request/request context.
self.temporary_login(self.commenter)

response = self.client.post(
url_for("comment.create"),
data=payload,
follow_redirects=True,
)
self.assertIn("You are not allowed to write new comments", str(response.data))

db_users.unblock(self.commenter.id)
self.temporary_login(self.commenter)

# comment with some text and a valid review_id must be saved
response = self.client.post(
Expand Down
8 changes: 8 additions & 0 deletions critiquebrainz/frontend/views/test/test_profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,14 @@ def test_edit(self):
response = self.client.post('/profile/edit', data=data,
query_string=data, follow_redirects=True)
self.assert200(response)

# because the g global persists for entire duration of the test, we need to manually logout/login
# the user again for the current_user to be refreshed. in production, this would happen automatically
# as the current_user is loaded at the start of each request/request context.
self.temporary_login(self.user)

response = self.client.get(f'/user/{self.user.id}')
self.assert200(response)
self.assertIn(data['display_name'], str(response.data))

def test_delete(self):
Expand Down
19 changes: 10 additions & 9 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
brainzutils@git+https://github.com/metabrainz/[email protected]
beautifulsoup4==4.8.0
click==8.1.3
Flask-Babel==2.0.0
Flask-Login==0.6.0
Flask-Babel==4.0.0
Flask-Login==0.6.3
Flask-SQLAlchemy==2.5.1
Flask-WTF==1.0.1
Flask-WTF==1.2.1
Markdown==3.3.6
bleach==5.0.1
musicbrainzngs==0.7.1
Expand All @@ -20,19 +20,20 @@ transifex-client==0.12.4
WTForms==3.0.1
email-validator==1.1.3
langdetect==1.0.7
Flask==2.2.5
Flask==3.0.0
Jinja2==3.1.2
werkzeug==2.2.3
Flask-DebugToolbar==0.13.1
werkzeug==3.0.1
Flask-DebugToolbar@git+https://github.com/amCap1712/flask-debugtoolbar.git@f42bb238cd3fbc79c51b93c341164c2be820025e
Flask-UUID==0.2
sentry-sdk[flask]==1.14.0
sentry-sdk[flask]==1.37.1
redis==4.4.4
msgpack==0.5.6
requests==2.31.0
SQLAlchemy==1.4.41
mbdata@git+https://github.com/amCap1712/mbdata.git@fix-sqlalchemy-warnings
sqlalchemy-dst==1.0.1
markupsafe==2.1.1
markupsafe==2.1.3
itsdangerous==2.1.2
flask-shell-ipython
requests-mock==1.9.3
requests-mock==1.9.3
orjson==3.9.10
Loading