From b417fd21b0070087ebacbbc6d82e4d425df89d96 Mon Sep 17 00:00:00 2001 From: Thinh Date: Thu, 14 Nov 2024 15:51:26 +0700 Subject: [PATCH] Revert "Restructure id logic and move private apps to plugins_data collection" --- backend/database/apps.py | 123 +++++++++++++++++++++++------------- backend/database/plugins.py | 50 +++++++++++++++ backend/requirements.txt | 2 - backend/routers/apps.py | 111 ++++++++++++++++---------------- backend/routers/chat.py | 10 +-- backend/routers/plugins.py | 38 +++++++---- backend/utils/apps.py | 18 ++---- backend/utils/plugins.py | 7 +- 8 files changed, 221 insertions(+), 138 deletions(-) diff --git a/backend/database/apps.py b/backend/database/apps.py index 8f840982f..32bb01730 100644 --- a/backend/database/apps.py +++ b/backend/database/apps.py @@ -1,9 +1,13 @@ import os +import random +from datetime import datetime, timezone from typing import List -from google.cloud.firestore_v1.base_query import BaseCompositeFilter, FieldFilter -from ulid import ULID +import requests +from models.app import App +from models.plugin import UsageHistoryType +from utils.other.storage import storage_client from ._client import db # ***************************** @@ -13,79 +17,112 @@ omi_plugins_bucket = os.getenv('BUCKET_PLUGINS_LOGOS') -def get_app_by_id_db(app_id: str): - app_ref = db.collection('plugins_data').document(app_id) +def get_app_by_id_db(app_id: str, uid: str): + if 'private' in app_id: + app_ref = db.collection('users').document(uid).collection('plugins').document(app_id) + else: + app_ref = db.collection('plugins_data').document(app_id) doc = app_ref.get() if doc.exists: - if doc.to_dict().get('deleted', True): - return None return doc.to_dict() return None def get_private_apps_db(uid: str) -> List: - filters = [FieldFilter('uid', '==', uid), FieldFilter('private', '==', True), FieldFilter('deleted', '==', False)] - private_apps = db.collection('plugins_data').where(filter=BaseCompositeFilter('AND', filters)).stream(), - data = [doc.to_dict() for doc in private_apps] + private_plugins = db.collection('users').document(uid).collection('plugins').stream() + data = [doc.to_dict() for doc in private_plugins] return data -# This returns public unapproved apps of all users def get_unapproved_public_apps_db() -> List: - filters = [FieldFilter('approved', '==', False), FieldFilter('private', '==', False), FieldFilter('deleted', '==', False)] - public_apps = db.collection('plugins_data').where(filter=BaseCompositeFilter('AND', filters)).stream() - return [doc.to_dict() for doc in public_apps] + public_plugins = db.collection('plugins_data').where('approved', '==', False).stream() + return [doc.to_dict() for doc in public_plugins] def get_public_apps_db(uid: str) -> List: - public_plugins = db.collection('plugins_data').stream() + public_plugins = db.collection('plugins_data').where('approved', '==', True).stream() data = [doc.to_dict() for doc in public_plugins] - return [plugin for plugin in data if plugin['approved'] == True or plugin['uid'] == uid] + # Include the doc if it is not approved but uid matches + unapproved = db.collection('plugins_data').where('approved', '==', False).where('uid', '==', uid).stream() + data.extend([doc.to_dict() for doc in unapproved]) + + return data def get_public_approved_apps_db() -> List: - filters = [FieldFilter('approved', '==', True), FieldFilter('deleted', '==', False)] - public_apps = db.collection('plugins_data').where(filter=BaseCompositeFilter('AND', filters)).stream() - return [doc.to_dict() for doc in public_apps] + public_plugins = db.collection('plugins_data').where('approved', '==', True).stream() + return [doc.to_dict() for doc in public_plugins] -# This returns public unapproved apps for a user def get_public_unapproved_apps_db(uid: str) -> List: - filters = [FieldFilter('approved', '==', False), FieldFilter('uid', '==', uid), FieldFilter('deleted', '==', False), FieldFilter('private', '==', False)] - public_apps = db.collection('plugins_data').where(filter=BaseCompositeFilter('AND', filters)).stream() - return [doc.to_dict() for doc in public_apps] + public_plugins = db.collection('plugins_data').where('approved', '==', False).where('uid', '==', uid).stream() + return [doc.to_dict() for doc in public_plugins] + +def public_app_id_exists_db(app_id: str) -> bool: + app_ref = db.collection('plugins_data').document(app_id) + return app_ref.get().exists -def add_app_to_db(app_data: dict): - app_ref = db.collection('plugins_data') - app_ref.add(app_data, app_data['id']) +def private_app_id_exists_db(app_id: str, uid: str) -> bool: + app_ref = db.collection('users').document(uid).collection('plugins').document(app_id) + return app_ref.get().exists -def update_app_in_db(app_data: dict): - app_ref = db.collection('plugins_data').document(app_data['id']) - app_ref.update(app_data) +def add_public_app(plugin_data: dict): + plugin_ref = db.collection('plugins_data') + plugin_ref.add(plugin_data, plugin_data['id']) -def delete_app_from_db(app_id: str): - app_ref = db.collection('plugins_data').document(app_id) - app_ref.update({'deleted': True}) +def add_private_app(plugin_data: dict, uid: str): + plugin_ref = db.collection('users').document(uid).collection('plugins') + plugin_ref.add(plugin_data, plugin_data['id']) -def update_app_visibility_in_db(app_id: str, private: bool): - app_ref = db.collection('plugins_data').document(app_id) - if 'private' in app_id and not private: - app = app_ref.get().to_dict() - app_ref.delete() - new_app_id = app_id.split('-private')[0] + str(ULID()) - app['id'] = new_app_id - app['private'] = private - app_ref = db.collection('plugins_data').document(new_app_id) - app_ref.set(app) - else: - app_ref.update({'private': private}) + +def update_public_app(plugin_data: dict): + plugin_ref = db.collection('plugins_data').document(plugin_data['id']) + plugin_ref.update(plugin_data) + + +def update_private_app(plugin_data: dict, uid: str): + plugin_ref = db.collection('users').document(uid).collection('plugins').document(plugin_data['id']) + plugin_ref.update(plugin_data) + + +def delete_private_app(plugin_id: str, uid: str): + plugin_ref = db.collection('users').document(uid).collection('plugins').document(plugin_id) + plugin_ref.update({'deleted': True}) + + +def delete_public_app(plugin_id: str): + plugin_ref = db.collection('plugins_data').document(plugin_id) + plugin_ref.update({'deleted': True}) def change_app_approval_status(plugin_id: str, approved: bool): plugin_ref = db.collection('plugins_data').document(plugin_id) plugin_ref.update({'approved': approved, 'status': 'approved' if approved else 'rejected'}) + + +def change_app_visibility_db(app_id: str, private: bool, was_public: bool, uid: str): + if was_public and private: # public -> private + plugin_ref = db.collection('plugins_data').document(app_id) + plugin = plugin_ref.get().to_dict() + plugin_ref.delete() + new_plugin_id = f'{app_id}-private' + plugin['id'] = new_plugin_id + plugin['private'] = private + plugin_ref = db.collection('users').document(uid).collection('plugins').document(new_plugin_id) + plugin_ref.set(plugin) + elif not was_public and not private: # private -> public + plugin_ref = db.collection('users').document(uid).collection('plugins').document(app_id) + plugin = plugin_ref.get().to_dict() + plugin_ref.delete() + new_plugin_id = app_id.split('-private')[0] + plugin['id'] = new_plugin_id + plugin['private'] = private + if public_app_id_exists_db(new_plugin_id): + new_plugin_id = new_plugin_id + '-' + ''.join([str(random.randint(0, 9)) for _ in range(5)]) + plugin_ref = db.collection('plugins_data').document(new_plugin_id) + plugin_ref.set(plugin) diff --git a/backend/database/plugins.py b/backend/database/plugins.py index 63b6c9fd7..9bcd386fe 100644 --- a/backend/database/plugins.py +++ b/backend/database/plugins.py @@ -1,4 +1,5 @@ import os +import random from datetime import datetime, timezone from typing import List @@ -38,6 +39,55 @@ def get_plugin_usage_history(plugin_id: str): return [doc.to_dict() for doc in usage] +def get_plugin_by_id_db(plugin_id: str, uid: str): + if 'private' in plugin_id: + plugin_ref = db.collection('users').document(uid).collection('plugins').document(plugin_id) + else: + plugin_ref = db.collection('plugins_data').document(plugin_id) + doc = plugin_ref.get() + if doc.exists: + return doc.to_dict() + return None + + +def add_public_plugin(plugin_data: dict): + plugin_ref = db.collection('plugins_data') + plugin_ref.add(plugin_data, plugin_data['id']) + + +def add_private_plugin(plugin_data: dict, uid: str): + plugin_ref = db.collection('users').document(uid).collection('plugins') + plugin_ref.add(plugin_data, plugin_data['id']) + + +def get_private_plugins_db(uid: str) -> List: + private_plugins = db.collection('users').document(uid).collection('plugins').stream() + data = [doc.to_dict() for doc in private_plugins] + return data + + +def get_unapproved_public_plugins_db() -> List: + public_plugins = db.collection('plugins_data').where('approved', '==', False).stream() + return [doc.to_dict() for doc in public_plugins] + + +def get_public_plugins_db(uid: str) -> List: + public_plugins = db.collection('plugins_data').stream() + data = [doc.to_dict() for doc in public_plugins] + + return [plugin for plugin in data if plugin['approved'] == True or plugin['uid'] == uid] + + +def public_plugin_id_exists_db(plugin_id: str) -> bool: + plugin_ref = db.collection('plugins_data').document(plugin_id) + return plugin_ref.get().exists + + +def private_plugin_id_exists_db(plugin_id: str, uid: str) -> bool: + plugin_ref = db.collection('users').document(uid).collection('plugins').document(plugin_id) + return plugin_ref.get().exists + + def add_plugin_from_community_json(plugin_data: dict): img = requests.get("https://raw.githubusercontent.com/BasedHardware/Omi/main/" + plugin_data['image'], stream=True) bucket = storage_client.bucket(omi_plugins_bucket) diff --git a/backend/requirements.txt b/backend/requirements.txt index b03583c6e..7d83dd964 100644 --- a/backend/requirements.txt +++ b/backend/requirements.txt @@ -178,8 +178,6 @@ pyparsing==3.1.2 python-dateutil==2.9.0.post0 python-dotenv==1.0.1 python-multipart==0.0.9 -python-slugify==8.0.4 -python-ulid==3.0.0 pytorch-lightning==2.4.0 pytorch-metric-learning==2.6.0 pytz==2024.1 diff --git a/backend/routers/apps.py b/backend/routers/apps.py index 085182b10..896a44ef4 100644 --- a/backend/routers/apps.py +++ b/backend/routers/apps.py @@ -1,18 +1,18 @@ import json import os +import random from datetime import datetime, timezone from typing import List import requests -from ulid import ULID from fastapi import APIRouter, Depends, Form, UploadFile, File, HTTPException, Header -from slugify import slugify -from database.apps import change_app_approval_status, get_unapproved_public_apps_db, \ - add_app_to_db, update_app_in_db, delete_app_from_db, update_app_visibility_in_db +from database.apps import private_app_id_exists_db, public_app_id_exists_db, add_public_app, add_private_app, \ + get_app_by_id_db, update_private_app, update_public_app, delete_private_app, delete_public_app, \ + change_app_approval_status, change_app_visibility_db, get_unapproved_public_apps_db from database.notifications import get_token_only from database.redis_db import set_plugin_review, delete_generic_cache, increase_plugin_installs_count, enable_plugin, \ disable_plugin, decrease_plugin_installs_count -from utils.apps import get_available_apps, get_available_app_by_id, get_approved_available_apps +from utils.apps import get_apps_data_from_db from utils.notifications import send_notification from utils.other import endpoints as auth from models.app import App @@ -27,12 +27,12 @@ @router.get('/v1/apps', tags=['v1'], response_model=List[App]) def get_apps(uid: str = Depends(auth.get_current_user_uid), include_reviews: bool = True): - return get_available_apps(uid, include_reviews=include_reviews) + return get_apps_data_from_db(uid, include_reviews=include_reviews) -@router.get('/v1/approved-apps', tags=['v1'], response_model=List[App]) -def get_approved_apps(): - return get_approved_available_apps(include_reviews=False) +@router.get('/v1/approved-apps', tags=['v1'], response_model=App) +def get_approved_apps(uid: str = Depends(auth.get_current_user_uid)): + return get_apps_data_from_db(uid, include_reviews=False) @router.post('/v1/apps', tags=['v1']) @@ -41,8 +41,17 @@ def submit_app(app_data: str = Form(...), file: UploadFile = File(...), uid=Depe data['approved'] = False data['status'] = 'under-review' data['name'] = data['name'].strip() - new_app_id = slugify(data['name']) + '-' + str(ULID()) - data['id'] = new_app_id + data['id'] = data['name'].replace(' ', '-').lower() + data['uid'] = uid + data['id'] = data['id'].replace(',', '-') + data['id'] = data['id'].replace("'", '') + if 'private' in data and data['private']: + data['id'] = data['id'] + '-private' + if private_app_id_exists_db(data['id'], uid): + data['id'] = data['id'] + '-' + ''.join([str(random.randint(0, 9)) for _ in range(5)]) + else: + if public_app_id_exists_db(data['id']): + data['id'] = data['id'] + '-' + ''.join([str(random.randint(0, 9)) for _ in range(5)]) if external_integration := data.get('external_integration'): # check if setup_instructions_file_path is a single url or a just a string of text if external_integration.get('setup_instructions_file_path'): @@ -59,7 +68,11 @@ def submit_app(app_data: str = Form(...), file: UploadFile = File(...), uid=Depe imgUrl = upload_plugin_logo(file_path, data['id']) data['image'] = imgUrl data['created_at'] = datetime.now(timezone.utc) - add_app_to_db(data) + if data.get('private', True): + print("Adding private app") + add_private_app(data, data['uid']) + else: + add_public_app(data) return {'status': 'ok'} @@ -67,9 +80,9 @@ def submit_app(app_data: str = Form(...), file: UploadFile = File(...), uid=Depe def update_app(app_id: str, app_data: str = Form(...), file: UploadFile = File(None), uid=Depends(auth.get_current_user_uid)): data = json.loads(app_data) - plugin = get_available_app_by_id(app_id, uid) + plugin = get_app_by_id_db(app_id, uid) if not plugin: - raise HTTPException(status_code=404, detail='App not found') + raise HTTPException(status_code=404, detail='Plugin not found') if plugin['uid'] != uid: raise HTTPException(status_code=403, detail='You are not authorized to perform this action') if file: @@ -78,37 +91,36 @@ def update_app(app_id: str, app_data: str = Form(...), file: UploadFile = File(N file_path = f"_temp/plugins/{file.filename}" with open(file_path, 'wb') as f: f.write(file.file.read()) - img_url = upload_plugin_logo(file_path, app_id) - data['image'] = img_url - data['updated_at'] = datetime.now(timezone.utc) - update_app_in_db(data) + imgUrl = upload_plugin_logo(file_path, app_id) + data['image'] = imgUrl + if data.get('private', True): + update_private_app(data, uid) + else: + update_public_app(data) return {'status': 'ok'} @router.delete('/v1/apps/{app_id}', tags=['v1']) def delete_app(app_id: str, uid: str = Depends(auth.get_current_user_uid)): - plugin = get_available_app_by_id(app_id, uid) + plugin = get_app_by_id_db(app_id, uid) if not plugin: raise HTTPException(status_code=404, detail='App not found') if plugin['uid'] != uid: raise HTTPException(status_code=403, detail='You are not authorized to perform this action') - delete_app_from_db(app_id) - if plugin['approved']: - delete_generic_cache('get_public_approved_apps_data') + if plugin['private']: + delete_private_app(app_id, uid) + else: + delete_public_app(app_id) + if plugin['approved']: + delete_generic_cache('get_public_approved_apps_data') return {'status': 'ok'} @router.get('/v1/apps/{app_id}', tags=['v1']) def get_app_details(app_id: str, uid: str = Depends(auth.get_current_user_uid)): - app = get_available_app_by_id(app_id, uid) - app = App(**app) if app else None + app = get_app_by_id_db(app_id, uid) if not app: raise HTTPException(status_code=404, detail='App not found') - if not app.approved: - raise HTTPException(status_code=404, detail='App not found') - if app.private is None: - if app.private and app.uid != uid: - raise HTTPException(status_code=403, detail='You are not authorized to view this app') return app @@ -117,16 +129,9 @@ def review_app(app_id: str, data: dict, uid: str = Depends(auth.get_current_user if 'score' not in data: raise HTTPException(status_code=422, detail='Score is required') - app = get_available_app_by_id(app_id, uid) - app = App(**app) if app else None - if not app: - raise HTTPException(status_code=404, detail='App not found') - - if app.uid == uid: - raise HTTPException(status_code=403, detail='You are not authorized to review your own app') - - if app.private and app.uid != uid: - raise HTTPException(status_code=403, detail='You are not authorized to review this app') + plugin = get_app_by_id_db(app_id, uid) + if not plugin: + raise HTTPException(status_code=404, detail='Plugin not found') score = data['score'] review = data.get('review', '') @@ -136,13 +141,11 @@ def review_app(app_id: str, data: dict, uid: str = Depends(auth.get_current_user @router.patch('/v1/apps/{app_id}/change-visibility', tags=['v1']) def change_app_visibility(app_id: str, private: bool, uid: str = Depends(auth.get_current_user_uid)): - app = get_available_app_by_id(app_id, uid) - app = App(**app) if app else None + app = get_app_by_id_db(app_id, uid) if not app: - raise HTTPException(status_code=404, detail='App not found') - if app.uid != uid: - raise HTTPException(status_code=403, detail='You are not authorized to perform this action') - update_app_visibility_in_db(app_id, private) + raise HTTPException(status_code=404, detail='Plugin not found') + was_public = not app['deleted'] and not app['private'] + change_app_visibility_db(app_id, private, was_public, uid) return {'status': 'ok'} @@ -176,13 +179,10 @@ def get_plugin_capabilities(): @router.post('/v1/apps/enable') def enable_app(app_id: str, uid: str = Depends(auth.get_current_user_uid)): - app = get_available_app_by_id(app_id, uid) - app = App(**app) if app else None + app = get_app_by_id_db(app_id, uid) + app = App(**app) if not app: raise HTTPException(status_code=404, detail='App not found') - if app.private is not None: - if app.private and app.uid != uid: - raise HTTPException(status_code=403, detail='You are not authorized to perform this action') if app.works_externally() and app.external_integration.setup_completed_url: res = requests.get(app.external_integration.setup_completed_url + f'?uid={uid}') print('enable_app_endpoint', res.status_code, res.content) @@ -195,13 +195,10 @@ def enable_app(app_id: str, uid: str = Depends(auth.get_current_user_uid)): @router.post('/v1/apps/disable') def disable_app(app_id: str, uid: str = Depends(auth.get_current_user_uid)): - app = get_available_app_by_id(app_id, uid) - app = App(**app) if app else None + app = get_app_by_id_db(app_id, uid) + app = App(**app) if not app: raise HTTPException(status_code=404, detail='App not found') - if app.private is None: - if app.private and app.uid != uid: - raise HTTPException(status_code=403, detail='You are not authorized to perform this action') disable_plugin(uid, app_id) decrease_plugin_installs_count(app_id) return {'status': 'ok'} @@ -224,7 +221,7 @@ def approve_app(app_id: str, uid: str, secret_key: str = Header(...)): if secret_key != os.getenv('ADMIN_KEY'): raise HTTPException(status_code=403, detail='You are not authorized to perform this action') change_app_approval_status(app_id, True) - app = get_available_app_by_id(app_id, uid) + app = get_app_by_id_db(app_id, uid) token = get_token_only(uid) if token: send_notification(token, 'App Approved 🎉', @@ -237,7 +234,7 @@ def reject_app(app_id: str, uid: str, secret_key: str = Header(...)): if secret_key != os.getenv('ADMIN_KEY'): raise HTTPException(status_code=403, detail='You are not authorized to perform this action') change_app_approval_status(app_id, False) - app = get_available_app_by_id(app_id, uid) + app = get_app_by_id_db(app_id, uid) token = get_token_only(uid) if token: # TODO: Add reason for rejection in payload and also redirect to the plugin page diff --git a/backend/routers/chat.py b/backend/routers/chat.py index 898392432..33c860d98 100644 --- a/backend/routers/chat.py +++ b/backend/routers/chat.py @@ -5,12 +5,12 @@ from fastapi import APIRouter, Depends, HTTPException import database.chat as chat_db +from database.apps import get_app_by_id_db from database.plugins import record_plugin_usage from models.app import App -from models.plugin import UsageHistoryType -from models.memory import Memory from models.chat import Message, SendMessageRequest, MessageSender, ResponseMessage -from utils.apps import get_available_app_by_id +from models.memory import Memory +from models.plugin import UsageHistoryType from utils.llm import initial_chat_message from utils.other import endpoints as auth from utils.retrieval.graph import execute_graph_chat @@ -39,7 +39,7 @@ def send_message( ) chat_db.add_message(uid, message.dict()) - plugin = get_available_app_by_id(plugin_id, uid) + plugin = get_app_by_id_db(plugin_id, uid) plugin = App(**plugin) if plugin else None plugin_id = plugin.id if plugin else None @@ -84,7 +84,7 @@ def clear_chat_messages(uid: str = Depends(auth.get_current_user_uid)): def initial_message_util(uid: str, plugin_id: Optional[str] = None): - plugin = get_available_app_by_id(plugin_id, uid) + plugin = get_app_by_id_db(plugin_id, uid) plugin = App(**plugin) if plugin else None text = initial_chat_message(uid, plugin) diff --git a/backend/routers/plugins.py b/backend/routers/plugins.py index 134066805..89d91ca60 100644 --- a/backend/routers/plugins.py +++ b/backend/routers/plugins.py @@ -8,16 +8,14 @@ import requests from fastapi import APIRouter, HTTPException, Depends, UploadFile from fastapi.params import File, Form -from slugify import slugify -from ulid import ULID -from database.apps import add_app_to_db -from database.plugins import get_plugin_usage_history +from database.apps import get_app_by_id_db +from database.plugins import get_plugin_usage_history, add_public_plugin, add_private_plugin, \ + public_plugin_id_exists_db, private_plugin_id_exists_db, get_plugin_by_id_db from database.redis_db import set_plugin_review, enable_plugin, disable_plugin, increase_plugin_installs_count, \ decrease_plugin_installs_count from models.app import App from models.plugin import Plugin, UsageHistoryItem, UsageHistoryType -from utils.apps import get_available_app_by_id from utils.other import endpoints as auth from utils.other.storage import upload_plugin_logo from utils.plugins import get_plugins_data, get_plugin_by_id, get_plugins_data_from_db @@ -27,8 +25,8 @@ @router.post('/v1/plugins/enable') def enable_plugin_endpoint(plugin_id: str, uid: str = Depends(auth.get_current_user_uid)): - plugin = get_available_app_by_id(plugin_id, uid) - plugin = App(**plugin) if plugin else None + plugin = get_app_by_id_db(plugin_id, uid) + plugin = App(**plugin) if not plugin: raise HTTPException(status_code=404, detail='Plugin not found') if plugin.works_externally() and plugin.external_integration.setup_completed_url: @@ -43,10 +41,10 @@ def enable_plugin_endpoint(plugin_id: str, uid: str = Depends(auth.get_current_u @router.post('/v1/plugins/disable') def disable_plugin_endpoint(plugin_id: str, uid: str = Depends(auth.get_current_user_uid)): - plugin = get_available_app_by_id(plugin_id, uid) - plugin = App(**plugin) if plugin else None + plugin = get_app_by_id_db(plugin_id, uid) + plugin = App(**plugin) if not plugin: - raise HTTPException(status_code=404, detail='App not found') + raise HTTPException(status_code=404, detail='Plugin not found') disable_plugin(uid, plugin_id) decrease_plugin_installs_count(plugin_id) return {'status': 'ok'} @@ -72,7 +70,7 @@ def review_plugin(plugin_id: str, data: dict, uid: str = Depends(auth.get_curren if 'score' not in data: raise HTTPException(status_code=422, detail='Score is required') - plugin = get_available_app_by_id(plugin_id, uid) + plugin = get_plugin_by_id_db(plugin_id, uid) if not plugin: raise HTTPException(status_code=404, detail='Plugin not found') @@ -139,8 +137,15 @@ def add_plugin(plugin_data: str = Form(...), file: UploadFile = File(...), uid=D data = json.loads(plugin_data) data['approved'] = False data['name'] = data['name'].strip() - new_app_id = slugify(data['name']) + '-' + str(ULID()) - data['id'] = new_app_id + data['id'] = data['name'].replace(' ', '-').lower() + data['uid'] = uid + if 'private' in data and data['private']: + data['id'] = data['id'] + '-private' + if private_plugin_id_exists_db(data['id'], uid): + data['id'] = data['id'] + '-' + ''.join([str(random.randint(0, 9)) for _ in range(5)]) + else: + if public_plugin_id_exists_db(data['id']): + data['id'] = data['id'] + '-' + ''.join([str(random.randint(0, 9)) for _ in range(5)]) os.makedirs(f'_temp/plugins', exist_ok=True) file_path = f"_temp/plugins/{file.filename}" with open(file_path, 'wb') as f: @@ -148,7 +153,12 @@ def add_plugin(plugin_data: str = Form(...), file: UploadFile = File(...), uid=D imgUrl = upload_plugin_logo(file_path, data['id']) data['image'] = imgUrl data['created_at'] = datetime.now(timezone.utc) - add_app_to_db(data) + if data.get('private', True): + print("Adding private plugin") + add_private_plugin(data, data['uid']) + else: + add_public_plugin(data) + # delete_generic_cache('get_public_plugins_data') return {'status': 'ok'} diff --git a/backend/utils/apps.py b/backend/utils/apps.py index 0fdadc457..0e2018d06 100644 --- a/backend/utils/apps.py +++ b/backend/utils/apps.py @@ -1,14 +1,15 @@ from typing import List -from database.apps import get_private_apps_db, get_public_unapproved_apps_db, \ - get_public_approved_apps_db, get_app_by_id_db +from database.apps import get_private_apps_db, get_public_apps_db, get_public_unapproved_apps_db, \ + get_public_approved_apps_db +from database.plugins import get_private_plugins_db from database.redis_db import get_enabled_plugins, get_plugin_installs_count, get_plugin_reviews, get_generic_cache, \ set_generic_cache from models.app import App from utils.plugins import weighted_rating -def get_available_apps(uid: str, include_reviews: bool = False) -> List[App]: +def get_apps_data_from_db(uid: str, include_reviews: bool = False) -> List[App]: private_data = [] public_approved_data = [] public_unapproved_data = [] @@ -47,16 +48,7 @@ def get_available_apps(uid: str, include_reviews: bool = False) -> List[App]: return apps -def get_available_app_by_id(app_id: str, uid: str | None) -> dict | None: - app = get_app_by_id_db(app_id) - if not app: - return None - if app['private'] and app['uid'] != uid: - return None - return app - - -def get_approved_available_apps(include_reviews: bool = False) -> list[App]: +def get_approved_apps_data_from_db(include_reviews: bool = False) -> List[App]: all_apps = [] if cached_apps := get_generic_cache('get_public_approved_apps_data'): print('get_public_approved_apps_data from cache') diff --git a/backend/utils/plugins.py b/backend/utils/plugins.py index 8a2227aa8..5a5a2fea0 100644 --- a/backend/utils/plugins.py +++ b/backend/utils/plugins.py @@ -4,9 +4,8 @@ import requests import database.notifications as notification_db -from database.apps import get_private_apps_db, get_public_apps_db from database.chat import add_plugin_message -from database.plugins import record_plugin_usage +from database.plugins import record_plugin_usage, get_private_plugins_db, get_public_plugins_db from database.redis_db import get_enabled_plugins, get_plugin_reviews, get_plugin_installs_count, get_generic_cache, \ set_generic_cache from models.memory import Memory, MemorySource @@ -89,8 +88,8 @@ def get_plugins_data_from_db(uid: str, include_reviews: bool = False) -> List[Pl # private_data = get_private_plugins_db(uid) # pass # else: - private_data = get_private_apps_db(uid) - public_data = get_public_apps_db(uid) + private_data = get_private_plugins_db(uid) + public_data = get_public_plugins_db(uid) # set_generic_cache('get_public_plugins_data', public_data, 60 * 10) # 10 minutes cached user_enabled = set(get_enabled_plugins(uid)) all_plugins = private_data + public_data