Пример #1
0
        private void ItmViaToken_Click(object sender, EventArgs e)
        {
            try
            {
                //check if there's a connection before trying to update the authentication token
                if (Internet.IsConnected)
                {
                    using (var frm = new Authenticate())
                    {
                        var existingInfo = new ConnectionInfo
                        {
                            PlexAccountToken = ObjectProvider.Settings.ConnectionInfo.PlexAccountToken
                        };

                        frm.ConnectionInfo = existingInfo;

                        if (frm.ShowDialog() != DialogResult.OK)
                        {
                            return;
                        }
                        if (!frm.Success)
                        {
                            return;
                        }

                        if (ApplyToken(frm.ConnectionInfo.PlexAccountToken))
                        {
                            UIMessages.Info(
                                @"Token applied successfully. You can now load servers and relays from Plex.tv");
                            LoadServers(true);

                            //status update
                            SetInterfaceAuthenticationStatus(true);
                        }
                        else
                        {
                            UIMessages.Error(@"An unknown error occurred");
                        }
                    }
                }
                else
                {
                    // trying to connect on no connection will not end well; alert the user.
                    UIMessages.Warning(
                        @"No internet connection. Please connect to a network before attempting to authenticate.",
                        @"Network Error");
                }
            }
            catch (Exception ex)
            {
                LoggingHelpers.RecordException(ex.Message, "ConnectionError");
                UIMessages.Error("Connection Error:\n\n" + ex, @"Connection Error");
            }
        }
Пример #2
0
 private void btnLoadDict_Click(object sender, EventArgs e)
 {
     if (!string.IsNullOrEmpty(txtLogdel.Text) && !string.IsNullOrEmpty(ofdLogdel.FileName))
     {
         LoadStats(ofdLogdel.FileName);
     }
     else
     {
         UIMessages.Error(@"Incorrect value(s)");
     }
 }
Пример #3
0
 private void ExportFlags()
 {
     if (dgvGlobalFlags.DataSource != null)
     {
         //use the generic exporter and the PlexDL data provider framework
         ProcessExport((DataTable)dgvGlobalFlags.DataSource);
     }
     else
     {
         //inform the user of the problem (invalid data)
         UIMessages.Error("Global boolean flag data was null");
     }
 }
Пример #4
0
 private void BtnLoadDict_Click(object sender, EventArgs e)
 {
     //ensure LogDel file TextBox is filled and the OpenFileDialog has a LogDel file selected
     if (!string.IsNullOrWhiteSpace(txtLogdel.Text) && !string.IsNullOrWhiteSpace(ofdLogdel.FileName))
     {
         //both are valid, load the statistics and process tokens
         LoadStats(ofdLogdel.FileName);
     }
     else
     {
         //alert the user
         UIMessages.Error(@"Incorrect value(s)");
     }
 }
