public HttpResponseMessage Get(string Method, string Ver = null, string Device = null, string Sid = null, string Md5 = null, int channel_id = 0, int start = 0, int end = 0, string group_id = null, string filter = null, int recording_id = 0, string name = null, int channel = 0, int time_t = 0, int duration = 0)
 {
     Logger.ServiceILog("Service Request: {0}, {1}", Method, Request.RequestUri.ToString());
     object response = new Response() { ErrorCode = 0, ErrorMessage = "Unknown method." };
     try
     {
         switch ((Method ?? "").ToLower())
         {
             case "session.initiate": response = Session_Initiate(Ver, Device); break;
             case "session.login": response = Session_Login(Sid, Md5); break;
             case "channel.icon": response = Channel_Icon(channel_id); break;
             default:
             {
                 var config = new Models.Configuration();
                 int userOid = 0;
                 if (config.EnableUserSupport) /* ensure a user is found if users are enabled */
                 {
                     if (!String.IsNullOrWhiteSpace(Sid) && SessionUserOids.ContainsKey(Sid))
                         userOid = SessionUserOids[Sid];
                     else
                         throw new UnauthorizedAccessException();
                 }
                 switch ((Method ?? "").ToLower())
                 {
                     case "setting.list": response = Setting_List(); break;
                     case "channel.listings": response = Channel_Listings(userOid, channel_id, start, end); break;
                     case "channel.list": response = Channel_List(userOid, group_id); break;
                     case "channel.groups": response = Channel_Groups(userOid); break;
                     case "recording.list": response = Recording_List(userOid, filter); break;
                     case "recording.delete": response = Recording_Delete(userOid, recording_id); break;
                     case "recording.save": response = Recording_Save(userOid, name, channel, time_t, duration); break;
                 }
             }
             break;
         }
     }
     catch (InvalidSessionException)
     {
         response = new Response()
         {
             ErrorCode = 8,
             ErrorMessage = "Invalid Session",
             Stat = Response.ResponseStat.fail /* NOTE: this is a "fail" response */
         };
     }
     catch (ChannelNotFoundException)
     {
         response = new Response()
         {
             ErrorCode = 5,
             ErrorMessage = "Channel not found",
             Stat = Response.ResponseStat.failed /* NOTE: this is a "fail" response */
         };
     }
     if (response is Response)
         return new HttpResponseMessage() { Content = new StringContent(response.ToString(), System.Text.Encoding.UTF8, "application/xml") };
     else if (response == null)
         return new HttpResponseMessage(HttpStatusCode.NotFound);
     return response as HttpResponseMessage;
 }
Exemplo n.º 2
0
        public static string Encrypt(string Text, string EncryptionKey = null)
        {
            if (EncryptionKey == null)
                EncryptionKey = new Configuration().PrivateSecret;
            Encoding unicode = Encoding.Unicode;

            string result = Convert.ToBase64String(Encrypt(unicode.GetBytes(EncryptionKey), unicode.GetBytes(Text)));
            return result.Replace("/", "_").Replace("+", "-"); // replace these characters for URLs
        }
Exemplo n.º 3
0
        public static string Decrypt(string Text, string EncryptionKey = null)
        {
            if (EncryptionKey == null)
                EncryptionKey = new Configuration().PrivateSecret;
            Encoding unicode = Encoding.Unicode;
            Text = Text.Replace("_", "/").Replace("-", "+"); // replace the characters used for URLs

            return unicode.GetString(Encrypt(unicode.GetBytes(EncryptionKey), Convert.FromBase64String(Text)));
        }
Exemplo n.º 4
0
 public void Application_BeginRequest()
 {
     string url = Request.Url.ToString().ToLower();
     if (!Regex.IsMatch(url, "/(setup|bundle|scripts|content|languages)"))
     {
         Models.Configuration config = new Models.Configuration();
         if (config.FirstRun)
             HttpContext.Current.Response.Redirect("~/Setup");
     }
 }
Exemplo n.º 5
0
        // GET api/guide
        public IEnumerable<Channel> Get(DateTime Date, string Group)
        {
            var userOid = this.GetUser().Oid;
            var config = new Configuration();
            if (!config.EnableUserSupport)
                userOid = Globals.SHARED_USER_OID;

            // round start to midnight today.
            DateTime start = new DateTime(Date.Year, Date.Month, Date.Day, 0, 0, 0);
            start = TimeZone.CurrentTimeZone.ToUniversalTime(start); // convert to utc
            return Models.Channel.LoadForTimePeriod(userOid, Group, start, start.AddDays(1));
        }
