示例#1
0
    protected void PlexGridView_RowCommand(object sender, GridViewCommandEventArgs e)
    {
        if (e.CommandName == "EditPlex")
        {
            int plexId = e.CommandArgument.ToString().ToInt();

            Response.Redirect(string.Format("{0}?PlexId={1}", PageReferrer.Page_FC_SelectMembers, plexId));
        }
        else if (e.CommandName == "DeletePlex")
        {
            int plexId = e.CommandArgument.ToString().ToInt();

            using (PlexingFleetDataContext context = new PlexingFleetDataContext(WebConfigurationManager.ConnectionStrings["PlexManagerConnectionString"].ConnectionString))
            {
                Plex p = context.Plexes.FirstOrDefault(x => x.PlexId == plexId);

                if (p != null)
                {
                    context.Plexes.DeleteOnSubmit(p);
                    context.SubmitChanges();
                }

                FillPlexes();
            }
        }
    }
示例#2
0
    private void UpdateFleet()
    {
        using (PlexingFleetDataContext context = new PlexingFleetDataContext(WebConfigurationManager.ConnectionStrings["PlexManagerConnectionString"].ConnectionString))
        {
            if (PlexId.HasValue)
            {
                Plex plex = context.Plexes.FirstOrDefault(x => x.PlexId == PlexId);

                plex.Participants = GetPilots();
            }
            else
            {
                Fleet fleet = context.Fleets.FirstOrDefault(x => x.FcId == CharacterId);

                if (fleet == null)
                {
                    fleet = new Fleet()
                    {
                        FcId = CharacterId, Participants = GetPilots()
                    };
                    context.Fleets.InsertOnSubmit(fleet);
                }
                else
                {
                    fleet.Participants = GetPilots();
                }
            }

            context.SubmitChanges();
        }
    }
示例#3
0
        public void Execute(IJobExecutionContext context)
        {
            try
            {
                var s = Plex.GetSettings();
                if (!s.EnableTvEpisodeSearching)
                {
                    return;
                }

                var jobs = Job.GetJobs();
                var job  = jobs.FirstOrDefault(x => x.Name.Equals(JobNames.EpisodeCacher, StringComparison.CurrentCultureIgnoreCase));
                if (job != null)
                {
                    if (job.LastRun > DateTime.Now.AddHours(-11)) // If it's been run in the last 11 hours
                    {
                        return;
                    }
                }
                Job.SetRunning(true, JobNames.EpisodeCacher);
                CacheEpisodes(s);
            }
            catch (Exception e)
            {
                Log.Error(e);
            }
            finally
            {
                Job.Record(JobNames.EpisodeCacher);
                Job.SetRunning(false, JobNames.EpisodeCacher);
            }
        }
示例#4
0
        public List <PlexMovie> GetPlexMoviesOld()
        {
            var settings = Plex.GetSettings();
            var movies   = new List <PlexMovie>();
            var libs     = Cache.Get <List <PlexSearch> >(CacheKeys.PlexLibaries);

            if (libs != null)
            {
                var movieLibs = libs.Where(x =>
                                           x.Video.Any(y =>
                                                       y.Type.Equals(PlexMediaType.Movie.ToString(), StringComparison.CurrentCultureIgnoreCase)
                                                       )
                                           ).ToArray();

                foreach (var lib in movieLibs)
                {
                    movies.AddRange(lib.Video.Select(video => new PlexMovie
                    {
                        ReleaseYear = video.Year,
                        Title       = video.Title,
                        ProviderId  = video.ProviderId,
                        Url         = PlexHelper.GetPlexMediaUrl(settings.MachineIdentifier, video.RatingKey)
                    }));
                }
            }
            return(movies);
        }