Пример #5
0
        /// <summary>
        /// Handles exporting to an eXtensible markup language file; will prompt the user with a 'Save As' dialog.
        /// </summary>
        /// <param name="table">The data to export; null checks are enforced.</param>
        private void ExportTableXml(DataTable table)
        {
            try
            {
                //the table mustn't be null; we cannot work on data that doesn't exist
                if (table != null)
                {
                    //the table must have data inside it; we cannot work on data that doesn't exist
                    if (table.Rows.Count > 0)
                    {
                        //dialog values
                        sfdExport.Filter     = @"XML File|*.xml";
                        sfdExport.DefaultExt = "xml";

                        //show the dialog and ensure the user pressed 'OK'
                        if (sfdExport.ShowDialog() != DialogResult.OK)
                        {
                            return;
                        }

                        //the path of the file to write to/create
                        var file = sfdExport.FileName;

                        //use the export extensions provider to save the data to an XML file
                        table.ToXml(file);

                        //inform the user
                        UIMessages.Info("Success!");
                    }
                    else
                    {
                        //inform the user of the problem (no data; but not null)
                        UIMessages.Error("Couldn't export; table has no rows.");
                    }
                }
                else
                {
                    //inform the user of the problem (table isn't set)
                    UIMessages.Error("Couldn't export; table is null.");
                }
            }
            catch (Exception ex)
            {
                //log the problem
                LoggingHelpers.RecordException(ex.Message, @"DebugExportXMLError");

                //inform the user of the problem (unhandled exception)
                UIMessages.Error("Error occurred whilst exporting table:\n\n" + ex);
            }
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="e"></param>
        /// <param name="silent"></param>
        public static void CriticalExceptionHandler(Exception e, bool silent = false)
        {
            //check if messages aren't disabled
            if (!silent)
            {
                //alert the user to the error
                UIMessages.Error(
                    "An unhandled exception has occurred. Please report this issue on GitHub, including any relevant logs or other information.\n\n" +
                    e, @"Unhandled Exception");
            }

            //log the exception
            LoggingHelpers.RecordException(e.Message, "UnhandledException");
        }
Пример #7
0
        private void LoadRelays(bool silent = false)
        {
            try
            {
                //check if there's a connection before trying to contact Plex.tv
                if (Internet.IsConnected)
                {
                    if (!IsTokenSet())
                    {
                        return;
                    }

                    var serversResult = WaitWindow.WaitWindow.Show(GetRelaysListWorker, "Fetching Relays");
                    var servers       = (List <Server>)serversResult;
                    if (servers.Count == 0)
                    {
                        if (!silent)
                        {
                            UIMessages.Error(
                                @"No relays found for current account token. Please update your token or try a direct connection.",
                                @"Authentication Error");
                        }
                    }
                    else
                    {
                        ObjectProvider.PlexServers = servers;
                        RenderServersView(servers);
                    }
                }
                else
                {
                    // trying to connect on no connection will not end well; alert the user.
                    if (!silent)
                    {
                        UIMessages.Warning(
                            @"No internet connection. Please connect to a network before attempting to load relays.",
                            @"Network Error");
                    }
                }
            }
            catch (Exception ex)
            {
                if (!silent)
                {
                    UIMessages.Error("Relay retrieval error\n\n" + ex, @"Data Error");
                }
                LoggingHelpers.RecordException(ex.Message, "RelayGetError");
            }
        }
Пример #8
0
 private void DoPxzLoad()
 {
     try
     {
         if (Pxz != null)
         {
             dgvAttributes.DataSource = Attributes();
             dgvRecords.DataSource    = Records();
         }
     }
     catch (Exception ex)
     {
         UIMessages.Error(ex.ToString(), @"Load Error");
     }
 }
Пример #9
0
 private void ExportTracks()
 {
     if (ObjectProvider.CurrentContentType == ContentType.Music)
     {
         //use the generic exporter and the PlexDL data provider framework
         ProcessExport(radModeTable.Checked
             ? DataProvider.TracksProvider.GetRawTable()
             : DataProvider.TracksProvider.GetViewTable());
     }
     else
     {
         //inform the user of the problem (invalid mode)
         UIMessages.Error("PlexDL is not in Music Mode");
     }
 }
Пример #10
0
        private void DoLoadFromSelected()
        {
            try
            {
                // if the index is -1 then nothing is selected at all
                if (lstLogFiles.SelectedIndex <= -1)
                {
                    return;
                }

                //apply the new file to the global internal variable
                _currentLogFile = lstLogFiles.SelectedItem.ToString();

                //get a table from the currently selected log file
                var table = TableFromSelected();

                //ensure the loaded log is valid (not null)
                if (table == null)
                {
                    return;
                }

                //assign the log to the log viewer grid
                dgvMain.DataSource = table;

                //the original data is stored safely to ensure searches can be cleared correctly
                _logRecords = table;

                //update record status
                SetInterfaceViewingStatus();
                SetInterfaceCurrentLog(_currentLogFile);
            }
            catch (Exception ex)
            {
                //alert the user
                UIMessages.Error("An error occurred whilst loading the log file. Details:\n\n" + ex,
                                 @"Data Error");

                //clear the log viewer grid
                dgvMain.DataSource = null;

                //clear the global
                _logRecords = null;

                //update record view status
                SetInterfaceViewingStatus();
            }
        }
Пример #11
0
        private void ServerManager_Load(object sender, EventArgs e)
        {
            try
            {
                //default status update
                SetInterfaceAuthenticationStatus(false);

                //check if there's an internet connection first; it may have been disconnected while the window was closed.
                if (Internet.IsConnected)
                {
                    //check to see if a loaded profile instated some valid server details. If there are, we can potentially fast-forward
                    //the connection process!
                    ProfileDefinedServer();

                    // this check must be done before checking the count, because if it is null, we'll get an error for trying to access "Count" on a null object.
                    if (ObjectProvider.PlexServers == null)
                    {
                        return;
                    }
                    if (ObjectProvider.PlexServers.Count <= 0)
                    {
                        return;
                    }

                    RenderServersView(ObjectProvider.PlexServers);
                    SelectServer();

                    itmLoad.Enabled    = true;
                    itmDisplay.Enabled = true;

                    //status update
                    SetInterfaceAuthenticationStatus(true);
                }
                else
                {
                    // trying to connect on no connection will not end well; close this window if there's no connection and alert the user.
                    UIMessages.Warning(
                        @"No internet connection. Please connect to a network before attempting to start a Plex server connection.",
                        @"Network Error");
                    Close();
                }
            }
            catch (Exception ex)
            {
                LoggingHelpers.RecordException(ex.Message, @"ServerManagerLoadError");
                UIMessages.Error("Server manager failed to load necessary data\n\n" + ex);
            }
        }
Пример #12
0
 private void ExportAlbums()
 {
     //the application MUST be set to the correct mode; exporting will be misaligned and corrupt otherwise
     if (ObjectProvider.CurrentContentType == ContentType.Music)
     {
         //use the generic exporter and the PlexDL data provider framework
         ProcessExport(radModeTable.Checked
             ? DataProvider.AlbumsProvider.GetRawTable()
             : DataProvider.AlbumsProvider.GetViewTable());
     }
     else
     {
         //inform the user of the problem (invalid mode)
         UIMessages.Error("PlexDL is not in Music Mode");
     }
 }
Пример #13
0
 private void ExportFiltered()
 {
     ////the application MUST be in the search state (current content type grid is filtered); exporting will be misaligned and corrupt otherwise
     if (Flags.IsFiltered)
     {
         //use the generic exporter and the PlexDL data provider framework
         ProcessExport(radModeTable.Checked
             ? DataProvider.FilteredProvider.GetRawTable()
             : DataProvider.FilteredProvider.GetViewTable());
     }
     else
     {
         //inform the user of the problem (invalid mode)
         UIMessages.Error("Titles are not currently filtered");
     }
 }
        public static DataTable MovieAttributesFromObject(PlexMovie content, bool silent = false)
        {
            var table = new DataTable("MovieAttributes");
            var columnAttributeName  = new DataColumn("Name", typeof(string));
            var columnAttributeValue = new DataColumn("Value");

            table.Columns.AddRange(
                new[]
            {
                columnAttributeName,
                columnAttributeValue
            });
            try
            {
                var genre      = new[] { "Genre", content.ContentGenre };
                var runtime    = new[] { "Runtime", Methods.CalculateTime(content.StreamInformation.ContentDuration) };
                var resolution = new[] { "Resolution", content.StreamResolution.ResolutionString() };
                var frameRate  = new[] { "Frame-rate", FormatFramerate(content) };
                var size       = new[] { "File size", Methods.FormatBytes(content.StreamInformation.ByteLength) };
                var container  = new[] { "Container", content.StreamInformation.Container };

                var newRows = new[]
                {
                    genre,
                    runtime,
                    resolution,
                    frameRate,
                    size,
                    container
                };

                foreach (object[] row in newRows)
                {
                    table.Rows.Add(row);
                }
            }
            catch (Exception ex)
            {
                LoggingHelpers.RecordException(ex.Message, "AttributeTableError");
                if (!silent)
                {
                    UIMessages.Error("Error occurred whilst building content attribute table:\n\n" + ex, @"Data Error");
                }
            }

            return(table);
        }
        public static DataTable MusicAttributesFromObject(PlexMusic content, bool silent = false)
        {
            var table = new DataTable("MusicAttributes");
            var columnAttributeName  = new DataColumn("Name", typeof(string));
            var columnAttributeValue = new DataColumn("Value");

            table.Columns.AddRange(
                new[]
            {
                columnAttributeName,
                columnAttributeValue
            });
            try
            {
                var artist    = new[] { "Artist", content.Artist };
                var album     = new[] { "Album", content.Album };
                var genre     = new[] { "Genre", content.ContentGenre };
                var duration  = new[] { "Duration", Methods.CalculateTime(content.StreamInformation.ContentDuration) };
                var size      = new[] { "File size", Methods.FormatBytes(content.StreamInformation.ByteLength) };
                var container = new[] { "Container", content.StreamInformation.Container };

                var newRows = new[]
                {
                    artist,
                    album,
                    genre,
                    duration,
                    size,
                    container
                };

                foreach (object[] row in newRows)
                {
                    table.Rows.Add(row);
                }
            }
            catch (Exception ex)
            {
                LoggingHelpers.RecordException(ex.Message, "AttributeTableError");
                if (!silent)
                {
                    UIMessages.Error("Error occurred whilst building content attribute table:\n\n" + ex, @"Data Error");
                }
            }

            return(table);
        }
Пример #16
0
 private void ItmCreateAssociations_Click(object sender, EventArgs e)
 {
     try
     {
         if (UIMessages.Question(
                 "You are about to create PlexDL file associations for:\n\n*.pxz\n*.pmxml\n*.prof\n\nProceed?"))
         {
             FileAssociationsManager.EnsureAssociationsSet();
             UIMessages.Info(@"Done!");
         }
     }
     catch (Exception ex)
     {
         LoggingHelpers.RecordException(ex.Message, @"FileAssociationError");
         UIMessages.Error($"Error whilst trying to set PlexDL file associations:\n\n{ex}");
     }
 }
Пример #17
0
        public DataTable Records()
        {
            var table = new DataTable();

            table.Columns.Add(@"Record Name", typeof(string));
            table.Columns.Add(@"Stored Name", typeof(string));
            table.Columns.Add(@"Type", typeof(string));
            table.Columns.Add(@"Protected", typeof(string));
            table.Columns.Add(@"Sizing", typeof(string));
            table.Columns.Add(@"C. Ratio", typeof(string));
            table.Columns.Add(@"CS Valid", typeof(string));

            try
            {
                foreach (var r in Pxz.Records)
                {
                    var recordName = r.Header.Naming.RecordName;
                    var storedName = r.Header.Naming.StoredName;
                    var recordType = r.Header.Naming.DataType.ToString();
                    var recordProt = r.ProtectedRecord.ToString();
                    var recordSize = $"{Utilities.FormatBytes((long)r.Header.Size.RawSize)}/{Utilities.FormatBytes((long)r.Header.Size.DecSize)}";
                    var comprRatio = $"{r.Header.Size.Ratio}%";
                    var checkValid = r.ChecksumValid.ToString();

                    object[] row =
                    {
                        recordName,
                        storedName,
                        recordType,
                        recordProt,
                        recordSize,
                        comprRatio,
                        checkValid
                    };

                    table.Rows.Add(row);
                }
            }
            catch (Exception ex)
            {
                UIMessages.Error(ex.ToString());
            }

            return(table);
        }
Пример #18
0
        private void BtnConnect_Click(object sender, EventArgs e)
        {
            if (!ValidToken(txtAccountToken.Text))
            {
                UIMessages.Error(
                    "Please enter a valid account token. A token must be 20 characters in length with no spaces.",
                    "Validation Error");
            }
            else
            {
                ConnectionInfo.PlexAccountToken = txtAccountToken.Text;

                ConnectionStarted = true;
                DialogResult      = DialogResult.OK;
                Success           = true;
                Close();
            }
        }
Пример #19
0
 public static void LaunchBrowser(PlexObject stream)
 {
     try
     {
         if (Methods.StreamAdultContentCheck(stream))
         {
             Process.Start(stream.StreamInformation.Links
                           .View); //normal MP4 stream (this won't trigger a browser download if it's a supported file)
             LoggingHelpers.RecordGeneralEntry("Started streaming " + stream.StreamInformation.ContentTitle +
                                               " (Browser)");
         }
     }
     catch (Exception ex)
     {
         UIMessages.Error("Error occurred whilst trying to launch the default browser\n\n" + ex,
                          @"Launch Error");
         LoggingHelpers.RecordException(ex.Message, "BrowserLaunchError");
     }
 }
Пример #20
0
        public static void LaunchPvs(PlexObject stream)
        {
            if (stream != null)
            {
                try
                {
                    if (!Methods.StreamAdultContentCheck(stream))
                    {
                        return;
                    }

                    //downloads won't work properly if you're streaming at the same time
                    if (!Flags.IsDownloadRunning && !Flags.IsEngineRunning)
                    {
                        var frm = new UI.Forms.Player
                        {
                            StreamingContent = stream
                        };
                        LoggingHelpers.RecordGeneralEntry("Started streaming " + stream.StreamInformation.ContentTitle +
                                                          " (PVS)");
                        frm.ShowDialog();
                    }
                    else
                    {
                        UIMessages.Warning(
                            "You cannot stream \n" + stream.StreamInformation.ContentTitle +
                            "\n because a download is already running. Cancel the download before attempting to stream within PlexDL.",
                            @"Validation Error");
                        LoggingHelpers.RecordGeneralEntry(
                            "Tried to stream content via PVS, but a download is running.");
                    }
                }
                catch (Exception ex)
                {
                    UIMessages.Error("Error occurred whilst trying to launch VLC\n\n" + ex, @"Launch Error");
                    LoggingHelpers.RecordException(ex.Message, "VLCLaunchError");
                }
            }
            else
            {
                LoggingHelpers.RecordGeneralEntry("Tried to stream content via PVS, but one or more values were null.");
            }
        }
Пример #21
0
        public static void ShowDownloadManager(HttpDownloadQueue queue)
        {
            try
            {
                //show the form
                new DownloadManager
                {
                    QueueProvider = queue
                }.ShowDialog();
            }
            catch (Exception ex)
            {
                //log the error
                LoggingHelpers.RecordException(ex.Message, @"DownloadManagerShowError");

                //alert the user
                UIMessages.Error($"Error in download manager show:\n\n{ex}");
            }
        }
Пример #22
0
        private void ItmExtractRecord_Click(object sender, EventArgs e)
        {
            if (dgvRecords.SelectedRows.Count == 1)
            {
                var recordName = dgvRecords.SelectedRows[0].Cells[0].Value.ToString();
                var record     = Pxz.LoadRecord(recordName);

                if (sfdExtract.ShowDialog() == DialogResult.OK)
                {
                    if (record.ExtractRecord(sfdExtract.FileName))
                    {
                        UIMessages.Info($"Successfully extracted '{recordName}'");
                    }
                    else
                    {
                        UIMessages.Error(@"Extraction failed; an unknown error occurred.");
                    }
                }
            }
        }
Пример #23
0
        private static StreamInfo GetContentDownloadInfo(int index)
        {
            if (index + 1 <= TableManager.ReturnCorrectTable().Rows.Count)
            {
                var result  = TableManager.ReturnCorrectTable().Rows[index];
                var key     = result["key"].ToString();
                var baseUri = Strings.GetBaseUri(false);
                key = key.TrimStart('/');
                var uri = baseUri + key + "/?X-Plex-Token=";

                var reply = XmlGet.GetXmlTransaction(uri, false, false, false);

                var obj = DownloadInfoGatherers.GetContentDownloadInfo(reply);
                return(obj);
            }

            UIMessages.Error(@"Index was higher than row count; could not process data.",
                             @"Indexing Error");
            return(new StreamInfo());
        }
Пример #24
0
        private void ItmCSV_Click(object sender, EventArgs e)
        {
            try
            {
                //ensure a log file is selected in the list
                if (lstLogFiles.SelectedIndex > -1)
                {
                    var sel = LogDir + @"\" + lstLogFiles.SelectedItem;

                    if (File.Exists(sel))
                    {
                        if (sfdExportCsv.ShowDialog() != DialogResult.OK)
                        {
                            return;
                        }

                        var f = sfdExportCsv.FileName;
                        var t = LogReader.TableFromFile(sel, false, false);
                        t.ToCsv(f);
                        UIMessages.Info("Successfully exported log file to CSV",
                                        "Success");
                    }
                    else
                    {
                        UIMessages.Error("Selected file does not exist",
                                         "Validation Error");
                    }
                }
                else
                {
                    UIMessages.Error("Nothing is selected",
                                     "Validation Error");
                }
            }
            catch (Exception ex)
            {
                //inform the user of the error
                UIMessages.Error("Error occurred whilst exporting your log file. Details:\n\n" + ex,
                                 "IO Error");
            }
        }
Пример #25
0
        public static ApplicationOptions ProfileFromFile(string fileName, bool silent = false)
        {
            try
            {
                if (File.Exists(fileName))
                {
                    return(File.ReadAllText(fileName).ProfileFromXml());
                }
            }
            catch (Exception ex)
            {
                LoggingHelpers.RecordException(ex.Message, "LoadProfileError");
                if (!silent)
                {
                    UIMessages.Error(ex.ToString(), @"XML Load Error");
                }
            }

            //default
            return(null);
        }
Пример #26
0
        private void ItmBackup_Click(object sender, EventArgs e)
        {
            try
            {
                //ensure the logging directory exists
                if (Directory.Exists(LogDir))
                {
                    //the OK button must be pressed in the dialog
                    if (sfdBackup.ShowDialog() != DialogResult.OK)
                    {
                        return;
                    }

                    //if the file already exists, delete it
                    if (File.Exists(sfdBackup.FileName))
                    {
                        File.Delete(sfdBackup.FileName);
                    }

                    //create a new ZIP file of all the logs in the logging directory
                    ZipFile.CreateFromDirectory(LogDir, sfdBackup.FileName, CompressionLevel.Optimal, false);

                    //inform the user of the successful operation
                    UIMessages.Info(@"Successfully backed up logs to " + sfdBackup.FileName);
                }
                else
                {
                    //alert the user
                    UIMessages.Error(
                        @"Could not backup logs due to no folder existing. This is a clear sign that no logs have been created, however you can check by clicking the Refresh button on the bottom left of this form.",
                        @"Validation Error");
                }
            }
            catch (Exception ex)
            {
                //report the error to the user
                UIMessages.Error("An error occurred whilst backing up log files. Details:\n\n" + ex,
                                 "IO Error");
            }
        }
Пример #27
0
        private bool ApplyToken(string token, bool silent = true)
        {
            try
            {
                //check if there's a connection before trying to update the authentication token
                if (Internet.IsConnected)
                {
                    ObjectProvider.User.authenticationToken = token;
                    ObjectProvider.Settings.ConnectionInfo.PlexAccountToken = token;
                    itmLoad.Enabled       = true;
                    itmDisplay.Enabled    = true;
                    dgvServers.DataSource = null;
                    if (!silent)
                    {
                        UIMessages.Info(
                            @"Token applied successfully. You can now load servers and relays from Plex.tv");
                    }

                    return(true);
                }

                // trying to connect on no connection will not end well; alert the user.
                if (!silent)
                {
                    UIMessages.Warning(
                        @"No internet connection. Please connect to a network before attempting to authenticate.",
                        @"Network Error");
                }
                return(false);
            }
            catch (Exception ex)
            {
                LoggingHelpers.RecordException(ex.Message, "ConnectionError");
                if (!silent)
                {
                    UIMessages.Error("Connection Error:\n\n" + ex, @"Connection Error");
                }
                return(false);
            }
        }
Пример #28
0
        public static void ProfileToFile(string fileName, ApplicationOptions options, bool silent = false)
        {
            try
            {
                //delete the existing file if there is one; the user was asked if they wanted to replace it.
                if (File.Exists(fileName))
                {
                    File.Delete(fileName);
                }

                //write the profile to the XML file
                File.WriteAllText(fileName, options.ProfileToXml());
            }
            catch (Exception ex)
            {
                LoggingHelpers.RecordException(ex.Message, "@SaveProfileError");
                if (!silent)
                {
                    UIMessages.Error(ex.ToString(), @"XML Save Error");
                }
            }
        }
Пример #29
0
 private void BtnTranslate_Click(object sender, EventArgs e)
 {
     try
     {
         if (!string.IsNullOrEmpty(txtLogdel.Text) && !string.IsNullOrEmpty(ofdLogdel.FileName))
         {
             pbMain.Maximum = TotalCount;
             pbMain.Value   = 0;
             bwTranslate.RunWorkerCompleted += BwTranslate_RunWorkerCompleted;
             bwTranslate.ProgressChanged    += BwTranslate_ProgressChanged;
             bwTranslate.RunWorkerAsync();
         }
         else
         {
             UIMessages.Error(@"Incorrect value(s)");
         }
     }
     catch (Exception ex)
     {
         UIMessages.Error(ex.ToString());
     }
 }
Пример #30
0
        private static void ExportTokenProf(string token, string dir = @"translator\profs")
        {
            try
            {
                if (!Directory.Exists(dir))
                {
                    Directory.CreateDirectory(dir);
                }
                var fileCount = Directory.GetFiles(dir, "plexdl_sv*.prof").Length;
                var fileIdx   = fileCount + 1;
                var fileName  = "plexdl_sv" + fileIdx + ".prof";
                var fqPath    = dir + @"\" + fileName;

                var options = ProfileFromToken(token);

                ProfileIO.ProfileToFile(fqPath, options);
            }
            catch (Exception ex)
            {
                UIMessages.Error(ex.ToString());
            }
        }