Exemplo n.º 6
0
        public static RecordingSchedule QuickRecord(int UserOid, int EpgEventOid)
        {
            var config = new Configuration();
            RecordingDirectory rd = null;
            if (config.EnableUserSupport && config.UserRecordingDirectoriesEnabled)
                rd = RecordingDirectory.LoadUserDefault(UserOid);

            if (rd == null)
                rd = RecordingDirectory.LoadSystemDefault();

            var schedule = new Models.RecordingSchedule()
            {
                NumberToKeep = 0,
                EpgEventOid = EpgEventOid,
                PostPadding = config.PostPadding,
                PrePadding = config.PrePadding,
                RecordingDirectoryId = rd == null ? "" : rd.RecordingDirectoryId,
                Type = RecordingType.Record_Once
            };
            if (schedule.Save(UserOid))
                return schedule;
            return null;
        }
        /// <summary>
        /// Saves the recording directories for a user, will delete any that aren't listed
        /// </summary>
        /// <param name="UserOid">the OID of the User</param>
        /// <param name="RecordingDirectories">the list of recording directories to save</param>
        internal static bool SaveForUser(int UserOid, List<RecordingDirectory> RecordingDirectories)
        {
            RecordingDirectories.ForEach(x => { if (x.UserOid == 0) x.UserOid = UserOid; });
            if (RecordingDirectories.Where(x => x.UserOid == UserOid).DuplicatesBy(x => x.Name.ToLower().Trim()).Count() > 0)
                throw new ArgumentException("Recording Directory names must be unique.");

            // validate path names
            foreach (var rd in RecordingDirectories.Where(x => x.UserOid == UserOid))
            {
                if (!Validators.Validator.IsValid(rd))
                    throw new ArgumentException("Invalid parameters");
            }

            var config = new Configuration();
            string username = User.GetUsername(UserOid);
            var db = DbHelper.GetDatabase();
            db.BeginTransaction();
            try
            {
                // delete the old
                string rdOids = String.Join(",", (from rd in RecordingDirectories where rd.Oid > 0 select rd.Oid.ToString()).ToArray());
                db.Execute("delete from recordingdirectory where useroid = {0} {1}".FormatStr(UserOid, String.IsNullOrWhiteSpace(rdOids) ? "" : "and oid not in ({0})".FormatStr(rdOids)));

                int defaultRecordingDirectoryOid = 0;
                // save the rest
                foreach (var rd in RecordingDirectories)
                {
                    if (rd.IsDefault)
                        defaultRecordingDirectoryOid = rd.Oid;
                    if (UserOid != Globals.SHARED_USER_OID && rd.IsShared) // dont let users update the shared directory
                        continue;

                    if (UserOid != Globals.SHARED_USER_OID && (!config.EnableUserSupport || !config.UserRecordingDirectoriesEnabled))
                        continue;

                    rd.UserOid = UserOid;
                    rd.Username = username;
                    if (rd.Oid < 1) // new one
                        db.Insert("recordingdirectory", "oid", true, rd);
                    else // update an old one
                        db.Update(rd);
                }

                if (UserOid != Globals.SHARED_USER_OID)
                {
                    if (defaultRecordingDirectoryOid == 0 && RecordingDirectories.Count > 0)
                        defaultRecordingDirectoryOid = RecordingDirectories[0].Oid;
                    if (defaultRecordingDirectoryOid > 0)
                        db.Execute("update [user] set [defaultrecordingdirectoryoid] = @0 where oid = @1", defaultRecordingDirectoryOid, UserOid);
                }

                db.CompleteTransaction();
                Configuration.Write();
                return true;
            }
            catch (Exception ex)
            {
                db.AbortTransaction();
                return false;
            }
        }
 public static List<RecordingDirectory> LoadForUser(int UserOid, bool IncludeShared = false)
 {
     var db = DbHelper.GetDatabase();
     var config = new Configuration();
     if (config.EnableUserSupport && config.UserRecordingDirectoriesEnabled)
     {
         int userDefault = db.ExecuteScalar<int>("select defaultrecordingdirectoryoid from[user] where oid = @0", UserOid);
         string select = "select rd.*, username from recordingdirectory rd inner join [user] u on rd.useroid = u.oid where useroid = {0} {1}".FormatStr(UserOid, IncludeShared ? " or useroid = {0}".FormatStr(Globals.SHARED_USER_OID) : "");
         List<RecordingDirectory> results = db.Fetch<RecordingDirectory>(select);
         foreach (var r in results)
             r.IsDefault = r.Oid == userDefault;
         return SetUserPaths(results);
     }
     else if (!IncludeShared && UserOid != Globals.SHARED_USER_OID)
     {
         return new List<RecordingDirectory>(); // nothing to return then
     }
     else
     {
         return db.Fetch<RecordingDirectory>("select rd.*, username from recordingdirectory rd inner join user u on rd.useroid = u.oid where useroid = @0", Globals.SHARED_USER_OID);
     }
 }
Exemplo n.º 9
0
        public static int[] LoadChannelOids(int UserOid, string GroupName)
        {
            var channelGroup = GetByName(UserOid, GroupName);
            if (channelGroup == null)
                return new int[] { };

            var db = DbHelper.GetDatabase();
            bool userSupport = new Configuration().EnableUserSupport;
            string sql = "select cgc.channeloid from channelgroupchannel cgc inner join channel c on cgc.channeloid = c.oid where c.enabled = 1 and channelgroupoid = @0";
            if (userSupport)
            {
                // need to filter out their disabled channels
                sql = "select cgc.channeloid from channelgroupchannel cgc inner join channel c on cgc.channeloid = c.oid inner join userchannel uc on cgc.channeloid = uc.channeloid where c.enabled = 1 and uc.enabled = 1 and channelgroupoid = @0 and uc.useroid = " + UserOid;
            }
            return db.Fetch<int>(sql, channelGroup.Oid).ToArray();
        }
Exemplo n.º 10
0
        public ActionResult Index(Models.SetupModel Model)
        {
            #if(DEBUG)
            System.Threading.Thread.Sleep(2000);
            #endif
            try
            {
                if (!new Models.Configuration().FirstRun)
                    return RedirectToAction("Login", "Account");
            }
            catch (Exception)
            {
                // db likely not created or setup.
            }

            if (!ModelState.IsValid)
                return View();

            // is valid

            // load recording directories from NextPVR and import as shared directories.
            #region import recording directories
            string defaultRecordingDirectory = Models.NextPvrConfigHelper.DefaultRecordingDirectory;
            KeyValuePair<string, string>[] extras = Models.NextPvrConfigHelper.ExtraRecordingDirectories;

            if (!String.IsNullOrWhiteSpace(defaultRecordingDirectory))
                new Models.RecordingDirectory() { Name = "Default", UserOid = Globals.SHARED_USER_OID, Path = defaultRecordingDirectory, Username = Globals.SHARED_USER_USERNAME, IsDefault = true }.Save();
            foreach (var extra in extras)
            {
                // make sure there aren't any directories from NextPVRWebConsole
                string name = "[{0}]".FormatStr(extra.Key);
                if (name.StartsWith("[Shared - "))
                    name = "[" + name.Substring("[Shared - ".Length);
                if (Regex.IsMatch(name, @"^\[[^\]\-]+\-[^\]]+\]$"))
                    continue; // must be a user directory, so skip it
                if (name.StartsWith("[") && name.EndsWith("]"))
                    name = name.Substring(1, name.Length - 2);
                new Models.RecordingDirectory() { Name = name, UserOid = Globals.SHARED_USER_OID, Path = extra.Value, Username = Globals.SHARED_USER_USERNAME }.Save();
            }
            #endregion

            var db = DbHelper.GetDatabase(false);
            #region import channels and groups
            db.BeginTransaction();
            try
            {
                // insert channels
                var channels = NUtility.Channel.LoadAll().OrderBy(x => x.Number).Select(x => new Models.Channel() { Oid = x.OID, Name = x.Name, Number = x.Number, Enabled = true }).ToArray();
                foreach (var c in channels)
                    db.Insert("channel", "oid", false, c);

                // insert groups
                var groups = NUtility.Channel.GetChannelGroups().Where(x => x != "All Channels" && x != "All TV Channels").Select(x => new Models.ChannelGroup() { Name = x, UserOid = Globals.SHARED_USER_OID }).ToArray();
                for (int i = 0; i < groups.Length; i++)
                {
                    groups[i].OrderOid = i + 1;
                    db.Insert("channelgroup", "oid", true, groups[i]);
                    foreach (int channelOid in NUtility.Channel.LoadForGroup(groups[i].Name).Select(x => x.OID))
                        db.Execute("insert into [channelgroupchannel](channelgroupoid, channeloid) values (@0, @1)", groups[i].Oid, channelOid);
                }

                db.CompleteTransaction();
            }
            catch (Exception ex) { db.AbortTransaction(); throw ex; }
            #endregion

            // create user, do this after importing folders, otherwise this users new folder with have an oid lower than the origial defaults (not a big deal, just prettier this way)
            var user = Models.User.CreateUser(Model.Username, Model.EmailAddress, Model.Password, Globals.USER_ROLE_ALL, true, DateTime.UtcNow);
            if (user == null)
                throw new Exception("Failed to create user: "******"/") + 1);

            // turn off first run
            config.FirstRun = false;
            config.Save();
            db.CompleteTransaction();

            return RedirectToAction("Index", "Home");
        }