示例#5
0
    protected void AddPlexLinkButton_Click(object sender, EventArgs e)
    {
        int plexInfoId = PlexInfoDropDownList.SelectedValue.ToInt();

        Plex plex;

        if (PlexCorpDropDownList.SelectedValue.ToInt() != CorpId)
        {
            plex = new Plex()
            {
                FCId = CharacterId, PlexInfoId = plexInfoId, PlexingDate = DateTime.UtcNow, PlexingPeriodId = GetPlexingPeriodId(PlexCorpDropDownList.SelectedValue.ToInt()), Participants = GetPilots(), CorpId = int.Parse(PlexCorpDropDownList.SelectedValue)
            };
        }
        else
        {
            plex = new Plex()
            {
                FCId = CharacterId, PlexInfoId = plexInfoId, PlexingDate = DateTime.UtcNow, PlexingPeriodId = PlexingPeriodId, Participants = GetPilots(), CorpId = int.Parse(PlexCorpDropDownList.SelectedValue)
            };
        }

        using (PlexingFleetDataContext context = new PlexingFleetDataContext(WebConfigurationManager.ConnectionStrings["PlexManagerConnectionString"].ConnectionString))
        {
            context.Plexes.InsertOnSubmit(plex);
            context.SubmitChanges();
        }

        FillPlexes();
    }
示例#6
0
        public List <PlexTvShow> GetPlexTvShows(List <PlexSearch> libs)
        {
            var settings = Plex.GetSettings();
            var shows    = new List <PlexTvShow>();

            if (libs != null)
            {
                var withDir = libs.Where(x => x.Directory != null);
                var tvLibs  = withDir.Where(x =>
                                            x.Directory.Any(y =>
                                                            y.Type.Equals(PlexMediaType.Show.ToString(), StringComparison.CurrentCultureIgnoreCase)
                                                            )
                                            ).ToArray();

                foreach (var lib in tvLibs)
                {
                    shows.AddRange(lib.Directory.Select(x => new PlexTvShow // shows are in the directory list
                    {
                        Title       = x.Title,
                        ReleaseYear = x.Year,
                        ProviderId  = x.ProviderId,
                        Seasons     = x.Seasons?.Select(d => PlexHelper.GetSeasonNumberFromTitle(d.Title)).ToArray(),
                        Url         = PlexHelper.GetPlexMediaUrl(settings.MachineIdentifier, x.RatingKey),
                        ItemId      = x.RatingKey
                    }));
                }
            }
            return(shows);
        }
示例#7
0
        public List <PlexAlbum> GetPlexAlbums(List <PlexSearch> libs)
        {
            var settings = Plex.GetSettings();
            var albums   = new List <PlexAlbum>();

            if (libs != null)
            {
                var albumLibs = libs.Where(x =>
                                           x.Directory.Any(y =>
                                                           y.Type.Equals(PlexMediaType.Artist.ToString(), StringComparison.CurrentCultureIgnoreCase)
                                                           )
                                           ).ToArray();

                foreach (var lib in albumLibs)
                {
                    albums.AddRange(lib.Directory.Select(x => new PlexAlbum()
                    {
                        Title       = x.Title,
                        ProviderId  = x.ProviderId,
                        ReleaseYear = x.Year,
                        Artist      = x.ParentTitle,
                        Url         = PlexHelper.GetPlexMediaUrl(settings.MachineIdentifier, x.RatingKey)
                    }));
                }
            }
            return(albums);
        }
示例#8
0
        /// <summary>
        /// Sets icon.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public async void SetIcon(object sender, ElapsedEventArgs e)
        {
            HttpStatusCode statusCode = await Plex.IsAvailable();

            if (statusCode == HttpStatusCode.OK)
            {
                if (Icon != "/PlexTray;component/Resources/Plex.ico")
                {
                    Icon = "/PlexTray;component/Resources/Plex.ico";
                    OnPropertyChanged("Icon");
                }
            }

            else if (statusCode == HttpStatusCode.Unauthorized)
            {
                if (Icon != "/PlexTray;component/Resources/error.ico")
                {
                    Icon = "/PlexTray;component/Resources/error.ico";
                    OnPropertyChanged("Icon");
                }
            }

            else if (Icon != "/PlexTray;component/Resources/error.ico")
            {
                Icon = "/PlexTray;component/Resources/error.ico";
                OnPropertyChanged("Icon");
            }
        }
