server/tools: created simple admin command script
This commit is contained in:
parent
9df090b4d9
commit
83442b4977
4 changed files with 90 additions and 81 deletions
|
@ -67,7 +67,19 @@ and Docker Compose (version 1.6.0 or greater) already installed.
|
||||||
|
|
||||||
### Additional Features
|
### Additional Features
|
||||||
|
|
||||||
1. **Using a seperate domain to host static files (image content)**
|
1. **CLI-level administrative tools**
|
||||||
|
|
||||||
|
You can use the included `szuru-admin` script to perform various
|
||||||
|
administrative tasks such as changing or resetting a user password. To
|
||||||
|
run from docker:
|
||||||
|
|
||||||
|
```console
|
||||||
|
user@host:szuru$ docker-compose run api ./szuru-admin --help
|
||||||
|
```
|
||||||
|
|
||||||
|
will give you a breakdown on all available commands.
|
||||||
|
|
||||||
|
2. **Using a seperate domain to host static files (image content)**
|
||||||
|
|
||||||
If you want to host your website on, (`http://example.com/`) but want
|
If you want to host your website on, (`http://example.com/`) but want
|
||||||
to serve the images on a different domain, (`http://static.example.com/`)
|
to serve the images on a different domain, (`http://static.example.com/`)
|
||||||
|
@ -76,7 +88,7 @@ and Docker Compose (version 1.6.0 or greater) already installed.
|
||||||
additional host has access contents to the `/data` volume mounted in the
|
additional host has access contents to the `/data` volume mounted in the
|
||||||
backend.
|
backend.
|
||||||
|
|
||||||
2. **Setting a specific base URI for proxying**
|
3. **Setting a specific base URI for proxying**
|
||||||
|
|
||||||
Some users may wish to access the service at a different base URI, such
|
Some users may wish to access the service at a different base URI, such
|
||||||
as `http://example.com/szuru/`, commonly when sharing multiple HTTP
|
as `http://example.com/szuru/`, commonly when sharing multiple HTTP
|
||||||
|
@ -104,7 +116,7 @@ and Docker Compose (version 1.6.0 or greater) already installed.
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
3. **Preparing for production**
|
4. **Preparing for production**
|
||||||
|
|
||||||
If you plan on using szurubooru in a production setting, you may opt to
|
If you plan on using szurubooru in a production setting, you may opt to
|
||||||
use a reverse proxy for added security and caching capabilities. Start
|
use a reverse proxy for added security and caching capabilities. Start
|
||||||
|
|
|
@ -1,36 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
'''
|
|
||||||
Checks post audio and list disrepancies between the content and flags.
|
|
||||||
'''
|
|
||||||
|
|
||||||
from szurubooru import db, model, errors
|
|
||||||
from szurubooru.func import files, images
|
|
||||||
from szurubooru.func import posts as postfuncs
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
post_list = (db.session
|
|
||||||
.query(model.Post)
|
|
||||||
.filter(model.Post.type == model.Post.TYPE_VIDEO)
|
|
||||||
.order_by(model.Post.post_id)
|
|
||||||
.all())
|
|
||||||
|
|
||||||
for post in post_list:
|
|
||||||
print('Checking post %d ...' % post.post_id, end='\r')
|
|
||||||
content = files.get(postfuncs.get_post_content_path(post))
|
|
||||||
|
|
||||||
has_existing_flag = model.Post.FLAG_SOUND in post.flags
|
|
||||||
try:
|
|
||||||
has_sound_data = images.Image(content).check_for_sound()
|
|
||||||
except errors.ProcessingError:
|
|
||||||
print('Post %d caused an error when checking for sound' % post.post_id)
|
|
||||||
|
|
||||||
if has_sound_data and not has_existing_flag:
|
|
||||||
print('Post %d has sound data but is not flagged' % post.post_id)
|
|
||||||
if not has_sound_data and has_existing_flag:
|
|
||||||
print('Post %d has no sound data but is flagged' % post.post_id)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main()
|
|
|
@ -1,42 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
'''
|
|
||||||
If the automatic email-based password reset is not enabled, system
|
|
||||||
administrators can still manually reset passwords with the help of
|
|
||||||
this script.
|
|
||||||
'''
|
|
||||||
|
|
||||||
from sys import stderr
|
|
||||||
from getpass import getpass
|
|
||||||
from szurubooru import db
|
|
||||||
from szurubooru.func import users as userfuncs
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
username = input('Enter username or email: ')
|
|
||||||
|
|
||||||
try:
|
|
||||||
user = userfuncs.get_user_by_name_or_email(username)
|
|
||||||
except userfuncs.UserNotFoundError as e:
|
|
||||||
print(e, file=stderr)
|
|
||||||
return
|
|
||||||
|
|
||||||
new_password = getpass('Enter new password for \'%s\': ' % user.name)
|
|
||||||
check_password = getpass('Re-enter password: ')
|
|
||||||
|
|
||||||
if check_password != new_password:
|
|
||||||
print('Passwords do not match.', file=stderr)
|
|
||||||
return
|
|
||||||
|
|
||||||
try:
|
|
||||||
userfuncs.update_user_password(user, new_password)
|
|
||||||
except userfuncs.InvalidPasswordError as e:
|
|
||||||
print(e, file=stderr)
|
|
||||||
return
|
|
||||||
|
|
||||||
db.get_session().commit()
|
|
||||||
print('Sucessfully changed password for \'%s\'' % user.name)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main()
|
|
75
server/szuru-admin
Executable file
75
server/szuru-admin
Executable file
|
@ -0,0 +1,75 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
'''
|
||||||
|
Collection of CLI commands for an administrator to use
|
||||||
|
'''
|
||||||
|
|
||||||
|
import logging
|
||||||
|
import time
|
||||||
|
from argparse import ArgumentParser
|
||||||
|
from getpass import getpass
|
||||||
|
from sys import stderr
|
||||||
|
|
||||||
|
from szurubooru import db, errors, model
|
||||||
|
from szurubooru.func import files, images, posts as postfuncs, users as userfuncs
|
||||||
|
|
||||||
|
|
||||||
|
def reset_password(username: str) -> None:
|
||||||
|
user = userfuncs.get_user_by_name_or_email(username)
|
||||||
|
|
||||||
|
new_password = getpass('Enter new password for \'%s\': ' % user.name)
|
||||||
|
check_password = getpass('Re-enter password: ')
|
||||||
|
|
||||||
|
if check_password != new_password:
|
||||||
|
raise errors.ValidationError('Passwords do not match')
|
||||||
|
|
||||||
|
userfuncs.update_user_password(user, new_password)
|
||||||
|
db.get_session().commit()
|
||||||
|
print('Sucessfully changed password for \'%s\'' % user.name)
|
||||||
|
|
||||||
|
|
||||||
|
def check_audio() -> None:
|
||||||
|
post_list = (db.session
|
||||||
|
.query(model.Post)
|
||||||
|
.filter(model.Post.type == model.Post.TYPE_VIDEO)
|
||||||
|
.order_by(model.Post.post_id)
|
||||||
|
.all())
|
||||||
|
|
||||||
|
for post in post_list:
|
||||||
|
print('Checking post %d ...' % post.post_id, end='\r')
|
||||||
|
content = files.get(postfuncs.get_post_content_path(post))
|
||||||
|
|
||||||
|
has_existing_flag = model.Post.FLAG_SOUND in post.flags
|
||||||
|
try:
|
||||||
|
has_sound_data = images.Image(content).check_for_sound()
|
||||||
|
except errors.ProcessingError:
|
||||||
|
print('Post %d caused an error when checking for sound' % post.post_id)
|
||||||
|
|
||||||
|
if has_sound_data and not has_existing_flag:
|
||||||
|
print('Post %d has sound data but is not flagged' % post.post_id)
|
||||||
|
if not has_sound_data and has_existing_flag:
|
||||||
|
print('Post %d has no sound data but is flagged' % post.post_id)
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> None:
|
||||||
|
parser_top = ArgumentParser(
|
||||||
|
description='Collection of CLI commands for an administrator to use',
|
||||||
|
epilog='Look at README.md for more info')
|
||||||
|
parser = parser_top.add_mutually_exclusive_group(required=True)
|
||||||
|
parser.add_argument('--change-password', metavar='<username>',
|
||||||
|
help='change the password of specified user')
|
||||||
|
parser.add_argument('--check-all-audio', action='store_true',
|
||||||
|
help='check the audio flags of all posts, noting discrepancies, without modifying posts')
|
||||||
|
command = parser_top.parse_args()
|
||||||
|
|
||||||
|
try:
|
||||||
|
if command.change_password:
|
||||||
|
reset_password(command.change_password)
|
||||||
|
elif command.check_all_audio:
|
||||||
|
check_audio()
|
||||||
|
except errors.BaseError as e:
|
||||||
|
print(e, file=stderr)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
Loading…
Reference in a new issue