public void TestSyndicationFetcher() { var opml = new Opml(); opml.LoadFromXML(_sampleOPML); var subscription = new RssSubscription(opml); var fetcher = new SyndicationFetcher(); var feeds = fetcher.DownloadAll(subscription); Assert.IsTrue(feeds.Count > 0, "All downloads must be bigger than zero"); }
public ActionResult Index(string url) { var uri = new Uri(url); var subFetcher = new SubscriptionFetcher(); var xml = subFetcher.Download(Texts.FromUriHost(uri), uri.PathAndQuery); var opml = new Opml(); opml.LoadFromXML(xml); var subscription = new RssSubscription(opml); var fetcher = new SyndicationFetcher(); var feeds = fetcher.DownloadAll(subscription); return Content("Feeds " + feeds.Count); }
public ActionResult RssJs(string url) { try { var cacheKey = "conversion_" + url; var cachedFeed = this.HttpContext.Cache[cacheKey] as CacheItem<RssJs>; RssJs feed; if (cachedFeed == null) { var fetcher = new SyndicationFetcher(); var content = fetcher.Fetch(new Uri(url)); if (content.IsFound) { feed = ConvertToRssJs(content.Item); //todo: implement ETAG //cache item for 6 hours HttpContext.Cache.Add(cacheKey, feed, null, Cache.NoAbsoluteExpiration, new TimeSpan(0, 5, 0), CacheItemPriority.Default, null); } else { return HttpNotFound(); } } else { feed = cachedFeed.Item; //todo implement ETAG } var json = JsonConvert.SerializeObject(feed, JsonSettings.Get()); var jsonP = "onGetRss(" + json + ")"; this.Compress(); return Content(jsonP, "application/javascript"); } catch (Exception ex) { return HttpDoc<EmptyHttpReponse>.PreconditionFailed(ex.Message).ToJson(); } }
public ActionResult GetRiverJs(string name) { var syndications = SyndicationRiverJsCache.Get(name, HttpContext.Cache); if (syndications == null) { var id = SyndicationList.NewId(name); var list = RavenSession.Load<SyndicationList>(id.Full()); if (list != null) { var subscription = list.Sources; var fetcher = new SyndicationFetcher(); var feeds = fetcher.DownloadAll(subscription); var river = FeedsRiver.FromSyndication(feeds, CutoffDate()); var jsonString = Newtonsoft.Json.JsonConvert.SerializeObject(river, JsonSettings.Get()); var jsonp = "onGetRiverStream (" + jsonString + ")"; SyndicationRiverJsCache.Store(name, jsonp, HttpContext.Cache); this.Compress(); return Content(jsonp, "application/json"); } else return HttpNotFound(); } else { this.Compress(); return Content(syndications, "application/json"); } }
public ActionResult AddSource(string syndicationGuid, string title, string uri) { if (string.IsNullOrWhiteSpace(syndicationGuid)) this.PropertyValidationMessage("SyndicationGuid", "A critical id is missing. Please refresh your page and try again"); if (string.IsNullOrWhiteSpace(title)) this.PropertyValidationMessage("Title", "Title is required"); if (string.IsNullOrWhiteSpace(uri)) this.PropertyValidationMessage("Uri", "Uri is required"); Uri xmlUrl = null; try { xmlUrl = new Uri(uri); } catch { this.PropertyValidationMessage("Uri", "Given Uri is invalid. Please do not forget to include http://"); } if (!ModelState.IsValid) { var errors = this.ProduceAJAXErrorMessage(ModelState); return HttpDoc<EmptyHttpReponse>.PreconditionFailed(errors.ToJson()).ToJson(); } var list = RavenSession.Query<SyndicationList>().Where(x => x.Guid == syndicationGuid).FirstOrDefault(); if (list == null) this.PropertyValidationMessage("SyndicationGuid", "The Syndication List Id is not valid. Please refresh your page."); else { try { var fetcher = new SyndicationFetcher(); var content = fetcher.Fetch(xmlUrl); if (content.IsFound) { var name = Texts.ConvertTitleToName(title); list.Sources.Items.Add(new RssSubscriptionItem { Name = name, Text = title, XmlUri = xmlUrl }); RavenSession.Store(list); this.RavenSession.SaveChanges(); SyndicationRiverJsCache.Flush(list.Name, HttpContext.Cache); return HttpDoc<dynamic>.OK(new { Message = "Source added", Name = name }).ToJson(); } else if (content.Exception != null) { var exception = content.Exception.Message; if (content.Exception.InnerException != null) exception += "-- Inner Exception --" + content.Exception.InnerException.Message; this.PropertyValidationMessage("Uri", String.Format( "Given Uri does not exist or is an invalid river format. The processing return the following error : {0}. Please try again.", exception)); } else this.PropertyValidationMessage("Uri", "Given Uri does not exist or is an invalid river format. Please try again."); } catch (Exception e) { this.PropertyValidationMessage("Uri", String.Format( "Given Uri does not exist or is an invalid river format. The processing return the following error : {0}. Please try again.", e.Message)); } } if (!ModelState.IsValid) { var errors = this.ProduceAJAXErrorMessage(ModelState); return HttpDoc<EmptyHttpReponse>.PreconditionFailed(errors.ToJson()).ToJson(); } return HttpDoc<dynamic>.OK(new { Message = "Source added" }).ToJson(); }
public ActionResult Slim(string url, int maxSize) { try { var cacheKey = url; var cachedFeed = this.HttpContext.Cache[cacheKey] as CacheItem<SyndicationFeed>; string cachedEtagValue = String.Empty; if (cachedFeed != null && cachedFeed.ETags.ContainsKey(maxSize.ToString())) cachedEtagValue = cachedFeed.ETags[maxSize.ToString()]; string cachedEtag = this.FormatEtag(cachedEtagValue); string ifNoneMatch = this.GetEtag(); if (!ifNoneMatch.IsNullOrWhiteSpace() && ifNoneMatch == cachedEtag) { return new HttpStatusCodeResult(304, "Not Modified"); } SyndicationFeed feed; if (cachedFeed == null) { var fetcher = new SyndicationFetcher(); var content = fetcher.Fetch(new Uri(url)); if (content.IsFound) { feed = Filter(content.Item, maxSize); string newEtag = Guid.NewGuid().ToString(); var newCacheItem = new CacheItem<SyndicationFeed>(content.Item); newCacheItem.ETags.Add(maxSize.ToString(), newEtag); //cache item for 6 hours HttpContext.Cache.Add(cacheKey, newCacheItem, null, Cache.NoAbsoluteExpiration, new TimeSpan(6, 0, 0), CacheItemPriority.Default, null); this.Response.Cache.SetCacheability(HttpCacheability.Public); this.Response.Cache.SetETag(this.FormatEtag(newEtag)); } else { return HttpNotFound(); } } else { feed = Filter(cachedFeed.Item, maxSize); if (cachedEtagValue.IsNullOrWhiteSpace()) { string newEtag = Guid.NewGuid().ToString(); if (cachedFeed.ETags.ContainsKey(maxSize.ToString())) cachedFeed.ETags[maxSize.ToString()] = newEtag; else cachedFeed.ETags.Add(maxSize.ToString(), newEtag); HttpContext.Cache[cacheKey] = cachedFeed; //refresh the cached item with new etag values this.Response.Cache.SetCacheability(HttpCacheability.Public); this.Response.Cache.SetETag(this.FormatEtag(newEtag)); } } var rssOutput = new StringBuilder(); using (var xml = XmlWriter.Create(rssOutput)) { feed.SaveAsRss20(xml); } //Read http://baleinoid.com/whaly/2009/07/xmlwriter-and-utf-8-encoding-without-signature/ var payload = rssOutput.ToString().Replace("encoding=\"utf-16\"", ""); //remove the Processing Instruction encoding mark for the xml body = it's a hack I know this.Compress(); return Content(payload, "application/rss+xml"); } catch (Exception ex) { return HttpDoc<EmptyHttpReponse>.PreconditionFailed(ex.Message).ToJson(); } }