示例#9
0
        public async Task CacheContent(bool recentlyAddedSearch = false)
        {
            var plexSettings = await Plex.GetSettingsAsync();

            if (!plexSettings.Enable)
            {
                return;
            }
            if (!ValidateSettings(plexSettings))
            {
                Logger.LogError("Plex Settings are not valid");
                return;
            }

            Logger.LogInformation("Starting Plex Content Cacher");
            try
            {
                await StartTheCache(plexSettings, recentlyAddedSearch);
            }
            catch (Exception e)
            {
                Logger.LogWarning(LoggingEvents.PlexContentCacher, e, "Exception thrown when attempting to cache the Plex Content");
            }

            Logger.LogInformation("Starting EP Cacher");
            BackgroundJob.Enqueue(() => EpisodeSync.Start());
        }
示例#10
0
        public async Task Execute(IJobExecutionContext context)
        {
            JobDataMap dataMap             = context.JobDetail.JobDataMap;
            var        recentlyAddedSearch = dataMap.GetBooleanValueFromString("recentlyAddedSearch");

            var plexSettings = await Plex.GetSettingsAsync();

            if (!plexSettings.Enable)
            {
                return;
            }
            if (!ValidateSettings(plexSettings))
            {
                Logger.LogError("Plex Settings are not valid");
                return;
            }
            var processedContent = new ProcessedContent();

            Logger.LogInformation("Starting Plex Content Cacher");
            try
            {
                if (recentlyAddedSearch)
                {
                    processedContent = await StartTheCache(plexSettings, true);
                }
                else
                {
                    await StartTheCache(plexSettings, false);
                }
            }
            catch (Exception e)
            {
                Logger.LogWarning(LoggingEvents.PlexContentCacher, e, "Exception thrown when attempting to cache the Plex Content");
            }

            if (!recentlyAddedSearch)
            {
                Logger.LogInformation("Starting EP Cacher");

                await OmbiQuartz.TriggerJob(nameof(IPlexEpisodeSync), "Plex");
            }

            if ((processedContent?.HasProcessedContent ?? false) && recentlyAddedSearch)
            {
                // Just check what we send it
                await OmbiQuartz.TriggerJob(nameof(IRefreshMetadata), "System");
            }

            if ((processedContent?.HasProcessedContent ?? false) && recentlyAddedSearch)
            {
                await OmbiQuartz.TriggerJob(nameof(IPlexAvailabilityChecker), "Plex");
            }

            Logger.LogInformation("Finished Plex Content Cacher, with processed content: {0}, episodes: {0}", processedContent.Content.Count(), processedContent.Episodes.Count());
        }
示例#11
0
        protected virtual void Dispose(bool disposing)
        {
            if (_disposed)
            {
                return;
            }

            if (disposing)
            {
                Plex?.Dispose();
                EpisodeSync?.Dispose();
            }
            _disposed = true;
        }
示例#12
0
        public async Task CacheContent(bool recentlyAddedSearch = false)
        {
            var plexSettings = await Plex.GetSettingsAsync();

            if (!plexSettings.Enable)
            {
                return;
            }
            if (!ValidateSettings(plexSettings))
            {
                Logger.LogError("Plex Settings are not valid");
                return;
            }
            var processedContent = new ProcessedContent();

            Logger.LogInformation("Starting Plex Content Cacher");
            try
            {
                if (recentlyAddedSearch)
                {
                    processedContent = await StartTheCache(plexSettings, true);
                }
                else
                {
                    await StartTheCache(plexSettings, false);
                }
            }
            catch (Exception e)
            {
                Logger.LogWarning(LoggingEvents.PlexContentCacher, e, "Exception thrown when attempting to cache the Plex Content");
            }

            if (!recentlyAddedSearch)
            {
                Logger.LogInformation("Starting EP Cacher");
                BackgroundJob.Enqueue(() => EpisodeSync.Start());
            }

            if ((processedContent?.HasProcessedContent ?? false) && recentlyAddedSearch)
            {
                // Just check what we send it
                BackgroundJob.Enqueue(() => Metadata.ProcessPlexServerContent(processedContent.Content));
            }

            if ((processedContent?.HasProcessedEpisodes ?? false) && recentlyAddedSearch)
            {
                BackgroundJob.Enqueue(() => Checker.Start());
            }
        }
