From 023783372e6349f8a8c26f52ab971cbfec355f44 Mon Sep 17 00:00:00 2001 From: John Wang Date: Thu, 25 May 2023 18:53:28 +0800 Subject: [PATCH] feat: explore support multi language (#202) --- api/commands.py | 26 +------------- api/controllers/console/admin.py | 31 ++++++++-------- .../console/explore/recommended_app.py | 21 ++++++----- ...4dfde53b_add_language_to_recommend_apps.py | 36 +++++++++++++++++++ api/models/model.py | 14 ++------ 5 files changed, 63 insertions(+), 65 deletions(-) create mode 100644 api/migrations/versions/a45f4dfde53b_add_language_to_recommend_apps.py diff --git a/api/commands.py b/api/commands.py index 2e883ada8d..1112333621 100644 --- a/api/commands.py +++ b/api/commands.py @@ -1,5 +1,4 @@ import datetime -import json import random import string @@ -9,7 +8,7 @@ from libs.password import password_pattern, valid_password, hash_password from libs.helper import email as email_validate from extensions.ext_database import db from models.account import InvitationCode -from models.model import Account, AppModelConfig, ApiToken, Site, App, RecommendedApp +from models.model import Account import secrets import base64 @@ -131,30 +130,7 @@ def generate_upper_string(): return result -@click.command('gen-recommended-apps', help='Number of records to generate') -def generate_recommended_apps(): - print('Generating recommended app data...') - apps = App.query.filter(App.is_public == True).all() - for app in apps: - recommended_app = RecommendedApp( - app_id=app.id, - description={ - 'en': 'Description for ' + app.name, - 'zh': '描述 ' + app.name - }, - copyright='Copyright ' + str(random.randint(1990, 2020)), - privacy_policy='https://privacypolicy.example.com', - category=random.choice(['Games', 'News', 'Music', 'Sports']), - position=random.randint(1, 100), - install_count=random.randint(100, 100000) - ) - db.session.add(recommended_app) - db.session.commit() - print('Done!') - - def register_commands(app): app.cli.add_command(reset_password) app.cli.add_command(reset_email) app.cli.add_command(generate_invitation_codes) - app.cli.add_command(generate_recommended_apps) diff --git a/api/controllers/console/admin.py b/api/controllers/console/admin.py index 9a52e304a3..92c94221b8 100644 --- a/api/controllers/console/admin.py +++ b/api/controllers/console/admin.py @@ -44,10 +44,11 @@ class InsertExploreAppListApi(Resource): def post(self): parser = reqparse.RequestParser() parser.add_argument('app_id', type=str, required=True, nullable=False, location='json') - parser.add_argument('desc_en', type=str, location='json') - parser.add_argument('desc_zh', type=str, location='json') + parser.add_argument('desc', type=str, location='json') parser.add_argument('copyright', type=str, location='json') parser.add_argument('privacy_policy', type=str, location='json') + parser.add_argument('language', type=str, required=True, nullable=False, choices=['en-US', 'zh-Hans'], + location='json') parser.add_argument('category', type=str, required=True, nullable=False, location='json') parser.add_argument('position', type=int, required=True, nullable=False, location='json') args = parser.parse_args() @@ -58,25 +59,24 @@ class InsertExploreAppListApi(Resource): site = app.site if not site: - desc = args['desc_en'] - copy_right = args['copyright'] - privacy_policy = args['privacy_policy'] + desc = args['desc'] if args['desc'] else '' + copy_right = args['copyright'] if args['copyright'] else '' + privacy_policy = args['privacy_policy'] if args['privacy_policy'] else '' else: - desc = site.description if not args['desc_en'] else args['desc_en'] - copy_right = site.copyright if not args['copyright'] else args['copyright'] - privacy_policy = site.privacy_policy if not args['privacy_policy'] else args['privacy_policy'] + desc = site.description if (site.description if not args['desc'] else args['desc']) else '' + copy_right = site.copyright if (site.copyright if not args['copyright'] else args['copyright']) else '' + privacy_policy = site.privacy_policy \ + if (site.privacy_policy if not args['privacy_policy'] else args['privacy_policy']) else '' recommended_app = RecommendedApp.query.filter(RecommendedApp.app_id == args['app_id']).first() if not recommended_app: recommended_app = RecommendedApp( app_id=app.id, - description={ - 'en': desc, - 'zh': desc if not args['desc_zh'] else args['desc_zh'] - }, + description=desc, copyright=copy_right, privacy_policy=privacy_policy, + language=args['language'], category=args['category'], position=args['position'] ) @@ -88,13 +88,10 @@ class InsertExploreAppListApi(Resource): return {'result': 'success'}, 201 else: - recommended_app.description = { - 'en': desc, - 'zh': desc if not args['desc_zh'] else args['desc_zh'] - } - + recommended_app.description = desc recommended_app.copyright = copy_right recommended_app.privacy_policy = privacy_policy + recommended_app.language = args['language'] recommended_app.category = args['category'] recommended_app.position = args['position'] diff --git a/api/controllers/console/explore/recommended_app.py b/api/controllers/console/explore/recommended_app.py index d3942c90bf..03a9ef4394 100644 --- a/api/controllers/console/explore/recommended_app.py +++ b/api/controllers/console/explore/recommended_app.py @@ -43,8 +43,11 @@ class RecommendedAppListApi(Resource): @account_initialization_required @marshal_with(recommended_app_list_fields) def get(self): + language_prefix = current_user.interface_language if current_user.interface_language else 'en-US' + recommended_apps = db.session.query(RecommendedApp).filter( - RecommendedApp.is_listed == True + RecommendedApp.is_listed == True, + RecommendedApp.language == language_prefix ).all() categories = set() @@ -62,21 +65,17 @@ class RecommendedAppListApi(Resource): if not app or not app.is_public: continue - language_prefix = current_user.interface_language.split('-')[0] - desc = None - if recommended_app.description: - if language_prefix in recommended_app.description: - desc = recommended_app.description[language_prefix] - elif 'en' in recommended_app.description: - desc = recommended_app.description['en'] + site = app.site + if not site: + continue recommended_app_result = { 'id': recommended_app.id, 'app': app, 'app_id': recommended_app.app_id, - 'description': desc, - 'copyright': recommended_app.copyright, - 'privacy_policy': recommended_app.privacy_policy, + 'description': site.description, + 'copyright': site.copyright, + 'privacy_policy': site.privacy_policy, 'category': recommended_app.category, 'position': recommended_app.position, 'is_listed': recommended_app.is_listed, diff --git a/api/migrations/versions/a45f4dfde53b_add_language_to_recommend_apps.py b/api/migrations/versions/a45f4dfde53b_add_language_to_recommend_apps.py new file mode 100644 index 0000000000..51e364e4d6 --- /dev/null +++ b/api/migrations/versions/a45f4dfde53b_add_language_to_recommend_apps.py @@ -0,0 +1,36 @@ +"""add language to recommend apps + +Revision ID: a45f4dfde53b +Revises: 9f4e3427ea84 +Create Date: 2023-05-25 17:50:32.052335 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = 'a45f4dfde53b' +down_revision = '9f4e3427ea84' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + with op.batch_alter_table('recommended_apps', schema=None) as batch_op: + batch_op.add_column(sa.Column('language', sa.String(length=255), server_default=sa.text("'en-US'::character varying"), nullable=False)) + batch_op.drop_index('recommended_app_is_listed_idx') + batch_op.create_index('recommended_app_is_listed_idx', ['is_listed', 'language'], unique=False) + + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + with op.batch_alter_table('recommended_apps', schema=None) as batch_op: + batch_op.drop_index('recommended_app_is_listed_idx') + batch_op.create_index('recommended_app_is_listed_idx', ['is_listed'], unique=False) + batch_op.drop_column('language') + + # ### end Alembic commands ### diff --git a/api/models/model.py b/api/models/model.py index c9fe5189ee..68b8417ac2 100644 --- a/api/models/model.py +++ b/api/models/model.py @@ -123,7 +123,7 @@ class RecommendedApp(db.Model): __table_args__ = ( db.PrimaryKeyConstraint('id', name='recommended_app_pkey'), db.Index('recommended_app_app_id_idx', 'app_id'), - db.Index('recommended_app_is_listed_idx', 'is_listed') + db.Index('recommended_app_is_listed_idx', 'is_listed', 'language') ) id = db.Column(UUID, primary_key=True, server_default=db.text('uuid_generate_v4()')) @@ -135,6 +135,7 @@ class RecommendedApp(db.Model): position = db.Column(db.Integer, nullable=False, default=0) is_listed = db.Column(db.Boolean, nullable=False, default=True) install_count = db.Column(db.Integer, nullable=False, default=0) + language = db.Column(db.String(255), nullable=False, server_default=db.text("'en-US'::character varying")) created_at = db.Column(db.DateTime, nullable=False, server_default=db.text('CURRENT_TIMESTAMP(0)')) updated_at = db.Column(db.DateTime, nullable=False, server_default=db.text('CURRENT_TIMESTAMP(0)')) @@ -143,17 +144,6 @@ class RecommendedApp(db.Model): app = db.session.query(App).filter(App.id == self.app_id).first() return app - # def set_description(self, lang, desc): - # if self.description is None: - # self.description = {} - # self.description[lang] = desc - - def get_description(self, lang): - if self.description and lang in self.description: - return self.description[lang] - else: - return self.description.get('en') - class InstalledApp(db.Model): __tablename__ = 'installed_apps'