mirror of
				https://github.com/hrfee/jellyfin-accounts.git
				synced 2025-11-03 19:49:35 +00:00 
			
		
		
		
	Added new user defaults setting to web ui
What previously had to be done through 'jf-accounts -g' can now be done in the settings menu on the web ui.
This commit is contained in:
		
							parent
							
								
									4041194d72
								
							
						
					
					
						commit
						39a27eb762
					
				@ -241,6 +241,115 @@ $("form#loginForm").submit(function() {
 | 
				
			|||||||
    });
 | 
					    });
 | 
				
			||||||
    return false;
 | 
					    return false;
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					document.getElementById('openSettings').onclick = function () {
 | 
				
			||||||
 | 
					    $('#settingsMenu').modal('show');
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					document.getElementById('openDefaultsWizard').onclick = function () {
 | 
				
			||||||
 | 
					    this.disabled = true;
 | 
				
			||||||
 | 
					    this.innerHTML =
 | 
				
			||||||
 | 
					        '<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true" style="margin-right: 0.5rem;"></span>' +
 | 
				
			||||||
 | 
					        'Loading...';
 | 
				
			||||||
 | 
					    $.ajax('getUsers', {
 | 
				
			||||||
 | 
					        type : 'GET',
 | 
				
			||||||
 | 
					        dataType : 'json',
 | 
				
			||||||
 | 
					        contentType : 'json',
 | 
				
			||||||
 | 
					        xhrFields : {
 | 
				
			||||||
 | 
					            withCredentials: true
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        beforeSend : function (xhr) {
 | 
				
			||||||
 | 
					            xhr.setRequestHeader("Authorization", "Basic " + btoa(window.token + ":"));
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        complete : function(data) {
 | 
				
			||||||
 | 
					            if (data['status'] == 200) {
 | 
				
			||||||
 | 
					                var radioList = document.getElementById('defaultUserRadios');
 | 
				
			||||||
 | 
					                radioList.textContent = '';
 | 
				
			||||||
 | 
					                if (document.getElementById('setDefaultUser')) {
 | 
				
			||||||
 | 
					                    document.getElementById('setDefaultUser').remove();
 | 
				
			||||||
 | 
					                };
 | 
				
			||||||
 | 
					                var users = data['responseJSON']['users'];
 | 
				
			||||||
 | 
					                for (var i = 0; i < users.length; i++) {
 | 
				
			||||||
 | 
					                    var user = users[i]
 | 
				
			||||||
 | 
					                    var radio = document.createElement('div');
 | 
				
			||||||
 | 
					                    radio.classList.add('radio');
 | 
				
			||||||
 | 
					                    if (i == 0) {
 | 
				
			||||||
 | 
					                        var checked = 'checked';
 | 
				
			||||||
 | 
					                    } else {
 | 
				
			||||||
 | 
					                        var checked = '';
 | 
				
			||||||
 | 
					                    };
 | 
				
			||||||
 | 
					                    radio.innerHTML =
 | 
				
			||||||
 | 
					                        '<label><input type="radio" name="defaultRadios" id="default_' +
 | 
				
			||||||
 | 
					                        user['name'] + '" style="margin-right: 1rem;"' + checked + '>' +
 | 
				
			||||||
 | 
					                        user['name'] + '</label>';
 | 
				
			||||||
 | 
					                    radioList.appendChild(radio);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                var button = document.getElementById('openDefaultsWizard');
 | 
				
			||||||
 | 
					                button.disabled = false;
 | 
				
			||||||
 | 
					                button.innerHTML = 'Set new account defaults';
 | 
				
			||||||
 | 
					                var submitButton = document.getElementById('storeDefaults');
 | 
				
			||||||
 | 
					                submitButton.disabled = false;
 | 
				
			||||||
 | 
					                submitButton.textContent = 'Submit';
 | 
				
			||||||
 | 
					                if (submitButton.classList.contains('btn-success')) {
 | 
				
			||||||
 | 
					                    submitButton.classList.remove('btn-success');
 | 
				
			||||||
 | 
					                    submitButton.classList.add('btn-primary');
 | 
				
			||||||
 | 
					                } else if (submitButton.classList.contains('btn-danger')) {
 | 
				
			||||||
 | 
					                    submitButton.classList.remove('btn-danger');
 | 
				
			||||||
 | 
					                    submitButton.classList.add('btn-primary');
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                $('#userDefaults').modal('show');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					document.getElementById('storeDefaults').onclick = function () {
 | 
				
			||||||
 | 
					    this.disabled = true;
 | 
				
			||||||
 | 
					    this.innerHTML =
 | 
				
			||||||
 | 
					        '<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true" style="margin-right: 0.5rem;"></span>' +
 | 
				
			||||||
 | 
					        'Loading...';
 | 
				
			||||||
 | 
					    var button = document.getElementById('storeDefaults');
 | 
				
			||||||
 | 
					    var radios = document.getElementsByName('defaultRadios');
 | 
				
			||||||
 | 
					    for (var i = 0; i < radios.length; i++) {
 | 
				
			||||||
 | 
					        if (radios[i].checked) {
 | 
				
			||||||
 | 
					            var data = {'username':radios[i].id.slice(8), 'homescreen':false};
 | 
				
			||||||
 | 
					            if (document.getElementById('storeDefaultHomescreen').checked) {
 | 
				
			||||||
 | 
					                data['homescreen'] = true;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            $.ajax('/setDefaults', {
 | 
				
			||||||
 | 
					                data : JSON.stringify(data),
 | 
				
			||||||
 | 
					                contentType : 'application/json',
 | 
				
			||||||
 | 
					                type : 'POST',
 | 
				
			||||||
 | 
					                xhrFields : {
 | 
				
			||||||
 | 
					                    withCredentials: true
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                beforeSend : function (xhr) {
 | 
				
			||||||
 | 
					                    xhr.setRequestHeader("Authorization", "Basic " + btoa(window.token + ":"));
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                success: function() {
 | 
				
			||||||
 | 
					                    button.textContent = 'Success';
 | 
				
			||||||
 | 
					                    if (button.classList.contains('btn-danger')) {
 | 
				
			||||||
 | 
					                        button.classList.remove('btn-danger');
 | 
				
			||||||
 | 
					                    } else if (button.classList.contains('btn-primary')) {
 | 
				
			||||||
 | 
					                        button.classList.remove('btn-primary');
 | 
				
			||||||
 | 
					                    };
 | 
				
			||||||
 | 
					                    button.classList.add('btn-success');
 | 
				
			||||||
 | 
					                    button.disabled = false;
 | 
				
			||||||
 | 
					                    setTimeout(function(){$('#userDefaults').modal('hide');}, 1000);
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                error: function() {
 | 
				
			||||||
 | 
					                    button.textContent = 'Failed';
 | 
				
			||||||
 | 
					                    button.classList.remove('btn-primary');
 | 
				
			||||||
 | 
					                    button.classList.add('btn-danger');
 | 
				
			||||||
 | 
					                    setTimeout(function(){
 | 
				
			||||||
 | 
					                        var button = document.getElementById('storeDefaults');
 | 
				
			||||||
 | 
					                        button.textContent = 'Submit';
 | 
				
			||||||
 | 
					                        button.classList.remove('btn-danger');
 | 
				
			||||||
 | 
					                        button.classList.add('btn-primary');
 | 
				
			||||||
 | 
					                        button.disabled = false;
 | 
				
			||||||
 | 
					                    }, 1000);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
document.getElementById('openUsers').onclick = function () {
 | 
					document.getElementById('openUsers').onclick = function () {
 | 
				
			||||||
    this.disabled = true;
 | 
					    this.disabled = true;
 | 
				
			||||||
    this.innerHTML =
 | 
					    this.innerHTML =
 | 
				
			||||||
@ -262,7 +371,7 @@ document.getElementById('openUsers').onclick = function () {
 | 
				
			|||||||
                var list = document.getElementById('userList');
 | 
					                var list = document.getElementById('userList');
 | 
				
			||||||
                list.textContent = '';
 | 
					                list.textContent = '';
 | 
				
			||||||
                if (document.getElementById('saveUsers')) {
 | 
					                if (document.getElementById('saveUsers')) {
 | 
				
			||||||
                    document.getElementById('saveUsers').remove()
 | 
					                    document.getElementById('saveUsers').remove();
 | 
				
			||||||
                };
 | 
					                };
 | 
				
			||||||
                var users = data['responseJSON']['users'];
 | 
					                var users = data['responseJSON']['users'];
 | 
				
			||||||
                for (var i = 0; i < users.length; i++) {
 | 
					                for (var i = 0; i < users.length; i++) {
 | 
				
			||||||
 | 
				
			|||||||
@ -82,6 +82,35 @@
 | 
				
			|||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
 | 
					        <div class="modal fade" id="settingsMenu" tabindex="-1" role="dialog" aria-labelledby="settings menu" aria-hidden="true">
 | 
				
			||||||
 | 
					            <div class="modal-dialog modal-dialog-centered" role="document">
 | 
				
			||||||
 | 
					                <div class="modal-content">
 | 
				
			||||||
 | 
					                    <div class="modal-header">
 | 
				
			||||||
 | 
					                        <h5 class="modal-title" id="settingsTitle">Settings</h5>
 | 
				
			||||||
 | 
					                        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
 | 
				
			||||||
 | 
					                            <span aria-hidden="true">×</span>
 | 
				
			||||||
 | 
					                        </button>
 | 
				
			||||||
 | 
					                    </div>
 | 
				
			||||||
 | 
					                    <div class="modal-body">
 | 
				
			||||||
 | 
					                        <ul class="list-group list-group-flush">
 | 
				
			||||||
 | 
					                            <li class="list-group-item">
 | 
				
			||||||
 | 
					                                <button type="button" class="btn btn-secondary" id="openUsers">
 | 
				
			||||||
 | 
					                                Users <i class="fa fa-user"></i>
 | 
				
			||||||
 | 
					                                </button>
 | 
				
			||||||
 | 
					                            </li>
 | 
				
			||||||
 | 
					                            <li class="list-group-item">
 | 
				
			||||||
 | 
					                                <button type="button" class="btn btn-secondary" id="openDefaultsWizard">
 | 
				
			||||||
 | 
					                                New account defaults
 | 
				
			||||||
 | 
					                                </button>
 | 
				
			||||||
 | 
					                            </li>
 | 
				
			||||||
 | 
					                        </ul>
 | 
				
			||||||
 | 
					                    </div>
 | 
				
			||||||
 | 
					                    <div class="modal-footer" id="settingsFooter">
 | 
				
			||||||
 | 
					                        <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
 | 
				
			||||||
 | 
					                    </div>
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
        <div class="modal fade" id="users" tabindex="-1" role="dialog" aria-labelledby="users" aria-hidden="true">
 | 
					        <div class="modal fade" id="users" tabindex="-1" role="dialog" aria-labelledby="users" aria-hidden="true">
 | 
				
			||||||
            <div class="modal-dialog modal-dialog-centered" role="document">
 | 
					            <div class="modal-dialog modal-dialog-centered" role="document">
 | 
				
			||||||
                <div class="modal-content">
 | 
					                <div class="modal-content">
 | 
				
			||||||
@ -101,12 +130,35 @@
 | 
				
			|||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
 | 
					        <div class="modal fade" id="userDefaults" tabindex="-1" role="dialog" aria-labelledby="users" aria-hidden="true">
 | 
				
			||||||
 | 
					            <div class="modal-dialog modal-dialog-centered" role="document">
 | 
				
			||||||
 | 
					                <div class="modal-content">
 | 
				
			||||||
 | 
					                    <div class="modal-header">
 | 
				
			||||||
 | 
					                        <h5 class="modal-title" id="defaultsTitle">New user defaults</h5>
 | 
				
			||||||
 | 
					                        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
 | 
				
			||||||
 | 
					                            <span aria-hidden="true">×</span>
 | 
				
			||||||
 | 
					                        </button>
 | 
				
			||||||
 | 
					                    </div>
 | 
				
			||||||
 | 
					                    <div class="modal-body">
 | 
				
			||||||
 | 
					                        <p>Create an account and configure it to your liking, then choose it from below to store the settings as a template for all new users.</p>
 | 
				
			||||||
 | 
					                        <div id="defaultUserRadios"></div>
 | 
				
			||||||
 | 
					                        <div class="checkbox">
 | 
				
			||||||
 | 
					                            <label><input type="checkbox" value="" style="margin-right: 1rem;" id="storeDefaultHomescreen" checked>Store homescreen layout</label>
 | 
				
			||||||
 | 
					                        </div>
 | 
				
			||||||
 | 
					                    </div>
 | 
				
			||||||
 | 
					                    <div class="modal-footer" id="defaultsFooter">
 | 
				
			||||||
 | 
					                        <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
 | 
				
			||||||
 | 
					                        <button type="button" class="btn btn-primary" id="storeDefaults">Submit</button>
 | 
				
			||||||
 | 
					                    </div>
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
        <div class="pageContainer">
 | 
					        <div class="pageContainer">
 | 
				
			||||||
            <h1>
 | 
					            <h1>
 | 
				
			||||||
                Accounts admin
 | 
					                Accounts admin
 | 
				
			||||||
            </h1>
 | 
					            </h1>
 | 
				
			||||||
            <button type="button" class="btn btn-secondary" id="openUsers">
 | 
					            <button type="button" class="btn btn-secondary" id="openSettings">
 | 
				
			||||||
                Users <i class="fa fa-user"></i>
 | 
					                Settings <i class="fa fa-cog"></i>
 | 
				
			||||||
            </button>
 | 
					            </button>
 | 
				
			||||||
            <div class="card bg-light mb-3 linkGroup">
 | 
					            <div class="card bg-light mb-3 linkGroup">
 | 
				
			||||||
                <div class="card-header">Current Invites</div>
 | 
					                <div class="card-header">Current Invites</div>
 | 
				
			||||||
 | 
				
			|||||||
@ -315,6 +315,42 @@ def modifyUsers():
 | 
				
			|||||||
            f.write(json.dumps(emails, indent=4))
 | 
					            f.write(json.dumps(emails, indent=4))
 | 
				
			||||||
        return resp()
 | 
					        return resp()
 | 
				
			||||||
    except:
 | 
					    except:
 | 
				
			||||||
 | 
					        log.error('Could not store email')
 | 
				
			||||||
        return resp(success=False)
 | 
					        return resp(success=False)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@app.route('/setDefaults', methods=['POST'])
 | 
				
			||||||
 | 
					@auth.login_required
 | 
				
			||||||
 | 
					def setDefaults():
 | 
				
			||||||
 | 
					    data = request.get_json()
 | 
				
			||||||
 | 
					    username = data['username']
 | 
				
			||||||
 | 
					    log.debug(f'storing default settings from user {username}')
 | 
				
			||||||
 | 
					    jf.authenticate(config['jellyfin']['username'],
 | 
				
			||||||
 | 
					                    config['jellyfin']['password'])
 | 
				
			||||||
 | 
					    try:
 | 
				
			||||||
 | 
					        user = jf.getUsers(username=username,
 | 
				
			||||||
 | 
					                           public=False)
 | 
				
			||||||
 | 
					    except Jellyfin.UserNotFoundError:
 | 
				
			||||||
 | 
					        log.error(f'couldn\'t find user {username}')
 | 
				
			||||||
 | 
					        return resp(success=False)
 | 
				
			||||||
 | 
					    uid = user['Id']
 | 
				
			||||||
 | 
					    policy = user['Policy']
 | 
				
			||||||
 | 
					    try:
 | 
				
			||||||
 | 
					        with open(config['files']['user_template'], 'w') as f:
 | 
				
			||||||
 | 
					            f.write(json.dumps(policy, indent=4))
 | 
				
			||||||
 | 
					    except:
 | 
				
			||||||
 | 
					        log.error('Could not store user template')
 | 
				
			||||||
 | 
					        return resp(success=False)
 | 
				
			||||||
 | 
					    if data['homescreen']:
 | 
				
			||||||
 | 
					        configuration = user['Configuration']
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            display_prefs = jf.getDisplayPreferences(uid)
 | 
				
			||||||
 | 
					            with open(config['files']['user_configuration'], 'w') as f:
 | 
				
			||||||
 | 
					                f.write(json.dumps(configuration, indent=4))
 | 
				
			||||||
 | 
					            with open(config['files']['user_displayprefs'], 'w') as f:
 | 
				
			||||||
 | 
					                f.write(json.dumps(display_prefs, indent=4))
 | 
				
			||||||
 | 
					        except:
 | 
				
			||||||
 | 
					            log.error('Could not store homescreen layout')
 | 
				
			||||||
 | 
					    return resp()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import jellyfin_accounts.setup
 | 
					import jellyfin_accounts.setup
 | 
				
			||||||
 | 
				
			|||||||
@ -152,7 +152,7 @@ if args.get_defaults:
 | 
				
			|||||||
              config['jellyfin']['version'],
 | 
					              config['jellyfin']['version'],
 | 
				
			||||||
              config['jellyfin']['device'],
 | 
					              config['jellyfin']['device'],
 | 
				
			||||||
              config['jellyfin']['device_id'])
 | 
					              config['jellyfin']['device_id'])
 | 
				
			||||||
    # No auth needed.
 | 
					    print("NOTE: This can now be done through the web ui.")
 | 
				
			||||||
    print(""" 
 | 
					    print(""" 
 | 
				
			||||||
    This tool lets you grab various settings from a user,
 | 
					    This tool lets you grab various settings from a user,
 | 
				
			||||||
    so that they can be applied every time a new account is
 | 
					    so that they can be applied every time a new account is
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user