-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
allow user to append own source content (#15)
* add accordion item for creating custom source items * add shadcn-card component * wip: add form for custom user source * cleanup custom source componentn * add shadcn input component * add components to get custom source by website url and copy/paste * add logic for extracting pdf and page content from url * wip: add component for rendering pdf content * define id field on URLContent * fetch custom sources from specified links - supports .pdf and any public webpage * retain formatting in web and pdf content; improve page content rendering * cleanup * wip: add logic to store and fetch custom sources * add endpoint to fetch custom sources for a given audiocast session * create a component for rendering audio_souces - ai-generated custom * setup firebase and rxjs * add a safe_to_dict method to db_manager * use generate-custom-source endpoint when adding custom source - this allows saving the custom source to firestore * fetch custom sources on mount page/drawer * read custom_sources from firebase using the js_sdk * add firebase.json and optimize_deps * parse firebase_config env variable in vite.config * define .firebaserc * update custom_source model; add toast notification * consolidate and cleanup * wip: create workflow to store copy/paste source * add useful helpers to CustomSourceManager * add endpoint and request logic to add copy/paste source * improve the layouts of copypast_source and website_url_source forms * refactor and cleanup * use improved module names * finalize endpoint to store uploaded content * improve class and module names * add ui logic for uploading dropped files * upload dragged&dropped file as form_data; allow up to 10mb * add a title field on source_content model * ensure the user cannot create more than 5 custom sources * allow uploading a file using the file dialog * cleanup * write source_content to db after it's generated * add user provided custom sources to the tts_prompt * specify the correct interface for _get_custom_sources * improve the prompt to exclude extraneous information in user-provided sources * add FIREBASE_CONFIG to env * remove firebase_config from env_vars
- Loading branch information
1 parent
16e88aa
commit f278a2d
Showing
56 changed files
with
2,055 additions
and
168 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"projects": {} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -30,4 +30,8 @@ uvicorn | |
uvloop | ||
redis[hiredis] | ||
|
||
async-web-search | ||
async-web-search | ||
|
||
lxml | ||
beautifulsoup4 | ||
pypdf[crypto] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
from typing import Literal, Optional, TypedDict, cast | ||
|
||
from google.cloud.firestore_v1 import DocumentReference | ||
from pydantic import BaseModel | ||
|
||
from src.services.firestore_sdk import ( | ||
Collection, | ||
DBManager, | ||
collections, | ||
) | ||
|
||
|
||
class SourceContent(BaseModel): | ||
id: str | ||
content: str | ||
content_type: str | ||
metadata: dict = {} | ||
title: Optional[str] = None | ||
|
||
def __str__(self): | ||
result = f"Content: {self.content}" | ||
if self.title: | ||
return f"Title: {self.title}\n{result}" | ||
return result | ||
|
||
|
||
class CustomSourceModel(SourceContent): | ||
source_type: Literal["link", "copy/paste", "file_upload"] | ||
url: Optional[str] = None | ||
created_at: Optional[str] = None | ||
updated_at: Optional[str] = None | ||
|
||
|
||
class SourceContentDict(TypedDict): | ||
id: str | ||
content: str | ||
content_type: str | ||
metadata: dict | ||
title: Optional[str] | ||
|
||
|
||
class CustomSourceModelDict(SourceContentDict): | ||
source_type: Literal["link", "copy/paste", "file_upload"] | ||
url: Optional[str] | ||
created_at: Optional[str] | ||
updated_at: Optional[str] | ||
|
||
|
||
class CustomSourceManager(DBManager): | ||
collection: Collection = collections["audiora_sessions"] | ||
sub_collection = "custom_sources" | ||
|
||
def __init__(self, session_id: str): | ||
super().__init__() | ||
self.doc_id = session_id | ||
|
||
def _check_document(self): | ||
"""if the collection does not exist, create it""" | ||
doc = self._get_document(self.collection, self.doc_id) | ||
if not doc.exists: | ||
raise Exception("Session not found") | ||
return doc | ||
|
||
def _get_doc_ref(self, source_id: str) -> DocumentReference: | ||
self._check_document() | ||
return ( | ||
self._get_collection(self.collection) | ||
.document(self.doc_id) | ||
.collection(self.sub_collection) | ||
.document(source_id) | ||
) | ||
|
||
def _set_custom_source(self, data: CustomSourceModel): | ||
return self._get_doc_ref(data.id).set( | ||
{ | ||
**(data.model_dump()), | ||
"created_at": self._timestamp, | ||
"updated_at": self._timestamp, | ||
} | ||
) | ||
|
||
def _get_custom_source(self, source_id: str) -> CustomSourceModel | None: | ||
doc = self._get_doc_ref(source_id).get() | ||
data = doc.to_dict() | ||
if doc.exists and data: | ||
return cast(CustomSourceModel, self._safe_to_dict(data)) | ||
|
||
def _get_custom_sources(self) -> list[CustomSourceModelDict]: | ||
self._check_document() | ||
|
||
try: | ||
session_ref = self._get_collection(self.collection).document(self.doc_id) | ||
docs = session_ref.collection(self.sub_collection).get() | ||
return [ | ||
cast(CustomSourceModelDict, self._safe_to_dict(doc.to_dict())) | ||
for doc in docs | ||
if doc.exists and doc.to_dict() | ||
] | ||
|
||
except Exception as e: | ||
print(f"Error getting custom sources for Session: {self.doc_id}", e) | ||
return [] | ||
|
||
def _delete_custom_source(self, source_id: str): | ||
return self._get_doc_ref(source_id).delete() |
Oops, something went wrong.