mirror of
https://github.com/hrfee/jellyfin-accounts.git
synced 2025-01-03 06:50:12 +00:00
Add ability to set default homescreen layout
--get_policy is now --get_defaults, as it now allows you to store a default user configuration and displayPreferences, which define the layout of the home screen. It can also now display non publicly visible accounts.
This commit is contained in:
parent
ac264a4f4b
commit
674636b3a2
19
README.md
19
README.md
@ -65,13 +65,14 @@ optional arguments:
|
|||||||
~/.jf-accounts.
|
~/.jf-accounts.
|
||||||
--host HOST address to host web ui on.
|
--host HOST address to host web ui on.
|
||||||
-p PORT, --port PORT port to host web ui on.
|
-p PORT, --port PORT port to host web ui on.
|
||||||
-g, --get_policy tool to grab a JF users policy (access, perms, etc.)
|
-g, --get_defaults tool to grab a JF users policy (access, perms, etc.)
|
||||||
and output as json to be used as a user template.
|
and homescreen layout and output it as json to be used
|
||||||
|
as a user template.
|
||||||
```
|
```
|
||||||
### Setup
|
### Setup
|
||||||
#### Policy template
|
#### New user template
|
||||||
* You may want to restrict a user from accessing certain libraries (e.g 4K Movies), or display their account on the login screen by default. Jellyfin stores these settings as a user's policy.
|
* You may want to restrict a user from accessing certain libraries (e.g 4K Movies), display their account on the login screen by default, or set a default homecrseen layout. Jellyfin stores these settings in the user's policy, configuration and displayPreferences.
|
||||||
* Make a temporary account and change its settings, then run `jf-accounts --get_policy`. Choose your user, and the policy will be stored at the location you set in `user_template`, and used for all subsequent new accounts.
|
* Make a temporary account and change its settings, then run `jf-accounts --get_defaults`. Choose your user, and this data will be stored at the location you set in `user_template`, `user_configuration` and `user_displayprefs` (or their default locations), and used for all subsequent new accounts.
|
||||||
#### Emails/Password Resets
|
#### Emails/Password Resets
|
||||||
* When someone initiates forget password on Jellyfin, a file named `passwordreset*.json` is created in its configuration directory. This directory is monitored and when created, the program reads the username, expiry time and PIN, puts it into a template and sends it to whatever address is specified in `emails.json`.
|
* When someone initiates forget password on Jellyfin, a file named `passwordreset*.json` is created in its configuration directory. This directory is monitored and when created, the program reads the username, expiry time and PIN, puts it into a template and sends it to whatever address is specified in `emails.json`.
|
||||||
* **The default forget password popup references the `passwordreset*.json` file created. This is confusing for users, so a quick fix is to edit the `MessageForgotPasswordFileCreated` string in Jellyfin's language folder.**
|
* **The default forget password popup references the `passwordreset*.json` file created. This is confusing for users, so a quick fix is to edit the `MessageForgotPasswordFileCreated` string in Jellyfin's language folder.**
|
||||||
@ -196,10 +197,14 @@ password = smtp password
|
|||||||
invites =
|
invites =
|
||||||
; Path to store emails addresses in JSON
|
; Path to store emails addresses in JSON
|
||||||
emails =
|
emails =
|
||||||
; Path to the user policy template. Can be acquired with get-template.
|
; Path to the user policy template. Can be acquired with get-defaults (jf-accounts -g).
|
||||||
user_template =
|
user_template =
|
||||||
|
; Path to the user configuration template (part of homescreen layout). Can be acquired with get-defaults (jf-accounts -g).
|
||||||
|
user_configuration =
|
||||||
|
; Path to the user display preferences template (part of homescreen layout). Can be acquired with get-defaults (jf-accounts -g).
|
||||||
|
user_displayprefs =
|
||||||
; Path to custom bootstrap.css
|
; Path to custom bootstrap.css
|
||||||
custom_css =
|
custom_css =
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
@ -105,8 +105,12 @@ password = smtp password
|
|||||||
invites =
|
invites =
|
||||||
; Path to store emails addresses in JSON
|
; Path to store emails addresses in JSON
|
||||||
emails =
|
emails =
|
||||||
; Path to the user policy template. Can be acquired with get-template.
|
; Path to the user policy template. Can be acquired with get-defaults (jf-accounts -g).
|
||||||
user_template =
|
user_template =
|
||||||
|
; Path to the user configuration template (part of homescreen layout). Can be acquired with get-defaults (jf-accounts -g).
|
||||||
|
user_configuration =
|
||||||
|
; Path to the user display preferences template (part of homescreen layout). Can be acquired with get-defaults (jf-accounts -g).
|
||||||
|
user_displayprefs =
|
||||||
; Path to custom bootstrap.css
|
; Path to custom bootstrap.css
|
||||||
custom_css =
|
custom_css =
|
||||||
|
|
||||||
|
@ -124,7 +124,7 @@ def newUser():
|
|||||||
valid = False
|
valid = False
|
||||||
if valid:
|
if valid:
|
||||||
log.debug('User password valid')
|
log.debug('User password valid')
|
||||||
try:
|
try:
|
||||||
jf.authenticate(config['jellyfin']['username'],
|
jf.authenticate(config['jellyfin']['username'],
|
||||||
config['jellyfin']['password'])
|
config['jellyfin']['password'])
|
||||||
user = jf.newUser(data['username'], data['password'])
|
user = jf.newUser(data['username'], data['password'])
|
||||||
@ -142,7 +142,21 @@ def newUser():
|
|||||||
default_policy = json.load(f)
|
default_policy = json.load(f)
|
||||||
jf.setPolicy(user.json()['Id'], default_policy)
|
jf.setPolicy(user.json()['Id'], default_policy)
|
||||||
except:
|
except:
|
||||||
log.debug('setPolicy failed')
|
log.error('Failed to set new user policy. ' +
|
||||||
|
'Ignore if you didn\'t create a template')
|
||||||
|
try:
|
||||||
|
with open(config['files']['user_configuration'], 'r') as f:
|
||||||
|
default_configuration = json.load(f)
|
||||||
|
with open(config['files']['user_displayprefs'], 'r') as f:
|
||||||
|
default_displayprefs = json.load(f)
|
||||||
|
if jf.setConfiguration(user.json()['Id'],
|
||||||
|
default_configuration):
|
||||||
|
jf.setDisplayPreferences(user.json()['Id'],
|
||||||
|
default_displayprefs)
|
||||||
|
log.debug('Set homescreen layout.')
|
||||||
|
except:
|
||||||
|
log.error('Failed to set new user homescreen kayout.' +
|
||||||
|
'Ignore if you didn\'t create a template')
|
||||||
if config.getboolean('password_resets', 'enabled'):
|
if config.getboolean('password_resets', 'enabled'):
|
||||||
try:
|
try:
|
||||||
with open(config['files']['emails'], 'r') as f:
|
with open(config['files']['emails'], 'r') as f:
|
||||||
|
63
jf-accounts
63
jf-accounts
@ -21,10 +21,11 @@ parser.add_argument("--host",
|
|||||||
help="address to host web ui on.")
|
help="address to host web ui on.")
|
||||||
parser.add_argument("-p", "--port",
|
parser.add_argument("-p", "--port",
|
||||||
help="port to host web ui on.")
|
help="port to host web ui on.")
|
||||||
parser.add_argument("-g", "--get_policy",
|
parser.add_argument("-g", "--get_defaults",
|
||||||
help=("tool to grab a JF users " +
|
help=("tool to grab a JF users " +
|
||||||
"policy (access, perms, etc.) and " +
|
"policy (access, perms, etc.) and " +
|
||||||
"output as json to be used as a user template."),
|
"homescreen layout and " +
|
||||||
|
"output it as json to be used as a user template."),
|
||||||
action='store_true')
|
action='store_true')
|
||||||
|
|
||||||
args, leftovers = parser.parse_known_args()
|
args, leftovers = parser.parse_known_args()
|
||||||
@ -91,6 +92,11 @@ for key in config['files']:
|
|||||||
log.debug(f'Using default {key}')
|
log.debug(f'Using default {key}')
|
||||||
config['files'][key] = str(data_dir / (key + '.json'))
|
config['files'][key] = str(data_dir / (key + '.json'))
|
||||||
|
|
||||||
|
for key in ['user_configuration', 'user_displayprefs']:
|
||||||
|
if key not in config['files']:
|
||||||
|
log.debug(f'Using default {key}')
|
||||||
|
config['files'][key] = str(data_dir / (key + '.json'))
|
||||||
|
|
||||||
|
|
||||||
def default_css():
|
def default_css():
|
||||||
css = {}
|
css = {}
|
||||||
@ -138,7 +144,7 @@ if ('public_server' not in config['jellyfin'] or
|
|||||||
config['jellyfin']['public_server'] == ''):
|
config['jellyfin']['public_server'] == ''):
|
||||||
config['jellyfin']['public_server'] = config['jellyfin']['server']
|
config['jellyfin']['public_server'] = config['jellyfin']['server']
|
||||||
|
|
||||||
if args.get_policy:
|
if args.get_defaults:
|
||||||
import json
|
import json
|
||||||
from jellyfin_accounts.jf_api import Jellyfin
|
from jellyfin_accounts.jf_api import Jellyfin
|
||||||
jf = Jellyfin(config['jellyfin']['server'],
|
jf = Jellyfin(config['jellyfin']['server'],
|
||||||
@ -147,14 +153,37 @@ if args.get_policy:
|
|||||||
config['jellyfin']['device'],
|
config['jellyfin']['device'],
|
||||||
config['jellyfin']['device_id'])
|
config['jellyfin']['device_id'])
|
||||||
# No auth needed.
|
# No auth needed.
|
||||||
print("Make sure the user is publicly visible!")
|
print("""
|
||||||
users = jf.getUsers()
|
This tool lets you grab various settings from a user,
|
||||||
|
so that they can be applied every time a new account is
|
||||||
|
created. """)
|
||||||
|
print("Step 1: User Policy.")
|
||||||
|
print("""
|
||||||
|
A user policy stores a users permissions (e.g access rights and
|
||||||
|
most of the other settings in the 'Profile' and 'Access' tabs
|
||||||
|
of a user). """)
|
||||||
|
success = False
|
||||||
|
msg = "Get public users only or all users? (requires auth) [public/all]: "
|
||||||
|
public = False
|
||||||
|
while not success:
|
||||||
|
choice = input(msg)
|
||||||
|
if choice == 'public':
|
||||||
|
public = True
|
||||||
|
print("Make sure the user is publicly visible!")
|
||||||
|
success = True
|
||||||
|
elif choice == 'all':
|
||||||
|
jf.authenticate(config['jellyfin']['username'],
|
||||||
|
config['jellyfin']['password'])
|
||||||
|
public = False
|
||||||
|
success = True
|
||||||
|
users = jf.getUsers(public=public)
|
||||||
for index, user in enumerate(users):
|
for index, user in enumerate(users):
|
||||||
print(f'{index+1}) {user["Name"]}')
|
print(f'{index+1}) {user["Name"]}')
|
||||||
success = False
|
success = False
|
||||||
while not success:
|
while not success:
|
||||||
try:
|
try:
|
||||||
policy = users[int(input(">: "))-1]['Policy']
|
user_index = int(input(">: "))-1
|
||||||
|
policy = users[user_index]['Policy']
|
||||||
success = True
|
success = True
|
||||||
except (ValueError, IndexError):
|
except (ValueError, IndexError):
|
||||||
pass
|
pass
|
||||||
@ -162,6 +191,28 @@ if args.get_policy:
|
|||||||
f.write(json.dumps(policy, indent=4))
|
f.write(json.dumps(policy, indent=4))
|
||||||
print(f'Policy written to "{config["files"]["user_template"]}".')
|
print(f'Policy written to "{config["files"]["user_template"]}".')
|
||||||
print('In future, this policy will be copied to all new users.')
|
print('In future, this policy will be copied to all new users.')
|
||||||
|
print('Step 2: Homescreen Layout')
|
||||||
|
print("""
|
||||||
|
You may want to customize the default layout of a new user's
|
||||||
|
home screen. These settings can be applied to an account through
|
||||||
|
the 'Home' section in a user's settings. """)
|
||||||
|
success = False
|
||||||
|
while not success:
|
||||||
|
choice = input("Grab the chosen user's homescreen layout? [y/n]: ")
|
||||||
|
if choice.lower() == 'y':
|
||||||
|
user_id = users[user_index]['Id']
|
||||||
|
configuration = users[user_index]['Configuration']
|
||||||
|
display_prefs = jf.getDisplayPreferences(user_id)
|
||||||
|
with open(config['files']['user_configuration'], 'w') as f:
|
||||||
|
f.write(json.dumps(configuration, indent=4))
|
||||||
|
print(f'Configuration written to "{config["files"]["user_configuration"]}".')
|
||||||
|
with open(config['files']['user_displayprefs'], 'w') as f:
|
||||||
|
f.write(json.dumps(display_prefs, indent=4))
|
||||||
|
print(f'Display Prefs written to "{config["files"]["user_displayprefs"]}".')
|
||||||
|
success = True
|
||||||
|
elif choice.lower() == 'n':
|
||||||
|
success = True
|
||||||
|
|
||||||
else:
|
else:
|
||||||
def signal_handler(sig, frame):
|
def signal_handler(sig, frame):
|
||||||
print('Quitting...')
|
print('Quitting...')
|
||||||
|
Loading…
Reference in New Issue
Block a user