Skip to content

Commit

Permalink
feat: custom app icon (#7196)
Browse files Browse the repository at this point in the history
Co-authored-by: crazywoola <[email protected]>
  • Loading branch information
xuzuodong and crazywoola authored Aug 19, 2024
1 parent a0c689c commit fbf31b5
Show file tree
Hide file tree
Showing 65 changed files with 1,068 additions and 352 deletions.
4 changes: 4 additions & 0 deletions api/controllers/console/app/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ def post(self):
parser.add_argument('name', type=str, required=True, location='json')
parser.add_argument('description', type=str, location='json')
parser.add_argument('mode', type=str, choices=ALLOW_CREATE_APP_MODES, location='json')
parser.add_argument('icon_type', type=str, location='json')
parser.add_argument('icon', type=str, location='json')
parser.add_argument('icon_background', type=str, location='json')
args = parser.parse_args()
Expand Down Expand Up @@ -94,6 +95,7 @@ def post(self):
parser.add_argument('data', type=str, required=True, nullable=False, location='json')
parser.add_argument('name', type=str, location='json')
parser.add_argument('description', type=str, location='json')
parser.add_argument('icon_type', type=str, location='json')
parser.add_argument('icon', type=str, location='json')
parser.add_argument('icon_background', type=str, location='json')
args = parser.parse_args()
Expand Down Expand Up @@ -167,6 +169,7 @@ def put(self, app_model):
parser = reqparse.RequestParser()
parser.add_argument('name', type=str, required=True, nullable=False, location='json')
parser.add_argument('description', type=str, location='json')
parser.add_argument('icon_type', type=str, location='json')
parser.add_argument('icon', type=str, location='json')
parser.add_argument('icon_background', type=str, location='json')
parser.add_argument('max_active_requests', type=int, location='json')
Expand Down Expand Up @@ -208,6 +211,7 @@ def post(self, app_model):
parser = reqparse.RequestParser()
parser.add_argument('name', type=str, location='json')
parser.add_argument('description', type=str, location='json')
parser.add_argument('icon_type', type=str, location='json')
parser.add_argument('icon', type=str, location='json')
parser.add_argument('icon_background', type=str, location='json')
args = parser.parse_args()
Expand Down
2 changes: 2 additions & 0 deletions api/controllers/console/app/site.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
def parse_app_site_args():
parser = reqparse.RequestParser()
parser.add_argument('title', type=str, required=False, location='json')
parser.add_argument('icon_type', type=str, required=False, location='json')
parser.add_argument('icon', type=str, required=False, location='json')
parser.add_argument('icon_background', type=str, required=False, location='json')
parser.add_argument('description', type=str, required=False, location='json')
Expand Down Expand Up @@ -53,6 +54,7 @@ def post(self, app_model):

for attr_name in [
'title',
'icon_type',
'icon',
'icon_background',
'description',
Expand Down
1 change: 1 addition & 0 deletions api/controllers/console/app/workflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,7 @@ def post(self, app_model: App):
if request.data:
parser = reqparse.RequestParser()
parser.add_argument('name', type=str, required=False, nullable=True, location='json')
parser.add_argument('icon_type', type=str, required=False, nullable=True, location='json')
parser.add_argument('icon', type=str, required=False, nullable=True, location='json')
parser.add_argument('icon_background', type=str, required=False, nullable=True, location='json')
args = parser.parse_args()
Expand Down
3 changes: 3 additions & 0 deletions api/controllers/web/site.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from controllers.web import api
from controllers.web.wraps import WebApiResource
from extensions.ext_database import db
from libs.helper import AppIconUrlField
from models.account import TenantStatus
from models.model import Site
from services.feature_service import FeatureService
Expand All @@ -28,8 +29,10 @@ class AppSiteApi(WebApiResource):
'title': fields.String,
'chat_color_theme': fields.String,
'chat_color_theme_inverted': fields.Boolean,
'icon_type': fields.String,
'icon': fields.String,
'icon_background': fields.String,
'icon_url': AppIconUrlField,
'description': fields.String,
'copyright': fields.String,
'privacy_policy': fields.String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ def handle(sender, **kwargs):
site = Site(
app_id=app.id,
title=app.name,
icon_type=app.icon_type,
icon=app.icon,
icon_background=app.icon_background,
default_language=account.interface_language,
Expand Down
10 changes: 9 additions & 1 deletion api/fields/app_fields.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
from flask_restful import fields

from libs.helper import TimestampField
from libs.helper import AppIconUrlField, TimestampField

app_detail_kernel_fields = {
"id": fields.String,
"name": fields.String,
"description": fields.String,
"mode": fields.String(attribute="mode_compatible_with_agent"),
"icon_type": fields.String,
"icon": fields.String,
"icon_background": fields.String,
"icon_url": AppIconUrlField,
}

related_app_list = {
Expand Down Expand Up @@ -71,8 +73,10 @@
"max_active_requests": fields.Raw(),
"description": fields.String(attribute="desc_or_prompt"),
"mode": fields.String(attribute="mode_compatible_with_agent"),
"icon_type": fields.String,
"icon": fields.String,
"icon_background": fields.String,
"icon_url": AppIconUrlField,
"model_config": fields.Nested(model_config_partial_fields, attribute="app_model_config", allow_null=True),
"created_at": TimestampField,
"tags": fields.List(fields.Nested(tag_fields)),
Expand Down Expand Up @@ -104,8 +108,10 @@
"access_token": fields.String(attribute="code"),
"code": fields.String,
"title": fields.String,
"icon_type": fields.String,
"icon": fields.String,
"icon_background": fields.String,
"icon_url": AppIconUrlField,
"description": fields.String,
"default_language": fields.String,
"chat_color_theme": fields.String,
Expand All @@ -125,8 +131,10 @@
"name": fields.String,
"description": fields.String,
"mode": fields.String(attribute="mode_compatible_with_agent"),
"icon_type": fields.String,
"icon": fields.String,
"icon_background": fields.String,
"icon_url": AppIconUrlField,
"enable_site": fields.Boolean,
"enable_api": fields.Boolean,
"model_config": fields.Nested(model_config_fields, attribute="app_model_config", allow_null=True),
Expand Down
4 changes: 3 additions & 1 deletion api/fields/installed_app_fields.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
from flask_restful import fields

from libs.helper import TimestampField
from libs.helper import AppIconUrlField, TimestampField

app_fields = {
"id": fields.String,
"name": fields.String,
"mode": fields.String,
"icon_type": fields.String,
"icon": fields.String,
"icon_background": fields.String,
"icon_url": AppIconUrlField,
}

installed_app_fields = {
Expand Down
13 changes: 13 additions & 0 deletions api/libs/helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from flask_restful import fields

from core.app.features.rate_limiting.rate_limit import RateLimitGenerator
from core.file.upload_file_parser import UploadFileParser
from extensions.ext_redis import redis_client
from models.account import Account

Expand All @@ -24,6 +25,18 @@ def run(script):
return subprocess.getstatusoutput("source /root/.bashrc && " + script)


class AppIconUrlField(fields.Raw):
def output(self, key, obj):
if obj is None:
return None

from models.model import IconType

if obj.icon_type == IconType.IMAGE.value:
return UploadFileParser.get_signed_temp_image_url(obj.icon)
return None


class TimestampField(fields.Raw):
def format(self, value) -> int:
return int(value.timestamp())
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
"""app and site icon type
Revision ID: a6be81136580
Revises: 8782057ff0dc
Create Date: 2024-08-15 10:01:24.697888
"""
import sqlalchemy as sa
from alembic import op

import models as models

# revision identifiers, used by Alembic.
revision = 'a6be81136580'
down_revision = '8782057ff0dc'
branch_labels = None
depends_on = None


def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('apps', schema=None) as batch_op:
batch_op.add_column(sa.Column('icon_type', sa.String(length=255), nullable=True))

with op.batch_alter_table('sites', schema=None) as batch_op:
batch_op.add_column(sa.Column('icon_type', sa.String(length=255), nullable=True))

# ### end Alembic commands ###


def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('sites', schema=None) as batch_op:
batch_op.drop_column('icon_type')

with op.batch_alter_table('apps', schema=None) as batch_op:
batch_op.drop_column('icon_type')

# ### end Alembic commands ###
6 changes: 6 additions & 0 deletions api/models/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ def value_of(cls, value: str) -> 'AppMode':
raise ValueError(f'invalid mode value {value}')


class IconType(Enum):
IMAGE = "image"
EMOJI = "emoji"

class App(db.Model):
__tablename__ = 'apps'
__table_args__ = (
Expand All @@ -63,6 +67,7 @@ class App(db.Model):
name = db.Column(db.String(255), nullable=False)
description = db.Column(db.Text, nullable=False, server_default=db.text("''::character varying"))
mode = db.Column(db.String(255), nullable=False)
icon_type = db.Column(db.String(255), nullable=True)
icon = db.Column(db.String(255))
icon_background = db.Column(db.String(255))
app_model_config_id = db.Column(StringUUID, nullable=True)
Expand Down Expand Up @@ -1087,6 +1092,7 @@ class Site(db.Model):
id = db.Column(StringUUID, server_default=db.text('uuid_generate_v4()'))
app_id = db.Column(StringUUID, nullable=False)
title = db.Column(db.String(255), nullable=False)
icon_type = db.Column(db.String(255), nullable=True)
icon = db.Column(db.String(255))
icon_background = db.Column(db.String(255))
description = db.Column(db.Text)
Expand Down
15 changes: 13 additions & 2 deletions api/services/app_dsl_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ def import_and_create_new_app(cls, tenant_id: str, data: str, args: dict, accoun
# get app basic info
name = args.get("name") if args.get("name") else app_data.get('name')
description = args.get("description") if args.get("description") else app_data.get('description', '')
icon_type = args.get("icon_type") if args.get("icon_type") else app_data.get('icon_type')
icon = args.get("icon") if args.get("icon") else app_data.get('icon')
icon_background = args.get("icon_background") if args.get("icon_background") \
else app_data.get('icon_background')
Expand All @@ -96,6 +97,7 @@ def import_and_create_new_app(cls, tenant_id: str, data: str, args: dict, accoun
account=account,
name=name,
description=description,
icon_type=icon_type,
icon=icon,
icon_background=icon_background
)
Expand All @@ -107,6 +109,7 @@ def import_and_create_new_app(cls, tenant_id: str, data: str, args: dict, accoun
account=account,
name=name,
description=description,
icon_type=icon_type,
icon=icon,
icon_background=icon_background
)
Expand Down Expand Up @@ -165,8 +168,8 @@ def export_dsl(cls, app_model: App, include_secret:bool = False) -> str:
"app": {
"name": app_model.name,
"mode": app_model.mode,
"icon": app_model.icon,
"icon_background": app_model.icon_background,
"icon": '🤖' if app_model.icon_type == 'image' else app_model.icon,
"icon_background": '#FFEAD5' if app_model.icon_type == 'image' else app_model.icon_background,
"description": app_model.description
}
}
Expand Down Expand Up @@ -207,6 +210,7 @@ def _import_and_create_new_workflow_based_app(cls,
account: Account,
name: str,
description: str,
icon_type: str,
icon: str,
icon_background: str) -> App:
"""
Expand All @@ -218,6 +222,7 @@ def _import_and_create_new_workflow_based_app(cls,
:param account: Account instance
:param name: app name
:param description: app description
:param icon_type: app icon type, "emoji" or "image"
:param icon: app icon
:param icon_background: app icon background
"""
Expand All @@ -231,6 +236,7 @@ def _import_and_create_new_workflow_based_app(cls,
account=account,
name=name,
description=description,
icon_type=icon_type,
icon=icon,
icon_background=icon_background
)
Expand Down Expand Up @@ -307,6 +313,7 @@ def _import_and_create_new_model_config_based_app(cls,
account: Account,
name: str,
description: str,
icon_type: str,
icon: str,
icon_background: str) -> App:
"""
Expand All @@ -331,6 +338,7 @@ def _import_and_create_new_model_config_based_app(cls,
account=account,
name=name,
description=description,
icon_type=icon_type,
icon=icon,
icon_background=icon_background
)
Expand Down Expand Up @@ -358,6 +366,7 @@ def _create_app(cls,
account: Account,
name: str,
description: str,
icon_type: str,
icon: str,
icon_background: str) -> App:
"""
Expand All @@ -368,6 +377,7 @@ def _create_app(cls,
:param account: Account instance
:param name: app name
:param description: app description
:param icon_type: app icon type, "emoji" or "image"
:param icon: app icon
:param icon_background: app icon background
"""
Expand All @@ -376,6 +386,7 @@ def _create_app(cls,
mode=app_mode.value,
name=name,
description=description,
icon_type=icon_type,
icon=icon,
icon_background=icon_background,
enable_site=True,
Expand Down
2 changes: 2 additions & 0 deletions api/services/app_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ def create_app(self, tenant_id: str, args: dict, account: Account) -> App:
app.name = args['name']
app.description = args.get('description', '')
app.mode = args['mode']
app.icon_type = args.get('icon_type', 'emoji')
app.icon = args['icon']
app.icon_background = args['icon_background']
app.tenant_id = tenant_id
Expand Down Expand Up @@ -210,6 +211,7 @@ def update_app(self, app: App, args: dict) -> App:
app.name = args.get('name')
app.description = args.get('description', '')
app.max_active_requests = args.get('max_active_requests')
app.icon_type = args.get('icon_type', 'emoji')
app.icon = args.get('icon')
app.icon_background = args.get('icon_background')
app.updated_at = datetime.now(timezone.utc).replace(tzinfo=None)
Expand Down
3 changes: 3 additions & 0 deletions api/services/workflow/workflow_converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class WorkflowConverter:
def convert_to_workflow(self, app_model: App,
account: Account,
name: str,
icon_type: str,
icon: str,
icon_background: str) -> App:
"""
Expand All @@ -50,6 +51,7 @@ def convert_to_workflow(self, app_model: App,
:param account: Account
:param name: new app name
:param icon: new app icon
:param icon_type: new app icon type
:param icon_background: new app icon background
:return: new App instance
"""
Expand All @@ -66,6 +68,7 @@ def convert_to_workflow(self, app_model: App,
new_app.name = name if name else app_model.name + '(workflow)'
new_app.mode = AppMode.ADVANCED_CHAT.value \
if app_model.mode == AppMode.CHAT.value else AppMode.WORKFLOW.value
new_app.icon_type = icon_type if icon_type else app_model.icon_type
new_app.icon = icon if icon else app_model.icon
new_app.icon_background = icon_background if icon_background else app_model.icon_background
new_app.enable_site = app_model.enable_site
Expand Down
1 change: 1 addition & 0 deletions api/services/workflow_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,7 @@ def convert_to_workflow(self, app_model: App, account: Account, args: dict) -> A
app_model=app_model,
account=account,
name=args.get('name'),
icon_type=args.get('icon_type'),
icon=args.get('icon'),
icon_background=args.get('icon_background'),
)
Expand Down
Loading

1 comment on commit fbf31b5

@BenjaminX
Copy link
Contributor

Choose a reason for hiding this comment

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

web/yarn.lock file need updates
yarn install

Please sign in to comment.