Unverified Commit e2f92f11 authored by Timothy Jaeryang Baek's avatar Timothy Jaeryang Baek Committed by GitHub
Browse files

Merge pull request #643 from ollama-webui/export-all-user-chats

feat: export all chats from db
parents c4ca4663 7c2f297c
...@@ -70,9 +70,9 @@ class ChatTable: ...@@ -70,9 +70,9 @@ class ChatTable:
**{ **{
"id": id, "id": id,
"user_id": user_id, "user_id": user_id,
"title": form_data.chat["title"] "title": (
if "title" in form_data.chat form_data.chat["title"] if "title" in form_data.chat else "New Chat"
else "New Chat", ),
"chat": json.dumps(form_data.chat), "chat": json.dumps(form_data.chat),
"timestamp": int(time.time()), "timestamp": int(time.time()),
} }
...@@ -131,6 +131,12 @@ class ChatTable: ...@@ -131,6 +131,12 @@ class ChatTable:
.order_by(Chat.timestamp.desc()) .order_by(Chat.timestamp.desc())
] ]
def get_all_chats(self) -> List[ChatModel]:
return [
ChatModel(**model_to_dict(chat))
for chat in Chat.select().order_by(Chat.timestamp.desc())
]
def get_all_chats_by_user_id(self, user_id: str) -> List[ChatModel]: def get_all_chats_by_user_id(self, user_id: str) -> List[ChatModel]:
return [ return [
ChatModel(**model_to_dict(chat)) ChatModel(**model_to_dict(chat))
......
...@@ -54,6 +54,25 @@ async def get_all_user_chats(user=Depends(get_current_user)): ...@@ -54,6 +54,25 @@ async def get_all_user_chats(user=Depends(get_current_user)):
] ]
############################
# GetAllChatsInDB
############################
@router.get("/all/db", response_model=List[ChatResponse])
async def get_all_user_chats_in_db(user=Depends(get_current_user)):
if user.role == "admin":
return [
ChatResponse(**{**chat.model_dump(), "chat": json.loads(chat.chat)})
for chat in Chats.get_all_chats()
]
else:
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail=ERROR_MESSAGES.ACCESS_PROHIBITED,
)
############################ ############################
# CreateNewChat # CreateNewChat
############################ ############################
......
...@@ -93,6 +93,37 @@ export const getAllChats = async (token: string) => { ...@@ -93,6 +93,37 @@ export const getAllChats = async (token: string) => {
return res; return res;
}; };
export const getAllUserChats = async (token: string) => {
let error = null;
const res = await fetch(`${WEBUI_API_BASE_URL}/chats/all/db`, {
method: 'GET',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
...(token && { authorization: `Bearer ${token}` })
}
})
.then(async (res) => {
if (!res.ok) throw await res.json();
return res.json();
})
.then((json) => {
return json;
})
.catch((err) => {
error = err;
console.log(err);
return null;
});
if (error) {
throw error;
}
return res;
};
export const getAllChatTags = async (token: string) => { export const getAllChatTags = async (token: string) => {
let error = null; let error = null;
......
...@@ -17,7 +17,13 @@ ...@@ -17,7 +17,13 @@
deleteModel deleteModel
} from '$lib/apis/ollama'; } from '$lib/apis/ollama';
import { updateUserPassword } from '$lib/apis/auths'; import { updateUserPassword } from '$lib/apis/auths';
import { createNewChat, deleteAllChats, getAllChats, getChatList } from '$lib/apis/chats'; import {
createNewChat,
deleteAllChats,
getAllChats,
getAllUserChats,
getChatList
} from '$lib/apis/chats';
import { WEB_UI_VERSION, WEBUI_API_BASE_URL } from '$lib/constants'; import { WEB_UI_VERSION, WEBUI_API_BASE_URL } from '$lib/constants';
import { config, models, voices, settings, user, chats } from '$lib/stores'; import { config, models, voices, settings, user, chats } from '$lib/stores';
...@@ -179,6 +185,13 @@ ...@@ -179,6 +185,13 @@
saveAs(blob, `chat-export-${Date.now()}.json`); saveAs(blob, `chat-export-${Date.now()}.json`);
}; };
const exportAllUserChats = async () => {
let blob = new Blob([JSON.stringify(await getAllUserChats(localStorage.token))], {
type: 'application/json'
});
saveAs(blob, `all-chats-export-${Date.now()}.json`);
};
const deleteChats = async () => { const deleteChats = async () => {
await goto('/'); await goto('/');
await deleteAllChats(localStorage.token); await deleteAllChats(localStorage.token);
...@@ -1954,6 +1967,33 @@ ...@@ -1954,6 +1967,33 @@
on:click={() => { on:click={() => {
showDeleteConfirm = true; showDeleteConfirm = true;
}} }}
>
<div class=" self-center mr-3">
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 16 16"
fill="currentColor"
class="w-4 h-4"
>
<path
fill-rule="evenodd"
d="M4 2a1.5 1.5 0 0 0-1.5 1.5v9A1.5 1.5 0 0 0 4 14h8a1.5 1.5 0 0 0 1.5-1.5V6.621a1.5 1.5 0 0 0-.44-1.06L9.94 2.439A1.5 1.5 0 0 0 8.878 2H4Zm7 7a.75.75 0 0 1-.75.75h-4.5a.75.75 0 0 1 0-1.5h4.5A.75.75 0 0 1 11 9Z"
clip-rule="evenodd"
/>
</svg>
</div>
<div class=" self-center text-sm font-medium">Delete Chats</div>
</button>
{/if}
{#if $user?.role === 'admin'}
<hr class=" dark:border-gray-700" />
<button
class=" flex rounded-md py-2 px-3.5 w-full hover:bg-gray-200 dark:hover:bg-gray-800 transition"
on:click={() => {
exportAllUserChats();
}}
> >
<div class=" self-center mr-3"> <div class=" self-center mr-3">
<svg <svg
...@@ -1967,16 +2007,14 @@ ...@@ -1967,16 +2007,14 @@
/> />
<path <path
fill-rule="evenodd" fill-rule="evenodd"
d="M13 6H3v6a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2V6ZM5.72 7.47a.75.75 0 0 1 1.06 0L8 8.69l1.22-1.22a.75.75 0 1 1 1.06 1.06L9.06 9.75l1.22 1.22a.75.75 0 1 1-1.06 1.06L8 10.81l-1.22 1.22a.75.75 0 0 1-1.06-1.06l1.22-1.22-1.22-1.22a.75.75 0 0 1 0-1.06Z" d="M13 6H3v6a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2V6ZM8.75 7.75a.75.75 0 0 0-1.5 0v2.69L6.03 9.22a.75.75 0 0 0-1.06 1.06l2.5 2.5a.75.75 0 0 0 1.06 0l2.5-2.5a.75.75 0 1 0-1.06-1.06l-1.22 1.22V7.75Z"
clip-rule="evenodd" clip-rule="evenodd"
/> />
</svg> </svg>
</div> </div>
<div class=" self-center text-sm font-medium">Delete All Chats</div> <div class=" self-center text-sm font-medium">Export All Chats (All Users)</div>
</button> </button>
{/if}
{#if $user?.role === 'admin'}
<hr class=" dark:border-gray-700" /> <hr class=" dark:border-gray-700" />
<button <button
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment