Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
chenpangpang
open-webui
Commits
20a6dbbe
"git@developer.sourcefind.cn:chenpangpang/open-webui.git" did not exist on "ea7ea52ba386c77c35a495c716394609600ca67e"
Commit
20a6dbbe
authored
May 01, 2024
by
Timothy J. Baek
Browse files
feat: csv bulk import
parent
bd3b5f1e
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
108 additions
and
83 deletions
+108
-83
backend/apps/web/routers/auths.py
backend/apps/web/routers/auths.py
+0
-70
src/lib/components/admin/AddUserModal.svelte
src/lib/components/admin/AddUserModal.svelte
+108
-13
No files found.
backend/apps/web/routers/auths.py
View file @
20a6dbbe
...
@@ -253,76 +253,6 @@ async def add_user(form_data: AddUserForm, user=Depends(get_admin_user)):
...
@@ -253,76 +253,6 @@ async def add_user(form_data: AddUserForm, user=Depends(get_admin_user)):
raise
HTTPException
(
500
,
detail
=
ERROR_MESSAGES
.
DEFAULT
(
err
))
raise
HTTPException
(
500
,
detail
=
ERROR_MESSAGES
.
DEFAULT
(
err
))
@
router
.
post
(
"/add/import"
,
response_model
=
SigninResponse
)
async
def
add_user_csv_import
(
file
:
UploadFile
=
File
(...),
user
=
Depends
(
get_admin_user
)
):
try
:
# Check if the file is a CSV file
if
file
.
filename
.
endswith
(
".csv"
):
# Read the contents of the CSV file
contents
=
await
file
.
read
()
# Decode the contents from bytes to string
decoded_content
=
contents
.
decode
(
"utf-8"
)
# Split the CSV content into lines
csv_lines
=
decoded_content
.
split
(
"
\n
"
)
# Parse CSV
csv_data
=
[]
csv_reader
=
csv
.
reader
(
csv_lines
)
for
row
in
csv_reader
:
csv_data
.
append
(
row
)
# Print the CSV data
for
row
in
csv_data
:
print
(
row
)
return
{
"message"
:
"CSV file uploaded successfully."
}
else
:
raise
"File must be a CSV."
except
Exception
as
err
:
raise
HTTPException
(
500
,
detail
=
ERROR_MESSAGES
.
DEFAULT
(
err
))
# if not validate_email_format(form_data.email.lower()):
# raise HTTPException(
# status.HTTP_400_BAD_REQUEST, detail=ERROR_MESSAGES.INVALID_EMAIL_FORMAT
# )
# if Users.get_user_by_email(form_data.email.lower()):
# raise HTTPException(400, detail=ERROR_MESSAGES.EMAIL_TAKEN)
# try:
# print(form_data)
# hashed = get_password_hash(form_data.password)
# user = Auths.insert_new_auth(
# form_data.email.lower(),
# hashed,
# form_data.name,
# form_data.profile_image_url,
# form_data.role,
# )
# if user:
# token = create_token(data={"id": user.id})
# return {
# "token": token,
# "token_type": "Bearer",
# "id": user.id,
# "email": user.email,
# "name": user.name,
# "role": user.role,
# "profile_image_url": user.profile_image_url,
# }
# else:
# raise HTTPException(500, detail=ERROR_MESSAGES.CREATE_USER_ERROR)
# except Exception as err:
# raise HTTPException(500, detail=ERROR_MESSAGES.DEFAULT(err))
############################
############################
# ToggleSignUp
# ToggleSignUp
############################
############################
...
...
src/lib/components/admin/AddUserModal.svelte
View file @
20a6dbbe
...
@@ -12,6 +12,7 @@
...
@@ -12,6 +12,7 @@
export let show = false;
export let show = false;
let loading = false;
let tab = '';
let tab = '';
let inputFiles;
let inputFiles;
...
@@ -32,19 +33,82 @@
...
@@ -32,19 +33,82 @@
}
}
const submitHandler = async () => {
const submitHandler = async () => {
const res = await addUser(
const stopLoading = () => {
localStorage.token,
_user.name,
_user.email,
_user.password,
_user.role
).catch((error) => {
toast.error(error);
});
if (res) {
dispatch('save');
dispatch('save');
show = false;
loading = false;
};
if (tab === '') {
loading = true;
const res = await addUser(
localStorage.token,
_user.name,
_user.email,
_user.password,
_user.role
).catch((error) => {
toast.error(error);
});
if (res) {
stopLoading();
show = false;
}
} else {
if (inputFiles) {
loading = true;
const file = inputFiles[0];
const reader = new FileReader();
reader.onload = async (e) => {
const csv = e.target.result;
const rows = csv.split('\n');
let userCount = 0;
for (const [idx, row] of rows.entries()) {
const columns = row.split(',').map((col) => col.trim());
console.log(idx, columns);
if (idx > 0) {
if (columns.length === 4 && ['admin', 'user', 'pending'].includes(columns[3])) {
const res = await addUser(
localStorage.token,
columns[0],
columns[1],
columns[2],
columns[3]
).catch((error) => {
toast.error(`Row ${idx + 1}: ${error}`);
return null;
});
if (res) {
userCount = userCount + 1;
}
} else {
toast.error(`Row ${idx + 1}: invalid format.`);
}
}
}
toast.success(`Successfully imported ${userCount} users`);
inputFiles = null;
const uploadInputElement = document.getElementById('upload-user-csv-input');
if (uploadInputElement) {
uploadInputElement.value = null;
}
stopLoading();
};
reader.readAsText(file);
} else {
toast.error(`File not found.`);
}
}
}
};
};
</script>
</script>
...
@@ -204,10 +268,41 @@
...
@@ -204,10 +268,41 @@
<div class="flex justify-end pt-3 text-sm font-medium">
<div class="flex justify-end pt-3 text-sm font-medium">
<button
<button
class=" px-4 py-2 bg-emerald-700 hover:bg-emerald-800 text-gray-100 transition rounded-lg"
class=" px-4 py-2 bg-emerald-700 hover:bg-emerald-800 text-gray-100 transition rounded-lg flex flex-row space-x-1 items-center {loading
? ' cursor-not-allowed'
: ''}"
type="submit"
type="submit"
disabled={loading}
>
>
{$i18n.t('Submit')}
{$i18n.t('Submit')}
{#if loading}
<div class="ml-2 self-center">
<svg
class=" w-4 h-4"
viewBox="0 0 24 24"
fill="currentColor"
xmlns="http://www.w3.org/2000/svg"
><style>
.spinner_ajPY {
transform-origin: center;
animation: spinner_AtaB 0.75s infinite linear;
}
@keyframes spinner_AtaB {
100% {
transform: rotate(360deg);
}
}
</style><path
d="M12,1A11,11,0,1,0,23,12,11,11,0,0,0,12,1Zm0,19a8,8,0,1,1,8-8A8,8,0,0,1,12,20Z"
opacity=".25"
/><path
d="M10.14,1.16a11,11,0,0,0-9,8.92A1.59,1.59,0,0,0,2.46,12,1.52,1.52,0,0,0,4.11,10.7a8,8,0,0,1,6.66-6.61A1.42,1.42,0,0,0,12,2.69h0A1.57,1.57,0,0,0,10.14,1.16Z"
class="spinner_ajPY"
/></svg
>
</div>
{/if}
</button>
</button>
</div>
</div>
</form>
</form>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment