protected override async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query) { // TODO verify this code is necessary for TZ data or if builtin exist var startTransition = TimeZoneInfo.TransitionTime.CreateFloatingDateRule( new DateTime(1, 1, 1, 3, 0, 0), 3, 5, DayOfWeek.Sunday); var endTransition = TimeZoneInfo.TransitionTime.CreateFloatingDateRule( new DateTime(1, 1, 1, 4, 0, 0), 10, 5, DayOfWeek.Sunday); var delta = new TimeSpan(1, 0, 0); var adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule( new DateTime(1999, 10, 1), DateTime.MaxValue.Date, delta, startTransition, endTransition); TimeZoneInfo.AdjustmentRule[] adjustments = { adjustment }; var germanyTz = TimeZoneInfo.CreateCustomTimeZone( "W. Europe Standard Time", new TimeSpan(1, 0, 0), "(GMT+01:00) W. Europe Standard Time", "W. Europe Standard Time", "W. Europe DST Time", adjustments); var releases = new List <ReleaseInfo>(); var searchString = query.GetQueryString(); var searchUrl = IndexUrl; var queryCollection = new NameValueCollection { { "strWebValue", "torrent" }, { "strWebAction", "search" }, { "sort", "torrent_added" }, { "by", "d" }, { "type", "0" }, { "do_search", "suchen" }, { "time", "0" }, { "details", "title" } }; if (!string.IsNullOrWhiteSpace(searchString)) { queryCollection.Add("searchstring", searchString); } foreach (var cat in MapTorznabCapsToTrackers(query)) { queryCollection.Add("dirs" + cat, "1"); } searchUrl += "?" + queryCollection.GetQueryString(); var response = await RequestStringWithCookies(searchUrl); var titleRegexp = new Regex(@"^return buildTable\('(.*?)',\s+"); try { var parser = new HtmlParser(); var dom = parser.ParseDocument(response.Content); var rows = dom.QuerySelectorAll("table.torrenttable > tbody > tr"); foreach (var row in rows.Skip(1)) { var qDetailsLink = row.QuerySelector("a[href^=\"index.php?strWebValue=torrent&strWebAction=details\"]"); var qCatLink = row.QuerySelector("a[href^=\"index.php?strWebValue=torrent&strWebAction=search&dir=\"]"); var qDlLink = row.QuerySelector("a[href^=\"index.php?strWebValue=torrent&strWebAction=download&id=\"]"); var qSeeders = row.QuerySelectorAll("td.column1")[2]; var qLeechers = row.QuerySelectorAll("td.column2")[3]; var qDateStr = row.QuerySelector("font:has(a)"); var qSize = row.QuerySelector("td.column2[align=center]"); var catStr = qCatLink.GetAttribute("href").Split('=')[3].Split('#')[0]; var link = new Uri(SiteLink + qDlLink.GetAttribute("href")); var sizeStr = qSize.TextContent; var dateStr = qDateStr.TextContent; var split = dateStr.IndexOf("Uploader", StringComparison.OrdinalIgnoreCase); dateStr = dateStr.Substring(0, split > 0 ? split : dateStr.Length).Trim().Replace("Heute", "Today") .Replace("Gestern", "Yesterday"); var dateGerman = DateTimeUtil.FromUnknown(dateStr); double downloadFactor; if (row.QuerySelector("img[src=\"themes/images/freeleech.png\"]") != null || row.QuerySelector("img[src=\"themes/images/onlyup.png\"]") != null) { downloadFactor = 0; } else if (row.QuerySelector("img[src=\"themes/images/DL50.png\"]") != null) { downloadFactor = 0.5; } else { downloadFactor = 1; } var title = titleRegexp.Match(qDetailsLink.GetAttribute("onmouseover")).Groups[1].Value; var comments = new Uri(SiteLink + qDetailsLink.GetAttribute("href")); var seeders = ParseUtil.CoerceInt(qSeeders.TextContent); var leechers = ParseUtil.CoerceInt(qLeechers.TextContent); var grabs = ParseUtil.CoerceInt(row.QuerySelector("td:nth-child(7)").TextContent); var publishDate = TimeZoneInfo.ConvertTime(dateGerman, germanyTz, TimeZoneInfo.Local); var release = new ReleaseInfo { MinimumRatio = 0.8, MinimumSeedTime = 0, Title = title, Category = MapTrackerCatToNewznab(catStr), Comments = comments, Link = link, Guid = link, Size = ReleaseInfo.GetBytes(sizeStr), Seeders = seeders, Peers = leechers + seeders, PublishDate = publishDate, Grabs = grabs, DownloadVolumeFactor = downloadFactor, UploadVolumeFactor = 1 }; releases.Add(release); } } catch (Exception ex) { OnParseError(response.Content, ex); } return(releases); }
public async Task Test(IScheduler scheduler, bool clearJobs, bool scheduleJobs) { try { if (clearJobs) { await scheduler.Clear(); } if (scheduleJobs) { ICalendar cronCalendar = new CronCalendar("0/5 * * * * ?"); ICalendar holidayCalendar = new HolidayCalendar(); // QRTZNET-86 ITrigger t = await scheduler.GetTrigger(new TriggerKey("NonExistingTrigger", "NonExistingGroup")); Assert.IsNull(t); AnnualCalendar cal = new AnnualCalendar(); cal.SetDayExcluded(new DateTime(2018, 7, 4), true); await scheduler.AddCalendar("annualCalendar", cal, false, true); IOperableTrigger calendarsTrigger = new SimpleTriggerImpl("calendarsTrigger", "test", 20, TimeSpan.FromMilliseconds(5)); calendarsTrigger.CalendarName = "annualCalendar"; JobDetailImpl jd = new JobDetailImpl("testJob", "test", typeof(NoOpJob)); await scheduler.ScheduleJob(jd, calendarsTrigger); // QRTZNET-93 await scheduler.AddCalendar("annualCalendar", cal, true, true); var annualCalendar = (AnnualCalendar)await scheduler.GetCalendar("annualCalendar"); Assert.That(annualCalendar.Description, Is.EqualTo(cal.Description)); Assert.That(annualCalendar.DaysExcluded, Is.EquivalentTo(cal.DaysExcluded)); await scheduler.AddCalendar("baseCalendar", new BaseCalendar(), false, true); await scheduler.AddCalendar("cronCalendar", cronCalendar, false, true); await scheduler.AddCalendar("dailyCalendar", new DailyCalendar(DateTime.Now.Date, DateTime.Now.AddMinutes(1)), false, true); await scheduler.AddCalendar("holidayCalendar", holidayCalendar, false, true); await scheduler.AddCalendar("monthlyCalendar", new MonthlyCalendar(), false, true); await scheduler.AddCalendar("weeklyCalendar", new WeeklyCalendar(), false, true); await scheduler.AddCalendar("cronCalendar", cronCalendar, true, true); await scheduler.AddCalendar("holidayCalendar", holidayCalendar, true, true); Assert.IsNotNull(scheduler.GetCalendar("annualCalendar")); JobDetailImpl lonelyJob = new JobDetailImpl("lonelyJob", "lonelyGroup", typeof(SimpleRecoveryJob)); lonelyJob.Durable = true; lonelyJob.RequestsRecovery = true; await scheduler.AddJob(lonelyJob, false); await scheduler.AddJob(lonelyJob, true); string schedId = scheduler.SchedulerInstanceId; int count = 1; JobDetailImpl job = new JobDetailImpl("job_" + count, schedId, typeof(SimpleRecoveryJob)); // ask scheduler to re-Execute this job if it was in progress when // the scheduler went down... job.RequestsRecovery = true; IOperableTrigger trigger = new SimpleTriggerImpl("trig_" + count, schedId, 20, TimeSpan.FromSeconds(5)); trigger.JobDataMap.Add("key", "value"); trigger.EndTimeUtc = DateTime.UtcNow.AddYears(10); trigger.StartTimeUtc = DateTime.Now.AddMilliseconds(1000L); await scheduler.ScheduleJob(job, trigger); // check that trigger was stored ITrigger persisted = await scheduler.GetTrigger(new TriggerKey("trig_" + count, schedId)); Assert.IsNotNull(persisted); Assert.IsTrue(persisted is SimpleTriggerImpl); count++; job = new JobDetailImpl("job_" + count, schedId, typeof(SimpleRecoveryJob)); // ask scheduler to re-Execute this job if it was in progress when // the scheduler went down... job.RequestsRecovery = true; trigger = new SimpleTriggerImpl("trig_" + count, schedId, 20, TimeSpan.FromSeconds(5)); trigger.StartTimeUtc = DateTime.Now.AddMilliseconds(2000L); await scheduler.ScheduleJob(job, trigger); count++; job = new JobDetailImpl("job_" + count, schedId, typeof(SimpleRecoveryStatefulJob)); // ask scheduler to re-Execute this job if it was in progress when // the scheduler went down... job.RequestsRecovery = true; trigger = new SimpleTriggerImpl("trig_" + count, schedId, 20, TimeSpan.FromSeconds(3)); trigger.StartTimeUtc = DateTime.Now.AddMilliseconds(1000L); await scheduler.ScheduleJob(job, trigger); count++; job = new JobDetailImpl("job_" + count, schedId, typeof(SimpleRecoveryJob)); // ask scheduler to re-Execute this job if it was in progress when // the scheduler went down... job.RequestsRecovery = true; trigger = new SimpleTriggerImpl("trig_" + count, schedId, 20, TimeSpan.FromSeconds(4)); trigger.StartTimeUtc = DateTime.Now.AddMilliseconds(1000L); await scheduler.ScheduleJob(job, trigger); count++; job = new JobDetailImpl("job_" + count, schedId, typeof(SimpleRecoveryJob)); // ask scheduler to re-Execute this job if it was in progress when // the scheduler went down... job.RequestsRecovery = true; trigger = new SimpleTriggerImpl("trig_" + count, schedId, 20, TimeSpan.FromMilliseconds(4500)); await scheduler.ScheduleJob(job, trigger); count++; job = new JobDetailImpl("job_" + count, schedId, typeof(SimpleRecoveryJob)); // ask scheduler to re-Execute this job if it was in progress when // the scheduler went down... job.RequestsRecovery = true; IOperableTrigger ct = new CronTriggerImpl("cron_trig_" + count, schedId, "0/10 * * * * ?"); ct.JobDataMap.Add("key", "value"); ct.StartTimeUtc = DateTime.Now.AddMilliseconds(1000); await scheduler.ScheduleJob(job, ct); count++; job = new JobDetailImpl("job_" + count, schedId, typeof(SimpleRecoveryJob)); // ask scheduler to re-Execute this job if it was in progress when // the scheduler went down... job.RequestsRecovery = true; var timeZone1 = TimeZoneUtil.FindTimeZoneById("Central European Standard Time"); var timeZone2 = TimeZoneUtil.FindTimeZoneById("Mountain Standard Time"); DailyTimeIntervalTriggerImpl nt = new DailyTimeIntervalTriggerImpl("nth_trig_" + count, schedId, new TimeOfDay(1, 1, 1), new TimeOfDay(23, 30, 0), IntervalUnit.Hour, 1); nt.StartTimeUtc = DateTime.Now.Date.AddMilliseconds(1000); nt.TimeZone = timeZone1; await scheduler.ScheduleJob(job, nt); var loadedNt = (IDailyTimeIntervalTrigger)await scheduler.GetTrigger(nt.Key); Assert.That(loadedNt.TimeZone.Id, Is.EqualTo(timeZone1.Id)); nt.TimeZone = timeZone2; await scheduler.RescheduleJob(nt.Key, nt); loadedNt = (IDailyTimeIntervalTrigger)await scheduler.GetTrigger(nt.Key); Assert.That(loadedNt.TimeZone.Id, Is.EqualTo(timeZone2.Id)); DailyTimeIntervalTriggerImpl nt2 = new DailyTimeIntervalTriggerImpl(); nt2.Key = new TriggerKey("nth_trig2_" + count, schedId); nt2.StartTimeUtc = DateTime.Now.Date.AddMilliseconds(1000); nt2.JobKey = job.Key; await scheduler.ScheduleJob(nt2); // GitHub issue #92 await scheduler.GetTrigger(nt2.Key); // GitHub issue #98 nt2.StartTimeOfDay = new TimeOfDay(1, 2, 3); nt2.EndTimeOfDay = new TimeOfDay(2, 3, 4); await scheduler.UnscheduleJob(nt2.Key); await scheduler.ScheduleJob(nt2); var triggerFromDb = (IDailyTimeIntervalTrigger)await scheduler.GetTrigger(nt2.Key); Assert.That(triggerFromDb.StartTimeOfDay.Hour, Is.EqualTo(1)); Assert.That(triggerFromDb.StartTimeOfDay.Minute, Is.EqualTo(2)); Assert.That(triggerFromDb.StartTimeOfDay.Second, Is.EqualTo(3)); Assert.That(triggerFromDb.EndTimeOfDay.Hour, Is.EqualTo(2)); Assert.That(triggerFromDb.EndTimeOfDay.Minute, Is.EqualTo(3)); Assert.That(triggerFromDb.EndTimeOfDay.Second, Is.EqualTo(4)); job.RequestsRecovery = true; CalendarIntervalTriggerImpl intervalTrigger = new CalendarIntervalTriggerImpl( "calint_trig_" + count, schedId, DateTime.UtcNow.AddMilliseconds(300), DateTime.UtcNow.AddMinutes(1), IntervalUnit.Second, 8); intervalTrigger.JobKey = job.Key; await scheduler.ScheduleJob(intervalTrigger); // custom time zone const string CustomTimeZoneId = "Custom TimeZone"; var webTimezone = TimeZoneInfo.CreateCustomTimeZone( CustomTimeZoneId, TimeSpan.FromMinutes(22), null, null); TimeZoneUtil.CustomResolver = id => { if (id == CustomTimeZoneId) { return(webTimezone); } return(null); }; var customTimeZoneTrigger = TriggerBuilder.Create() .WithIdentity("customTimeZoneTrigger") .WithCronSchedule("0/5 * * * * ?", x => x.InTimeZone(webTimezone)) .StartNow() .ForJob(job) .Build(); await scheduler.ScheduleJob(customTimeZoneTrigger); var loadedCustomTimeZoneTrigger = (ICronTrigger)await scheduler.GetTrigger(customTimeZoneTrigger.Key); Assert.That(loadedCustomTimeZoneTrigger.TimeZone.BaseUtcOffset, Is.EqualTo(TimeSpan.FromMinutes(22))); // bulk operations var info = new Dictionary <IJobDetail, IReadOnlyCollection <ITrigger> >(); IJobDetail detail = new JobDetailImpl("job_" + count, schedId, typeof(SimpleRecoveryJob)); ITrigger simple = new SimpleTriggerImpl("trig_" + count, schedId, 20, TimeSpan.FromMilliseconds(4500)); var triggers = new List <ITrigger>(); triggers.Add(simple); info[detail] = triggers; await scheduler.ScheduleJobs(info, true); Assert.IsTrue(await scheduler.CheckExists(detail.Key)); Assert.IsTrue(await scheduler.CheckExists(simple.Key)); // QRTZNET-243 await scheduler.GetJobKeys(GroupMatcher <JobKey> .GroupContains("a").DeepClone()); await scheduler.GetJobKeys(GroupMatcher <JobKey> .GroupEndsWith("a").DeepClone()); await scheduler.GetJobKeys(GroupMatcher <JobKey> .GroupStartsWith("a").DeepClone()); await scheduler.GetJobKeys(GroupMatcher <JobKey> .GroupEquals("a").DeepClone()); await scheduler.GetTriggerKeys(GroupMatcher <TriggerKey> .GroupContains("a").DeepClone()); await scheduler.GetTriggerKeys(GroupMatcher <TriggerKey> .GroupEndsWith("a").DeepClone()); await scheduler.GetTriggerKeys(GroupMatcher <TriggerKey> .GroupStartsWith("a").DeepClone()); await scheduler.GetTriggerKeys(GroupMatcher <TriggerKey> .GroupEquals("a").DeepClone()); await scheduler.Start(); await Task.Delay(TimeSpan.FromSeconds(3)); await scheduler.PauseAll(); await scheduler.ResumeAll(); await scheduler.PauseJob(new JobKey("job_1", schedId)); await scheduler.ResumeJob(new JobKey("job_1", schedId)); await scheduler.PauseJobs(GroupMatcher <JobKey> .GroupEquals(schedId)); await Task.Delay(TimeSpan.FromSeconds(1)); await scheduler.ResumeJobs(GroupMatcher <JobKey> .GroupEquals(schedId)); await scheduler.PauseTrigger(new TriggerKey("trig_2", schedId)); await scheduler.ResumeTrigger(new TriggerKey("trig_2", schedId)); await scheduler.PauseTriggers(GroupMatcher <TriggerKey> .GroupEquals(schedId)); var pausedTriggerGroups = await scheduler.GetPausedTriggerGroups(); Assert.AreEqual(1, pausedTriggerGroups.Count); await Task.Delay(TimeSpan.FromSeconds(3)); await scheduler.ResumeTriggers(GroupMatcher <TriggerKey> .GroupEquals(schedId)); Assert.IsNotNull(scheduler.GetTrigger(new TriggerKey("trig_2", schedId))); Assert.IsNotNull(scheduler.GetJobDetail(new JobKey("job_1", schedId))); Assert.IsNotNull(scheduler.GetMetaData()); Assert.IsNotNull(scheduler.GetCalendar("weeklyCalendar")); var genericjobKey = new JobKey("genericJob", "genericGroup"); GenericJobType.Reset(); var genericJob = JobBuilder.Create <GenericJobType>() .WithIdentity(genericjobKey) .StoreDurably() .Build(); await scheduler.AddJob(genericJob, false); genericJob = await scheduler.GetJobDetail(genericjobKey); Assert.That(genericJob, Is.Not.Null); await scheduler.TriggerJob(genericjobKey); GenericJobType.WaitForTrigger(TimeSpan.FromSeconds(20)); Assert.That(GenericJobType.TriggeredCount, Is.EqualTo(1)); await scheduler.Standby(); CollectionAssert.IsNotEmpty(await scheduler.GetCalendarNames()); CollectionAssert.IsNotEmpty(await scheduler.GetJobKeys(GroupMatcher <JobKey> .GroupEquals(schedId))); CollectionAssert.IsNotEmpty(await scheduler.GetTriggersOfJob(new JobKey("job_2", schedId))); Assert.IsNotNull(scheduler.GetJobDetail(new JobKey("job_2", schedId))); await scheduler.DeleteCalendar("cronCalendar"); await scheduler.DeleteCalendar("holidayCalendar"); await scheduler.DeleteJob(new JobKey("lonelyJob", "lonelyGroup")); await scheduler.DeleteJob(job.Key); await scheduler.GetJobGroupNames(); await scheduler.GetCalendarNames(); await scheduler.GetTriggerGroupNames(); await TestMatchers(scheduler); } } finally { await scheduler.Shutdown(false); } }
protected override async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query) { TimeZoneInfo.TransitionTime startTransition = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 3, 0, 0), 3, 5, DayOfWeek.Sunday); TimeZoneInfo.TransitionTime endTransition = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 4, 0, 0), 10, 5, DayOfWeek.Sunday); TimeSpan delta = new TimeSpan(1, 0, 0); TimeZoneInfo.AdjustmentRule adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(new DateTime(1999, 10, 1), DateTime.MaxValue.Date, delta, startTransition, endTransition); TimeZoneInfo.AdjustmentRule[] adjustments = { adjustment }; TimeZoneInfo germanyTz = TimeZoneInfo.CreateCustomTimeZone("W. Europe Standard Time", new TimeSpan(1, 0, 0), "(GMT+01:00) W. Europe Standard Time", "W. Europe Standard Time", "W. Europe DST Time", adjustments); var releases = new List <ReleaseInfo>(); var searchString = query.GetQueryString(); var searchUrl = IndexUrl; var queryCollection = new NameValueCollection(); queryCollection.Add("strWebValue", "torrent"); queryCollection.Add("strWebAction", "search"); queryCollection.Add("sort", "torrent_added"); queryCollection.Add("by", "d"); queryCollection.Add("type", "0"); queryCollection.Add("do_search", "suchen"); queryCollection.Add("time", "0"); queryCollection.Add("details", "title"); if (!string.IsNullOrWhiteSpace(searchString)) { queryCollection.Add("searchstring", searchString); } foreach (var cat in MapTorznabCapsToTrackers(query)) { queryCollection.Add("dirs" + cat, "1"); } searchUrl += "?" + queryCollection.GetQueryString(); var response = await RequestStringWithCookies(searchUrl); var results = response.Content; var TitleRegexp = new Regex(@"^return buildTable\('(.*?)',\s+"); try { CQ dom = results; var rows = dom["table.torrenttable > tbody > tr"]; foreach (var row in rows.Skip(1)) { var release = new ReleaseInfo(); release.MinimumRatio = 0.8; release.MinimumSeedTime = 0; var qRow = row.Cq(); var qDetailsLink = qRow.Find("a[href^=index.php?strWebValue=torrent&strWebAction=details]").First(); release.Title = TitleRegexp.Match(qDetailsLink.Attr("onmouseover")).Groups[1].Value; var qCatLink = qRow.Find("a[href^=index.php?strWebValue=torrent&strWebAction=search&dir=]").First(); var qDLLink = qRow.Find("a[href^=index.php?strWebValue=torrent&strWebAction=download&id=]").First(); var qSeeders = qRow.Find("td.column1:eq(3)"); var qLeechers = qRow.Find("td.column2:eq(3)"); var qDateStr = qRow.Find("font:has(a)").First(); var qSize = qRow.Find("td.column2[align=center]").First(); var catStr = qCatLink.Attr("href").Split('=')[3].Split('#')[0]; release.Category = MapTrackerCatToNewznab(catStr); release.Link = new Uri(SiteLink + qDLLink.Attr("href")); release.Comments = new Uri(SiteLink + qDetailsLink.Attr("href")); release.Guid = release.Link; var sizeStr = qSize.Text(); release.Size = ReleaseInfo.GetBytes(sizeStr); release.Seeders = ParseUtil.CoerceInt(qSeeders.Text()); release.Peers = ParseUtil.CoerceInt(qLeechers.Text()) + release.Seeders; var dateStr = qDateStr.Text().Trim(); var dateStrParts = dateStr.Split(); DateTime dateGerman; if (dateStrParts[0] == "Heute") { dateGerman = DateTime.SpecifyKind(DateTime.UtcNow.Date, DateTimeKind.Unspecified) + TimeSpan.Parse(dateStrParts[1]); } else if (dateStrParts[0] == "Gestern") { dateGerman = DateTime.SpecifyKind(DateTime.UtcNow.Date, DateTimeKind.Unspecified) + TimeSpan.Parse(dateStrParts[1]) - TimeSpan.FromDays(1); } else { dateGerman = DateTime.SpecifyKind(DateTime.ParseExact(dateStrParts[0] + dateStrParts[1], "dd.MM.yyyyHH:mm", CultureInfo.InvariantCulture), DateTimeKind.Unspecified); } DateTime pubDateUtc = TimeZoneInfo.ConvertTimeToUtc(dateGerman, germanyTz); release.PublishDate = pubDateUtc.ToLocalTime(); var grabs = qRow.Find("td:nth-child(7)").Text(); release.Grabs = ParseUtil.CoerceInt(grabs); if (qRow.Find("img[src=\"themes/images/freeleech.png\"]").Length >= 1) { release.DownloadVolumeFactor = 0; } else if (qRow.Find("img[src=\"themes/images/DL50.png\"]").Length >= 1) { release.DownloadVolumeFactor = 0.5; } else { release.DownloadVolumeFactor = 1; } release.UploadVolumeFactor = 1; releases.Add(release); } } catch (Exception ex) { OnParseError(results, ex); } return(releases); }
protected override async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query) { TimeZoneInfo.TransitionTime startTransition = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 3, 0, 0), 3, 5, DayOfWeek.Sunday); TimeZoneInfo.TransitionTime endTransition = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 4, 0, 0), 10, 5, DayOfWeek.Sunday); TimeSpan delta = new TimeSpan(1, 0, 0); TimeZoneInfo.AdjustmentRule adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(new DateTime(1999, 10, 1), DateTime.MaxValue.Date, delta, startTransition, endTransition); TimeZoneInfo.AdjustmentRule[] adjustments = { adjustment }; TimeZoneInfo germanyTz = TimeZoneInfo.CreateCustomTimeZone("W. Europe Standard Time", new TimeSpan(1, 0, 0), "(GMT+01:00) W. Europe Standard Time", "W. Europe Standard Time", "W. Europe DST Time", adjustments); var releases = new List <ReleaseInfo>(); var searchString = query.GetQueryString(); var searchUrl = BrowseUrl; var queryCollection = new NameValueCollection(); queryCollection.Add("showsearch", "1"); queryCollection.Add("incldead", "1"); queryCollection.Add("blah", "0"); queryCollection.Add("orderby", "added"); queryCollection.Add("sort", "desc"); if (!string.IsNullOrWhiteSpace(searchString)) { queryCollection.Add("search", searchString); } foreach (var cat in MapTorznabCapsToTrackers(query)) { queryCollection.Add("c" + cat, "1"); } searchUrl += "?" + queryCollection.GetQueryString(); var response = await RequestStringWithCookiesAndRetry(searchUrl, null, BrowseUrl); var results = response.Content; try { CQ dom = results; var rows = dom["table.tableinborder > tbody > tr:has(td.tableb)"]; foreach (var row in rows) { var release = new ReleaseInfo(); release.MinimumRatio = 0.75; release.MinimumSeedTime = 0; var qRow = row.Cq(); var qDetailsLink = qRow.Find("a[href^=details.php?id=]").First(); release.Title = qDetailsLink.Attr("title"); if (!query.MatchQueryStringAND(release.Title)) { continue; } var qCatLink = qRow.Find("a[href^=browse.php?cat=]").First(); // use negative indexes as if a user has "Wartezeit" there's an extra column after the title var qSeeders = qRow.Find("td:nth-last-child(4)"); var qLeechers = qRow.Find("td:nth-last-child(3)"); var qDateStr = qRow.Find("td:nth-last-child(7)"); var qSize = qRow.Find("td:nth-last-child(6)"); var torrentId = qDetailsLink.Attr("href").Replace("&hit=1", "").Split('=')[1]; var catStr = qCatLink.Attr("href").Split('=')[1]; release.Category = MapTrackerCatToNewznab(catStr); release.Link = new Uri(SiteLink + "download.php?torrent=" + torrentId); release.Comments = new Uri(SiteLink + qDetailsLink.Attr("href")); release.Guid = release.Link; var sizeStr = qSize.Text(); release.Size = ReleaseInfo.GetBytes(sizeStr.Replace(",", ".")); release.Seeders = ParseUtil.CoerceInt(qSeeders.Text()); release.Peers = ParseUtil.CoerceInt(qLeechers.Text()) + release.Seeders; var dateStr = qDateStr.Text(); var dateGerman = DateTime.SpecifyKind(DateTime.ParseExact(dateStr, "dd.MM.yyyyHH:mm:ss", CultureInfo.InvariantCulture), DateTimeKind.Unspecified); DateTime pubDateUtc = TimeZoneInfo.ConvertTimeToUtc(dateGerman, germanyTz); release.PublishDate = pubDateUtc; var files = qRow.Find("td:nth-last-child(9)").Text(); release.Files = ParseUtil.CoerceInt(files); var grabs = qRow.Find("td:nth-last-child(5)").Text(); release.Grabs = ParseUtil.CoerceInt(grabs); if (qRow.Find("font[color=\"red\"]:contains(OnlyUp)").Length >= 1) { release.DownloadVolumeFactor = 0; } else { release.DownloadVolumeFactor = 1; } release.UploadVolumeFactor = 1; releases.Add(release); } } catch (Exception ex) { OnParseError(results, ex); } return(releases); }
protected override async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query) { TimeZoneInfo.TransitionTime startTransition = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 3, 0, 0), 3, 5, DayOfWeek.Sunday); TimeZoneInfo.TransitionTime endTransition = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 4, 0, 0), 10, 5, DayOfWeek.Sunday); TimeSpan delta = new TimeSpan(1, 0, 0); TimeZoneInfo.AdjustmentRule adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(new DateTime(1999, 10, 1), DateTime.MaxValue.Date, delta, startTransition, endTransition); TimeZoneInfo.AdjustmentRule[] adjustments = { adjustment }; TimeZoneInfo Tz = TimeZoneInfo.CreateCustomTimeZone("custom", new TimeSpan(1, 0, 0), "custom", "custom", "custom", adjustments); var releases = new List <ReleaseInfo>(); NameValueCollection qParams = new NameValueCollection(); qParams.Add("api", ""); if (query.ImdbIDShort != null) { qParams.Add("imdb", query.ImdbIDShort); } else { qParams.Add("search", query.SearchTerm); } foreach (var cat in MapTorznabCapsToTrackers(query)) { qParams.Add("categories[" + cat + "]", "1"); } string urlSearch = SearchUrl; urlSearch += "?" + qParams.GetQueryString(); var response = await RequestStringWithCookiesAndRetry(urlSearch); if (response.IsRedirect) { throw new Exception("not logged in"); } try { var jsonContent = JArray.Parse(response.Content); var sitelink = new Uri(SiteLink); foreach (var item in jsonContent) { var release = new ReleaseInfo(); var id = item.Value <long>("id"); release.Title = item.Value <string>("name"); var imdbid = item.Value <string>("imdbid"); if (!string.IsNullOrEmpty(imdbid)) { release.Imdb = long.Parse(imdbid); } var category = item.Value <string>("category"); release.Category = MapTrackerCatToNewznab(category); release.Link = new Uri(sitelink, "/download.php?id=" + id); release.Comments = new Uri(sitelink, "/details.php?id=" + id); release.Guid = release.Comments; var dateStr = item.Value <string>("added"); var dateTime = DateTime.SpecifyKind(DateTime.ParseExact(dateStr, "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture), DateTimeKind.Unspecified); var pubDateUtc = TimeZoneInfo.ConvertTimeToUtc(dateTime, Tz); release.PublishDate = pubDateUtc; release.Grabs = item.Value <long>("times_completed"); release.Files = item.Value <long>("numfiles"); release.Seeders = item.Value <int>("seeders"); release.Peers = item.Value <int>("leechers") + release.Seeders; var size = item.Value <string>("size"); release.Size = ReleaseInfo.GetBytes(size); var is_freeleech = item.Value <int>("is_freeleech"); if (is_freeleech == 1) { release.DownloadVolumeFactor = 0; } else { release.DownloadVolumeFactor = 1; } release.UploadVolumeFactor = 1; releases.Add(release); } } catch (Exception ex) { OnParseError(response.Content, ex); } return(releases); }
/// <summary> /// Converts this time zone definition into a TimeZoneInfo structure. /// </summary> /// <param name="service">The service.</param> /// <returns>A TimeZoneInfo representing the same time zone as this definition.</returns> internal TimeZoneInfo ToTimeZoneInfo(ExchangeService service) { this.Validate(); TimeZoneInfo result; // Retrieve the base offset to UTC, standard and daylight display names from // the last transition group, which is the one that currently applies given that // transitions are ordered chronologically. TimeZoneTransitionGroup.CustomTimeZoneCreateParams creationParams = this.transitions[this.transitions.Count - 1].TargetGroup.GetCustomTimeZoneCreationParams(); List <TimeZoneInfo.AdjustmentRule> adjustmentRules = new List <TimeZoneInfo.AdjustmentRule>(); DateTime startDate = DateTime.MinValue; DateTime endDate; DateTime effectiveEndDate; for (int i = 0; i < this.transitions.Count; i++) { if (i < this.transitions.Count - 1) { endDate = (this.transitions[i + 1] as AbsoluteDateTransition).DateTime; effectiveEndDate = endDate.AddDays(-1); } else { endDate = DateTime.MaxValue; effectiveEndDate = endDate; } // OM:1648848 Due to bad timezone data from clients the // startDate may not always come before the effectiveEndDate if (startDate < effectiveEndDate) { TimeZoneInfo.AdjustmentRule adjustmentRule = this.transitions[i].TargetGroup.CreateAdjustmentRule(startDate, effectiveEndDate); if (adjustmentRule != null) { adjustmentRules.Add(adjustmentRule); } startDate = endDate; } else { service.TraceMessage( TraceFlags.EwsTimeZones, string.Format( "The startDate '{0}' is not before the effectiveEndDate '{1}'. Will skip creating adjustment rule.", startDate, effectiveEndDate)); } } if (adjustmentRules.Count == 0) { // If there are no adjustment rule, the time zone does not support Daylight // saving time. result = TimeZoneInfo.CreateCustomTimeZone( this.Id, creationParams.BaseOffsetToUtc, this.Name, creationParams.StandardDisplayName); } else { result = TimeZoneInfo.CreateCustomTimeZone( this.Id, creationParams.BaseOffsetToUtc, this.Name, creationParams.StandardDisplayName, creationParams.DaylightDisplayName, adjustmentRules.ToArray()); } return(result); }
// </Snippet4> private TimeZoneInfo CreateNewCentralStandardTimeZone() { // <Snippet5> TimeZoneInfo cst; // Declare necessary TimeZoneInfo.AdjustmentRule objects for time zone TimeSpan delta = new TimeSpan(1, 0, 0); TimeZoneInfo.AdjustmentRule adjustment; List <TimeZoneInfo.AdjustmentRule> adjustmentList = new List <TimeZoneInfo.AdjustmentRule>(); // Declare transition time variables to hold transition time information TimeZoneInfo.TransitionTime transitionRuleStart, transitionRuleEnd; // Define new Central Standard Time zone 6 hours earlier than UTC // Define rule 1 (for 1918-1919) transitionRuleStart = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 2, 0, 0), 03, 05, DayOfWeek.Sunday); transitionRuleEnd = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 2, 0, 0), 10, 05, DayOfWeek.Sunday); adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(new DateTime(1918, 1, 1), new DateTime(1919, 12, 31), delta, transitionRuleStart, transitionRuleEnd); adjustmentList.Add(adjustment); // Define rule 2 (for 1942) transitionRuleStart = TimeZoneInfo.TransitionTime.CreateFixedDateRule(new DateTime(1, 1, 1, 2, 0, 0), 02, 09); adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(new DateTime(1942, 1, 1), new DateTime(1942, 12, 31), delta, transitionRuleStart, transitionRuleEnd); adjustmentList.Add(adjustment); // Define rule 3 (for 1945) transitionRuleStart = TimeZoneInfo.TransitionTime.CreateFixedDateRule(new DateTime(1, 1, 1, 23, 0, 0), 08, 14); transitionRuleEnd = TimeZoneInfo.TransitionTime.CreateFixedDateRule(new DateTime(1, 1, 1, 2, 0, 0), 09, 30); adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(new DateTime(1945, 1, 1), new DateTime(1945, 12, 31), delta, transitionRuleStart, transitionRuleEnd); adjustmentList.Add(adjustment); // Define end rule (for 1967-2006) transitionRuleEnd = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 2, 0, 0), 10, 5, DayOfWeek.Sunday); // Define rule 4 (for 1967-73) transitionRuleStart = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 2, 0, 0), 04, 05, DayOfWeek.Sunday); adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(new DateTime(1967, 1, 1), new DateTime(1973, 12, 31), delta, transitionRuleStart, transitionRuleEnd); adjustmentList.Add(adjustment); // Define rule 5 (for 1974 only) transitionRuleStart = TimeZoneInfo.TransitionTime.CreateFixedDateRule(new DateTime(1, 1, 1, 2, 0, 0), 01, 06); adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(new DateTime(1974, 1, 1), new DateTime(1974, 12, 31), delta, transitionRuleStart, transitionRuleEnd); adjustmentList.Add(adjustment); // Define rule 6 (for 1975 only) transitionRuleStart = TimeZoneInfo.TransitionTime.CreateFixedDateRule(new DateTime(1, 1, 1, 2, 0, 0), 02, 23); adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(new DateTime(1975, 1, 1), new DateTime(1975, 12, 31), delta, transitionRuleStart, transitionRuleEnd); adjustmentList.Add(adjustment); // Define rule 7 (1976-1986) transitionRuleStart = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 2, 0, 0), 04, 05, DayOfWeek.Sunday); adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(new DateTime(1976, 1, 1), new DateTime(1986, 12, 31), delta, transitionRuleStart, transitionRuleEnd); adjustmentList.Add(adjustment); // Define rule 8 (1987-2006) transitionRuleStart = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 2, 0, 0), 04, 01, DayOfWeek.Sunday); adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(new DateTime(1987, 1, 1), new DateTime(2006, 12, 31), delta, transitionRuleStart, transitionRuleEnd); adjustmentList.Add(adjustment); // Define rule 9 (2007- ) transitionRuleStart = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 2, 0, 0), 03, 02, DayOfWeek.Sunday); transitionRuleEnd = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 2, 0, 0), 11, 01, DayOfWeek.Sunday); adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(new DateTime(2007, 1, 1), DateTime.MaxValue.Date, delta, transitionRuleStart, transitionRuleEnd); adjustmentList.Add(adjustment); // Convert list of adjustment rules to an array TimeZoneInfo.AdjustmentRule[] adjustments = new TimeZoneInfo.AdjustmentRule[adjustmentList.Count]; adjustmentList.CopyTo(adjustments); cst = TimeZoneInfo.CreateCustomTimeZone("Central Standard Time", new TimeSpan(-6, 0, 0), "(GMT-06:00) Central Time (US Only)", "Central Standard Time", "Central Daylight Time", adjustments); // </Snippet5> return(cst); }
public async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query) { TimeZoneInfo.TransitionTime startTransition = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 3, 0, 0), 3, 5, DayOfWeek.Sunday); TimeZoneInfo.TransitionTime endTransition = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 4, 0, 0), 10, 5, DayOfWeek.Sunday); TimeSpan delta = new TimeSpan(1, 0, 0); TimeZoneInfo.AdjustmentRule adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(new DateTime(1999, 10, 1), DateTime.MaxValue.Date, delta, startTransition, endTransition); TimeZoneInfo.AdjustmentRule[] adjustments = { adjustment }; TimeZoneInfo germanyTz = TimeZoneInfo.CreateCustomTimeZone("W. Europe Standard Time", new TimeSpan(1, 0, 0), "(GMT+01:00) W. Europe Standard Time", "W. Europe Standard Time", "W. Europe DST Time", adjustments); var releases = new List <ReleaseInfo>(); var searchString = query.GetQueryString(); var searchUrl = BrowseUrl; var queryCollection = new NameValueCollection(); queryCollection.Add("showsearch", "1"); queryCollection.Add("incldead", "1"); queryCollection.Add("orderby", "added"); queryCollection.Add("sort", "desc"); if (!string.IsNullOrWhiteSpace(searchString)) { queryCollection.Add("search", searchString); } var cats = MapTorznabCapsToTrackers(query); string cat = "0"; if (cats.Count == 1) { cat = cats[0]; } queryCollection.Add("cat", cat); searchUrl += "?" + queryCollection.GetQueryString(); var response = await RequestStringWithCookies(searchUrl); var results = response.Content; try { CQ dom = results; var rows = dom["table.testtable> tbody > tr:has(td.tableb)"]; foreach (var row in rows) { var release = new ReleaseInfo(); release.MinimumRatio = 0.75; release.MinimumSeedTime = 0; var qRow = row.Cq(); var qDetailsLink = qRow.Find("a[href^=details.php?id=]").First(); release.Title = qDetailsLink.Text(); if (!query.MatchQueryStringAND(release.Title)) { continue; } var qCatLink = qRow.Find("a[href^=browse.php?cat=]").First(); var qSeeders = qRow.Find("td > table.testtable > tbody > tr > td > strong:eq(3)"); var qLeechers = qRow.Find("td > table.testtable > tbody > tr > td > strong:eq(4)"); var qDateStr = qRow.Find("td > table.testtable > tbody > tr > td:eq(6)"); var qSize = qRow.Find("td > table.testtable > tbody > tr > td > strong:eq(1)"); var qDownloadLink = qRow.Find("a[href*=download]").First(); var catStr = qCatLink.Attr("href").Split('=')[1]; release.Category = MapTrackerCatToNewznab(catStr); var dlLink = qDownloadLink.Attr("href"); if (dlLink.Contains("javascript")) // depending on the user agent the DL link is a javascript call { var dlLinkParts = dlLink.Split(new char[] { '\'', ',' }); dlLink = SiteLink + "download/" + dlLinkParts[3] + "/" + dlLinkParts[5]; } release.Link = new Uri(dlLink); release.Comments = new Uri(SiteLink + qDetailsLink.Attr("href")); release.Guid = release.Link; var sizeStr = qSize.Text(); release.Size = ReleaseInfo.GetBytes(sizeStr.Replace(".", "").Replace(",", ".")); release.Seeders = ParseUtil.CoerceInt(qSeeders.Text()); release.Peers = ParseUtil.CoerceInt(qLeechers.Text()) + release.Seeders; var dateStr = qDateStr.Text().Replace('\xA0', ' '); var dateGerman = DateTime.SpecifyKind(DateTime.ParseExact(dateStr, "dd.MM.yyyy HH:mm:ss", CultureInfo.InvariantCulture), DateTimeKind.Unspecified); DateTime pubDateUtc = TimeZoneInfo.ConvertTimeToUtc(dateGerman, germanyTz); release.PublishDate = pubDateUtc; var files = qRow.Find("td:contains(Datei) > strong ~ strong").Text(); release.Files = ParseUtil.CoerceInt(files); if (qRow.Find("img[title=\"OnlyUpload\"]").Length >= 1) { release.DownloadVolumeFactor = 0; } else { release.DownloadVolumeFactor = 1; } release.UploadVolumeFactor = 1; releases.Add(release); } } catch (Exception ex) { OnParseError(results, ex); } return(releases); }
// <Snippet1> TimeZoneSerialization() { TextWriter writeStream; Dictionary <string, string> resources = new Dictionary <string, string>(); // Determine if .resx file exists if (File.Exists(resxName)) { // Open reader TextReader readStream = new StreamReader(resxName); ResXResourceReader resReader = new ResXResourceReader(readStream); foreach (DictionaryEntry item in resReader) { if (!(((string)item.Key) == "CentralStandardTime" || ((string)item.Key) == "PalmerStandardTime")) { resources.Add((string)item.Key, (string)item.Value); } } readStream.Close(); // Delete file, since write method creates duplicate xml headers File.Delete(resxName); } // Open stream to write to .resx file try { writeStream = new StreamWriter(resxName, true); } catch (FileNotFoundException e) { // Handle failure to find file Console.WriteLine("{0}: The file {1} could not be found.", e.GetType().Name, resxName); return; } // Get resource writer ResXResourceWriter resWriter = new ResXResourceWriter(writeStream); // Add resources from existing file foreach (KeyValuePair <string, string> item in resources) { resWriter.AddResource(item.Key, item.Value); } // Serialize Central Standard Time try { TimeZoneInfo cst = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time"); resWriter.AddResource(cst.Id.Replace(" ", string.Empty), cst.ToSerializedString()); } catch (TimeZoneNotFoundException) { Console.WriteLine("The Central Standard Time zone could not be found."); } // Create time zone for Palmer, Antarctica // // Define transition times to/from DST TimeZoneInfo.TransitionTime startTransition = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 4, 0, 0), 10, 2, DayOfWeek.Sunday); TimeZoneInfo.TransitionTime endTransition = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 3, 0, 0), 3, 2, DayOfWeek.Sunday); // Define adjustment rule TimeSpan delta = new TimeSpan(1, 0, 0); TimeZoneInfo.AdjustmentRule adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(new DateTime(1999, 10, 1), DateTime.MaxValue.Date, delta, startTransition, endTransition); // Create array for adjustment rules TimeZoneInfo.AdjustmentRule[] adjustments = { adjustment }; // Define other custom time zone arguments string DisplayName = "(GMT-04:00) Antarctica/Palmer Time"; string standardName = "Palmer Standard Time"; string daylightName = "Palmer Daylight Time"; TimeSpan offset = new TimeSpan(-4, 0, 0); TimeZoneInfo palmer = TimeZoneInfo.CreateCustomTimeZone(standardName, offset, DisplayName, standardName, daylightName, adjustments); resWriter.AddResource(palmer.Id.Replace(" ", String.Empty), palmer.ToSerializedString()); // Save changes to .resx file resWriter.Generate(); resWriter.Close(); writeStream.Close(); }
public async Task <IEnumerable <ReleaseInfo> > PerformQuery(TorznabQuery query) { TimeZoneInfo.TransitionTime startTransition = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 2, 0, 0), 3, 5, DayOfWeek.Sunday); TimeZoneInfo.TransitionTime endTransition = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 3, 0, 0), 10, 5, DayOfWeek.Sunday); TimeSpan delta = new TimeSpan(1, 0, 0); TimeZoneInfo.AdjustmentRule adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(new DateTime(1999, 10, 1), DateTime.MaxValue.Date, delta, startTransition, endTransition); TimeZoneInfo.AdjustmentRule[] adjustments = { adjustment }; TimeZoneInfo denmarkTz = TimeZoneInfo.CreateCustomTimeZone("Denmark Time", new TimeSpan(1, 0, 0), "(GMT+01:00) Denmark Time", "Denmark Time", "Denmark DST", adjustments); var releasesPerPage = 100; var releases = new List <ReleaseInfo>(); var page = (query.Offset / releasesPerPage) + 1; string episodeSearchUrl; if (string.IsNullOrEmpty(query.GetQueryString())) { episodeSearchUrl = SearchUrl + "?page=" + page; } else { var cats = MapTorznabCapsToTrackers(query); var catsUrlPart = string.Join("&", cats.Select(c => $"filter_{c}=on")); episodeSearchUrl = $"{SearchUrl}?page={page}&group=0&{catsUrlPart}&search={HttpUtility.UrlEncode(query.GetQueryString())}&pre_type=torrents&type="; } var results = await RequestStringWithCookiesAndRetry(episodeSearchUrl); if (string.IsNullOrEmpty(results.Content)) { CookieHeader = string.Empty; var pairs = new Dictionary <string, string> { { "username", configData.Username.Value }, { "password", configData.Password.Value }, { "langlang", null }, { "login", "login" } }; var response = await RequestLoginAndFollowRedirect(LoginUrl, pairs, CookieHeader, true, null, LoginUrl); await ConfigureIfOK(response.Cookies, response.Content != null && response.Content.Contains("logout.php"), () => { CQ dom = response.Content; var messageEl = dom["#loginform .warning"]; var errorMessage = messageEl.Text().Trim(); throw new ExceptionWithConfigData(errorMessage, configData); }); results = await RequestStringWithCookiesAndRetry(episodeSearchUrl); } try { CQ dom = results.Content; var rows = dom["#torrent_table tr.torrent"]; foreach (var row in rows) { var qRow = row.Cq(); var release = new ReleaseInfo { MinimumRatio = 1, MinimumSeedTime = 172800 }; var catAnchor = row.FirstChild.FirstChild; var catUrl = catAnchor.GetAttribute("href"); var catStr = Regex.Match(catUrl, "filter_(?<catNo>[0-9]+)=on").Groups["catNo"].Value; var catNo = int.Parse(catStr); var moviesCatsDanish = new[] { 2, 3, 10, 28, 29, 31 }; var moviesCatsIntl = new[] { 8, 9, 11, 22, 24 }; var moviesCats = configData.OnlyDanishCategories.Value ? moviesCatsDanish : moviesCatsDanish.Concat(moviesCatsIntl); var seriesCatsDanish = new[] { 1, 4, 30 }; var seriesCatsIntl = new[] { 20, 21 }; var seriesCats = configData.OnlyDanishCategories.Value ? seriesCatsDanish : seriesCatsDanish.Concat(seriesCatsIntl); if (moviesCats.Contains(catNo)) { release.Category = TorznabCatType.Movies.ID; } else if (seriesCats.Contains(catNo)) { release.Category = TorznabCatType.TV.ID; } else if (catNo == 12) { release.Category = TorznabCatType.BooksEbook.ID; } else if (catNo == 6) { release.Category = TorznabCatType.AudioAudiobook.ID; } else { continue; } var titleAnchor = qRow.Find("div.croptorrenttext a").FirstElement(); var title = titleAnchor.GetAttribute("title"); release.Title = title; var dlUrlAnchor = qRow.Find("span.right a").FirstElement(); var dlUrl = dlUrlAnchor.GetAttribute("href"); var authkey = Regex.Match(dlUrl, "authkey=(?<authkey>[0-9a-zA-Z]+)").Groups["authkey"].Value; var torrentPass = Regex.Match(dlUrl, "torrent_pass=(?<torrent_pass>[0-9a-zA-Z]+)").Groups["torrent_pass"].Value; var torrentId = Regex.Match(dlUrl, "id=(?<id>[0-9]+)").Groups["id"].Value; release.Link = new Uri($"{SearchUrl}/{title}.torrent/?action=download&authkey={authkey}&torrent_pass={torrentPass}&id={torrentId}"); var torrentLink = titleAnchor.GetAttribute("href"); release.Guid = new Uri(SiteLink + torrentLink); release.Comments = new Uri(SearchUrl + torrentLink); var addedElement = qRow.Find("span.time").FirstElement(); var addedStr = addedElement.GetAttribute("title"); release.PublishDate = TimeZoneInfo.ConvertTimeToUtc(DateTime.ParseExact(addedStr, "MMM dd yyyy, HH:mm", CultureInfo.InvariantCulture), denmarkTz).ToLocalTime(); var columns = qRow.Children(); var seedersElement = columns.Reverse().Skip(1).First(); release.Seeders = int.Parse(seedersElement.InnerText); var leechersElement = columns.Last().FirstElement(); release.Peers = release.Seeders + int.Parse(leechersElement.InnerText); var sizeElement = columns.Skip(2).First(); var sizeStr = sizeElement.InnerText; release.Size = ReleaseInfo.GetBytes(sizeStr); var imdbAnchor = qRow.Find(".torrentnotes a") .FirstOrDefault(a => a.GetAttribute("href").Contains("imdb.com")); if (imdbAnchor != null) { var referrerUrl = imdbAnchor.GetAttribute("href"); release.Imdb = long.Parse(Regex.Match(referrerUrl, "tt(?<imdbId>[0-9]+)").Groups["imdbId"].Value); } var Files = qRow.Find("td:nth-child(3) > div"); release.Files = ParseUtil.CoerceLong(Files.Text().Split(' ')[0]); var Grabs = qRow.Find("td:nth-child(6)"); release.Grabs = ParseUtil.CoerceLong(Grabs.Text()); if (qRow.Find("img[src=\"/static/common/torrents/gratis.png\"]").Length >= 1) { release.DownloadVolumeFactor = 0; } else { release.DownloadVolumeFactor = 1; } if (qRow.Find("img[src=\"/static/common/torrents/toxupload.png\"]").Length >= 1) { release.UploadVolumeFactor = 2; } else { release.UploadVolumeFactor = 1; } releases.Add(release); } } catch (Exception ex) { OnParseError(results.Content, ex); } return(releases); }