Exemplo n.º 11
0
        public static NUtility.ScheduledRecording QuickRecord(int UserOid, int Oid)
        {
            var config = new Configuration();
            RecordingDirectory rd = null;
            if (config.EnableUserSupport && config.UserRecordingDirectoriesEnabled)
                rd = RecordingDirectory.LoadUserDefault(UserOid);

            if (rd == null)
                rd = RecordingDirectory.LoadSystemDefault();

            return Record(UserOid, new Models.RecordingSchedule()
            {
                NumberToKeep = 0,
                Oid = Oid,
                PostPadding = config.PostPadding,
                PrePadding = config.PrePadding,
                RecordingDirectoryId = rd == null ? "" : rd.RecordingDirectoryId,
                Type = RecordingType.Record_Once
            });
        }
Exemplo n.º 12
0
        public static List<EpgListing> LoadEpgListings(int UserOid, int[] ChannelOids, IEnumerable<NUtility.EPGEvent> Data, RecordingDirectory UserDefault = null)
        {
            Stopwatch timer = new Stopwatch();
            timer.Start();
            Logger.Log("Loading EPG Listings [0]: " + timer.Elapsed);
            var config = new Configuration();
            if(UserDefault == null)
                UserDefault = RecordingDirectory.LoadUserDefault(UserOid);

            var allowedRecordings = EpgRecordingData.LoadAllowedRecordings(UserOid);
            Logger.Log("Loading EPG Listings [2]: " + timer.Elapsed);

            timer.Stop();
            return Data.Select(x =>
            {
                var listing = new EpgListing(x);
                if (allowedRecordings.ContainsKey(x.OID))
                {
                    listing.PrePadding = allowedRecordings[x.OID].PrePadding;
                    listing.PostPadding = allowedRecordings[x.OID].PostPadding;
                    listing.RecordingDirectoryId = allowedRecordings[x.OID].RecordingDirectoryId;
                    listing.Keep = allowedRecordings[x.OID].Keep;
                    listing.IsRecurring = allowedRecordings[x.OID].IsRecurring;
                    listing.RecordingType = allowedRecordings[x.OID].RecordingType;
                    listing.RecordingOid = allowedRecordings[x.OID].RecordingOid;
                    listing.IsRecording = true;
                }
                else
                {
                    listing.PrePadding = config.PrePadding;
                    listing.PostPadding = config.PostPadding;
                    listing.RecordingDirectoryId = UserDefault == null ? null : UserDefault.RecordingDirectoryId;
                }
                return listing;
            }).ToList();
        }
Exemplo n.º 13
0
        internal static User ValidateResetCode(string Code)
        {
            var config = new Configuration();
            string decrypted = Helpers.Encrypter.Decrypt(Code);
            string[] parts = decrypted.Split(':');
            if(parts.Length != 3)
                throw new Exception("Invalid code.");

            string username = parts[0];
            string email = parts[1];
            long dateticks = 0;
            if(!long.TryParse(parts[2], out dateticks))
                throw new Exception("Invalid code.");

            var user = GetByUsername(username);
            if (user == null || user.EmailAddress != email)
                throw new Exception("Invalid code.");

            DateTime code = new DateTime(dateticks);
            if (code > DateTime.UtcNow) // should never be greater than now, since THIS server must have generated this code in the past.
                throw new Exception("Invalid code.");
            if (code < DateTime.UtcNow.AddDays(-1))
                throw new Exception("Expired code.");

            // generate new password and send it to them
            string newPassword = Membership.GeneratePassword(12, 2);
            user.ChangePassword(newPassword);

            Helpers.Emailer.Send(user.EmailAddress, "NextPVR Web Console Password Reset", Resources.Files.PasswordResetBody.Replace("{Username}", user.Username).Replace("{Password}", newPassword).Replace("{Url}", config.WebsiteAddress));

            return user;
        }