示例#13
0
        public void CacheContent()
        {
            var plexSettings = Plex.GetSettings();

            if (!ValidateSettings(plexSettings))
            {
                Log.Debug("Validation of the plex settings failed.");
                return;
            }
            var libraries = CachedLibraries(plexSettings);

            if (libraries == null || !libraries.Any())
            {
                Log.Debug("Did not find any libraries in Plex.");
                return;
            }
        }
    protected void PlexingPeriodInfoGridView_RowCommand(object sender, CommandEventArgs e)
    {
        if (e.CommandName == "EditPlex")
        {
            Response.Redirect(string.Format("{0}?PlexId={1}&ReturnUrl={2}&PlexingPeriodId={3}&CharacterName={4}", PageReferrer.Page_FC_SelectMembers, e.CommandArgument.ToString(), PageReferrer.Page_User_PlexingPeriod, PlexingPeriodId, CharName));
        }
        else if (e.CommandName == "DeletePlex")
        {
            int plexId = e.CommandArgument.ToString().ToInt();

            using (PlexingFleetDataContext context = new PlexingFleetDataContext(WebConfigurationManager.ConnectionStrings["PlexManagerConnectionString"].ConnectionString))
            {
                Plex p = context.Plexes.FirstOrDefault(x => x.PlexId == plexId);

                if (p != null)
                {
                    p.Participants = p.Participants.Replace(string.Format("{0}, ", CharName), "").Replace(string.Format(", {0}", CharName), "");
                    p.Participants = p.Participants.Replace(CharName, "");

                    if (string.IsNullOrEmpty(p.Participants.Trim()))
                    {
                        context.Plexes.DeleteOnSubmit(p);
                    }
                    context.SubmitChanges();
                }

                if (SelectedDate.HasValue)
                {
                    FillPlexingPeriodDateData(PlexingPeriodId, SelectedDate.Value);
                }
                else
                {
                    FillPlexingPeriodData(PlexingPeriodId);
                }
            }
        }
    }
示例#15
0
        public void Start()
        {
            try
            {
                var s = Plex.GetSettings();
                if (!s.EnableTvEpisodeSearching)
                {
                    return;
                }


                Job.SetRunning(true, JobNames.EpisodeCacher);
                CacheEpisodes(s);
            }
            catch (Exception e)
            {
                Log.Error(e);
            }
            finally
            {
                Job.Record(JobNames.EpisodeCacher);
                Job.SetRunning(false, JobNames.EpisodeCacher);
            }
        }
