{"id":13583571,"url":"https://github.com/Drewpeifer/medialytics","last_synced_at":"2025-04-06T21:32:26.977Z","repository":{"id":72071830,"uuid":"231921436","full_name":"Drewpeifer/medialytics","owner":"Drewpeifer","description":"A basic, free tool that shows information about Plex Media Server content","archived":false,"fork":false,"pushed_at":"2024-08-01T00:08:45.000Z","size":260,"stargazers_count":97,"open_issues_count":2,"forks_count":8,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-08-02T02:54:57.900Z","etag":null,"topics":["axios","c3js","d3js","data-visualization","plex","plex-server","vue2"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Drewpeifer.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-01-05T13:28:14.000Z","updated_at":"2024-08-01T00:52:52.000Z","dependencies_parsed_at":"2024-04-26T09:28:52.023Z","dependency_job_id":"b16af97c-19eb-48af-9012-16a361df5b3e","html_url":"https://github.com/Drewpeifer/medialytics","commit_stats":null,"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Drewpeifer%2Fmedialytics","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Drewpeifer%2Fmedialytics/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Drewpeifer%2Fmedialytics/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Drewpeifer%2Fmedialytics/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Drewpeifer","download_url":"https://codeload.github.com/Drewpeifer/medialytics/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223264864,"owners_count":17116224,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["axios","c3js","d3js","data-visualization","plex","plex-server","vue2"],"created_at":"2024-08-01T15:03:35.855Z","updated_at":"2024-11-06T00:30:26.855Z","avatar_url":"https://github.com/Drewpeifer.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"# Medialytics 2.3.6\n### A free analytics tool for Plex server content\n\n--------\n# What is Medialytics?\nPlex itself, as well as other tools, generate statistics regarding your server activity (most watched, most active, etc.)\nbut they don't report much on the nature of your media content itself. Medialytics is a small client-side app that\nruns in the browser and generates statistics specifically about the content of your server, e.g. top production studio across a library.\n\n![header](https://i.imgur.com/VVI6mci.png)\n\n![visualizations](https://i.imgur.com/zdtq7LF.png)\n\n![visualizations-2](https://i.imgur.com/idnDNWJ.png)\n\n## Main features\n* Bar + pie charts for genre, country, decade, studio, content rating, resolution*, container* (file type), actor, writer*, and director* analysis\n* Scatter chart of audience rating (TMDB) vs content rating\n* Statistics for size and duration of entire library\n* Statistics for longest (duration), oldest (release date), and earliest / latest additions (to library)\n* Watched/unwatched comparison across entire library and within each chart\n* Detects unmatched library items\n\n_Items marked with \"*\" are only available for Movie libraries_\n\n## How does it work?\n[Plex](http://www.plex.tv) servers generate an XML feed that returns a list of libraries associated with a server, as well\nas the content within each library. Medialytics parses that XML feed and performs calculations on the content to\naggregate and display statistics.\n\nWhen the page loads, a single API call is made to your server to return a list of available libraries.\nAfter selecting an available library, a call will be made to the corresponding endpoint that returns that library's data. **The larger the library, the\nlonger this call may take**. The response is then parsed, stats are aggregated, and (depending on the library type) the UI displays relevant data and charts.\n\n**Please note, currently Medialytics only supports Movie and TV libraries (audio, image, etc. have been excluded) but you may customize the code to your liking.**\n\n## What is it built with?\nVersion 2.0 was rebuilt with [Vue 2](https://v2.vuejs.org/), [Axios](https://axios-http.com/docs/api_intro) for API calls,\nand charts are built with [D3](https://d3js.org/) and [plotly.js](https://plotly.com/javascript/).\n\n# SECURITY WARNING:\nThis application relies upon using the private Plex token of your server, which you do **not** want to share\nwith anyone (a malicious user can leverage it to access your server as an administrator). This is a limitation due to the way Plex leverages the token itself,\nthere is no \"read-only\" option.\n\nI am not liable for any damages or inconvenience caused by the improper sharing of your token, **it is your responsibility to ensure it is never shared with anyone**.\nAdditionally, **you should not host your copy of Medialytics anywhere that is publicly accessible**, as the token itself is sent as part of the API request. Medialytics\nis only recommended for local usage at this time (just drag the html file into your browser, no server needed), but you are welcome to host it securely if you have the knowledge base\nto do so safely (at your own risk).\n\n# Getting Started\nClone the repository to a local directory on your computer, or download the repository as a zip file and extract the contents. Open the contents in a text editor and do the following option:\n\n## Within the Application\n1. At the top of `scripts.js`, set the `serverIp` variable equal to your Plex server's public IP (found in Plex Settings \u003e Remote Access)\n1. At the top of `scripts.js`, set the `serverToken` variable equal to your **PRIVATE** plex token. **Do not share this value with anyone!** If compromised, generate a new one ([instructions on locating and generating a token](https://support.plex.tv/articles/204059436-finding-an-authentication-token-x-plex-token/))\n1. Drag `index.html` into a browser\n1. You should now see your server IP in the \"Targeted Server\" section of the page, and links to any available libraries on that server (Movie and TV only).\n\n## With Docker\n\nThere are 2 ways, you likely want the first set of instructions.\n\n### Simple Installation with Docker Compose\n\nSet up:\n\n1. Copy .env.sample from the repository as .env\n1. Set the `SERVER_IP` variable equal to your Plex server's public IP (found in Plex Settings \u003e Remote Access)\n1. Set the `SERVER_TOKEN` variable equal to your **PRIVATE** plex token. **Do not share this value with anyone!** If compromised, generate a new one ([instructions on locating and generating a token](https://support.plex.tv/articles/204059436-finding-an-authentication-token-x-plex-token/))\n\nThis assumes you followed the instructions and have a `.env` file in the same repo as a `docker-compose.yml` file with the following:\n\n```\nversion: \"3.9\"\nservices:\n  medialytics:\n    image: ghcr.io/drewpeifer/medialytics:latest\n    container_name: medialytics\n    environment:\n      - SERVER_IP=${SERVER_IP}\n      - SERVER_TOKEN=${SERVER_TOKEN}\n    ports:\n      - \"8088:80\"\n```\n\nFinally run with:\n\n1. Run the image\n    ```bash\n    docker compose up -d\n    ```\n1. Go to http://localhost:8088/ You should now see your server IP in the \"Targeted Server\" section of the page, and links to any available libraries on that server (Movie and TV only).\n\n### Run and Build Locally with Docker\n\n1. Copy .env.sample from the repository as .env\n1. Set the `SERVER_IP` variable equal to your Plex server's public IP (found in Plex Settings \u003e Remote Access)\n1. Set the `SERVER_TOKEN` variable equal to your **PRIVATE** plex token. **Do not share this value with anyone!** If compromised, generate a new one ([instructions on locating and generating a token](https://support.plex.tv/articles/204059436-finding-an-authentication-token-x-plex-token/))\n1. Run the image\n    ```bash\n    docker compose up -d\n    ```\n1. Go to http://localhost:8088/ You should now see your server IP in the \"Targeted Server\" section of the page, and links to any available libraries on that server (Movie and TV only).\n\nIf you know HTML/CSS/JS you can edit the code to your liking. All the application logic and parsing is done in `scripts.js`, styling is in `styles.css`, and the page elements are\nin `index.html`.\n\n**Anyone is welcome to fork / contribute / utilize for non-commercial purposes.** Credit for use elsewhere is appreciated but not required.\n\n## Troubleshooting / FAQ\n*Medialytics is not designed for libraries with non-video content (e.g. music, photos, or audiobook functionality is untested). Only Movie and TV libraries will be parsed by default.*\n\nIf your libraries do not automatically load after following the instructions above, you may need to refer to the documentation for [Plex XML interactions](https://support.plex.tv/articles/201638786-plex-media-server-url-commands/). The following steps should help clear up any basic issues:\n\n1. Confirm that you have entered the correct values for your (public) `serverIp` and (very **private**) `serverToken` at the top of the `medialytics/js/scripts.js` file.\n1. Confirm that your public IP (found in Plex web Settings \u003e Remote Access) is correct and resolves in a local browser\n1. Confirm that you are using the correct / most current plex token ([related documentation](https://support.plex.tv/articles/204059436-finding-an-authentication-token-x-plex-token/))\n1. Near the top of `scripts.js`, set the `debugMode` variable equal to `true`. Now return to the browser, refresh the page, and there should be a message saying that debug mode is enabled. Press F12 or ctrl+click to open the developer tools for your browser, and navigate to the console. You should see information printed about your server's available libraries, and if you select a library in the UI more info will be displayed in the console.\n\n### How recent is this data?\nData is retrieved from Plex in real time. When you load the page or select a library, you are making a fresh request to the targeted server each time.\n\n### How accurate is this data?\nThe short answer is that the data is as accurate as the XML feed can provide. The feed returns every title in a library, and so the counts for the library\nas a whole and any \"basic\" attribute that the feed reports for that item should be accurate when cross referenced with your Plex server, such as release date, length, etc. If the value\nfor any tracked data point is left blank or otherwise returns `undefined`, I have chosen to omit that single value from all counts and calculations.\n\n**However**, the XML feed does abbreviate some information that could otherwise generate many results, and instead of returning the full list that is available in Plex\nit only returns the first few items. For example, a movie can have an infinite number of genres added manually by a user, so the XML feed just returns the first two genres in the list\n(not alphabetically, just the first two in the list). This means that a film with Action, Mystery, and Crime genres will only get reported in the XML as being in Action and Mystery.\n\nIn terms of what Medialytics reports on, the only statistics affected by this process are as follows:\n* Directors (first 2)\n* Actors (first 3)\n* Genres (first 2)\n\nThe only other nuance I've encountered is that different \"editions\" of a movie will be counted as separate instances, so `Aliens (1986) {edition-SD}.avi` and\n`Aliens (1986) {edition-4K}.mkv` each count as separate films, with separate (duplicate) metadata. While this may inflate certain statistics if you have many editions\nof the same film, it also allows for accurate tracking of resolution and container (file type) across editions. Ignoring separate editions would create inconsistencies with counts\nin Medialytics vs the Plex UI, so I have chosen to track them this way for now. When comparing numbers between Medialytics and the Plex UI, also consider that Medialytics does not\ncount Collections as library items (and the Plex UI does, if they are visible).\n\n### Why are some charts only available for certain types of libraries?\nThe XML feed does not return the same information for all library types. For example, the feed for a TV library only returns data about shows, so it does not include Director,\nResolution, or Container information since that could be specific to each episode.\n\n### Related documentation\nFor anyone who wishes to fork and modify this repo, here are some links you may find useful:\n\n1. [Plex XML docs](https://support.plex.tv/articles/201638786-plex-media-server-url-commands/) (for retrieving and parsing data)\n1. [Plex token docs](https://support.plex.tv/articles/204059436-finding-an-authentication-token-x-plex-token/) (for token management)\n1. [Vue 2 docs](https://v2.vuejs.org/) (for general app logic and architecture)\n1. [Axios docs](https://axios-http.com/docs/api_intro) (for API calls)\n1. [D3.js](https://d3js.org/) / [plotly.js](https://plotly.com/javascript/) for editing charts\n1. [Guide to Flexbox](https://css-tricks.com/snippets/css/a-guide-to-flexbox/) (for UI editing)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FDrewpeifer%2Fmedialytics","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FDrewpeifer%2Fmedialytics","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FDrewpeifer%2Fmedialytics/lists"}