summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/INSTALL.md18
-rwxr-xr-xserver/recheck-post-audio36
-rwxr-xr-xserver/reset-password42
-rwxr-xr-xserver/szuru-admin75
4 files changed, 90 insertions, 81 deletions
diff --git a/doc/INSTALL.md b/doc/INSTALL.md
index 901ae62..447b9f5 100644
--- a/doc/INSTALL.md
+++ b/doc/INSTALL.md
@@ -67,7 +67,19 @@ and Docker Compose (version 1.6.0 or greater) already installed.
### 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
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
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
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
use a reverse proxy for added security and caching capabilities. Start
diff --git a/server/recheck-post-audio b/server/recheck-post-audio
deleted file mode 100755
index 8e5dfb2..0000000
--- a/server/recheck-post-audio
+++ /dev/null
@@ -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()
diff --git a/server/reset-password b/server/reset-password
deleted file mode 100755
index fb4cb35..0000000
--- a/server/reset-password
+++ /dev/null
@@ -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()
diff --git a/server/szuru-admin b/server/szuru-admin
new file mode 100755
index 0000000..5fe54c1
--- /dev/null
+++ b/server/szuru-admin
@@ -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()