示例#16
0
    private void LoadFleet()
    {
        PilotListBox.Items.Clear();

        using (PlexingFleetDataContext context = new PlexingFleetDataContext(WebConfigurationManager.ConnectionStrings["PlexManagerConnectionString"].ConnectionString))
        {
            if (PlexId.HasValue)
            {
                Plex plex = context.Plexes.FirstOrDefault(x => x.PlexId == PlexId);

                if (plex != null)
                {
                    string[] pilots = plex.Participants.Split(',');

                    foreach (string pilot in pilots)
                    {
                        PilotListBox.Items.Add(new ListItem(pilot.Trim(), pilot.Trim()));
                    }
                }
            }
            else
            {
                Fleet fleet = context.Fleets.FirstOrDefault(x => x.FcId == CharacterId);

                if (fleet != null)
                {
                    string[] pilots = fleet.Participants.Split(',');

                    foreach (string pilot in pilots)
                    {
                        PilotListBox.Items.Add(new ListItem(pilot.Trim(), pilot.Trim()));
                    }
                }
            }
        }
    }
        public void CheckAndUpdateAll()
        {
            Log.Trace("Getting the settings");
            var plexSettings = Plex.GetSettings();
            var authSettings = Auth.GetSettings();
            Log.Trace("Getting all the requests");

            if (!ValidateSettings(plexSettings, authSettings))
            {
                Log.Info("Validation of the plex settings failed.");
                return;
            }

            var libraries = CachedLibraries(authSettings, plexSettings, true); //force setting the cache (10 min intervals via scheduler)

            if (libraries == null || !libraries.Any())
            {
                Log.Info("Did not find any libraries in Plex.");
                return;
            }

            var movies = GetPlexMovies().ToArray();
            var shows = GetPlexTvShows().ToArray();
            var albums = GetPlexAlbums().ToArray();

            var requests = RequestService.GetAll();
            var requestedModels = requests as RequestedModel[] ?? requests.Where(x => !x.Available).ToArray();
            Log.Trace("Requests Count {0}", requestedModels.Length);

            if (!requestedModels.Any())
            {
                Log.Info("There are no requests to check.");
                return;
            }

            var modifiedModel = new List<RequestedModel>();
            foreach (var r in requestedModels)
            {
                Log.Trace("We are going to see if Plex has the following title: {0}", r.Title);

                Log.Trace("Search results from Plex for the following request: {0}", r.Title);

                var releaseDate = r.ReleaseDate == DateTime.MinValue ? string.Empty : r.ReleaseDate.ToString("yyyy");

                bool matchResult;
                switch (r.Type)
                {
                    case RequestType.Movie:
                        matchResult = IsMovieAvailable(movies, r.Title, releaseDate);
                        break;
                    case RequestType.TvShow:
                        matchResult = IsTvShowAvailable(shows, r.Title, releaseDate);
                        break;
                    case RequestType.Album:
                        matchResult = IsAlbumAvailable(albums, r.Title, r.ReleaseDate.Year.ToString(), r.ArtistName);
                        break;
                    default:
                        throw new ArgumentOutOfRangeException();
                }

                if (matchResult)
                {
                    r.Available = true;
                    modifiedModel.Add(r);
                    continue;
                }

                Log.Trace("The result from Plex where the title's match was null, so that means the content is not yet in Plex.");
            }

            Log.Trace("Updating the requests now");
            Log.Trace("Requests that will be updated count {0}", modifiedModel.Count);

            if (modifiedModel.Any())
            {
                NotifyUsers(modifiedModel, authSettings.PlexAuthToken);
                RequestService.BatchUpdate(modifiedModel);
            }

            Job.Record(JobNames.PlexChecker);

        }
示例#18
0
 GraphComponent ComposeRendering(Plex plex)
 // Strategy: compose the component strands individually. Then connect the hydrogen bonds.
     {
     // Each plex forms a (new) component of the graph
     //
     GraphComponent component = new GraphComponent(this);
     //
     // Compose each strand. For starters, we place them vertically one atop another.
     //
     double y = 0;
     foreach (Strand strand in plex.CanonicallyOrderedStrands)
         {
         this.ComposeRendering(component, strand, y);
         y += Constants.StrandRenderingInitialDY;
         }
     //
     // Hydrogen bonds within the plex will need additional visualization
     // 
     WireHydrogenBonds(component, plex.AllStrands());
     //
     return component;
     }
 partial void UpdatePlex(Plex instance);
 partial void DeletePlex(Plex instance);
