internal RSSDiscoverResult(string url, string name, string hintText) { _url = url; _name = name; _hintText = hintText; _existingFeed = RSSPlugin.GetExistingFeed(url); }
private void ScheduleForUpdate(IResource root) { RSSPlugin plug = RSSPlugin.GetInstance(); if (plug == null) { return; } foreach (IResource res in root.GetLinksTo(null, Core.Props.Parent).ValidResources) { if (res.Type == "RSSFeedGroup") { ScheduleForUpdate(res); } else if (res.Type == "RSSFeed" && _oldRSSFeedList.IndexOf(res) == -1) { if (!res.HasProp(Props.UpdateFrequency) || !res.HasProp(Props.UpdatePeriod)) { res.SetProp(Props.UpdateFrequency, 4); res.SetProp(Props.UpdatePeriod, UpdatePeriods.Hourly); } plug.ScheduleFeedUpdate(res); } } }
private void DiscoverDone() { if (_rssDiscover.Results.Count > 0) { if (_rssDiscover.Results.Count == 1) { IResource existingFeed = RSSPlugin.GetExistingFeed(_rssDiscover.Results[0].URL); if (existingFeed != null) { _feedAddressPane.ErrorMessage = "You are already subscribed to that feed."; _feedAddressPane.SetExistingFeedLink(existingFeed); } else { _newFeedProxy.BeginUpdate(); _newFeedProxy.SetProp(Core.Props.Name, _rssDiscover.Results[0].Name); _newFeedProxy.SetProp(Props.URL, _rssDiscover.Results[0].URL); _newFeedProxy.EndUpdate(); _feedsToSubscribe = new ResourceProxy[] { _newFeedProxy }; ShowTitleGroupPage(OnBackToFirstPage); } } else { ShowMultipleResultsPage(); } } else { ShowErrorInformation("Could't find a feed for the selected site", string.Empty); } }
/// <summary> /// Returns a 16 by 16 icon that indicates a particular state of downloading the enclosure. /// </summary> /// <param name="state">Enclosure download state.</param> /// <returns>The icon (the same instance for the same parameters).</returns> public static Icon GetEnclosureStateIcon(EnclosureDownloadState state) { if (!Core.UserInterfaceAP.IsOwnerThread) { throw new InvalidOperationException("This method must be accessed only from the User Interface Async Processor thread."); } // Load the icons on the first call if (_arEnclosureStateIcons == null) { _arEnclosureStateIcons = new Icon[5]; String[] sNames = new[] { "NotDownloaded", "Planned", "Completed", "Failed", "InProgress" }; for (int a = 0; a < sNames.Length; a++) { _arEnclosureStateIcons[a] = RSSPlugin.LoadIconFromAssembly(string.Format("download{0}.ico", sNames[a])); } } // Range check if ((state < EnclosureDownloadState.MinValue) || (state >= EnclosureDownloadState.MaxValue)) { throw new ArgumentException("The enclosure download state is out of range."); } // Hand out the icon return(_arEnclosureStateIcons[(int)state]); }
public Icon[] GetOverlayIcons(IResource resource) { string updateStatus = resource.GetStringProp(Props.UpdateStatus); if (updateStatus == "(updating)") { if (_updating == null) { _updating = new Icon[1]; _updating[0] = RSSPlugin.LoadIconFromAssembly("updating.ico"); } return(_updating); } if (updateStatus == "(error)") { if (_error == null) { _error = new Icon[1]; _error[0] = RSSPlugin.LoadIconFromAssembly("error.ico"); } return(_error); } if (resource.HasProp(Props.IsPaused)) { if (_paused == null) { _paused = new Icon[1]; _paused[0] = RSSPlugin.LoadIconFromAssembly("RSSFeedPaused.ico"); } return(_paused); } return(null); }
private static int ConfirmImportRecursive(IResource res) { int count = 0; foreach (IResource child in res.GetLinksTo(null, Core.Props.Parent)) { if (child.Type == "RSSFeedGroup") { int childCount = ConfirmImportRecursive(child); if (childCount == 0) { child.Delete(); } count += childCount; } else if (child.GetIntProp(Props.Transient) == 1) { IResourceList items = child.GetLinksOfType("RSSItem", Props.RSSItem); items.DeleteAll(); child.Delete(); } else { if (RSSPlugin.GetInstance() != null) { RSSPlugin.GetInstance().QueueFeedUpdate(child); } count++; } } return(count); }
private void OnDownloadClick() { _feedAddressPane.SetExistingFeedLink(null); if (File.Exists(_feedAddressPane.FeedUrl)) { _feedAddressPane.FeedUrl = "file://" + _feedAddressPane.FeedUrl; } else if (_feedAddressPane.FeedUrl.IndexOf("://") < 0) { _feedAddressPane.FeedUrl = "http://" + _feedAddressPane.FeedUrl; } else { string url = _feedAddressPane.FeedUrl.ToLower(); if (!HttpReader.IsSupportedProtocol(url)) { _feedAddressPane.ErrorMessage = "Unknown URL schema. Only http:, https: and file: are supported."; return; } } try { new Uri(_feedAddressPane.FeedUrl); } catch (Exception ex) { _feedAddressPane.ErrorMessage = ex.Message; return; } IResource existingFeed = RSSPlugin.GetExistingFeed(_feedAddressPane.FeedUrl); if (existingFeed != null) { _feedAddressPane.ErrorMessage = "You are already subscribed to that feed."; _feedAddressPane.SetExistingFeedLink(existingFeed); return; } _progressLabel.Text = "Downloading..."; _nextButton.Enabled = false; _feedAddressPane.ControlsEnabled = false; if (_newFeedProxy != null) { _newFeedProxy.DeleteAsync(); _newFeedProxy = null; } _newFeedProxy = CreateFeedProxy(_feedAddressPane.FeedUrl, null); _rssUnitOfWork = new RSSUnitOfWork(_newFeedProxy.Resource, false, true); _rssUnitOfWork.DownloadProgress += OnDownloadProgress; _rssUnitOfWork.ParseDone += OnParseDone; Core.NetworkAP.QueueJob(JobPriority.Immediate, _rssUnitOfWork); }
private void ProcessUrlDrop(IResource targetResource, IDataObject data, string format, Encoding encoding) { Stream dataStream = (Stream)data.GetData(format); if (dataStream != null) { string url = Utils.StreamToString(dataStream, encoding); RSSPlugin.GetInstance().ShowAddFeedWizard(url, targetResource); } }
internal void ExecuteOperation() { IResource rootGroup = _importRoot; if (_importPreview) { _previewRoot = Core.ResourceStore.NewResource("RSSFeedGroup"); rootGroup = _previewRoot; } bool hasOPML = true; try { hasOPML = OPMLProcessor.Import(new StreamReader(_importStream), rootGroup, !_importPreview); } catch (Exception ex) { MessageBox.Show(Core.MainWindow, "Error importing OPML file " + _importFileName + ":\n" + ex.Message, "Import OPML", MessageBoxButtons.OK); // the import may have been partially successful, and we still want to // update the feeds that were imported successfully } if (!hasOPML) { MessageBox.Show(Core.MainWindow, _importFileName + " is not an OPML file", "Import OPML", MessageBoxButtons.OK); return; } if (_importPreview) { if (_previewRoot.GetLinksOfType(null, "Parent").Count > 0) { Core.UIManager.QueueUIJob(new MethodInvoker(ShowImportPreviewDialog)); } else { _previewRoot.Delete(); } } else { foreach (IResource feed in Core.ResourceStore.GetAllResources("RSSFeed")) { if (!feed.HasProp(Props.LastUpdateTime) && !feed.HasProp(Props.ItemCommentFeed)) { RSSPlugin.GetInstance().QueueFeedUpdate(feed); } } } }
internal OPMLImporter(ImportManager manager, IResource importRoot) { if (manager == null) { RSSPlugin.GetInstance().RegisterFeedImporter("OPML Files", this); } else { _manager = manager; _importRoot = importRoot; } }
private static IResource FindOrCreateGroup(IResource parentGroup, string name) { IResourceList childGroups = parentGroup.GetLinksTo("RSSFeedGroup", "Parent"); foreach (IResource child in childGroups) { if (child.GetStringProp("Name") == name) { return(child); } } return(RSSPlugin.CreateFeedGroup(parentGroup, name)); }
/// <summary> /// Import subscription /// </summary> public void DoImport(IResource importRoot, bool addToWorkspace) { if (_login.Length == 0 || _password.Length == 0) { return; } RSSPlugin plugin = RSSPlugin.GetInstance(); string authInfo = Convert.ToBase64String(Encoding.ASCII.GetBytes(_login + ":" + _password)); ImportUtils.UpdateProgress(0, _progressMessage); importRoot = plugin.FindOrCreateGroup("Bloglines Subscriptions", importRoot); ImportUtils.UpdateProgress(10, _progressMessage); WebClient client = new WebClient(); client.Headers.Add("Authorization", "basic " + authInfo); ImportUtils.UpdateProgress(20, _progressMessage); try { Stream stream = client.OpenRead(_ImportURL); ImportUtils.UpdateProgress(30, _progressMessage); OPMLProcessor.Import(new StreamReader(stream), importRoot, addToWorkspace); ImportUtils.UpdateProgress(90, _progressMessage); } catch (Exception ex) { Trace.WriteLine("BlogLines subscrption load failed: '" + ex.Message + "'"); RemoveFeedsAndGroupsAction.DeleteFeedGroup(importRoot); string message = "Import of BlogLines subscription failed:\n" + ex.Message; if (ex is WebException) { WebException e = (WebException)ex; if (e.Status == WebExceptionStatus.ProtocolError && ((HttpWebResponse)e.Response).StatusCode == HttpStatusCode.Unauthorized) { message = "Import of BlogLines subscription failed:\nInvalid login or password."; } } ImportUtils.ReportError("BlogLines Subscription Import", message); } ImportUtils.UpdateProgress(100, _progressMessage); return; }
public Icon GetResourceIcon(IResource resource) { // Try to get the feed's favicon Icon favicon = TryGetResourceIcon(resource); if (favicon != null) { return(favicon); } // No favicon available, return resource-type's default icon (lazy loading) if (_default == null) { _default = RSSPlugin.LoadIconFromAssembly("RSSFeed.ico"); } return(_default); }
private void OnSaveFeedImpl() { foreach (IResource feed in _feeds) { feed.BeginUpdate(); } if (!_chkAuthentication.Checked) { _edtUserName.Text = string.Empty; _edtPassword.Text = string.Empty; } _needUpdate = _needUpdate || _udUpdateFrequency.Changed || _cmbUpdatePeriod.Changed; if (!_chkUpdate.Checked) { _cmbUpdatePeriod.SetValue("daily"); _cmbUpdatePeriod.Changed = true; _udUpdateFrequency.Minimum = -1; _udUpdateFrequency.SetValue(-1); _udUpdateFrequency.Changed = true; } SettingSaver.Save(Controls); if (_feeds.Count == 1) { _feed.SetProp(Props.URL, _edtAddress.Text); _feed.SetProp(Core.Props.Name, _edtTitle.Text); _feed.SetProp(Core.Props.Annotation, _edtAnnotation.Text); } foreach (IResource feed in _feeds) { feed.EndUpdate(); } if (_needUpdate) { foreach (IResource feed in _feeds) { RSSPlugin.GetInstance().QueueFeedUpdate(feed); } } }
internal static void DoConfirmImport(IResource previewRoot, IResource importRoot) { foreach (IResource res in previewRoot.GetLinksTo(null, Core.Props.Parent)) { if (res.Type == "RSSFeedGroup") { int count = ConfirmImportRecursive(res); if (count == 0) { res.Delete(); continue; } if (RelinkExistingGroup(res, importRoot)) { continue; } Core.WorkspaceManager.AddToActiveWorkspaceRecursive(res); } if (res.Type == "RSSFeed" && res.GetIntProp(Props.Transient) == 1) { // Delete all items IResourceList items = res.GetLinksOfType("RSSItem", Props.RSSItem); items.DeleteAll(); res.Delete(); } else { res.DeleteProp(Props.Transient); res.SetProp(Core.Props.Parent, importRoot); if (res.Type == "RSSFeed") { Core.WorkspaceManager.AddToActiveWorkspace(res); if (RSSPlugin.GetInstance() != null) { RSSPlugin.GetInstance().QueueFeedUpdate(res); } } } } previewRoot.Delete(); }
public FeedDemonImporter() { bool FeedDemonFound = true; string basePath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); string daemonPath = Path.Combine(basePath, @"Bradsoft.com\FeedDemon\1.0"); _channelsPath = Path.Combine(daemonPath, "Channels"); _groupsPath = Path.Combine(daemonPath, "Groups"); FeedDemonFound = Directory.Exists(_channelsPath) && Directory.Exists(_groupsPath); if (!FeedDemonFound) { // don't build additional data structures return; } RSSPlugin.GetInstance().RegisterFeedImporter("FeedDemon", this); _flag = Core.ResourceStore.FindUniqueResource("Flag", "FlagId", "RedFlag"); }
/// <summary> /// Import subscription /// </summary> public void DoImport(IResource importRoot, bool addToWorkspace) { RSSPlugin plugin = RSSPlugin.GetInstance(); importRoot = plugin.FindOrCreateGroup("FeedDemon subscriptions", importRoot); // Count full count of resources string[] allFiles = Directory.GetFiles(_groupsPath, "*.opml"); int totalFiles = Math.Max(allFiles.Length, 1); int processedFiles = 0; ImportUtils.UpdateProgress(processedFiles / totalFiles, _progressMessage); foreach (string file in allFiles) { IResource group = null; string name = Path.GetFileNameWithoutExtension(file); group = plugin.FindOrCreateGroup(name, importRoot); try { Hashtable ns = new Hashtable(); Stream stream = new FileStream(file, FileMode.Open, FileAccess.Read); // Fix bugs in OPML ns["fd"] = _fdNS; OPMLProcessor.Import(new StreamReader(stream), group, addToWorkspace, ns); } catch (Exception ex) { RemoveFeedsAndGroupsAction.DeleteFeedGroup(group); ImportUtils.ReportError("FeedDemon Subscription Import", "Import of FeedDemon group '" + name + "' failed:\n" + ex.Message); } processedFiles += 100; ImportUtils.UpdateProgress(processedFiles / totalFiles, _progressMessage); } // Read summary.xml string summary = Path.Combine(_channelsPath, "summary.xml"); if (File.Exists(summary)) { try { XmlDocument xdoc = new XmlDocument(); xdoc.Load(summary); foreach (XmlElement channel in xdoc.GetElementsByTagName("channel")) { string title = null; string url = null; XmlNodeList l = null; l = channel.GetElementsByTagName("title"); if (l.Count < 1) { continue; } title = l[0].InnerText; l = channel.GetElementsByTagName("newsFeed"); if (l.Count < 1) { continue; } url = l[0].InnerText; _name2url.Add(title, url); } } catch (Exception ex) { Trace.WriteLine("FeedDemon subscrption load failed: '" + ex.Message + "'"); } } return; }
internal BloglinesImporter() { RSSPlugin.GetInstance().RegisterFeedImporter("Bloglines", this); }
private void OnFinishClick() { Trace.WriteLine("SubscribeToSearchFeeds -- OnFinishClick."); _nextButton.Enabled = false; if (_feedsToSubscribe == null) { throw new InvalidOperationException("Trying to finish wizard with unknown feeds to subscribe"); } if (_feedsToSubscribe.Length == 0) { DoCancel(); Close(); return; } if (_feedsToSubscribe.Length == 1 && RSSPlugin.GetExistingFeed(_feedsToSubscribe [0].Resource.GetStringProp(Props.URL)) != null) { MessageBox.Show(this, "You have already subscribed to this feed.", "Subscribe to Feed"); DoCancel(); return; } IResource parentGroup = _titleGroupPane.SelectedGroup; if (parentGroup == null) { parentGroup = RSSPlugin.RootFeedGroup; } Trace.WriteLine("SubscribeToSearchFeeds -- Starting to link feeds to parent."); foreach (ResourceProxy proxy in _feedsToSubscribe) { if (proxy == _newFeedProxy) { _newFeedProxy = null; } proxy.BeginUpdate(); try { if (_feedsToSubscribe.Length == 1) { proxy.SetProp(Core.Props.Name, _titleGroupPane.FeedTitle); } proxy.DeleteProp(Props.Transient); proxy.SetProp(Core.Props.Parent, parentGroup); Trace.WriteLine("SubscribeToSearchFeeds -- Link feed to parent [" + parentGroup.DisplayName + "]"); } finally { proxy.EndUpdate(); Trace.WriteLine("SubscribeToSearchFeeds -- EndUpdate called for a feed"); } Core.WorkspaceManager.AddToActiveWorkspace(proxy.Resource); Trace.WriteLine("SubscribeToSearchFeeds -- AddToActiveWorkspace called for a feed."); RSSPlugin.GetInstance().QueueFeedUpdate(proxy.Resource); Trace.WriteLine("SubscribeToSearchFeeds -- QueueFeedUpdate called for a feed."); } Core.UIManager.BeginUpdateSidebar(); if (Core.TabManager.ActivateTab("Feeds")) { Core.LeftSidebar.ActivateViewPane("Feeds"); } Core.UIManager.EndUpdateSidebar(); RSSPlugin.RSSTreePane.SelectResource(_feedsToSubscribe [0].Resource); RSSPlugin.SaveSubscription(); _newFeedProxy = null; _feedsToSubscribe = null; Close(); }
/// <summary> /// Import subscription /// </summary> public void DoImport(IResource importRoot, bool addToWorkspace) { if (null == FileNames) { return; } int totalFeeds = Math.Max(FileNames.Length, 1); int processedFeeds = 0; ImportUtils.UpdateProgress(processedFeeds / totalFeeds, _progressMessage); IResource currentRoot = null; foreach (string fileName in FileNames) { string defaultName = null; Stream opml = null; if (!File.Exists(fileName)) { defaultName = fileName; // Try to load as URL try { opml = new JetMemoryStream(new WebClient().DownloadData(fileName), true); } catch (Exception ex) { Trace.WriteLine("OPML file '" + fileName + "' can not be load: '" + ex.Message + "'"); opml = null; } } else { defaultName = Path.GetFileName(fileName); // Try to load title from this file try { opml = new FileStream(fileName, FileMode.Open, FileAccess.Read); } catch (Exception ex) { Trace.WriteLine("OPML file '" + fileName + "' can not be load: '" + ex.Message + "'"); opml = null; } } if (null == opml) { continue; } // Try to get name string name = null; try { XmlDocument xml = new XmlDocument(); xml.Load(opml); XmlElement title = xml.SelectSingleNode("/opml/head/title") as XmlElement; name = title.InnerText; } catch (Exception ex) { Trace.WriteLine("OPML file '" + fileName + "' doesn't have title: '" + ex.Message + "'"); } if (name == null || name.Length == 0) { name = defaultName; } try { opml.Seek(0, SeekOrigin.Begin); if (_manager == null || FileNames.Length > 1) { currentRoot = RSSPlugin.GetInstance().FindOrCreateGroup("Subscription from " + name, importRoot); } else { currentRoot = importRoot; } OPMLProcessor.Import(new StreamReader(opml), currentRoot, addToWorkspace); } catch (Exception ex) { Trace.WriteLine("OPML file '" + fileName + "' can not be load: '" + ex.Message + "'"); RemoveFeedsAndGroupsAction.DeleteFeedGroup(currentRoot); ImportUtils.ReportError("OPML File Import", "Import of OPML file '" + fileName + "' failed:\n" + ex.Message); } processedFeeds += 100; ImportUtils.UpdateProgress(processedFeeds / totalFeeds, _progressMessage); } return; }
public void RegisterViewsFirstRun() { IResource res; string[] applType = new string[] { "RSSItem" }; IFilterRegistry fMgr = Core.FilterRegistry; //----------------------------------------------------------------- // All conditions, templates and actions must have their deep names //----------------------------------------------------------------- res = Core.ResourceStore.FindUniqueResource(FilterManagerProps.ConditionResName, "Name", RSSViewsConstructor.AuthorWrotePostName); if (res != null) { res.SetProp("DeepName", RSSViewsConstructor.AuthorWrotePostDeep); } res = Core.ResourceStore.FindUniqueResource(FilterManagerProps.ConditionResName, "Name", RSSViewsConstructor.AuthorHasFeedName); if (res != null) { res.SetProp("DeepName", RSSViewsConstructor.AuthorHasFeedDeep); } res = Core.ResourceStore.FindUniqueResource(FilterManagerProps.ConditionResName, "Name", RSSViewsConstructor.PostHasEnclosuredName); if (res != null) { res.SetProp("DeepName", RSSViewsConstructor.PostHasEnclosuredDeep); } res = Core.ResourceStore.FindUniqueResource(FilterManagerProps.ConditionResName, "Name", RSSViewsConstructor.PostHasCommentName); if (res != null) { res.SetProp("DeepName", RSSViewsConstructor.PostHasCommentDeep); } res = Core.ResourceStore.FindUniqueResource(FilterManagerProps.ConditionResName, "Name", RSSViewsConstructor.DownloadFailedName); if (res != null) { res.SetProp("DeepName", RSSViewsConstructor.DownloadFailedDeep); } res = Core.ResourceStore.FindUniqueResource(FilterManagerProps.ConditionResName, "Name", RSSViewsConstructor.DownloadCompletedName); if (res != null) { res.SetProp("DeepName", RSSViewsConstructor.DownloadCompletedDeep); } res = Core.ResourceStore.FindUniqueResource(FilterManagerProps.ConditionResName, "Name", RSSViewsConstructor.DownloadNotName); if (res != null) { res.SetProp("DeepName", RSSViewsConstructor.DownloadNotDeep); } res = Core.ResourceStore.FindUniqueResource(FilterManagerProps.ConditionResName, "Name", RSSViewsConstructor.DownloadPlannedName); if (res != null) { res.SetProp("DeepName", RSSViewsConstructor.DownloadPlannedDeep); } res = Core.ResourceStore.FindUniqueResource(FilterManagerProps.ConditionTemplateResName, "Name", RSSViewsConstructor.PostInFeedName); if (res != null) { res.SetProp("DeepName", RSSViewsConstructor.PostInFeedDeep); } res = Core.ResourceStore.FindUniqueResource(FilterManagerProps.ConditionTemplateResName, "Name", RSSViewsConstructor.PostInCategoryName); if (res != null) { res.SetProp("DeepName", RSSViewsConstructor.PostInCategoryDeep); } res = Core.ResourceStore.FindUniqueResource(FilterManagerProps.ConditionTemplateResName, "Name", RSSViewsConstructor.EnclosureSizeName); if (res != null) { res.SetProp("DeepName", RSSViewsConstructor.EnclosureSizeDeep); } res = Core.ResourceStore.FindUniqueResource(FilterManagerProps.ConditionTemplateResName, "Name", RSSViewsConstructor.EnclosureTypeName); if (res != null) { res.SetProp("DeepName", RSSViewsConstructor.EnclosureTypeDeep); } res = Core.ResourceStore.FindUniqueResource(FilterManagerProps.RuleActionResName, "Name", RSSViewsConstructor.DownloadEnclosureName); if (res != null) { res.SetProp("DeepName", RSSViewsConstructor.DownloadEnclosureDeep); } // Tray Icon Rules and Notifications Core.TrayIconManager.RegisterTrayIconRule("Unread RSS/ATOM Posts", applType, new IResource[] { fMgr.Std.ResourceIsUnread }, null, RSSPlugin.LoadIconFromAssembly("RSSItemUnread.ico")); }
public void GetItemHtml(IResource item, TextWriter writer) { TextWriterDecor decor = new TextWriterDecor(writer); //////////////////////// // Prepare the strings /* * // Date — date/time of this item * string sDate; * DateTime date = item.GetDateProp( Core.Props.Date ); * if( date.Date == DateTime.Today ) * sDate = "Today " + date.ToShortTimeString(); * else * sDate = date.ToShortDateString() + ' ' + date.ToShortTimeString(); * * // Origin — name of the feed author, etc * string sOrigin = ""; * if( item.HasProp( Core.ContactManager.Props.LinkFrom ) ) * sOrigin = HttpUtility.HtmlEncode( item.GetPropText( Core.ContactManager.Props.LinkFrom ) ); * * ////////// * // Title * writer.WriteLine( "<div class=\"title\">" ); * GenericNewspaperProvider.RenderIcon( item, writer ); // Icon * RssBodyConstructor.AppendLink( item, decor, true ); // Title text & link * writer.WriteLine( "<em class=\"Origin\">{0}{2}{1}</em>", sOrigin, sDate, ((sOrigin.Length > 0) && (sDate.Length > 0) ? " — " : "") ); // Origin (feed name) & Date * writer.WriteLine( "</div>" ); // class=title * * GenericNewspaperProvider.RenderFlag( item, writer ); // Flag (optional) * GenericNewspaperProvider.RenderAnnotation( item, writer ); // Annotation (optional) * * writer.WriteLine( "<br class=\"clear\" />" ); */ // TODO: remove IResource feed = item.GetLinkProp(-Props.RSSItem); GenericNewspaperProvider.RenderCaption(item, writer); ////////////// // Item Body writer.WriteLine("<div>"); if (feed != null && feed.HasProp(Props.URL)) { writer.WriteLine(HtmlTools.FixRelativeLinks(item.GetPropText(Core.Props.LongBody), feed.GetStringProp("URL"))); } else { writer.WriteLine(item.GetPropText(Core.Props.LongBody)); } writer.WriteLine("</div>"); // Enclosure info if (item.HasProp(Props.EnclosureURL)) { writer.Write("<p class=\"Origin\"><span title=\"Enclosure is an attachment to the RSS feed item.\">Enclosure</span>"); // Specify the enclosure size, if available if (item.HasProp(Props.EnclosureSize)) { writer.Write(" ({0})", Utils.SizeToString(item.GetIntProp(Props.EnclosureSize))); } writer.Write(": "); // Add a link to the locally-saved enclosure file string sDownloadComment = null; // Will contain an optional download comment if (item.HasProp(Props.EnclosureDownloadingState)) { // Choose the tooltip text and whether the icon will be clickable, depending on the state string sText = null; bool bLink = false; EnclosureDownloadState nEnclosureDownloadState = (EnclosureDownloadState)item.GetIntProp(Props.EnclosureDownloadingState); switch (nEnclosureDownloadState) { case EnclosureDownloadState.Completed: sText = "The enclosure has been downloaded to your computer.\nClick to open the local file."; bLink = true; break; case EnclosureDownloadState.Failed: sText = "Failed to download the enclosure.\nUse the Web link to download manually."; break; case EnclosureDownloadState.InProgress: sText = "Downloading the enclosure, please wait…\nClick to open the partially-downloaded file."; // Write percentage to the comment if (item.HasProp(Props.EnclosureDownloadedSize)) { if (item.HasProp(Props.EnclosureSize)) // The total size is available, as needed for the percentage { sDownloadComment = String.Format("({0}%)", item.GetIntProp(Props.EnclosureDownloadedSize) * 100 / item.GetIntProp(Props.EnclosureSize)); } else // The total size is not available, percentage not available, show the size downloaded { sDownloadComment = String.Format("({0} downloaded so far)", Utils.SizeToString(item.GetIntProp(Props.EnclosureDownloadedSize))); } } bLink = true; break; case EnclosureDownloadState.NotDownloaded: sText = "The enclosure has not been downloaded.\nUse the Web link to download manually."; break; case EnclosureDownloadState.Planned: sText = "The enclosure has been schedulled for download.\nUse the Web link to download manually."; sDownloadComment = "(0%)"; break; default: throw new Exception("Unexpected enclosure download state."); } // Ensure that there's the path to the local file specified, if we're going to provide a link to it if ((bLink) && (!item.HasProp(Props.EnclosureTempFile))) { Trace.WriteLine("Warning: path to the downloaded or in-progress enclosure is missing, though the downloading state implies on it should be present."); bLink = false; } // Open the link (if available) if (bLink) { writer.Write("<a href=\"{0}\">", "file://" + HttpUtility.HtmlEncode(item.GetStringProp(Props.EnclosureTempFile))); } // Render the icon Icon icon = EnclosureDownloadManager.GetEnclosureStateIcon(nEnclosureDownloadState); writer.Write("<img src=\"{0}\" align=\"top\" width=\"{1}\" height=\"{2}\" alt=\"{3}\" title=\"{3}\" />", FavIconManager.GetIconFile(icon, "EnclosureDownload", null, true), icon.Width, icon.Height, sText, sText); // Close the link if (bLink) { writer.Write("</a>"); } writer.Write(" "); } // Add a link to the Web location of the enclosure writer.Write("<a href=\"{0}\">", HttpUtility.HtmlEncode(item.GetStringProp(Props.EnclosureURL))); if (_iconEnclosureWeb == null) { _iconEnclosureWeb = RSSPlugin.LoadIconFromAssembly("BlogExtensionComposer.Submit.ico"); } writer.Write("<img src=\"{0}\" align=\"top\" width=\"{1}\" height=\"{2}\" alt=\"{3}\" title=\"{3}\" /> ", FavIconManager.GetIconFile(_iconEnclosureWeb, "EnclosureWeb", null, true), _iconEnclosureWeb.Width, _iconEnclosureWeb.Height, "Download enclosure from the Web."); writer.Write("</a>"); // Add the optional download comment if (sDownloadComment != null) { writer.Write(" "); } writer.Write(sDownloadComment); // Close the paragraph writer.WriteLine("</p>"); } // Link to the Source RssBodyConstructor.AppendSourceTag(item, decor); // Link to the comments if (item.HasProp(Props.CommentURL)) { decor.AppendText("<p class=\"Origin\">"); RssBodyConstructor.AppendCommentsTag(item, decor); writer.WriteLine("</p>"); } }
public override void DisplayResource(IResource rssItem, WordPtr[] wordsToHighlight) { string subject = rssItem.GetPropText(Core.Props.Subject); ShowSubject(subject, wordsToHighlight); IResource feed = rssItem.GetLinkProp(-Props.RSSItem); if (feed != null && feed.HasProp(Props.AutoFollowLink) && rssItem.GetPropText(Props.Link).Length > 0) { AttachWebBrowser(); Core.WebBrowser.NavigateInPlace(rssItem.GetPropText(Props.Link)); } else { StringBuilderDecor decor = new StringBuilderDecor("<html>"); decor.AppendText(GetItemStyle()); decor.AppendText(Core.MessageFormatter.StandardStyledHeader(subject)); string body = rssItem.GetPropText(Core.Props.LongBody); if (_showSummary) { RssBodyConstructor.ConstructSummary(rssItem, SummaryStyle, body, decor); } //------------------------------------------------------------- // Update the search results offsets //------------------------------------------------------------- if (wordsToHighlight != null) { int inc = decor.ToString().Length; // Prepended length for (int a = 0; a < wordsToHighlight.Length; a++) { wordsToHighlight[a].StartOffset += inc; } } ProcessBody(decor, body, rssItem); //------------------------------------------------------------- if (!_useDetailedURLs) { RssBodyConstructor.AppendLink(rssItem, decor, cLinkAlias); } else { RssBodyConstructor.AppendLink(rssItem, decor); } RssBodyConstructor.AppendRelatedPosts(rssItem, decor, _useDetailedURLs); RssBodyConstructor.AppendEnclosure(rssItem, decor); RssBodyConstructor.AppendSourceTag(rssItem, decor); RssBodyConstructor.AppendCommentsTag(rssItem, decor); decor.AppendText("</body></html>"); ShowHtml(decor.ToString(), _ctxRestricted, wordsToHighlight); } IResourceList feeds = rssItem.GetLinksOfType(Props.RSSFeedResource, Props.RSSItem); IResource owner = Core.ResourceBrowser.OwnerResource; if ((owner != null && owner.Type == Props.RSSFeedGroupResource) || (feeds.Count > 0 && owner == feeds [0])) { RSSPlugin.GetInstance().RememberSelection(owner, rssItem); } }
/// <summary> /// Import cached items, flags, etc. /// </summary> public void DoImportCache() { RSSPlugin plugin = RSSPlugin.GetInstance(); _readItems = new ArrayList(); // Register us for special tags plugin.RegisterItemElementParser(FeedType.Rss, _fdNS, "state", this); plugin.RegisterItemElementParser(FeedType.Atom, _fdNS, "state", this); string[] allFiles = Directory.GetFiles(_channelsPath, "*.rss"); int totalFiles = Math.Max(allFiles.Length, 1); int processedFiles = 0; foreach (string file in allFiles) { ImportUtils.UpdateProgress(processedFiles / totalFiles, _progressMessageCache); processedFiles += 100; IResource feed = null; string name = HtmlTools.SafeHtmlDecode(Path.GetFileNameWithoutExtension(file)); if (_name2url.ContainsKey(name)) { IResourceList feeds = Core.ResourceStore.FindResources("RSSFeed", Props.URL, _name2url[name]); if (feeds.Count > 0) { feed = feeds[0]; } } if (feed == null) { IResourceList feeds = Core.ResourceStore.FindResources("RSSFeed", Core.Props.Name, name); if (feeds.Count > 0) { feed = feeds[0]; } } // Not found (import of this feed was canceled?) if (feed == null) { continue; } _readItems.Clear(); using (Stream rss = new FileStream(file, FileMode.Open)) { try { RSSParser parser = new RSSParser(feed); parser.Parse(rss, Encoding.UTF8, true); } catch (Exception ex) { Trace.WriteLine("FeedDemon cache '" + file + "' load failed: '" + ex.Message + "'"); } } foreach (IResource r in _readItems) { if (!r.IsDeleted) { r.DeleteProp(Core.Props.IsUnread); } } } ImportUtils.UpdateProgress(processedFiles / totalFiles, _progressMessageCache); }