Exemple #1
0
        /// <summary>
        /// Initializes the library.
        /// </summary>
        public static void Initialize()
        {
            if (!Signature.IsActivated)
            {
                return;
            }

            if (Files.Count != 0)
            {
                Log.Debug("Library data loaded; checking to see if files still exist.");

                foreach (var ep in Files)
                {
                    var files = ep.Value.ToList();

                    foreach (var file in files)
                    {
                        try
                        {
                            if (!File.Exists(file))
                            {
                                ep.Value.Remove(file);
                            }
                        }
                        catch { }
                    }
                }
            }

            _stmr = new Timer
            {
                AutoReset = false,
                Interval  = 3000
            };
            _stmr.Elapsed += (sender, args) =>
            {
                try
                {
                    SaveList();
                }
                catch (Exception ex)
                {
                    Log.Warn("Error while saving library.", ex);
                }

                if (UPnP.IsRunning)
                {
                    try
                    {
                        UPnP.RebuildList();
                    }
                    catch (Exception ex)
                    {
                        Log.Warn("Error while rebuilding UPnP/DLNA library.", ex);
                    }
                }
            };

            SearchForFiles();
        }
Exemple #2
0
        /// <summary>
        /// Propagates data changes.
        /// </summary>
        /// <param name="delaySave">if set to <c>true</c> the database commit will be delayed for 3 seconds.</param>
        private static void DataChanged(bool delaySave = true)
        {
            try
            {
                if (MainWindow.Active != null && MainWindow.Active.activeGuidesPage != null && MainWindow.Active.activeGuidesPage._activeShowID != 0)
                {
                    MainWindow.Active.Run(MainWindow.Active.activeGuidesPage.Refresh);
                }
            }
            catch { }

            if (delaySave)
            {
                if (_stmr.Enabled)
                {
                    _stmr.Stop();
                }

                _stmr.Start();
            }
            else
            {
                try
                {
                    SaveList();
                }
                catch (Exception ex)
                {
                    Log.Warn("Error while saving library.", ex);
                }

                if (UPnP.IsRunning)
                {
                    try
                    {
                        UPnP.RebuildList();
                    }
                    catch (Exception ex)
                    {
                        Log.Warn("Error while rebuilding UPnP/DLNA library.", ex);
                    }
                }
            }
        }
        /// <summary>
        /// Checks for open files on the specified processes and marks them if recognized.
        /// </summary>
        public static void CheckOpenFiles()
        {
            if (!Settings.Get("Monitor Processes", true))
            {
                return;
            }

            Log.Debug("Checking for open files...");

            var alt    = Settings.Get("Process Monitoring Method", "Internal") == "WindowTitle";
            var netmon = Settings.Get <bool>("Monitor Network Shares");

            if (!alt && !Utils.IsAdmin)
            {
                Log.Info("You are not running with administrator rights but requested file handle monitoring.");
            }

            var procs = new List <string>();

            procs.AddRange(Settings.Get <List <string> >("Processes to Monitor"));

            try
            {
                procs.AddRange(Utils.GetDefaultVideoPlayers().Select(Path.GetFileName));
            }
            catch (Exception ex)
            {
                Log.Warn("Error while getting list of default video players.", ex);
            }

            if (Log.IsTraceEnabled)
            {
                Log.Trace("Requested processes:", procs);
            }

            if (!procs.Any() && !netmon && !UPnP.IsRunning)
            {
                Log.Debug("No processes specified to monitor and network share monitoring is disabled.");
                return;
            }

            var pids = GetPIDs(procs).Distinct().ToList();

            if (Log.IsTraceEnabled)
            {
                Log.Trace("Running PIDs:", pids);
            }

            if (!pids.Any() && !netmon && !UPnP.IsRunning)
            {
                Log.Debug("Unable to get at least one PID for the specified processes and network share monitoring is disabled.");
                return;
            }

            var files  = new List <FileInfo>();
            var titles = new List <string>();

            if (pids.Any())
            {
                if (!alt)
                {
                    using (var mre = new ManualResetEvent(false))
                    {
                        var thd = new Thread(() =>
                        {
                            try
                            {
                                files.AddRange(GetHandleList(pids));
                            }
                            finally
                            {
                                mre.Set();
                            }
                        })
                        {
                            IsBackground = true
                        };

                        thd.Start();

                        if (!mre.WaitOne(TimeSpan.FromMinutes(3)))
                        {
                            Log.Error("Process monitoring method timed out after 3 minutes. Please consider switching implementations from the Settings menu.");

                            try
                            {
                                thd.Interrupt();
                                thd.Abort();
                            } catch { }
                        }
                    }

                    if (files.Count != 0)
                    {
                        Log.Debug(Utils.FormatNumber(files.Count, "file handle", true) + " open for the PID" + (pids.Count != 1 ? "s" : string.Empty) + ": " + string.Join(", ", pids).TrimEnd(", ".ToCharArray()) + ".");
                    }
                }
                else
                {
                    titles.AddRange(GetWindownTitles(pids));

                    if (titles.Count != 0)
                    {
                        Log.Debug(Utils.FormatNumber(files.Count, "window title", true) + " found for the PID" + (pids.Count != 1 ? "s" : string.Empty) + ": " + string.Join(", ", pids).TrimEnd(", ".ToCharArray()) + ".");
                    }

                    if (Log.IsTraceEnabled)
                    {
                        Log.Trace("Window titles:", titles);
                    }
                }
            }

            if (Signature.IsActivated && UPnP.IsRunning)
            {
                try
                {
                    var cnt = files.Count;

                    files.AddRange(UPnP.GetActiveTransfers());

                    if (files.Count != cnt)
                    {
                        Log.Debug(Utils.FormatNumber(files.Count - cnt, "file handle", true) + " open through the UPnP/DLNA server.");
                    }
                }
                catch (Exception ex)
                {
                    Log.Warn("Cannot get active transfer list from the UPnP/DLNA server due to an exception.", ex);
                }
            }

            if (Signature.IsActivated && netmon)
            {
                try
                {
                    var cnt = files.Count;

                    files.AddRange(NetworkShares.GetActiveTransfers());

                    if (files.Count != cnt)
                    {
                        Log.Debug(Utils.FormatNumber(files.Count - cnt, "file handle", true) + " open through Windows file sharing.");
                    }
                }
                catch (Exception ex)
                {
                    Log.Warn("Cannot get active network share transfer list from Windows due to an exception.", ex);
                }
            }

            if (Log.IsTraceEnabled)
            {
                Log.Trace("Open file handles:", files.Select(fi => fi.FullName));
            }

            if (files.Count == 0 && titles.Count == 0)
            {
                Log.Debug("No " + (alt ? "window titles" : "file handles open") + " for the specified processes (" + (pids.Count == 0 ? "none running" : "PID" + (pids.Count != 1 ? "s" : string.Empty) + ": " + string.Join(", ", pids).TrimEnd(", ".ToCharArray())) + ") and services.");
                return;
            }

            foreach (var show in Database.TVShows)
            {
                var titleRegex   = Parser.GenerateTitleRegex(show.Value.Title, show.Value);
                var releaseExpr  = string.Empty;
                var releaseRegex = show.Value.Data.TryGetValue("regex", out releaseExpr) && !string.IsNullOrWhiteSpace(releaseExpr) ? new Regex(releaseExpr) : null;

                foreach (var file in files)
                {
                    if (Parser.IsMatch(file.DirectoryName + @"\" + file.Name, titleRegex) || (releaseRegex != null && Parser.IsMatch(file.DirectoryName + @"\" + file.Name, releaseRegex)))
                    {
                        var pf = FileNames.Parser.ParseFile(file.Name, file.DirectoryName.Split(Path.DirectorySeparatorChar), false);
                        if (pf.Success && show.Value.Title == pf.Show)
                        {
                            Log.Debug("Identified open file " + file.Name + " as " + pf + ".");

                            if (!OpenFiles.Contains(file.ToString()))
                            {
                                // add to open files list
                                // 5 minutes later we'll check again, and if it's still open we'll mark it as seen
                                // the reason for this is that an episode will be marked as seen only if you're watching it for more than 10 minutes (5 minute checks twice)

                                OpenFiles.Add(file.ToString());
                            }
                            else
                            {
                                MarkAsSeen(show.Value.ID, pf);
                            }
                        }
                    }
                }

                foreach (var title in titles)
                {
                    if (Parser.IsMatch(title, titleRegex, null, false) || (releaseRegex != null && Parser.IsMatch(title, releaseRegex, null, false)))
                    {
                        var pf = FileNames.Parser.ParseFile(title, null, false);
                        if (pf.Success && show.Value.Title == pf.Show)
                        {
                            Log.Debug("Identified window title " + title + " as " + pf + ".");

                            if (!OpenFiles.Contains(pf.ToString()))
                            {
                                OpenFiles.Add(pf.ToString());
                            }
                            else
                            {
                                MarkAsSeen(show.Value.ID, pf);
                            }
                        }
                    }
                }
            }
        }