Manage Users Bulk Library Change

I’ve been increasingly frustrated by the lack of functionality to manage user (friend) library access in bulk on Plex. I share my library with around 30 friends, and every time I need to add a new library, I’m forced to update each individual user’s profile manually. This process is time-consuming and inefficient. I am not sure why Plex hasn’t added this feature… But I felt like I had waited long enough and wrote a small program just to do that. This runs in Windows but it doesn’t matter where you plex server resides because all that program cares about is the IP address of your server, the token and the port (most likely 32400). Once you connect to plex, you will have a window open with your users and all your libraries, and at that point, all you all to do is click and save… This was writte in Python and obvisouly it leverages the plexapi… Give it a try with just one user to make sure you get the expected outcome. Give me some feedack if you wish… Youc an download the exe here… Don’t worry, it’s virus and adware free, but it’s never a terrible idea to run a virus scan regardless. Enjoy.

Any chance you would be willing to share the source file(s) as well? Or have a link to GitHub if you happen to have it source controlled there. I’m sure your .exe is safe, but it’s nice to see the source, especially on a random executable file. :sweat_smile:

I’d love to use this but it does nothing when I click “Connect”, it just refreshes the page… I’m getting the “token” from https://www.plex.tv/claim/, is that correct? I’ve tried local IP, 127.0.0.1, and the external IP just for giggles. Thanks!

I supposed I can share the code but the exe has some advantages in that it has all the libraries included and you won’t have a need to install them -

from flask import Flask, render_template, request, redirect, url_for, flash
from plexapi.server import PlexServer
import webbrowser

app = Flask(name)
app.secret_key = ‘your_secret_key’

Global variables to store Plex server details

plex_server_address = None
plex_token = None
plex_port = “32400” # Default Plex port
plex = None

Function to connect to the Plex server

def connect_to_plex():
global plex_server_address, plex_token, plex_port, plex
full_plex_url = f"http://{plex_server_address}:{plex_port}"

try:
    print(f"Connecting to Plex at {full_plex_url} with token {plex_token}")
    plex = PlexServer(full_plex_url, plex_token)
    print("Successfully connected to Plex.")
    return plex
except Exception as e:
    print(f"Failed to connect to Plex server: {e}")
    flash(f"Failed to connect to Plex server: {str(e)}", 'error')
    return None

Route for the configuration page

@app.route(‘/’, methods=[‘GET’, ‘POST’])
def config():
global plex_server_address, plex_token, plex_port
if request.method == ‘POST’:
plex_server_address = request.form[‘server_address’]
plex_token = request.form[‘plex_token’]
plex_port = request.form.get(‘port’) or “32400” # Default to 32400 if port is empty or None

    print(f"Server Address: {plex_server_address}")
    print(f"Plex Token: {plex_token}")
    print(f"Plex Port: {plex_port}")

    if not plex_server_address or not plex_token:
        flash('Please fill in both fields', 'error')
        return render_template('config.html')

    if connect_to_plex():
        return redirect(url_for('user_library_list'))
    else:
        return render_template('config.html')

return render_template('config.html')

Route to list users and libraries

@app.route(‘/list’, methods=[‘GET’, ‘POST’])
def user_library_list():
if plex is None:
print(“Plex is None. Redirecting to config.”)
return redirect(url_for(‘config’))

try:
    all_users = plex.myPlexAccount().users()  # Get all Plex users
    users_with_libraries = []  # To store users who have shared libraries
    libraries = plex.library.sections()  # Get all libraries on the server

    for user in all_users:
        # Check if the user has any shared libraries
        shared_libraries = plex.myPlexAccount().resource(user.username).servers[0].sections()
        if shared_libraries:  # If they have at least one shared library, add them to the list
            users_with_libraries.append(user)

    print(f"Filtered Users: {[user.username for user in users_with_libraries]}")
    print(f"Libraries: {[library.title for library in libraries]}")
except Exception as e:
    print(f"Error fetching users or libraries: {e}")
    flash(f"Error fetching users or libraries: {str(e)}", 'error')
    return render_template('list.html', users=[], libraries=[])

if request.method == 'POST':
    try:
        selected_users = request.form.getlist('users')
        selected_libraries = request.form.getlist('libraries')

        print(f"Selected Users: {selected_users}")
        print(f"Selected Libraries: {selected_libraries}")

        if not selected_users or not selected_libraries:
            flash('Please select both users and libraries', 'error')
            return render_template('list.html', users=users_with_libraries, libraries=libraries)

        libraries_to_share = [lib for lib in libraries if lib.title in selected_libraries]

        for username in selected_users:
            for user in users_with_libraries:
                if user.username == username:
                    print(f"Updating library access for {user.username}")
                    plex.myPlexAccount().updateFriend(user, server=plex, sections=libraries_to_share)
                    flash(f"Updated library access for {user.username}", 'success')

        return redirect(url_for('user_library_list'))

    except Exception as e:
        print(f"Error during POST: {e}")
        flash(f"An error occurred: {str(e)}", 'error')
        return render_template('list.html', users=users_with_libraries, libraries=libraries)

return render_template('list.html', users=users_with_libraries, libraries=libraries)

if name == ‘main’:
print(“Starting Flask app…”)
webbrowser.open(‘http://127.0.0.1:5006’) # Automatically opens the browser when the script is run
app.run(host=‘0.0.0.0’, port=5006, debug=True) # Bind to all interfaces and set port 5006

You canuse 127.0.0.1 - you have to use thw actual IP of your server… it would most likely start with 192.168

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.