示例#21
0
        public void CheckAndUpdateAll()
        {
            var plexSettings = Plex.GetSettings();

            if (!ValidateSettings(plexSettings))
            {
                Log.Debug("Validation of the plex settings failed.");
                return;
            }
            //var libraries = CachedLibraries(plexSettings, true); //force setting the cache (10 min intervals via scheduler)

            //if (libraries == null || !libraries.Any())
            //{
            //    Log.Debug("Did not find any libraries in Plex.");
            //    return;
            //}
            var content = PlexContent.GetAll().ToList();
            var movies  = GetPlexMovies(content).ToArray();
            var shows   = GetPlexTvShows(content).ToArray();
            var albums  = GetPlexAlbums(content).ToArray();

            var requests        = RequestService.GetAll();
            var requestedModels = requests as RequestedModel[] ?? requests.Where(x => !x.Available).ToArray();

            if (!requestedModels.Any())
            {
                Log.Debug("There are no requests to check.");
                return;
            }

            var modifiedModel = new List <RequestedModel>();

            foreach (var r in requestedModels)
            {
                var  releaseDate = r.ReleaseDate == DateTime.MinValue ? string.Empty : r.ReleaseDate.ToString("yyyy");
                bool matchResult;

                switch (r.Type)
                {
                case RequestType.Movie:
                    matchResult = IsMovieAvailable(movies, r.Title, releaseDate, r.ImdbId);
                    break;

                case RequestType.TvShow:
                    if (!plexSettings.EnableTvEpisodeSearching)
                    {
                        matchResult = IsTvShowAvailable(shows, r.Title, releaseDate, r.TvDbId, r.SeasonList);
                    }
                    else
                    {
                        matchResult = r.Episodes.Any() ?
                                      r.Episodes.All(x => IsEpisodeAvailable(r.TvDbId, x.SeasonNumber, x.EpisodeNumber)) :
                                      IsTvShowAvailable(shows, r.Title, releaseDate, r.TvDbId, r.SeasonList);
                    }
                    break;

                case RequestType.Album:
                    matchResult = IsAlbumAvailable(albums, r.Title, r.ReleaseDate.Year.ToString(), r.ArtistName);
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }


                if (matchResult)
                {
                    r.Available = true;
                    modifiedModel.Add(r);
                    continue;
                }
            }

            Log.Debug("Requests that will be updated count {0}", modifiedModel.Count);

            if (modifiedModel.Any())
            {
                NotificationEngine.NotifyUsers(modifiedModel, plexSettings.PlexAuthToken, NotificationType.RequestAvailable);
                RequestService.BatchUpdate(modifiedModel);
            }
        }
 partial void InsertPlex(Plex instance);
示例#23
0
        public async Task Execute(IJobExecutionContext context)
        {
            JobDataMap dataMap             = context.JobDetail.JobDataMap;
            var        recentlyAddedSearch = dataMap.GetBooleanValueFromString(JobDataKeys.RecentlyAddedSearch);

            var plexSettings = await Plex.GetSettingsAsync();

            if (!plexSettings.Enable)
            {
                return;
            }
            await NotifyClient(recentlyAddedSearch? "Plex Recently Added Sync Started" : "Plex Content Sync Started");

            if (!ValidateSettings(plexSettings))
            {
                Logger.LogError("Plex Settings are not valid");
                await NotifyClient(recentlyAddedSearch? "Plex Recently Added Sync, Settings Not Valid" : "Plex Content, Settings Not Valid");

                return;
            }
            var processedContent = new ProcessedContent();

            Logger.LogInformation(recentlyAddedSearch
                ? "Starting Plex Content Cacher Recently Added Scan"
                : "Starting Plex Content Cacher");
            try
            {
                if (recentlyAddedSearch)
                {
                    processedContent = await StartTheCache(plexSettings, true);
                }
                else
                {
                    await StartTheCache(plexSettings, false);
                }
            }
            catch (Exception e)
            {
                await NotifyClient(recentlyAddedSearch? "Plex Recently Added Sync Errored" : "Plex Content Sync Errored");

                Logger.LogWarning(LoggingEvents.PlexContentCacher, e, "Exception thrown when attempting to cache the Plex Content");
            }

            if (!recentlyAddedSearch)
            {
                await NotifyClient("Plex Sync - Starting Episode Sync");

                Logger.LogInformation("Starting EP Cacher");
                await OmbiQuartz.TriggerJob(nameof(IPlexEpisodeSync), "Plex");
            }

            if ((processedContent?.HasProcessedContent ?? false) && recentlyAddedSearch)
            {
                await NotifyClient("Plex Sync - Checking if any requests are now available");

                Logger.LogInformation("Kicking off Plex Availability Checker");
                await _mediaCacheService.Purge();

                await OmbiQuartz.TriggerJob(nameof(IPlexAvailabilityChecker), "Plex");
            }
            var processedCont = processedContent?.Content?.Count() ?? 0;
            var processedEp   = processedContent?.Episodes?.Count() ?? 0;

            Logger.LogInformation("Finished Plex Content Cacher, with processed content: {0}, episodes: {1}. Recently Added Scan: {2}", processedCont, processedEp, recentlyAddedSearch);

            await NotifyClient(recentlyAddedSearch?$"Plex Recently Added Sync Finished, We processed {processedCont}, and {processedEp} Episodes" : "Plex Content Sync Finished");
        }
