├── PlexPlaylistImport ├── Assets │ ├── plex.png │ ├── icons8-help-32.png │ ├── play-x-trans.png │ ├── Plex_vector_logo.png │ ├── StoreLogo.backup.png │ ├── LargeTile.scale-100.png │ ├── LargeTile.scale-125.png │ ├── LargeTile.scale-150.png │ ├── LargeTile.scale-200.png │ ├── LargeTile.scale-400.png │ ├── SmallTile.scale-100.png │ ├── SmallTile.scale-125.png │ ├── SmallTile.scale-150.png │ ├── SmallTile.scale-200.png │ ├── SmallTile.scale-400.png │ ├── StoreLogo.scale-100.png │ ├── StoreLogo.scale-125.png │ ├── StoreLogo.scale-150.png │ ├── StoreLogo.scale-200.png │ ├── StoreLogo.scale-400.png │ ├── LockScreenLogo.scale-200.png │ ├── SplashScreen.scale-100.png │ ├── SplashScreen.scale-125.png │ ├── SplashScreen.scale-150.png │ ├── SplashScreen.scale-200.png │ ├── SplashScreen.scale-400.png │ ├── Square44x44Logo.scale-100.png │ ├── Square44x44Logo.scale-125.png │ ├── Square44x44Logo.scale-150.png │ ├── Square44x44Logo.scale-200.png │ ├── Square44x44Logo.scale-400.png │ ├── Wide310x150Logo.scale-100.png │ ├── Wide310x150Logo.scale-125.png │ ├── Wide310x150Logo.scale-150.png │ ├── Wide310x150Logo.scale-200.png │ ├── Wide310x150Logo.scale-400.png │ ├── Square150x150Logo.scale-100.png │ ├── Square150x150Logo.scale-125.png │ ├── Square150x150Logo.scale-150.png │ ├── Square150x150Logo.scale-200.png │ ├── Square150x150Logo.scale-400.png │ ├── Square44x44Logo.targetsize-16.png │ ├── Square44x44Logo.targetsize-24.png │ ├── Square44x44Logo.targetsize-32.png │ ├── Square44x44Logo.targetsize-48.png │ ├── Square44x44Logo.targetsize-256.png │ ├── Square44x44Logo.altform-unplated_targetsize-16.png │ ├── Square44x44Logo.altform-unplated_targetsize-32.png │ ├── Square44x44Logo.altform-unplated_targetsize-48.png │ ├── Square44x44Logo.targetsize-24_altform-unplated.png │ ├── Square44x44Logo.altform-unplated_targetsize-256.png │ ├── Square44x44Logo.altform-lightunplated_targetsize-16.png │ ├── Square44x44Logo.altform-lightunplated_targetsize-24.png │ ├── Square44x44Logo.altform-lightunplated_targetsize-32.png │ ├── Square44x44Logo.altform-lightunplated_targetsize-48.png │ ├── Square44x44Logo.altform-lightunplated_targetsize-256.png │ └── plex-logo.svg ├── App.xaml ├── FormModel.cs ├── PlexPlaylistImport.csproj.user ├── Properties │ ├── AssemblyInfo.cs │ └── Default.rd.xml ├── Logger.cs ├── Package.appxmanifest ├── App.xaml.cs ├── MainPage.xaml ├── MainPage.xaml.cs └── PlexPlaylistImport.csproj ├── .gitignore ├── README.md ├── PLEX.sln └── LICENSE /PlexPlaylistImport/Assets/plex.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregchak/plex-playlist-import/HEAD/PlexPlaylistImport/Assets/plex.png -------------------------------------------------------------------------------- /PlexPlaylistImport/Assets/icons8-help-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregchak/plex-playlist-import/HEAD/PlexPlaylistImport/Assets/icons8-help-32.png -------------------------------------------------------------------------------- /PlexPlaylistImport/Assets/play-x-trans.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregchak/plex-playlist-import/HEAD/PlexPlaylistImport/Assets/play-x-trans.png -------------------------------------------------------------------------------- /PlexPlaylistImport/Assets/Plex_vector_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregchak/plex-playlist-import/HEAD/PlexPlaylistImport/Assets/Plex_vector_logo.png -------------------------------------------------------------------------------- /PlexPlaylistImport/Assets/StoreLogo.backup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregchak/plex-playlist-import/HEAD/PlexPlaylistImport/Assets/StoreLogo.backup.png -------------------------------------------------------------------------------- /PlexPlaylistImport/Assets/LargeTile.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregchak/plex-playlist-import/HEAD/PlexPlaylistImport/Assets/LargeTile.scale-100.png -------------------------------------------------------------------------------- /PlexPlaylistImport/Assets/LargeTile.scale-125.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregchak/plex-playlist-import/HEAD/PlexPlaylistImport/Assets/LargeTile.scale-125.png -------------------------------------------------------------------------------- /PlexPlaylistImport/Assets/LargeTile.scale-150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregchak/plex-playlist-import/HEAD/PlexPlaylistImport/Assets/LargeTile.scale-150.png -------------------------------------------------------------------------------- /PlexPlaylistImport/Assets/LargeTile.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregchak/plex-playlist-import/HEAD/PlexPlaylistImport/Assets/LargeTile.scale-200.png -------------------------------------------------------------------------------- /PlexPlaylistImport/Assets/LargeTile.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregchak/plex-playlist-import/HEAD/PlexPlaylistImport/Assets/LargeTile.scale-400.png -------------------------------------------------------------------------------- /PlexPlaylistImport/Assets/SmallTile.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregchak/plex-playlist-import/HEAD/PlexPlaylistImport/Assets/SmallTile.scale-100.png -------------------------------------------------------------------------------- /PlexPlaylistImport/Assets/SmallTile.scale-125.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregchak/plex-playlist-import/HEAD/PlexPlaylistImport/Assets/SmallTile.scale-125.png -------------------------------------------------------------------------------- /PlexPlaylistImport/Assets/SmallTile.scale-150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregchak/plex-playlist-import/HEAD/PlexPlaylistImport/Assets/SmallTile.scale-150.png -------------------------------------------------------------------------------- /PlexPlaylistImport/Assets/SmallTile.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregchak/plex-playlist-import/HEAD/PlexPlaylistImport/Assets/SmallTile.scale-200.png -------------------------------------------------------------------------------- /PlexPlaylistImport/Assets/SmallTile.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregchak/plex-playlist-import/HEAD/PlexPlaylistImport/Assets/SmallTile.scale-400.png -------------------------------------------------------------------------------- /PlexPlaylistImport/Assets/StoreLogo.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregchak/plex-playlist-import/HEAD/PlexPlaylistImport/Assets/StoreLogo.scale-100.png -------------------------------------------------------------------------------- /PlexPlaylistImport/Assets/StoreLogo.scale-125.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregchak/plex-playlist-import/HEAD/PlexPlaylistImport/Assets/StoreLogo.scale-125.png -------------------------------------------------------------------------------- /PlexPlaylistImport/Assets/StoreLogo.scale-150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregchak/plex-playlist-import/HEAD/PlexPlaylistImport/Assets/StoreLogo.scale-150.png -------------------------------------------------------------------------------- /PlexPlaylistImport/Assets/StoreLogo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregchak/plex-playlist-import/HEAD/PlexPlaylistImport/Assets/StoreLogo.scale-200.png -------------------------------------------------------------------------------- /PlexPlaylistImport/Assets/StoreLogo.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregchak/plex-playlist-import/HEAD/PlexPlaylistImport/Assets/StoreLogo.scale-400.png -------------------------------------------------------------------------------- /PlexPlaylistImport/Assets/LockScreenLogo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregchak/plex-playlist-import/HEAD/PlexPlaylistImport/Assets/LockScreenLogo.scale-200.png -------------------------------------------------------------------------------- /PlexPlaylistImport/Assets/SplashScreen.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregchak/plex-playlist-import/HEAD/PlexPlaylistImport/Assets/SplashScreen.scale-100.png -------------------------------------------------------------------------------- /PlexPlaylistImport/Assets/SplashScreen.scale-125.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregchak/plex-playlist-import/HEAD/PlexPlaylistImport/Assets/SplashScreen.scale-125.png -------------------------------------------------------------------------------- /PlexPlaylistImport/Assets/SplashScreen.scale-150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregchak/plex-playlist-import/HEAD/PlexPlaylistImport/Assets/SplashScreen.scale-150.png -------------------------------------------------------------------------------- /PlexPlaylistImport/Assets/SplashScreen.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregchak/plex-playlist-import/HEAD/PlexPlaylistImport/Assets/SplashScreen.scale-200.png -------------------------------------------------------------------------------- /PlexPlaylistImport/Assets/SplashScreen.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregchak/plex-playlist-import/HEAD/PlexPlaylistImport/Assets/SplashScreen.scale-400.png -------------------------------------------------------------------------------- /PlexPlaylistImport/Assets/Square44x44Logo.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregchak/plex-playlist-import/HEAD/PlexPlaylistImport/Assets/Square44x44Logo.scale-100.png -------------------------------------------------------------------------------- /PlexPlaylistImport/Assets/Square44x44Logo.scale-125.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregchak/plex-playlist-import/HEAD/PlexPlaylistImport/Assets/Square44x44Logo.scale-125.png -------------------------------------------------------------------------------- /PlexPlaylistImport/Assets/Square44x44Logo.scale-150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregchak/plex-playlist-import/HEAD/PlexPlaylistImport/Assets/Square44x44Logo.scale-150.png -------------------------------------------------------------------------------- /PlexPlaylistImport/Assets/Square44x44Logo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregchak/plex-playlist-import/HEAD/PlexPlaylistImport/Assets/Square44x44Logo.scale-200.png -------------------------------------------------------------------------------- /PlexPlaylistImport/Assets/Square44x44Logo.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregchak/plex-playlist-import/HEAD/PlexPlaylistImport/Assets/Square44x44Logo.scale-400.png -------------------------------------------------------------------------------- /PlexPlaylistImport/Assets/Wide310x150Logo.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregchak/plex-playlist-import/HEAD/PlexPlaylistImport/Assets/Wide310x150Logo.scale-100.png -------------------------------------------------------------------------------- /PlexPlaylistImport/Assets/Wide310x150Logo.scale-125.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregchak/plex-playlist-import/HEAD/PlexPlaylistImport/Assets/Wide310x150Logo.scale-125.png -------------------------------------------------------------------------------- /PlexPlaylistImport/Assets/Wide310x150Logo.scale-150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregchak/plex-playlist-import/HEAD/PlexPlaylistImport/Assets/Wide310x150Logo.scale-150.png -------------------------------------------------------------------------------- /PlexPlaylistImport/Assets/Wide310x150Logo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregchak/plex-playlist-import/HEAD/PlexPlaylistImport/Assets/Wide310x150Logo.scale-200.png -------------------------------------------------------------------------------- /PlexPlaylistImport/Assets/Wide310x150Logo.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregchak/plex-playlist-import/HEAD/PlexPlaylistImport/Assets/Wide310x150Logo.scale-400.png -------------------------------------------------------------------------------- /PlexPlaylistImport/Assets/Square150x150Logo.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregchak/plex-playlist-import/HEAD/PlexPlaylistImport/Assets/Square150x150Logo.scale-100.png -------------------------------------------------------------------------------- /PlexPlaylistImport/Assets/Square150x150Logo.scale-125.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregchak/plex-playlist-import/HEAD/PlexPlaylistImport/Assets/Square150x150Logo.scale-125.png -------------------------------------------------------------------------------- /PlexPlaylistImport/Assets/Square150x150Logo.scale-150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregchak/plex-playlist-import/HEAD/PlexPlaylistImport/Assets/Square150x150Logo.scale-150.png -------------------------------------------------------------------------------- /PlexPlaylistImport/Assets/Square150x150Logo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregchak/plex-playlist-import/HEAD/PlexPlaylistImport/Assets/Square150x150Logo.scale-200.png -------------------------------------------------------------------------------- /PlexPlaylistImport/Assets/Square150x150Logo.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregchak/plex-playlist-import/HEAD/PlexPlaylistImport/Assets/Square150x150Logo.scale-400.png -------------------------------------------------------------------------------- /PlexPlaylistImport/Assets/Square44x44Logo.targetsize-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregchak/plex-playlist-import/HEAD/PlexPlaylistImport/Assets/Square44x44Logo.targetsize-16.png -------------------------------------------------------------------------------- /PlexPlaylistImport/Assets/Square44x44Logo.targetsize-24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregchak/plex-playlist-import/HEAD/PlexPlaylistImport/Assets/Square44x44Logo.targetsize-24.png -------------------------------------------------------------------------------- /PlexPlaylistImport/Assets/Square44x44Logo.targetsize-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregchak/plex-playlist-import/HEAD/PlexPlaylistImport/Assets/Square44x44Logo.targetsize-32.png -------------------------------------------------------------------------------- /PlexPlaylistImport/Assets/Square44x44Logo.targetsize-48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregchak/plex-playlist-import/HEAD/PlexPlaylistImport/Assets/Square44x44Logo.targetsize-48.png -------------------------------------------------------------------------------- /PlexPlaylistImport/Assets/Square44x44Logo.targetsize-256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregchak/plex-playlist-import/HEAD/PlexPlaylistImport/Assets/Square44x44Logo.targetsize-256.png -------------------------------------------------------------------------------- /PlexPlaylistImport/Assets/Square44x44Logo.altform-unplated_targetsize-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregchak/plex-playlist-import/HEAD/PlexPlaylistImport/Assets/Square44x44Logo.altform-unplated_targetsize-16.png -------------------------------------------------------------------------------- /PlexPlaylistImport/Assets/Square44x44Logo.altform-unplated_targetsize-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregchak/plex-playlist-import/HEAD/PlexPlaylistImport/Assets/Square44x44Logo.altform-unplated_targetsize-32.png -------------------------------------------------------------------------------- /PlexPlaylistImport/Assets/Square44x44Logo.altform-unplated_targetsize-48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregchak/plex-playlist-import/HEAD/PlexPlaylistImport/Assets/Square44x44Logo.altform-unplated_targetsize-48.png -------------------------------------------------------------------------------- /PlexPlaylistImport/Assets/Square44x44Logo.targetsize-24_altform-unplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregchak/plex-playlist-import/HEAD/PlexPlaylistImport/Assets/Square44x44Logo.targetsize-24_altform-unplated.png -------------------------------------------------------------------------------- /PlexPlaylistImport/Assets/Square44x44Logo.altform-unplated_targetsize-256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregchak/plex-playlist-import/HEAD/PlexPlaylistImport/Assets/Square44x44Logo.altform-unplated_targetsize-256.png -------------------------------------------------------------------------------- /PlexPlaylistImport/Assets/Square44x44Logo.altform-lightunplated_targetsize-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregchak/plex-playlist-import/HEAD/PlexPlaylistImport/Assets/Square44x44Logo.altform-lightunplated_targetsize-16.png -------------------------------------------------------------------------------- /PlexPlaylistImport/Assets/Square44x44Logo.altform-lightunplated_targetsize-24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregchak/plex-playlist-import/HEAD/PlexPlaylistImport/Assets/Square44x44Logo.altform-lightunplated_targetsize-24.png -------------------------------------------------------------------------------- /PlexPlaylistImport/Assets/Square44x44Logo.altform-lightunplated_targetsize-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregchak/plex-playlist-import/HEAD/PlexPlaylistImport/Assets/Square44x44Logo.altform-lightunplated_targetsize-32.png -------------------------------------------------------------------------------- /PlexPlaylistImport/Assets/Square44x44Logo.altform-lightunplated_targetsize-48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregchak/plex-playlist-import/HEAD/PlexPlaylistImport/Assets/Square44x44Logo.altform-lightunplated_targetsize-48.png -------------------------------------------------------------------------------- /PlexPlaylistImport/Assets/Square44x44Logo.altform-lightunplated_targetsize-256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gregchak/plex-playlist-import/HEAD/PlexPlaylistImport/Assets/Square44x44Logo.altform-lightunplated_targetsize-256.png -------------------------------------------------------------------------------- /PlexPlaylistImport/App.xaml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /PlexPlaylistImport/FormModel.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace PlexPlaylistImport 4 | { 5 | internal class FormModel 6 | { 7 | [JsonProperty("url")] 8 | internal string Url {get;set;} 9 | 10 | [JsonProperty("token")] 11 | internal string Token { get; set; } 12 | 13 | [JsonProperty("sectionId")] 14 | internal byte SectionId { get; set; } 15 | 16 | [JsonProperty("path")] 17 | internal string Path { get; set; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # This .gitignore file was automatically created by Microsoft(R) Visual Studio. 3 | ################################################################################ 4 | 5 | /App1/obj 6 | /PlexPlaylistImport/bin 7 | /PlexPlaylistImport/obj 8 | /PlexPlaylistImport/AppPackages 9 | /PlexPlaylistImport/BundleArtifacts 10 | /PlexPlaylistImport/*.pfx 11 | /*.user 12 | /*.suo 13 | /.vs 14 | /*.cer 15 | /*.p7b 16 | *cert-instructions.txt 17 | *stuff.txt -------------------------------------------------------------------------------- /PlexPlaylistImport/PlexPlaylistImport.csproj.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | SideloadOnly 5 | False 6 | x86|x64 7 | False 8 | 9 | 10 | true 11 | localhost 12 | 13 | -------------------------------------------------------------------------------- /PlexPlaylistImport/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("PLEX Playlist Import")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("PlexPlaylistImport")] 13 | [assembly: AssemblyCopyright("Copyright © 2022")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Version information for an assembly consists of the following four values: 18 | // 19 | // Major Version 20 | // Minor Version 21 | // Build Number 22 | // Revision 23 | // 24 | // You can specify all the values or you can default the Build and Revision Numbers 25 | // by using the '*' as shown below: 26 | // [assembly: AssemblyVersion("1.0.*")] 27 | [assembly: AssemblyVersion("1.1.0.0")] 28 | [assembly: AssemblyFileVersion("1.1.0.0")] 29 | [assembly: ComVisible(false)] -------------------------------------------------------------------------------- /PlexPlaylistImport/Assets/plex-logo.svg: -------------------------------------------------------------------------------- 1 | plex-logo -------------------------------------------------------------------------------- /PlexPlaylistImport/Properties/Default.rd.xml: -------------------------------------------------------------------------------- 1 | 17 | 18 | 19 | 20 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /PlexPlaylistImport/Logger.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using Windows.Storage; 8 | using Serilog; 9 | 10 | namespace PlexPlaylistImport 11 | { 12 | internal static class Logger 13 | { 14 | private static bool isInitialized = false; 15 | public static void Information(string message) 16 | { 17 | if (!isInitialized) 18 | { 19 | Initialize(); 20 | } 21 | Log.Information(message); 22 | } 23 | public static void Debug(string message) 24 | { 25 | if (!isInitialized) 26 | { 27 | Initialize(); 28 | } 29 | Log.Debug(message); 30 | } 31 | public static void Warning(string message) 32 | { 33 | if (!isInitialized) 34 | { 35 | Initialize(); 36 | } 37 | Log.Warning(message); 38 | } 39 | public static void Error(string message) 40 | { 41 | if (!isInitialized) 42 | { 43 | Initialize(); 44 | } 45 | Log.Error(message); 46 | } 47 | private static void Initialize() 48 | { 49 | string logFilePath = Path.Combine(ApplicationData.Current.LocalFolder.Path, "logs\\log.txt"); 50 | Log.Logger = new LoggerConfiguration() 51 | .MinimumLevel.Debug() 52 | .WriteTo.File(logFilePath, rollingInterval: RollingInterval.Day) 53 | .CreateLogger(); 54 | isInitialized = true; 55 | Log.Debug("Initialized Serilog"); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /PlexPlaylistImport/Package.appxmanifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 13 | 14 | 15 | 16 | 17 | PlexPlaylistImport 18 | ChakFrost 19 | Assets\StoreLogo.png 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 34 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PLEX Playlist Import 2 | This is an application written to help PLEX Media Server (PMS) owners import playlists into PLEX. This is written as a Universal Windows Platform application. Current builds are for x86 and x64 architectures only. This application is not currently available in the Microsoft Store. 3 | 4 | # Motivation 5 | Currently PMS does not have an GUI for importing playlists. However, there are exposed endpoints that can be utilized for this purpose. 6 | 7 | # Installation 8 | Currently the release is not signed with a certficate. This is one of the reasons why its not currently on Microsoft Store. In order to install you need to run the powershell script `Install.ps1`. After extracting the zip file, `Install.ps1` will be located in the root of the extracted folder. You may be asked to install a certificate during the installation process. This is a development/testing certificate. 9 | 10 | # Usage 11 | This tool is quite simple in execution. The most important thing is getting the correct information to fill into the form. There are instructions in the app for getting Section ID and X-Plex Token and is also noted below. 12 | 13 | The "Path to playlist file" is very important to understand. This path is an absolute path that is relative to the PMS server. For example, if your PMS is hosted on Windows, the path would starting with something like `C:\plex\music...`. If your PMS is hosted on Linux, like a NAS or something, the path would start with something like `/volume1/plex/music...`. 14 | 15 | In addition to making sure the Path to playlist file is correct, the path to the music files in your `.m3u` file need to be setup the same way. 16 | 17 | **Its important to note that in a scenario in which you are running the PLEX Playlist Import tool from a computer that is NOT your PMS, the above mentioned paths are NOT relative to the computer this tool is running on, but rather relative to the computer your on which your PMS is hosted.** 18 | 19 | **To Get Section ID and X-Plex Token:** 20 | 21 | Taken from reddit 22 | https://www.reddit.com/r/PleX/comments/ecirqa/how_to_manually_import_an_m3u_playlist_into_plex/ 23 | 1. Open your Plex server web app , as normal. 24 | 25 | 2. In Plex , navigate to any file in the library for which you want to import a playlist. (e.g. in your 'Rock Music' library, navigate to 'BornToBeWild.mp3'). 26 | 27 | 3. On the play bar for that library item, click the More Actions ellipses (...) , select Get Info , and then click View XML. A new browser window opens containing XML details about the library item. 28 | 29 | 4. From the URL, copy the X-Plex-Token value into a text editor. 30 | 31 | 5. From the page content, copy the librarySectionID value into a text editor. 32 | 33 | # Screenshot 34 | ![image](https://user-images.githubusercontent.com/5882933/116017209-fe3a8b00-a60c-11eb-8667-b39be11241e8.png) 35 | 36 | # Version History 37 | 38 | **1.1.1.0** - 2023-11-01 39 | - Updated certificate. This is also the first build from VS2022 40 | 41 | **1.1.0.0** - 2022-05-17 42 | - Added detailed logging; Issue #6 43 | - Added ability to save infomation in form to be loaded when application is started; Issue #4 44 | 45 | **1.0.4.0** - 2021-04-25 46 | Initial release. 47 | 48 | # License 49 | GNU General Public License v3.0 50 | 51 | https://github.com/gregchak/plex-playlist-import/blob/main/LICENSE 52 | 53 | -------------------------------------------------------------------------------- /PLEX.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.31025.194 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PlexPlaylistImport", "PlexPlaylistImport\PlexPlaylistImport.csproj", "{5CCF193D-D05A-40F6-8DDD-311AA0A8DBEB}" 7 | EndProject 8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{D6D38D6B-21BB-417E-BD2D-931FBDE5CB7C}" 9 | ProjectSection(SolutionItems) = preProject 10 | .gitignore = .gitignore 11 | EndProjectSection 12 | EndProject 13 | Global 14 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 15 | Debug|Any CPU = Debug|Any CPU 16 | Debug|ARM = Debug|ARM 17 | Debug|ARM64 = Debug|ARM64 18 | Debug|x64 = Debug|x64 19 | Debug|x86 = Debug|x86 20 | Release|Any CPU = Release|Any CPU 21 | Release|ARM = Release|ARM 22 | Release|ARM64 = Release|ARM64 23 | Release|x64 = Release|x64 24 | Release|x86 = Release|x86 25 | EndGlobalSection 26 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 27 | {5CCF193D-D05A-40F6-8DDD-311AA0A8DBEB}.Debug|Any CPU.ActiveCfg = Debug|x86 28 | {5CCF193D-D05A-40F6-8DDD-311AA0A8DBEB}.Debug|ARM.ActiveCfg = Debug|ARM 29 | {5CCF193D-D05A-40F6-8DDD-311AA0A8DBEB}.Debug|ARM.Build.0 = Debug|ARM 30 | {5CCF193D-D05A-40F6-8DDD-311AA0A8DBEB}.Debug|ARM.Deploy.0 = Debug|ARM 31 | {5CCF193D-D05A-40F6-8DDD-311AA0A8DBEB}.Debug|ARM64.ActiveCfg = Debug|ARM64 32 | {5CCF193D-D05A-40F6-8DDD-311AA0A8DBEB}.Debug|ARM64.Build.0 = Debug|ARM64 33 | {5CCF193D-D05A-40F6-8DDD-311AA0A8DBEB}.Debug|ARM64.Deploy.0 = Debug|ARM64 34 | {5CCF193D-D05A-40F6-8DDD-311AA0A8DBEB}.Debug|x64.ActiveCfg = Debug|x64 35 | {5CCF193D-D05A-40F6-8DDD-311AA0A8DBEB}.Debug|x64.Build.0 = Debug|x64 36 | {5CCF193D-D05A-40F6-8DDD-311AA0A8DBEB}.Debug|x64.Deploy.0 = Debug|x64 37 | {5CCF193D-D05A-40F6-8DDD-311AA0A8DBEB}.Debug|x86.ActiveCfg = Debug|x86 38 | {5CCF193D-D05A-40F6-8DDD-311AA0A8DBEB}.Debug|x86.Build.0 = Debug|x86 39 | {5CCF193D-D05A-40F6-8DDD-311AA0A8DBEB}.Debug|x86.Deploy.0 = Debug|x86 40 | {5CCF193D-D05A-40F6-8DDD-311AA0A8DBEB}.Release|Any CPU.ActiveCfg = Release|x86 41 | {5CCF193D-D05A-40F6-8DDD-311AA0A8DBEB}.Release|ARM.ActiveCfg = Release|ARM 42 | {5CCF193D-D05A-40F6-8DDD-311AA0A8DBEB}.Release|ARM.Build.0 = Release|ARM 43 | {5CCF193D-D05A-40F6-8DDD-311AA0A8DBEB}.Release|ARM.Deploy.0 = Release|ARM 44 | {5CCF193D-D05A-40F6-8DDD-311AA0A8DBEB}.Release|ARM64.ActiveCfg = Release|ARM64 45 | {5CCF193D-D05A-40F6-8DDD-311AA0A8DBEB}.Release|ARM64.Build.0 = Release|ARM64 46 | {5CCF193D-D05A-40F6-8DDD-311AA0A8DBEB}.Release|ARM64.Deploy.0 = Release|ARM64 47 | {5CCF193D-D05A-40F6-8DDD-311AA0A8DBEB}.Release|x64.ActiveCfg = Release|x64 48 | {5CCF193D-D05A-40F6-8DDD-311AA0A8DBEB}.Release|x64.Build.0 = Release|x64 49 | {5CCF193D-D05A-40F6-8DDD-311AA0A8DBEB}.Release|x64.Deploy.0 = Release|x64 50 | {5CCF193D-D05A-40F6-8DDD-311AA0A8DBEB}.Release|x86.ActiveCfg = Release|x86 51 | {5CCF193D-D05A-40F6-8DDD-311AA0A8DBEB}.Release|x86.Build.0 = Release|x86 52 | {5CCF193D-D05A-40F6-8DDD-311AA0A8DBEB}.Release|x86.Deploy.0 = Release|x86 53 | EndGlobalSection 54 | GlobalSection(SolutionProperties) = preSolution 55 | HideSolutionNode = FALSE 56 | EndGlobalSection 57 | GlobalSection(ExtensibilityGlobals) = postSolution 58 | SolutionGuid = {E59547A4-6A41-4B7B-B586-A050041279DD} 59 | EndGlobalSection 60 | EndGlobal 61 | -------------------------------------------------------------------------------- /PlexPlaylistImport/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Runtime.InteropServices.WindowsRuntime; 6 | using Windows.ApplicationModel; 7 | using Windows.ApplicationModel.Activation; 8 | using Windows.Foundation; 9 | using Windows.Foundation.Collections; 10 | using Windows.UI.Xaml; 11 | using Windows.UI.Xaml.Controls; 12 | using Windows.UI.Xaml.Controls.Primitives; 13 | using Windows.UI.Xaml.Data; 14 | using Windows.UI.Xaml.Input; 15 | using Windows.UI.Xaml.Media; 16 | using Windows.UI.Xaml.Navigation; 17 | 18 | namespace App1 19 | { 20 | /// 21 | /// Provides application-specific behavior to supplement the default Application class. 22 | /// 23 | sealed partial class App : Application 24 | { 25 | /// 26 | /// Initializes the singleton application object. This is the first line of authored code 27 | /// executed, and as such is the logical equivalent of main() or WinMain(). 28 | /// 29 | public App() 30 | { 31 | this.InitializeComponent(); 32 | this.Suspending += OnSuspending; 33 | } 34 | 35 | /// 36 | /// Invoked when the application is launched normally by the end user. Other entry points 37 | /// will be used such as when the application is launched to open a specific file. 38 | /// 39 | /// Details about the launch request and process. 40 | protected override void OnLaunched(LaunchActivatedEventArgs e) 41 | { 42 | Frame rootFrame = Window.Current.Content as Frame; 43 | 44 | // Do not repeat app initialization when the Window already has content, 45 | // just ensure that the window is active 46 | if (rootFrame == null) 47 | { 48 | // Create a Frame to act as the navigation context and navigate to the first page 49 | rootFrame = new Frame(); 50 | 51 | rootFrame.NavigationFailed += OnNavigationFailed; 52 | 53 | if (e.PreviousExecutionState == ApplicationExecutionState.Terminated) 54 | { 55 | //TODO: Load state from previously suspended application 56 | } 57 | 58 | // Place the frame in the current Window 59 | Window.Current.Content = rootFrame; 60 | } 61 | 62 | if (e.PrelaunchActivated == false) 63 | { 64 | if (rootFrame.Content == null) 65 | { 66 | // When the navigation stack isn't restored navigate to the first page, 67 | // configuring the new page by passing required information as a navigation 68 | // parameter 69 | rootFrame.Navigate(typeof(MainPage), e.Arguments); 70 | } 71 | // Ensure the current window is active 72 | Window.Current.Activate(); 73 | } 74 | } 75 | 76 | /// 77 | /// Invoked when Navigation to a certain page fails 78 | /// 79 | /// The Frame which failed navigation 80 | /// Details about the navigation failure 81 | void OnNavigationFailed(object sender, NavigationFailedEventArgs e) 82 | { 83 | throw new Exception("Failed to load Page " + e.SourcePageType.FullName); 84 | } 85 | 86 | /// 87 | /// Invoked when application execution is being suspended. Application state is saved 88 | /// without knowing whether the application will be terminated or resumed with the contents 89 | /// of memory still intact. 90 | /// 91 | /// The source of the suspend request. 92 | /// Details about the suspend request. 93 | private void OnSuspending(object sender, SuspendingEventArgs e) 94 | { 95 | var deferral = e.SuspendingOperation.GetDeferral(); 96 | //TODO: Save application state and stop any background activity 97 | deferral.Complete(); 98 | } 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /PlexPlaylistImport/MainPage.xaml: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 13 | 14 | 15 | 17 | 20 | 21 | 22 | 23 | 26 | 28 | 31 | 33 | This will be a numeric value 34 | 35 | 38 | 40 | NOTE: The path is an absolute path that exists on your PMS 41 | 42 | 43 | 45 | 47 | 48 | To Get Section ID and X-Plex Token: 49 | 50 | 51 | 52 | 1. Open your 53 | Plex server web app , as normal. 54 | 55 | 56 | 57 | 2. In 58 | Plex , navigate to any file in the library for which you want to import a playlist. 59 | (e.g. in your 'Rock Music' library, navigate to 'BornToBeWild.mp3'). 60 | 61 | 62 | 63 | 3. On the play bar for that library item, click the 64 | More Actions ellipses (...) , select 65 | Get Info , and then click View XML. 66 | 67 | 68 | 69 | A new browser window opens containing XML details about the library item. 70 | 71 | 72 | 73 | 4. From the URL, copy the 74 | X-Plex-Token value into a text editor. 75 | 76 | 77 | 78 | 5. From the page content, copy the 79 | librarySectionID value into a text editor. 80 | 81 | 82 | 83 | 84 |