Exemplo n.º 14
0
        public static void SendPasswordResetRequest(string UsernameOrEmailAddress)
        {
            var db = DbHelper.GetDatabase();
            var user = db.FirstOrDefault<User>("select * from [user] where username = @0 or emailaddress = @0", UsernameOrEmailAddress);
            if (user == null)
                throw new Exception("User not found.");

            var config = new Configuration();
            string url = "{0}ResetPassword?code={1}".FormatStr(config.WebsiteAddress, Helpers.Encrypter.Encrypt("{0}:{1}:{2}".FormatStr(user.Username, user.EmailAddress, DateTime.UtcNow.Ticks)));

            Helpers.Emailer.Send(user.EmailAddress, "NextPVR Web Console Password Reset Request", Resources.Files.PasswordResetRequestBody.Replace("{Url}", url));
        }
Exemplo n.º 15
0
        protected void Application_Start()
        {
            Globals.WebConsolePhysicalPath = Server.MapPath("~/");
            Globals.WebConsoleLoggingDirectory = Server.MapPath("~/Logging");
            Globals.NextPvrWebConsoleVersion = Assembly.GetExecutingAssembly().GetName().Version;
            Globals.NextPvrVersion = new Version(NUtility.SettingsHelper.GetInstance().GetSetting("/Settings/Version/CurrentVersion", "0.0.0") + ".0");

            Models.DbHelper.Test();

            //NUtility.Logger.SetLogFileName(@"logs\reven.log");

            AreaRegistration.RegisterAllAreas();

            // Register CustomRegularExpressionValidator
            DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(Validators.DirectoryAttribute), typeof(Validators.DirectoryValidator));
            DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(Validators.EmailAttribute), typeof(Validators.EmailValidator));
            DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(Validators.UsernameAttribute), typeof(Validators.UsernameValidator));
            DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(Validators.WebsiteAddressAttribute), typeof(Validators.WebsiteAddressValidator));

            DisplayModeProvider.Instance.Modes.Insert(0, new MobileDisplayMode());

            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);

            GlobalConfiguration.Configuration.Formatters.JsonFormatter.MediaTypeMappings.Add(new QueryStringMapping("json", "true", "application/json"));

            Workers.DeviceWatcher watcherDevice = new Workers.DeviceWatcher();
            watcherDevice.Start();
            watcherDevice.TunerStatusUpdated += delegate(Workers.DeviceUpdateEvent[] Events)
            {
                Hubs.NextPvrEventHub.Clients_DeviceStatusUpdated(Events);
            };

            Models.Configuration config = new Models.Configuration();
            Logger.Log("Application started.");

            timer_Elapsed(null, null); // it on startup
            timer = new System.Timers.Timer(60 * 60 * 1000);
            timer.AutoReset = true;
            timer.Elapsed += timer_Elapsed;
            timer.Start();
        }
 private static List<RecordingDirectory> SetUserPaths(List<RecordingDirectory> Directories)
 {
     var config = new Configuration();
     foreach (var dir in Directories)
     {
         if (dir.UserOid != Globals.SHARED_USER_OID)
             dir.Path = config.UserBaseRecordingDirectory == null ? null : System.IO.Path.Combine(config.UserBaseRecordingDirectory, dir.Username, dir.Name);
     }
     return Directories;
 }
 internal static bool DeleteByOid(int UserOid, int Oid)
 {
     var recurrence = Helpers.NpvrCoreHelper.RecurringRecordingLoadByOID(Oid);
     if (recurrence == null)
         throw new Exception("Failed to locate recurrence.");
     var config = new Configuration();
     if (config.EnableUserSupport && !String.IsNullOrWhiteSpace(recurrence.RecordingDirectoryID)) // if dir is null or empty then its the default shared directory
     {
         var recurrenceDirs = Models.RecordingDirectory.LoadForUserAsDictionaryIndexedByDirectoryId(UserOid, true);
         if (!recurrenceDirs.ContainsKey(recurrence.RecordingDirectoryID))
             throw new UnauthorizedAccessException();
     }
     Helpers.NpvrCoreHelper.CancelRecurring(recurrence.OID);
     return true;
 }