示例#24
0
        private static void Main(string[] args)
        {
            // Configure the console
            Console.Title = "PlexBird";

            // Configure the logger
            var xmlDocument = new XmlDocument();

            xmlDocument.LoadXml(Resources.log4net);

            XmlConfigurator.Configure(xmlDocument.DocumentElement);

            Logger.Info("Launching PlexBird..");

            // Check config
            var configPath = Path.Combine(Environment.CurrentDirectory, "config.json");

            if (!File.Exists(configPath))
            {
                var defaultConfiguration = new Configuration
                {
                    Username     = string.Empty,
                    AuthToken    = string.Empty,
                    PlexUrl      = "http://localhost:32400/",
                    AnimeLibrary = "Anime TV Series",
                    SyncTime     = 60
                };

                File.WriteAllText(configPath, JsonConvert.SerializeObject(defaultConfiguration, Formatting.Indented));

                Logger.Error("Configuration file not found!");
                Logger.Warn("A configuration file has been generated, please edit config.json!");

                Console.ReadKey();
                return;
            }

            Configuration = JsonConvert.DeserializeObject <Configuration>(File.ReadAllText(configPath));

            if (Configuration.Username.Equals(string.Empty) || Configuration.AuthToken.Equals(string.Empty))
            {
                Logger.Info("No AuthToken was found, you have to sign in to connect with HummingBird.");

                while (Configuration.AuthToken.Equals(string.Empty))
                {
                    Console.Write("HummingBird username: "******"HummingBird password: "******"Wrong username/password combination, try again.");
                    }
                }
            }

            HummingBird.SetAuthenticationToken(Configuration.AuthToken);
            User = HummingBird.GetUser(Configuration.Username);

            Logger.Info($"Connected to HummingBird as the user {User.Name}, you've spent {User.LifeSpentOnAnime} minutes watching anime.");

            // Check database
            var databasePath = Path.Combine(Environment.CurrentDirectory, "database.json");

            if (!File.Exists(databasePath))
            {
                Database = new Dictionary <string, DatabaseEntry>();
                SaveDatabase();
            }
            else
            {
                Database = JsonConvert.DeserializeObject <Dictionary <string, DatabaseEntry> >(File.ReadAllText(databasePath));
            }

            // Setup plex
            var         plex        = new Plex(Configuration.PlexUrl);
            PlexLibrary plexLibrary = null;

            // Search plexLibrary
            foreach (var plexLib in plex.GetLibraries())
            {
                if (!plexLib.Title.Equals(Configuration.AnimeLibrary))
                {
                    continue;
                }

                if (plexLibrary != null)
                {
                    throw new Exception($"The plex installation '{plex.Information.FriendlyName}' seems to have more than one '{plexLib.Title}' library.");
                }

                plexLibrary = plexLib;
            }

            if (plexLibrary == null)
            {
                throw new Exception($"The plex installation '{plex.Information.FriendlyName}' seems to not have '{Configuration.AnimeLibrary}' library.");
            }

            // Connected
            new Thread(SynchronizeLibrary).Start(new ThreadData
            {
                Plex        = plex,
                PlexLibrary = plexLibrary
            });

            // End
            SaveDatabase();
        }