protected override void LoadFullDetailCore(IResourceInfo info) { var ctx = NetworkClient.Create <HtmlDocument>(HttpMethod.Get, GetDetailUrl(info), ReferUrlPage).Send(); if (!ctx.IsValid()) { return; } //hash var mlink = ctx.Result.DocumentNode.SelectSingleNode("//h3[contains(text(), 'Hash')]/following::p"); if (mlink == null) { return; } var hash = Regex.Match(mlink.InnerText, @"[a-f\d]{40}").Value; info.Hash = hash; //files var fileContainer = ctx.Result.DocumentNode.SelectSingleNode("//h3[contains(text(), 'Files')]/following::div/following::div"); ProcessFileList(fileContainer, info); base.LoadFullDetailCore(info); }
/// <summary> /// 执行下载 /// </summary> /// <param name="torrent"></param> /// <returns></returns> public override byte[] Download(IResourceInfo torrent) { if (torrent == null || torrent.Provider == null || torrent.Provider.GetType() != typeof(RarbgSearchProvider)) { return(null); } var provider = (torrent.Provider as RarbgSearchProvider); var client = provider.NetworkClient; var siteinfo = torrent.SiteData as SiteInfo; var ctx = client.Create <byte[]>(HttpMethod.Get, siteinfo.SiteDownloadLink, ReferUrlPage, allowAutoRedirect: false).Send(); if (!ctx.IsValid()) { return(null); } if (provider.IsHostChanged(ctx)) { return(Download(torrent)); } if (provider.IsBotCheckNeeded(ctx)) { if (provider.RequireBotCheck()) { return(Download(torrent)); } return(null); } return(ValidateTorrentContent(ctx)); }
string BindInfo(string template, IResourceInfo resource, string link) { if (template.IsNullOrEmpty()) { return(string.Empty); } template = Regex.Replace(template, @"\${([a-z]+)}", _ => { if (_.Groups[1].Value.IsIgnoreCaseEqualTo("url")) { return(link); } if (_.Groups[1].Value.IsIgnoreCaseEqualTo("base64(url)")) { return(BitConverter.ToString(Encoding.UTF8.GetBytes(link))); } if (_.Groups[1].Value.IsIgnoreCaseEqualTo("urlencode(url)")) { return(System.Web.HttpUtility.UrlEncode(link)); } return(_.Value); }); return(template); }
/// <summary> /// 加载内容 /// </summary> public override void LookupTorrentContents(IResourceInfo torrent) { var url = GetDetailUrl(torrent); var htmlContext = NetworkClient.Create <string>(HttpMethod.Get, url, _referUrl).Send(); if (!htmlContext.IsValid()) { return; } var html = htmlContext.Result.SearchStringTag("<th>文件名</th></tr>", "</table>"); if (string.IsNullOrEmpty(html)) { return; } var charPos = 0; var row = ""; while (!string.IsNullOrEmpty((row = html.SearchStringTag("<tr", "</tr>", ref charPos)))) { var m = Regex.Match(row, @"<td>([\.\d]+(\s| )+\w+)</td>.*?<td>(.*?)</td>", RegexOptions.IgnoreCase); if (!m.Success) { continue; } var path = m.GetGroupValue(3); var size = m.GetGroupValue(1); AddFileNode(torrent, BrtUtility.ClearString(path), null, BrtUtility.ClearString(size)); } }
protected override void LoadFullDetailCore(IResourceInfo info) { var url = GetDetailUrl(info); var ctx = NetworkClient.Create <string>(HttpMethod.Get, url, ReferUrlPage).Send(); if (!ctx.IsValid()) { return; } var html = DecodePage(ctx.Result); //btih:16429c32f383d5e49b9ca2084c8e57473646a62d var hash = Regex.Match(html, @"btih:([a-z\d]{40})", RegexOptions.IgnoreCase).GetGroupValue(1); if (hash.IsNullOrEmpty()) { //找不到hash,可能是之前被清理了。所以先直接下载种子看看 FetchOriginalTorrent(info); } else { info.Hash = hash; LookupTorrentContentsCore(url, info, html); } base.LoadFullDetailCore(info); }
/// <summary> /// 加载相信信息 /// </summary> protected override void LoadFullDetailCore(IResourceInfo info) { if (info.IsHashLoaded && (info.SiteData == null || (info.SiteData as SiteInfo).ProvideSiteDownload != null)) { return; } //load detail page var data = GetExtraData(info); var page = GetDetailUrl(info); var ctx = NetworkClient.Create <string>(HttpMethod.Get, page, ReferUrlPage).Send(); if (!ctx.IsValid()) { return; } ((ResourceInfo)info).Hash = Regex.Match(ctx.Result, @"Hash:</span>([a-z\d]{40})", RegexOptions.Singleline | RegexOptions.IgnoreCase).GetGroupValue(1) ?? ""; //有直接下载链接? var downloadLink = Regex.Match(ctx.Result, "href=\"([^\"]+?/torrent/download/[^\"]+)\"", RegexOptions.IgnoreCase | RegexOptions.Singleline); if (downloadLink.Success) { data.ProvideSiteDownload = true; data.SiteDownloadLink = $"https:{downloadLink.Groups[1].Value}"; } else { data.ProvideSiteDownload = false; } base.LoadFullDetailCore(info); }
/// <summary> /// 加载相信信息 /// </summary> protected override void LoadFullDetailCore(IResourceInfo info) { if (info.IsHashLoaded) { return; } var ctx = NetworkClient.Create <string>(HttpMethod.Get, GetDetailUrl(info), ReferUrlPage).Send(); if (!ctx.IsValid()) { return; } var doc = new HtmlDocument(); var tinfo = (ResourceInfo)info; doc.LoadHtml(ctx.Result); //hash tinfo.Hash = doc.DocumentNode.SelectSingleNode("//div[@class='info-table']//dl[5]/dd").InnerText; ParseDocumentFiles(tinfo, doc); base.LoadFullDetailCore(info); }
/// <summary> /// 加载相信信息 /// </summary> protected override void LoadFullDetailCore(IResourceInfo info) { if (info.IsHashLoaded && (info.SiteData == null || (info.SiteData as SiteInfo).ProvideSiteDownload != null)) { return; } var detailurl = GetDetailUrl(info); var ctx = NetworkClient.Create <string>(HttpMethod.Get, detailurl, ReferUrlPage, allowAutoRedirect: true).Send(); if (!ctx.IsValid()) { return; } //Hash ((ResourceInfo)info).Hash = (Regex.Match(ctx.Result, @"Hash=([a-z\d]{40})", RegexOptions.IgnoreCase | RegexOptions.Singleline).GetGroupValue(1) ?? "").ToUpper(); //download url var downloadLink = Regex.Match(ctx.Result, @"""([^""]*?isohunt[^""]*?/download\.php\?id[^""]*?)""", RegexOptions.Singleline | RegexOptions.IgnoreCase); var data = GetExtraData(info); if (downloadLink.Success) { data.SiteDownloadLink = downloadLink.Groups[1].Value; data.ProvideSiteDownload = true; } else { data.ProvideSiteDownload = false; } base.LoadFullDetailCore(info); }
public void UpdatePreview(IResourceInfo info) { foreach (var previewHandler in _handlers.Values) { previewHandler.Hide(); } if (info == null || info.SupportPreivewType == PreviewType.None) { _currentInfo = null; return; } _currentInfo = info; if (info.PreviewInfo == null) { _previewInfoLoading.Show(); LocatePreview(_previewInfoLoading); _previewInfoLoading.BringToFront(); info.PreviewInfoLoaded -= Info_PreviewInfoLoaded; info.PreviewInfoLoaded += Info_PreviewInfoLoaded; info.Provider.LoadPreviewInfo(info); } else { ShowPreview(info); } }
/// <summary> /// 加载内容 /// </summary> /// <param name="url"></param> public override void LookupTorrentContentsCore(string url, IResourceInfo torrent, string htmlContent) { if (htmlContent.IndexOf("<h2>404") != -1) { throw new Exception("此种子已经从网站上移除,无法查看内容,请尝试直接下载。"); } htmlContent = DecodePage(htmlContent); var doc = new HtmlDocument(); doc.LoadHtml(htmlContent); var nodes = doc.DocumentNode.SelectNodes("//dd[@class='filelist']/p"); if (nodes != null) { foreach (var node in nodes) { var sizeNode = node.SelectSingleNode("span"); var size = sizeNode.InnerText; var filepath = node.SelectSingleNode("text()").InnerText; AddFileNode(torrent, filepath, null, size); } } base.LookupTorrentContentsCore(url, torrent, htmlContent); }
/// <summary> /// 加载相信信息 /// </summary> protected override void LoadFullDetailCore(IResourceInfo info) { var url = GetDetailUrl(info); var html = NetworkClient.Create <string>(HttpMethod.Get, url, ReferUrlPage).Send(); var sinfo = (ResourceInfo)info; if (html.IsValid()) { if (IsHostChanged(html)) { base.LoadFullDetail(info); return; } if (IsBotCheckNeeded(html)) { if (RequireBotCheck()) { base.LoadFullDetail(info); } return; } sinfo.Hash = Regex.Match(html.Result, @"btih:([a-z\d]{40})", RegexOptions.IgnoreCase).GetGroupValue(1); LookupTorrentContentsCore(url, info, html.Result); } base.LoadFullDetailCore(info); }
protected virtual void LoadFullDetailCore(IResourceInfo info) { if (SiteID == 0 || !info.IsHashLoaded || info.SiteData == null) { return; } var sid = 0L; var pn = ""; if (info.SiteData is SiteInfo) { sid = (info.SiteData as SiteInfo).SiteID; pn = (info.SiteData as SiteInfo).PageName; } if (sid > 0L) { AppContext.Instance.HashSiteMap.UpdateHash(SiteID, sid, info.Hash); } else if (!pn.IsNullOrEmpty()) { AppContext.Instance.HashSiteMapStr.UpdateHash(SiteID, pn, info.Hash); } }
/// <summary> /// 执行下载 /// </summary> /// <param name="torrent"></param> /// <returns></returns> public virtual byte[] Download(IResourceInfo torrent) { if (torrent.Data is byte[]) { return(torrent.Data as byte[]); } if (torrent == null || (_filterDownloadType != null && !_filterDownloadType.Contains(torrent.Provider.GetType())) || !torrent.IsHashLoaded || torrent.SiteData == null || !(torrent.SiteData is SiteInfo)) { return(null); } var data = torrent.SiteData as SiteInfo; if (data.ProvideSiteDownload == null) { torrent.Provider.LoadFullDetail(torrent); } var link = data.SiteDownloadLink; if (data.ProvideSiteDownload == false || link.IsNullOrEmpty()) { return(null); } return(DownloadCore(link, link)); }
/// <summary> /// 加载内容 /// </summary> public override void LookupTorrentContents(IResourceInfo torrent) { var detailPage = GetDetailUrl(torrent); var html = NetworkClient.Create <string>(HttpMethod.Get, detailPage, ReferUrlPage).Send(); if (!html.IsValid()) { return; } var bodycontent = html.Result.SearchStringTag("<div class=\"files\">", "</div>"); if (string.IsNullOrEmpty(bodycontent)) { return; } var pos = 0; var row = ""; while (!string.IsNullOrEmpty((row = bodycontent.SearchStringTag("<li>", "</li>", ref pos)))) { var mcs = Regex.Match(row, @"<li>(.*)\s([\d\.]+\s+\w+)</li>", RegexOptions.IgnoreCase | RegexOptions.Singleline); if (!mcs.Success) { continue; } var path = HttpUtility.HtmlDecode(mcs.Groups[1].Value); AddFileNode(torrent, path, null, mcs.Groups[2].Value); } }
/// <summary> /// 加载内容 /// </summary> public override void LookupTorrentContents(IResourceInfo torrent) { var url = GetDetailUrl(torrent); var htmlContext = NetworkClient.Create <string>(HttpMethod.Get, url, ReferUrlPage).Send(); if (!htmlContext.IsValid()) { return; } var html = htmlContext.Result.SearchStringTag("id=\"filelist\">", "</ul>"); if (string.IsNullOrEmpty(html)) { return; } var charPos = 0; var row = ""; while (!string.IsNullOrEmpty((row = html.SearchStringTag("<li", "</li>", ref charPos)))) { var m = Regex.Match(row, "<span.*?>([^<]+)</span><span.*?>([^<]+)</span>", RegexOptions.IgnoreCase | RegexOptions.Singleline); if (!m.Success) { continue; } var path = m.GetGroupValue(1); var size = m.GetGroupValue(2); AddFileNode(torrent, BrtUtility.ClearString(path), null, BrtUtility.ClearString(size)); } }
/// <summary> /// 将指定的文件节点加到树中 /// </summary> /// <param name="resource"></param> /// <param name="path"></param> /// <param name="size"></param> /// <param name="sizeValue"></param> protected virtual void AddFileNode(IResourceInfo resource, string path, long?size, string sizeValue) { var pathlist = path.Split(PathSpliter, StringSplitOptions.RemoveEmptyEntries); var container = (ICollection <IFileNode>)resource; for (var i = 0; i < pathlist.Length - 1; i++) { var subcontainer = container.FirstOrDefault(s => s.Name.IsIgnoreCaseEqualTo(pathlist[i])); if (subcontainer == null) { subcontainer = new FileNode() { Name = pathlist[i], IsDirectory = true }; container.Add(subcontainer); } container = subcontainer.Children; } container.Add(new FileNode() { IsDirectory = false, Name = pathlist.Last(), Size = size, SizeString = sizeValue }); }
void TaskDownloadQueue() { Thread.CurrentThread.Name = "TaskDownloadThread"; while (!IsDisposed) { while (_downloadQueue.Count > 0) { //查找下一个任务 lock (_downloadQueue) { _downloadTask = _downloadQueue.Count == 0 ? null : _downloadQueue.Dequeue(); if (_downloadTask == null) { continue; } } DownloadQueueItem lvitem = null; this.Invoke(() => { lvitem = queue.Items.Cast <DownloadQueueItem>().FirstOrDefault(x => x.ResourceItem == _downloadTask && x.Status == QueueStatus.Wait); if (lvitem != null) { lvitem.EnsureVisible(); } }); if (lvitem == null) { continue; } lvitem.StartDownload(_downloadTarget, _ => _downloadedHashSet.Contains(_)); } Thread.Sleep(100); } }
public static async Task <string> DeserializeTextAsync(this IResourceInfo resource) { if (!resource.Exists) { throw new InvalidOperationException($"Cannot deserialize a resource that does not exist: '{resource.Uri.ToString()}'"); } var format = resource.Metadata.Get(Use <IResourceNamespace> .Namespace, x => x.Format); // todo - find a cleaner solution; maybe a new comparer for MimeType? if (!format.Name.StartsWith("text/")) { throw new ArgumentException($"Resource must be '{MimeType.Text}' but is '{format}'."); } using (var memoryStream = new MemoryStream()) { await resource.CopyToAsync(memoryStream); using (var streamReader = new StreamReader(memoryStream.Rewind())) { return(await streamReader.ReadToEndAsync()); } } }
/// <summary> /// 查看种子内容 /// </summary> /// <param name="provider"></param> /// <param name="resource"></param> public void ViewTorrentContents(IResourceProvider provider, IResourceInfo resource) { if (provider == null || resource == null || !provider.SupportLookupTorrentContents) { return; } new TorrentContentVisualizer(provider, resource).Show(); }
/// <summary> /// 查看详细信息 /// </summary> /// <param name="provider"></param> /// <param name="resource"></param> public void ViewDetail(IResourceProvider provider, IResourceInfo resource) { if (provider == null || resource == null) { return; } Process.Start(provider.GetDetailUrl(resource)); }
/// <summary> /// 获得指定资源的标注名 /// </summary> /// <param name="resource"></param> /// <returns></returns> public string GetResourceMarkName(IResourceInfo resource) { if (resource == null || resource.Hash.IsNullOrEmpty()) { return(null); } return(HashMarkCollection.GetValue(resource.Hash)); }
public static byte[] SerializeAndCompressMetaData(IResourceInfo info) { var serializedStream = new MemoryStream(); new XmlSerializer(info.GetType()).Serialize(serializedStream, info); serializedStream.Position = 0; return(serializedStream.ToArray().Compress()); }
public virtual void LoadPreviewInfo(IResourceInfo resource) { if (resource == null || resource.SupportPreivewType == PreviewType.None || resource.PreviewInfo != null) { return; } new TaskFactory().StartNew(() => LoadPreviewInfoCore(resource)); }
/// <summary> /// 加载相信信息 /// </summary> public override void LoadFullDetail(IResourceInfo info) { if (info.Count == 0) { FillFullInfo(info); } base.LoadFullDetail(info); }
public TorrentContentVisualizer(IResourceProvider provider, IResourceInfo resource) { _provider = provider; _resource = resource; InitializeComponent(); //初始化文件图标 il.ImageSize = new Size(20, 20); il.Images.Add("video", Utility.Get20PxImageFrom16PxImg(Properties.Resources.video)); il.Images.Add("image", Utility.Get20PxImageFrom16PxImg(Properties.Resources.image)); il.Images.Add("file", Utility.Get20PxImageFrom16PxImg(Properties.Resources.file)); il.Images.Add("folder", Utility.Get20PxImageFrom16PxImg(Properties.Resources.clear_folder)); il.Images.Add("folderopen", Utility.Get20PxImageFrom16PxImg(Properties.Resources.clear_folder_open)); il.Images.Add("zip", Utility.Get20PxImageFrom16PxImg(Properties.Resources.zip)); il.Images.Add("html", Utility.Get20PxImageFrom16PxImg(Properties.Resources.badge_html)); il.Images.Add("doc", Utility.Get20PxImageFrom16PxImg(Properties.Resources.document_word)); Load += TorrentContentVisualizer_Load; files.AfterExpand += (s, e) => { e.Node.ImageKey = e.Node.SelectedImageKey = "folderopen"; }; files.AfterCollapse += (s, e) => { e.Node.ImageKey = e.Node.SelectedImageKey = "folder"; }; tsCollapse.Click += (s, e) => files.CollapseAll(); tsExpand.Click += (s, e) => files.ExpandAll(); tsDownload.Click += (s, e) => AppContext.Instance.ResourceOperation.AccquireDownloadTorrent(_resource); tsCopy.Click += (s, e) => AppContext.Instance.ResourceOperation.CopyMagnetLink(_resource); //标记 var markItems = AppContext.Instance.Options.HashMarks.Select(s => (ToolStripItem) new ToolStripMenuItem(s.Key) { ForeColor = s.Value.Color, BackColor = s.Value.BackColor }).ToArray(); var currentMaskType = AppContext.Instance.GetResourceMarkName(_resource); tsMarkNone.Checked = string.IsNullOrEmpty(currentMaskType); tsMark.DropDownItems.AddRange(markItems); foreach (var toolStripItem in markItems) { toolStripItem.Click += (s, e) => { tsMark.DropDownItems.OfType <ToolStripMenuItem>().Skip(1).ForEach(_ => _.Checked = _ == s); AppContext.Instance.ResourceOperation.SetTorrentMask((s as ToolStripMenuItem).Text, _resource); tsMarkNone.Checked = false; }; if (!string.IsNullOrEmpty(currentMaskType) && currentMaskType == toolStripItem.Text) { ((ToolStripMenuItem)toolStripItem).Checked = true; } } tsMarkNone.Click += tsMarkNone_Click; }
/// <summary> /// 加载相信信息 /// </summary> public virtual void LoadFullDetail(IResourceInfo info) { if (info.IsHashLoaded || info.SiteData == null) { return; } LoadFullDetailCore(info); }
/// <summary> /// 加载内容 /// </summary> public override void LookupTorrentContents(IResourceInfo torrent) { if (torrent.Count == 0) { FillFullInfo(torrent); } base.LookupTorrentContents(torrent); }
/// <summary> /// 创建 <see cref="DownloadQueueItem" /> 的新实例(DownloadQueueItem) /// </summary> /// <param name="resourceItem"></param> public DownloadQueueItem(IResourceInfo resourceItem) : base(new[] { resourceItem.Title.GetSubString(150), "等待中..." }) { Contract.Requires(resourceItem != null); ResourceItem = resourceItem; ImageIndex = 0; _engineIndex = 0; }
/// <summary> /// 校验特定资源 /// </summary> /// <param name="info"></param> /// <returns></returns> public VerifyState Check(IResourceInfo info) { if (Regex.IsMatch(info.Title, @"\.(bc!|td|cfg|part)$", RegexOptions.IgnoreCase)) { return(VerifyState.AutoFake); } return(VerifyState.Unknown); }
/// <summary> /// 加载内容 /// </summary> /// <param name="url"></param> public override void LookupTorrentContentsCore(string url, IResourceInfo torrent, string htmlContent) { var files = Regex.Matches(htmlContent, @"<tr>.*?<td.*?fileRows"">(.*?)</td>\s*<td.*?fileRowsRight"">(.*?)</td>", RegexOptions.Singleline | RegexOptions.IgnoreCase); foreach (Match match in files) { AddFileNode(torrent, match.Groups[1].Value, null, match.Groups[2].Value); } base.LookupTorrentContentsCore(url, torrent, htmlContent); }
public static byte[] SerializeAndCompressMetaData(IResourceInfo info) { var serializedStream = new MemoryStream(); new XmlSerializer(info.GetType()).Serialize(serializedStream, info); serializedStream.Position = 0; return serializedStream.ToArray().Compress(); }