Exemplo n.º 18
0
        private bool Create(int UserOid)
        {
            var config = new Configuration();
            string recordingDirectoryId = this.RecordingDirectoryId ?? ""; // default
            // make sure they have access to the recording directory
            if (!String.IsNullOrEmpty(recordingDirectoryId))
            {
                if (!RecordingDirectory.LoadForUserAsDictionaryIndexedByDirectoryId(UserOid, true).ContainsKey(recordingDirectoryId))
                    throw new UnauthorizedAccessException();
            }

            var epgevent = Helpers.NpvrCoreHelper.EPGEventLoadByOID(this.EpgEventOid);
            if (epgevent == null)
                throw new Exception("Failed to locate EPG Event to record.");

            var instance = NShared.RecordingServiceProxy.GetInstance();

            int prePadding = (this.PrePadding ?? (int?)config.PrePadding).Value;
            int postPadding = (this.PostPadding ?? (int?)config.PostPadding).Value;

            bool onlyNew = false;
            DayMask dayMask = DayMask.ANY;
            bool timeslot = true;
            switch (this.Type)
            {
                case RecordingType.Record_Once: // special cast, effectively a "Quick Record" but with a couple more options
                    {
                        var result = instance.ScheduleRecording(epgevent, prePadding, postPadding, NUtility.RecordingQuality.QUALITY_DEFAULT, recordingDirectoryId);
                        if (result == null)
                            return false;
                        this.RecordingOid = result.OID;
                        this.RecurrenceOid = result.RecurrenceOID;
                    }
                    return true;
                case RecordingType.Record_Season_New_This_Channel:
                    onlyNew = true;
                    dayMask = DayMask.ANY;
                    timeslot = false;
                    break;
                case RecordingType.Record_Season_All_This_Channel:
                    onlyNew = false;
                    dayMask = DayMask.ANY;
                    timeslot = false;
                    break;
                case RecordingType.Record_Season_Daily_This_Timeslot:
                    onlyNew = false;
                    dayMask = DayMask.ANY;
                    timeslot = true;
                    break;
                case RecordingType.Record_Season_Weekly_This_Timeslot:
                    onlyNew = false;
                    dayMask = dayMask = (DayMask)(1 << ((int)epgevent.StartTime.ToLocalTime().DayOfWeek));
                    timeslot = true;
                    break;
                case RecordingType.Record_Season_Weekdays_This_Timeslot:
                    onlyNew = false;
                    dayMask = DayMask.MONDAY | DayMask.TUESDAY | DayMask.WEDNESDAY | DayMask.THURSDAY | DayMask.FRIDAY;
                    timeslot = true;
                    break;
                case RecordingType.Record_Season_Weekends_This_Timeslot:
                    onlyNew = false;
                    dayMask = DayMask.SATURDAY | DayMask.SUNDAY;
                    timeslot = true;
                    break;
                case RecordingType.Record_Season_All_Episodes_All_Channels: // another special case
                    {
                        string advancedRules = "title like '" + epgevent.Title.Replace("'", "''") + "%'";
                        if (config.RecurringMatch == RecurringMatchType.Exact)
                            advancedRules = "title like '" + epgevent.Title.Replace("'", "''") + "'";
                        var result = instance.ScheduleRecording(epgevent.Title, 0 /* all channels */, epgevent.StartTime, epgevent.EndTime, prePadding, postPadding, dayMask, this.NumberToKeep, RecordingQuality.QUALITY_DEFAULT, advancedRules, recordingDirectoryId);
                        if (result == null)
                            return false;
                        this.RecordingOid = result.OID;
                        this.RecurrenceOid = result.RecurrenceOID;
                        return true;
                    }
                default:
                    return false; // unknown type.
            }

            var recording = instance.ScheduleRecording(epgevent, onlyNew, prePadding, postPadding, dayMask, this.NumberToKeep, RecordingQuality.QUALITY_DEFAULT, timeslot, recordingDirectoryId);
            if (recording == null)
                return false;
            this.RecordingOid = recording.OID;
            this.RecurrenceOid = recording.RecurrenceOID;
            return true;
        }