public static void Finalize(Calinfo calinfo, ZonelessEventStore es_zoneless) { es_zoneless.events = EventStore.UniqueByTitleAndStart(calinfo.id, es_zoneless.events, save_tag_sources: true); // deduplicate es_zoneless.ExcludePastEvents(); // the EventCollector should already have done this, but in case not... es_zoneless.SortEventList(); // order by dtstart Utils.BuildTagStructures(es_zoneless, calinfo); // build structures used to generate tag picklists var i = 0; foreach (var evt in es_zoneless.events) { var str = evt.dtstart.ToString() + evt.title.ToString() + evt.source.ToString() + evt.url; var hash = HttpUtils.GetMd5Hash(Encoding.UTF8.GetBytes(str)); evt.uid = i; i++; evt.hash = hash; } es_zoneless.PopulateDaysAndCounts(); // do this here for a) renderer efficiency, b) renderer simplification // (it only updates these structures for category views) es_zoneless.when_finalized = DateTime.UtcNow; es_zoneless.Serialize(); }
public EventCollectorTest() { test_calinfo = new Calinfo(ElmcityUtils.Configurator.azure_compute_account); lookup_lat = test_calinfo.lat; lookup_lon = test_calinfo.lon; radius = Configurator.default_radius; test_upcoming_args = string.Format("location={0},{1}&radius={2}&min_date={3}", lookup_lat, lookup_lon, radius, min_date); settings = GenUtils.GetSettingsFromAzureTable(); basic_ics = BlobStorage.MakeDefaultBlobStorage().GetBlob("admin", "basic.ics").HttpResponse.DataAsString(); bs = BlobStorage.MakeDefaultBlobStorage(); calinfo_berkeley = new Calinfo(berkeley_test_hub); calinfo_keene = new Calinfo(keene_test_hub); collector_berkeley = new Collector(calinfo_berkeley, settings); collector_keene = new Collector(calinfo_keene,settings); foreach (var example in ics_examples) UpdateYYYY(example, "ics"); foreach (var example in eventful_examples) UpdateYYYY(example, "xml"); foreach (var example in upcoming_examples) UpdateYYYY(example, "xml"); foreach (var example in eventbrite_examples) UpdateYYYY(example, "xml"); }
// used by the service in both WorkerRole and WebRole // in WorkerRole: when saving renderings // in WebRole: when serving renderings public CalendarRenderer(string id) { this.calinfo = Utils.AcquireCalinfo(id); this.cache = null; this.ResetCounters(); this.es_getter = new EventStoreGetter(GetEventStoreWithCaching); try { this.id = id; try { this.template_html = HttpUtils.FetchUrl(calinfo.template_url).DataAsString(); } catch (Exception e) { GenUtils.PriorityLogMsg("exception", "CalendarRenderer: cannot fetch template", e.InnerException.Message); throw (e); } this.xmlfile = this.id + ".xml"; this.jsonfile = this.id + ".json"; this.htmlfile = this.id + ".html"; // this.ical_sources = Collector.GetIcalSources(this.id); } catch (Exception e) { GenUtils.PriorityLogMsg("exception", "CalenderRenderer.CalendarRenderer: " + id, e.Message + e.StackTrace); } }
public EventCollectorTest() { test_calinfo = new Calinfo(ElmcityUtils.Configurator.azure_compute_account); lookup_lat = test_calinfo.lat; lookup_lon = test_calinfo.lon; radius = Configurator.default_radius; test_upcoming_args = string.Format("location={0},{1}&radius={2}&min_date={3}", lookup_lat, lookup_lon, radius, min_date); settings = GenUtils.GetSettingsFromAzureTable(); basic_ics = BlobStorage.MakeDefaultBlobStorage().GetBlob("admin", "basic.ics").HttpResponse.DataAsString(); bs = BlobStorage.MakeDefaultBlobStorage(); calinfo_berkeley = new Calinfo(berkeley_test_hub); calinfo_keene = new Calinfo(keene_test_hub); collector_berkeley = new Collector(calinfo_berkeley, settings); collector_keene = new Collector(calinfo_keene, settings); foreach (var example in ics_examples) { UpdateYYYY(example, "ics"); } foreach (var example in eventful_examples) { UpdateYYYY(example, "xml"); } //foreach (var example in upcoming_examples) // UpdateYYYY(example, "xml"); foreach (var example in eventbrite_examples) { UpdateYYYY(example, "xml"); } }
public static List<TaggableSource> GetEventBriteOrganizers(Calinfo calinfo, Dictionary<string, string> settings) { var organizers = new List<TaggableSource>(); var name_and_pk = "eventbritesources"; var collector = new Collector(calinfo, settings); string method = "event_search"; string args = collector.MakeEventBriteArgs(); int page_count = collector.GetEventBritePageCount(method, args); var results = from evt in collector.EventBriteIterator(page_count, method, args) select new { id = evt.Descendants("organizer").Descendants("id").FirstOrDefault().Value, name = evt.Descendants("organizer").Descendants("name").FirstOrDefault().Value, city = evt.Descendants("venue").Descendants("city").FirstOrDefault().Value.ToLower() }; results = results.Distinct(); Parallel.ForEach(source: results, body: (id_name_city) => { if (id_name_city.city != calinfo.City) return; var organizer_id = id_name_city.id; var name = id_name_city.name; var home_url = "http://www.eventbrite.com/org/" + organizer_id; var escaped_name = Uri.EscapeDataString(name); var ical_url = string.Format("http://elmcity.cloudapp.net/ics_from_eventbrite_organizer?organizer={0}&elmcity_id={1}", escaped_name, calinfo.id); var taggable = new TaggableSource(name, calinfo.id, home_url, ical_url, id_name_city.city); RememberTaggable(name_and_pk, organizer_id, taggable); organizers.Add(taggable); }); return organizers; }
public void AdvanceToAnHourAgo(Calinfo calinfo) { var now_in_tz = Utils.NowInTz(calinfo.tzinfo); // advance to an hour ago var dtnow = now_in_tz.LocalTime - TimeSpan.FromHours(1); this.events = this.events.FindAll(evt => evt.dtstart >= dtnow); }
public ZonedEventStore(Calinfo calinfo, SourceType type) : base(calinfo) { // qualifier is "ical" or one of the non-ical types, so for example: // http://elmcity.blob.core.windows.net/a2cal/a2cal.ical.zoned.obj // http://elmcity.blob.core.windows.net/a2cal/a2cal.eventful.zoned.obj this.objfile = this.id + "." + type.ToString() + ".zoned.obj"; this.uri = BlobStorage.MakeAzureBlobUri(this.id, this.objfile, false); }
public static void StoreTaggables(string id, string location, Dictionary <string, string> settings) { var calinfo = new Calinfo(id); StoreFacebookTaggables(id, location, calinfo); StoreEventfulTaggables(id, settings, calinfo); // StoreUpcomingTaggables(id, settings, calinfo); StoreEventBriteTaggables(id, settings, calinfo); StoreMeetupTaggables(id, settings, calinfo); }
public void RssPlusXcalYieldsIcal() { var url = "http://events.pressdemocrat.com/search?city=Santa+Rosa&new=n&rss=1&srad=90&svt=text&swhat=&swhen=&swhere="; var calinfo = new Calinfo("berkeley"); var ical_str = Utils.IcsFromRssPlusXcal(url, "test source", calinfo); var sr = new StringReader(ical_str); var ical = iCalendar.LoadFromStream(sr).First().Calendar; Assert.AreNotEqual(0, ical.Events.Count); }
public static ZonelessEventStore ZonedToZoneless(string id, Calinfo calinfo, ZonedEventStore es_zoned) { var es_zoneless = new ZonelessEventStore(calinfo); foreach (var evt in es_zoned.events) { es_zoneless.AddEvent(evt.title, evt.url, evt.source, evt.lat, evt.lon, evt.dtstart.LocalTime, evt.dtend.LocalTime, evt.allday, evt.categories, evt.description, evt.location); } ZonelessEventStore.Finalize(calinfo, es_zoneless); return(es_zoneless); }
public static void StoreFacebookTaggables(string id, string location, Calinfo calinfo) { try { var facebook_taggables = GetFacebookPages(calinfo, location); bs.SerializeObjectToAzureBlob(facebook_taggables, id, "facebook.taggables.obj"); } catch (Exception e) { GenUtils.PriorityLogMsg("exception", "StoreTaggables: Facebook", e.Message); } }
private ZonelessEventStore CreateFilterable(Calinfo calinfo) { var filterable = new ZonelessEventStore(calinfo); filterable.AddEvent("e1", "", "s1", null, null, DateTime.Parse("2013/11/01 8 AM"), DateTime.MinValue, false, null, null, null); filterable.AddEvent("e2", "", "s1", null, null, DateTime.Parse("2013/11/02 8 AM"), DateTime.MinValue, false, null, null, null); filterable.AddEvent("e3", "", "s2", null, null, DateTime.Parse("2013/11/03 8 AM"), DateTime.MinValue, false, null, null, null); filterable.AddEvent("e4", "", "s2", null, null, DateTime.Parse("2013/11/04 8 AM"), DateTime.MinValue, false, null, null, null); filterable.AddEvent("e5", "", "s2", null, null, DateTime.Parse("2013/11/05 8 AM"), DateTime.MinValue, false, "music", null, null); Assert.That(filterable.events.Count == 5); return(filterable); }
private static List <TaggableSource> InitializeTaggables(Calinfo calinfo, string flavor) { List <TaggableSource> taggable_sources; try { taggable_sources = (List <TaggableSource>)ObjectUtils.GetTypedObj <List <TaggableSource> >(calinfo.id, flavor + ".taggables.obj"); } catch { taggable_sources = new List <TaggableSource>(); } return(taggable_sources); }
public static List <TaggableSource> GetMeetupGroups(Calinfo calinfo, int delay, Dictionary <string, string> settings) { var meetup_key = settings["meetup_api_key"]; var template = "https://api.meetup.com/2/groups?key={0}&lat={1}&lon={2}&radius={3}&page=200"; var url = String.Format(template, meetup_key, calinfo.lat, calinfo.lon, calinfo.radius); var json = HttpUtils.SlowFetchUrl(new Uri(url), delay).DataAsString(); var obj = JsonConvert.DeserializeObject <Dictionary <string, object> >(json); var taggable_sources = new List <TaggableSource>(); string name_and_pk = "meetupsources"; foreach (var group in ((JArray)obj["results"]).ToList()) { try { var name = (string)group["name"]; var urlname = (string)group["urlname"]; var id = group["id"].ToString(); var home_url = "http://www.meetup.com/" + urlname; var ical_url = string.Format("http://www.meetup.com/{0}/events/ical/{1}/", urlname, Uri.EscapeDataString(name)); ical_url = ical_url.Replace("%20", "+"); // otherwise meetup weirdly reports a 505 error var taggable = new TaggableSource( name, calinfo.id, home_url, ical_url, calinfo.where); taggable_sources.Add(taggable); RememberTaggable(name_and_pk, id, taggable); } catch (Exception e) { GenUtils.PriorityLogMsg("exception", "FindMeetupGroups", e.Message + e.StackTrace); } } return(taggable_sources); }
public static void CombineZonedEventStoresToZonelessEventStore(string id, Dictionary <string, string> settings) { var bs = BlobStorage.MakeDefaultBlobStorage(); var calinfo = new Calinfo(id); var lists_of_zoned_events = new List <List <ZonedEvent> >(); var ical_uri = BlobStorage.MakeAzureBlobUri(container: id, name: id + "." + SourceType.ical + ".zoned.obj", use_cdn: false); DeserializeZoned(ical_uri, lists_of_zoned_events); //if (calinfo.hub_type == HubType.where.ToString()) if (calinfo.hub_enum == HubType.where) { Uri non_ical_uri; //foreach (var type in non_ical_types) foreach (NonIcalType type in Enum.GetValues(typeof(CalendarAggregator.NonIcalType))) { if (Utils.UseNonIcalService(type, settings, calinfo) == false) { continue; } non_ical_uri = BlobStorage.MakeAzureBlobUri(container: id, name: id + "." + type + ".zoned.obj", use_cdn: false); if (BlobStorage.ExistsBlob(non_ical_uri)) // // might not exist, e.g. if facebook=no in hub metadata { DeserializeZoned(non_ical_uri, lists_of_zoned_events); } } } var es_zoneless = new ZonelessEventStore(calinfo); // combine the various List<ZonedEvent> objects into our new ZonelessEventStore // always add the local time foreach (var list in lists_of_zoned_events) { foreach (var evt in list) { es_zoneless.AddEvent(evt.title, evt.url, evt.source, evt.lat, evt.lon, evt.dtstart.LocalTime, evt.dtend.LocalTime, evt.allday, evt.categories, evt.description, evt.location); } } ZonelessEventStore.Finalize(calinfo, es_zoneless); }
public static List <TaggableSource> GetEventfulVenues(Calinfo calinfo, int min_per_venue, Dictionary <string, string> settings) { var collector = new Collector(calinfo, settings); string args = collector.MakeEventfulArgs(calinfo.where, 100, ""); string method = "venues/search"; var xdoc = collector.CallEventfulApi(method, args); var str_page_count = XmlUtils.GetXeltValue(xdoc.Root, ElmcityUtils.Configurator.no_ns, "page_count"); int page_count = Convert.ToInt16(str_page_count); var ns = ElmcityUtils.Configurator.no_ns; var results = from venue in collector.EventfulIterator(page_count, args, "venues/search", "venue") select new { id = venue.Attribute("id").Value, name = XmlUtils.GetXeltValue(venue, ns, "name"), city_name = XmlUtils.GetXeltValue(venue, ns, "city_name").ToLower(), count = Convert.ToInt32(XmlUtils.GetXeltValue(venue, ns, "event_count")), home_url = XmlUtils.GetXeltValue(venue, ns, "url") }; var venues = new List <TaggableSource>(); var name_and_pk = "eventfulsources"; Parallel.ForEach(source: results, body: (venue) => { //if (venue.city_name != calinfo.City) if (!calinfo.City.Contains(venue.city_name)) { return; } if (venue.count < min_per_venue) { return; } var home_url = Regex.Replace(venue.home_url, "\\?.+", ""); var ical_url = home_url.Replace("eventful.com/", "eventful.com/ical/"); var taggable = new TaggableSource(venue.name, calinfo.id, home_url, ical_url, venue.city_name); RememberTaggable(name_and_pk, venue.id, taggable); venues.Add(taggable); }); return(venues); }
public static TaskType MaybeStartTaskForId(DateTime now, Calinfo calinfo, TaskType type) { var id = calinfo.id; TimeSpan interval = IntervalFromType(type); var task = FetchTaskForId(id, type); var start = task.start; if (now - interval > start) // interval has expired { StartTaskForId(id, type); return(type); } else { return(TaskType.none); } }
public static List<TaggableSource> GetEventfulVenues(Calinfo calinfo, int min_per_venue, Dictionary<string, string> settings) { var collector = new Collector(calinfo, settings); string args = collector.MakeEventfulArgs(calinfo.where, 100, ""); string method = "venues/search"; var xdoc = collector.CallEventfulApi(method, args); var str_page_count = XmlUtils.GetXeltValue(xdoc.Root, ElmcityUtils.Configurator.no_ns, "page_count"); int page_count = Convert.ToInt16(str_page_count); var ns = ElmcityUtils.Configurator.no_ns; var results = from venue in collector.EventfulIterator(page_count, args, "venues/search", "venue") select new { id = venue.Attribute("id").Value, name = XmlUtils.GetXeltValue(venue, ns, "name"), city_name = XmlUtils.GetXeltValue(venue, ns, "city_name").ToLower(), count = Convert.ToInt32(XmlUtils.GetXeltValue(venue, ns, "event_count")), home_url = XmlUtils.GetXeltValue(venue, ns, "url") }; var venues = new List<TaggableSource>(); var name_and_pk = "eventfulsources"; Parallel.ForEach(source: results, body: (venue) => { //if (venue.city_name != calinfo.City) if ( ! calinfo.City.Contains(venue.city_name) ) return; if (venue.count < min_per_venue) return; var home_url = Regex.Replace(venue.home_url, "\\?.+", ""); var ical_url = home_url.Replace("eventful.com/", "eventful.com/ical/"); var taggable = new TaggableSource(venue.name, calinfo.id, home_url, ical_url, venue.city_name); RememberTaggable(name_and_pk, venue.id, taggable); venues.Add(taggable); }); return venues; }
public static List <TaggableSource> GetEventBriteOrganizers(Calinfo calinfo, Dictionary <string, string> settings) { var organizers = new List <TaggableSource>(); var name_and_pk = "eventbritesources"; var collector = new Collector(calinfo, settings); string method = "event_search"; string args = collector.MakeEventBriteArgs(); int page_count = collector.GetEventBritePageCount(method, args); var results = from evt in collector.EventBriteIterator(page_count, method, args) select new { id = evt.Descendants("organizer").Descendants("id").FirstOrDefault().Value, name = evt.Descendants("organizer").Descendants("name").FirstOrDefault().Value, city = evt.Descendants("venue").Descendants("city").FirstOrDefault().Value.ToLower() }; results = results.Distinct(); Parallel.ForEach(source: results, body: (id_name_city) => { if (id_name_city.city != calinfo.City) { return; } var organizer_id = id_name_city.id; var name = id_name_city.name; var home_url = "http://www.eventbrite.com/org/" + organizer_id; var escaped_name = Uri.EscapeDataString(name); var ical_url = string.Format("http://{0}/ics_from_eventbrite_organizer?organizer={1}&elmcity_id={2}", ElmcityUtils.Configurator.appdomain, escaped_name, calinfo.id); var taggable = new TaggableSource(name, calinfo.id, home_url, ical_url, id_name_city.city); RememberTaggable(name_and_pk, organizer_id, taggable); organizers.Add(taggable); }); return(organizers); }
public static void StoreFacebookTaggables(string id, string location, Calinfo calinfo) { try { var facebook_taggables = GetFacebookPages(calinfo, location); bs.SerializeObjectToAzureBlob(facebook_taggables, id, "facebook.taggables.obj"); } catch (Exception e) { GenUtils.PriorityLogMsg("exception", "StoreTaggables: Facebook", e.Message); } }
public void RssPlusXcalYieldsIcal() { var url = "http://events.pressdemocrat.com/search?city=Santa+Rosa&new=n&rss=1&srad=90&svt=text&swhat=&swhen=&swhere="; var calinfo = new Calinfo("berkeley"); var ical_str = Utils.IcsFromRssPlusXcal(url, "test source", calinfo); var sr = new StringReader(ical_str); var ical = iCalendar.LoadFromStream(sr).First().Calendar; Assert.AreNotEqual(0, ical.Events.Count); }
public static List <TaggableSource> GetFacebookPages(Calinfo calinfo, string location) { var search_template = String.Format("site:www.facebook.com/__TARGET__ \"{0}\"", location); var search_for_fan_pages = search_template.Replace("__TARGET__", "pages"); var search_for_groups = search_template.Replace("__TARGET__", "groups"); var stats = new Dictionary <string, object>(); var fan_page_results = Search.BingSearch(search_for_fan_pages, 1000, stats); // var group_results = Search.BingSearch(search_for_groups, 1000, stats); // doesn't work, location string won't usually appear var group_results = new List <SearchResult>(); // placeholder for now var bing_results = fan_page_results.Concat(group_results).ToList(); var taggable_sources = InitializeTaggables(calinfo, "facebook"); var seen_ids = new List <string>(); string name_and_pk = "facebooksources"; var settings = GenUtils.GetSettingsFromAzureTable(); var options = new ParallelOptions(); Parallel.ForEach(source: bing_results, parallelOptions: options, body: (result) => //foreach (var result in bing_results) { try { var url = Regex.Replace(result.url, @"\?.+", ""); // remove query string if any var name = Regex.Match(result.url, "facebook.com/(pages|groups)/([^/]+)").Groups[2].Value; name = name.Replace('-', ' '); var fb_id = Utils.id_from_fb_fanpage_or_group(url); if (seen_ids.Exists(x => x == fb_id)) { return; } else { seen_ids.Add(fb_id); } string slat = null; string slon = null; var ical = new DDay.iCal.iCalendar(); var facebook_access_token = settings["facebook_access_token"]; // todo: merge with code in collector var j_obj = Utils.GetFacebookEventsAsJsonObject(fb_id, facebook_access_token); var events = Utils.iCalendarizeJsonObjectFromFacebook(j_obj, calinfo, ical, slat, slon, settings); if (events.Count == 0) // no calendar on this page { return; } string page; if (FacebookPageMatchesLocation(url, location, settings, out page) == false) { return; } string origin_url = ""; if (!String.IsNullOrEmpty(page)) { origin_url = GetFacebookPageOrGroupOriginUrl(page); } var ical_url = string.Format("http://{0}/ics_from_fb_page?fb_id={1}&elmcity_id={2}", ElmcityUtils.Configurator.appdomain, fb_id, calinfo.id); var has_future_events = FacebookPageHasFutureEvents(events, calinfo); var taggable = new TaggableSource(name, calinfo.id, url + "?sk=events", ical_url, has_future_events, origin_url); taggable_sources.Add(taggable); RememberTaggable(name_and_pk, fb_id, taggable); } catch (Exception e) { GenUtils.PriorityLogMsg("exception", "GetFacebookPages", e.Message + e.StackTrace); return; } }); return(taggable_sources); }
private static bool FacebookPageHasFutureEvents(List <DDay.iCal.Event> events, Calinfo calinfo) { try { foreach (DDay.iCal.Event evt in events) { if (Utils.IsCurrentOrFutureDateTime(evt.Start.Date, calinfo.tzinfo)) { return(true); } } } catch (Exception e) { GenUtils.PriorityLogMsg("exception", "FacebookPageHasFutureEvents", e.Message + e.StackTrace); return(false); } return(false); }
private static ZonelessEventStore ProcessIcalExample(string example, string source, Calinfo calinfo, FeedRegistry fr, Collector collector) { DeleteZonedObjects(calinfo.id); var feedurl = BlobStorage.MakeAzureBlobUri("admin", example + ".ics", false).ToString(); fr.AddFeed(feedurl, source); var es = new ZonedEventStore(calinfo, SourceType.ical); collector.CollectIcal(fr, es, false); EventStore.CombineZonedEventStoresToZonelessEventStore(calinfo.id, settings); var zes = new ZonelessEventStore(calinfo).Deserialize(); return zes; }
public static void StoreEventBriteTaggables(string id, Dictionary <string, string> settings, Calinfo calinfo) { try { var eventbrite_taggables = GetEventBriteOrganizers(calinfo, settings); bs.SerializeObjectToAzureBlob(eventbrite_taggables, id, "eventbrite.taggables.obj"); } catch (Exception e) { GenUtils.PriorityLogMsg("exception", "StoreTaggables: EventBrite", e.Message); } }
public ActionResult view_calendar(string feedurl, string id) { var r = new ContentResult(); r.ContentType = "text/html"; if (id != String.Empty && Utils.CachedFeedObjExists(id, feedurl)) return view_cached_calendar(feedurl, id); DDay.iCal.iCalendar ical; var source = ""; // unneeded for this single-cal purpose try { ical = Utils.iCalFromFeedUrl(feedurl, settings); } catch (Exception e) { r.Content = string.Format(@"Sorry, unable to parse {0} as an iCalendar feed. The error was: {1}", feedurl, e.Message + e.StackTrace); return r; } var events_to_include = new List<DDay.iCal.Event>(); var event_recurrence_types = new Dictionary<DDay.iCal.Event, Collector.RecurrenceType>(); var calinfo = new Calinfo(id); var collector = new Collector(calinfo, settings); try { DateTime utc_midnight_in_tz = Utils.MidnightInTz(calinfo.tzinfo).UniversalTime; DateTime then = utc_midnight_in_tz.AddDays(calinfo.icalendar_horizon_days); collector.FeedGather(utc_midnight_in_tz, then, 0, ical, source, events_to_include, event_recurrence_types, false); var es_zoned = new ZonedEventStore(calinfo, SourceType.ical); var fr = new FeedRegistry(id); foreach (var evt in events_to_include) collector.AddIcalEvent(evt, fr, es_zoned, feedurl, source); var es_zoneless = new ZonelessEventStore(calinfo); r = view_calendar_helper(id, r, es_zoned, es_zoneless); } catch (Exception e) { r.Content = "Unable to view calendar. " + e.Message + e.StackTrace; return r; } return r; }
// render a single event as an xml element private string RenderEvtAsXml(ZonelessEvent evt, Calinfo calinfo, Dictionary<string,object> args) { var xml = new StringBuilder(); xml.Append("<event>\n"); xml.Append(string.Format("<title>{0}</title>\n", HttpUtility.HtmlEncode(evt.title))); xml.Append(string.Format("<url>{0}</url>\n", HttpUtility.HtmlEncode(evt.url))); xml.Append(string.Format("<source>{0}</source>\n", HttpUtility.HtmlEncode(evt.source))); xml.Append(string.Format("<dtstart>{0}</dtstart>\n", evt.dtstart.ToString(DATETIME_FORMAT_FOR_XML))); if (evt.dtend != null) xml.Append(string.Format("<dtend>{0}</dtend>\n", evt.dtend.ToString(DATETIME_FORMAT_FOR_XML))); xml.Append(string.Format("<allday>{0}</allday>\n", evt.allday)); xml.Append(string.Format("<categories>{0}</categories>\n", HttpUtility.HtmlEncode(evt.categories))); xml.Append(string.Format("<description>{0}</description>\n", HttpUtility.HtmlEncode(evt.description))); xml.Append(string.Format("<location>{0}</location>\n", HttpUtility.HtmlEncode(evt.location))); //if (this.calinfo.hub_type == HubType.where.ToString()) if (calinfo.hub_enum == HubType.where) { var lat = evt.lat != null ? evt.lat : this.calinfo.lat; var lon = evt.lon != null ? evt.lon : this.calinfo.lon; xml.Append(string.Format("<lat>{0}</lat>\n", lat)); xml.Append(string.Format("<lon>{0}</lon>\n", lon)); } xml.Append("</event>\n"); return xml.ToString(); }
public string RenderEvtAsHtml(ZonelessEvent evt, Calinfo calinfo, Dictionary<string,object> args) { if (evt.urls_and_sources == null) evt.urls_and_sources = new Dictionary<string, string>() { { evt.url, evt.source } }; string dtstart; if (evt.allday && evt.dtstart.Hour == 0) dtstart = " "; else dtstart = evt.dtstart.ToString("ddd hh:mm tt"); var month_day = evt.dtstart.ToString("M/d"); string categories = ""; List<string> catlist_links = new List<string>(); if (!String.IsNullOrEmpty(evt.categories)) { List<string> catlist = Utils.GetTagListFromTagString(evt.categories); if (args.ContainsKey("hub_tags") ) // exclude autogenerated hub names { var hub_tags = (List<string>)args["hub_tags"]; catlist = catlist.FindAll(c => hub_tags.Contains(c) == false); } // catlist = catlist.FindAll(c => c.Contains("{") == false); // don't show squiggly tags inline? // actually leave them in so client can show related images. curator can suppress display if desired using css foreach (var cat in catlist) { var category_url = string.Format("javascript:show_view('{0}')", cat); catlist_links.Add(string.Format(@"<a title=""open the {1} view"" href=""{0}"">{1}</a>", category_url, cat)); } categories = string.Format(@" <span class=""cat"">{0}</span>", string.Join(", ", catlist_links.ToArray())); } String description = ( String.IsNullOrEmpty(evt.description) || evt.description.Length < 10 ) ? "" : evt.description.UrlsToLinks(); string dom_id = "e" + evt.uid; string expander = ""; if ( ! String.IsNullOrEmpty(description) && args.HasValue("eventsonly",true) ) expander = String.Format(@"<span class=""sd""><a title=""show description"" href=""javascript:show_desc('{0}')"">...</a></span>", dom_id); string add_to_cal = String.Format(@"<span class=""atc""><a title=""add to calendar"" href=""javascript:add_to_cal('{0}')"">+</a></span>", dom_id); if ( args.HasValue("add_to_cal",false) ) // for view_calendar add_to_cal = ""; string visibility = ""; string more = ""; string source_key = ""; //string source_attr = ""; // not needed, int sequence_count = 1; int sequence_position = 1; string show_more_call; if (evt.urls_and_sources.Count == 1) { sequence_count = (int)args["sequence_count"]; source_key = (string)args["source_key"]; sequence_position = (int)args["sequence_position"]; } visibility = (sequence_count > 1 && sequence_position > 1) ? @" style=""display:none"" " : ""; if (sequence_count > 1 && sequence_position == 1) { show_more_call = "javascript:show_more('" + source_key + "')"; more = string.Format(@" <span class=""{0}""><a title=""show {2} more from {3}"" href=""{1}"">show {2} more</a></span>", source_key, show_more_call, sequence_count - 1, evt.source ); } else { more = ""; } var html = string.Format( @"<div id=""{0}"" class=""bl {12}"" {13} xmlns:v=""http://rdf.data-vocabulary.org/#"" typeof=""v:Event"" > <span style=""display:none"" class=""uid"">{15}</span> <span style=""display:none"" class=""hash"">{16}</span> <span class=""md"">{14}</span> <span class=""st"" property=""v:startDate"" content=""{1}"">{2}</span> <span href=""{3}"" rel=""v:url""></span> <span class=""ttl"">{4}</span> <span class=""src"" property=""v:description"">{5}</span> {6} {7} {8} {9} {11} </div>", dom_id, // 0 String.Format("{0:yyyy-MM-ddTHH:mm}", evt.dtstart), // 1 dtstart, // 2 evt.url, // 3 MakeTitleForRDFa(evt, dom_id, args), // 4 evt.urls_and_sources.Keys.Count == 1 ? evt.source : "", // 5 suppress source if multiple categories, // 6 MakeGeoForRDFa(evt), // 7 expander, // 8 add_to_cal, // 9 "", // 10 was source_attr, not needed more, // 11 source_key, // 12 visibility, // 13 month_day, // 14 evt.uid, // 15 evt.hash // 16 ); this.event_counter += 1; return html; }
public CalendarRenderer(string id) { this.timestamp = DateTime.UtcNow; this.calinfo = Utils.AcquireCalinfo(id); this.cache = null; this.ResetCounters(); this.es_getter = new EventStoreGetter(GetEventStoreWithCaching); this.category_images = new Dictionary<string, string>(); this.source_images = new Dictionary<string, string>(); this.is_region = Utils.IsRegion(id); this.default_js_url = "http://elmcity.blob.core.windows.net/admin/elmcity-1.17.js"; this.default_args = new Dictionary<string, object>(); try { this.id = id; try { var metadict = Metadata.LoadMetadataForIdFromAzureTable(id); if (metadict.ContainsKey("args")) { this.default_args_json = metadict["args"]; this.default_args = JsonConvert.DeserializeObject<Dictionary<string, object>>(this.default_args_json); } else { this.default_args = new Dictionary<string, object>(); } } catch (Exception e) { GenUtils.LogMsg("exception", "CalendarRenderer: acquiring args", e.Message); } try { this.template_html = HttpUtils.FetchUrl(calinfo.template_url).DataAsString(); this.default_template_html = this.template_html; } catch (Exception e) { GenUtils.PriorityLogMsg("exception", "CalendarRenderer: cannot fetch template", e.Message); throw (e); } try { GetImages("category"); } catch (Exception e) { GenUtils.PriorityLogMsg("exception", "CalendarRenderer: loading category images", e.Message); throw (e); } try { GetImages("source"); } catch (Exception e) { GenUtils.PriorityLogMsg("exception", "CalendarRenderer: loading source images", e.Message); throw (e); } var settings = GenUtils.GetSettingsFromAzureTable(); try { this.max_events = Convert.ToInt32(settings["max_html_events_default"]); // start with service-wide setting if (this.default_args.ContainsKey("max_events")) // look for hub setting this.max_events = Convert.ToInt32( default_args["max_events"] ); } catch (Exception e) { GenUtils.PriorityLogMsg("exception", "CalendarRenderer: setting max events", e.Message); this.max_events = 1000; throw (e); } finally { settings = null; } } catch (Exception e) { GenUtils.PriorityLogMsg("exception", "CalenderRenderer.CalendarRenderer: " + id, e.Message + e.StackTrace); } }
// public methods used by worker to collect events from all source types public Collector(Calinfo calinfo, Dictionary<string, string> settings) { this.calinfo = calinfo; this.settings = settings; this.mock_eventful = false; this.mock_upcoming = false; this.mock_eventbrite = false; this.id = calinfo.id; this.bs = BlobStorage.MakeDefaultBlobStorage(); // an instance of a DDay.iCal for each source type, used to collect intermediate ICS // results which are saved, then combined to produce a merged ICS, e.g.: // http://elmcity.blob.core.windows.net/a2cal/a2cal.ics this.ical_ical = NewCalendarWithTimezone(); this.eventful_ical = NewCalendarWithTimezone(); this.upcoming_ical = NewCalendarWithTimezone(); this.eventbrite_ical = NewCalendarWithTimezone(); this.facebook_ical = NewCalendarWithTimezone(); this.estats = new NonIcalStats(); this.estats.blobname = "eventful_stats"; this.ustats = new NonIcalStats(); this.ustats.blobname = "upcoming_stats"; this.ebstats = new NonIcalStats(); this.ebstats.blobname = "eventbrite_stats"; this.fbstats = new NonIcalStats(); this.fbstats.blobname = "facebook_stats"; this.mustats = new NonIcalStats(); this.mustats.blobname = "meetup_stats"; }
public static List <TaggableSource> GetMeetupGroups2(Calinfo calinfo, int delay, Dictionary <string, string> settings) { var meetup_key = settings["meetup_api_key"]; var template = "https://api.meetup.com/2/open_events?key={0}&lat={1}&lon={2}&radius={3}"; var url = String.Format(template, meetup_key, calinfo.lat, calinfo.lon, calinfo.radius); var json = HttpUtils.SlowFetchUrl(new Uri(url), delay).DataAsString(); var dict = JsonConvert.DeserializeObject <Dictionary <String, object> >(json); var results = (JArray)dict["results"]; var ids_and_cities = from result in results select new { id = result["group"]["id"].Value <string>(), city = GetMeetupCity(result) }; var unique_ids_and_cities = ids_and_cities.Distinct(); var taggable_sources = new List <TaggableSource>(); Parallel.ForEach(source: unique_ids_and_cities, body: (id_and_city) => { if (id_and_city.city != calinfo.City) { return; } string name_and_pk = "meetupsources"; try { template = "https://api.meetup.com/2/groups?key={0}&group_id={1}"; url = String.Format(template, meetup_key, id_and_city.id); json = HttpUtils.SlowFetchUrl(new Uri(url), delay).DataAsString(); dict = JsonConvert.DeserializeObject <Dictionary <String, object> >(json); results = (JArray)dict["results"]; var result = results.First(); var name = result["name"].Value <string>(); var urlname = result["urlname"].Value <string>(); var home_url = "http://www.meetup.com/" + urlname; var ical_url = string.Format("http://www.meetup.com/{0}/events/ical/{1}/", urlname, Uri.EscapeDataString(name)); ical_url = ical_url.Replace("%20", "+"); // otherwise meetup weirdly reports a 505 error var taggable = new TaggableSource( name, calinfo.id, home_url, ical_url, id_and_city.city); taggable_sources.Add(taggable); RememberTaggable(name_and_pk, id_and_city.id, taggable); } catch (Exception e) { GenUtils.PriorityLogMsg("exception", "FindMeetupGroups", e.Message + e.StackTrace); } }); return(taggable_sources); }
// render a single event as an xml element private string RenderEvtAsXml(ZonelessEvent evt, Calinfo calinfo, Dictionary<string,object> args) { var xml = new StringBuilder(); xml.Append("<event>\n"); xml.Append(string.Format("<title>{0}</title>\n", HttpUtility.HtmlEncode(evt.title))); xml.Append(string.Format("<url>{0}</url>\n", HttpUtility.HtmlEncode(evt.url))); xml.Append(string.Format("<source>{0}</source>\n", HttpUtility.HtmlEncode(evt.source))); xml.Append(string.Format("<dtstart>{0}</dtstart>\n", evt.dtstart.ToString(DATETIME_FORMAT_FOR_XML))); if (evt.dtend != null) xml.Append(string.Format("<dtend>{0}</dtend>\n", evt.dtend.ToString(DATETIME_FORMAT_FOR_XML))); xml.Append(string.Format("<allday>{0}</allday>\n", evt.allday)); xml.Append(string.Format("<categories>{0}</categories>\n", HttpUtility.HtmlEncode(evt.categories))); xml.Append(string.Format("<description>{0}</description>\n", HttpUtility.HtmlEncode(evt.description))); xml.Append(string.Format("<location>{0}</location>\n", HttpUtility.HtmlEncode(evt.location))); var lat = ! String.IsNullOrEmpty(evt.lat) ? evt.lat : ""; var lon = ! String.IsNullOrEmpty(evt.lon) ? evt.lon : ""; xml.Append(string.Format("<lat>{0}</lat>\n", lat)); xml.Append(string.Format("<lon>{0}</lon>\n", lon)); xml.Append("</event>\n"); return xml.ToString(); }
public static void StoreMeetupTaggables(string id, Dictionary<string, string> settings, Calinfo calinfo) { try { var meetup_taggables = GetMeetupGroups(calinfo, 1, settings); bs.SerializeObjectToAzureBlob(meetup_taggables, id, "meetup.taggables.obj"); } catch (Exception e) { GenUtils.PriorityLogMsg("exception", "StoreTaggables: Meetup", e.Message); } }
public string RenderEvtAsCsv(ZonelessEvent evt, Calinfo calinfo, Dictionary<string, object> args) { var line = (string) args["csv_fields_template"]; var date_fmt = "yyyy-MM-dd"; var time_fmt = "hh:mm:ss"; line = line.Replace("__title__", evt.title.EscapeValueForCsv()); line = line.Replace("__start_day__", evt.dtstart.ToString(date_fmt)); line = line.Replace("__start_time__", evt.dtstart.ToString(time_fmt)); if (evt.dtend != DateTime.MinValue) { line = line.Replace("__stop_day__", evt.dtstart.ToString(date_fmt)); line = line.Replace("__stop_time__", evt.dtstart.ToString(time_fmt)); } else { line = line.Replace("__stop_day__", ""); line = line.Replace("__stop_time__", ""); } line = line.Replace("__uid__", evt.hash); line = line.Replace("__description__", evt.description.EscapeValueForCsv()); line = line.Replace("__location__", evt.location.EscapeValueForCsv()); line = line.Replace("__url__", evt.url.ToString().EscapeValueForCsv()); line = line.Replace("__categories__", evt.categories.EscapeValueForCsv()); return line + "\n"; }
public static void StoreTaggables(string id, string location, Dictionary<string, string> settings) { var calinfo = new Calinfo(id); StoreFacebookTaggables(id, location, calinfo); StoreEventfulTaggables(id, settings, calinfo); // StoreUpcomingTaggables(id, settings, calinfo); StoreEventBriteTaggables(id, settings, calinfo); StoreMeetupTaggables(id, settings, calinfo); }
// render a single event as text public string RenderEvtAsText(ZonelessEvent evt, Calinfo calinfo, Dictionary<string, object> args) { var text = new StringBuilder(); text.AppendLine(evt.title); var start = evt.dtstart.ToString("M/d/yyyy h:m tt").Replace(":0 ", " "); text.AppendLine(start); if ( ! String.IsNullOrEmpty(evt.source) ) text.AppendLine(evt.source); if ( ! String.IsNullOrEmpty(evt.location) ) text.AppendLine(evt.location); if ( ! String.IsNullOrEmpty(evt.description) && evt.description != evt.location) text.AppendLine(evt.description); text.AppendLine(); return text.ToString(); }
public static void StoreUpcomingTaggables(string id, Dictionary<string, string> settings, Calinfo calinfo) { try { var upcoming_taggables = GetUpcomingVenues(calinfo, settings); bs.SerializeObjectToAzureBlob(upcoming_taggables, id, "upcoming.taggables.obj"); } catch (Exception e) { GenUtils.PriorityLogMsg("exception", "StoreTaggables: Upcoming", e.Message); } }
public string RenderEvtAsHtml(ZonelessEvent evt, Calinfo calinfo, Dictionary<string,object> args) { if (evt.urls_and_sources == null) evt.urls_and_sources = new Dictionary<string, string>() { { evt.url, evt.source } }; string dtstart; if (evt.allday && evt.dtstart.Hour == 0) dtstart = " "; else dtstart = evt.dtstart.ToString("ddd hh:mm tt"); var month_day = evt.dtstart.ToString("M/d"); string categories = ""; List<string> catlist_links = new List<string>(); if (!String.IsNullOrEmpty(evt.categories)) { List<string> catlist = evt.categories.Split(',').ToList(); foreach (var cat in catlist) { var category_url = string.Format("/{0}/html?view={1}", this.id, cat); catlist_links.Add(string.Format(@"<a title=""open the {1} view"" href=""{0}"">{1}</a>", category_url, cat)); } categories = string.Format(@" <span class=""cat"">{0}</span>", string.Join(", ", catlist_links.ToArray())); } string label = "e" + this.event_counter.ToString(); String description = ( String.IsNullOrEmpty(evt.description) || evt.description.Length < 10 ) ? "" : evt.description.UrlsToLinks(); string show_desc = ( ! String.IsNullOrEmpty(description) ) ? String.Format(@"<span class=""sd""><a title=""show description ({0} chars)"" href=""javascript:show_desc('{1}')"">...</a></span>", description.Length, label) : ""; if (args.ContainsKey("inline_descriptions") && (bool)args["inline_descriptions"] == true) // for view_calendar { var location = string.IsNullOrEmpty(evt.location) ? "" : String.Format("{0}<br/><br/>", evt.location); show_desc = String.Format(@"<div style=""text-indent:0""><p>{0}</div>", location + description); } if (args.ContainsKey("show_desc") && (bool)args["show_desc"] == false) // in case need to suppress, not used yet show_desc = ""; string add_to_cal = String.Format(@"<span class=""atc""><a title=""add to calendar"" href=""javascript:add_to_cal('{0}')"">+</a></span>", label); if (args.ContainsKey("add_to_cal") && (bool)args["add_to_cal"] == false) // for view_calendar add_to_cal = ""; string visibility = ""; string more = ""; string source_key = ""; string source_attr = ""; int sequence_count = 1; int sequence_position = 1; string show_more_call; if (evt.urls_and_sources.Count == 1) { source_attr = MakeSourceAttr(evt); sequence_count = (int)args["sequence_count"]; source_key = (string)args["source_key"]; sequence_position = (int)args["sequence_position"]; } visibility = (sequence_count > 1 && sequence_position > 1) ? @" style=""display:none"" " : ""; if (sequence_count > 1 && sequence_position == 1) { show_more_call = "javascript:show_more('" + source_key + "')"; more = string.Format(@" <span class=""{0}""><a title=""show {2} more from {3}"" href=""{1}"">show {2} more</a></span>", source_key, show_more_call, sequence_count - 1, evt.source ); } else { more = ""; } var html = string.Format( @"<a name=""{0}""></a> <div id=""{0}"" class=""bl {10} {12}"" {13} xmlns:v=""http://rdf.data-vocabulary.org/#"" typeof=""v:Event"" > <span class=""md"">{14}</span> <span class=""st"" property=""v:startDate"" content=""{1}"">{2}</span> <span href=""{3}"" rel=""v:url""></span> <span class=""ttl"">{4}</span> <span class=""src"" property=""v:description"">{5}</span> {6} {7} {8} {9} {11} </div>", label, // 0 String.Format("{0:yyyy-MM-ddTHH:mm}", evt.dtstart), // 1 dtstart, // 2 evt.url, // 3 MakeTitleForRDFa(evt), // 4 evt.urls_and_sources.Keys.Count == 1 ? evt.source : "", // 5 suppress source if multiple categories, // 6 MakeGeoForRDFa(evt), // 7 show_desc, // 8 add_to_cal, // 9 source_attr, // 10 more, // 11 source_key, // 12 visibility, // 13 month_day // 14 ); this.event_counter += 1; return html; }
private static bool FacebookPageHasFutureEvents(List<FacebookEvent> events, Calinfo calinfo) { try { foreach (FacebookEvent evt in events) { if (Utils.IsCurrentOrFutureDateTime(evt.dt, calinfo.tzinfo)) return true; } } catch (Exception e) { GenUtils.PriorityLogMsg("exception", "FacebookPageHasFutureEvents", e.Message + e.StackTrace); return false; } return false; }
private ZonelessEventStore CreateFilterable(Calinfo calinfo) { var filterable = new ZonelessEventStore(calinfo); filterable.AddEvent("e1", "", "s1", null, null, DateTime.Parse("2013/11/01 8 AM"), DateTime.MinValue, false, null, null, null); filterable.AddEvent("e2", "", "s1", null, null, DateTime.Parse("2013/11/02 8 AM"), DateTime.MinValue, false, null, null, null); filterable.AddEvent("e3", "", "s2", null, null, DateTime.Parse("2013/11/03 8 AM"), DateTime.MinValue, false, null, null, null); filterable.AddEvent("e4", "", "s2", null, null, DateTime.Parse("2013/11/04 8 AM"), DateTime.MinValue, false, null, null, null); filterable.AddEvent("e5", "", "s2", null, null, DateTime.Parse("2013/11/05 8 AM"), DateTime.MinValue, false, "music", null, null); Assert.That(filterable.events.Count == 5); return filterable; }
public static void StoreEventfulTaggables(string id, Dictionary <string, string> settings, Calinfo calinfo) { try { var eventful_taggables = GetEventfulVenues(calinfo, min_per_venue: 1, settings: settings); bs.SerializeObjectToAzureBlob(eventful_taggables, id, "eventful.taggables.obj"); } catch (Exception e) { GenUtils.PriorityLogMsg("exception", "StoreTaggables: Eventful", e.Message); } }
public static void ClearObjFeedInCache(Calinfo calinfo, string cache_dir, string feedurl) { var blob_name = Utils.MakeCachedFeedObjName(calinfo.id, feedurl); var es = new ZonedEventStore(calinfo, SourceType.ical); bs.SerializeObjectToAzureBlob(es, cache_dir, blob_name); }
public static void StoreMeetupTaggables(string id, Dictionary <string, string> settings, Calinfo calinfo) { try { var meetup_taggables = GetMeetupGroups(calinfo, 1, settings); bs.SerializeObjectToAzureBlob(meetup_taggables, id, "meetup.taggables.obj"); } catch (Exception e) { GenUtils.PriorityLogMsg("exception", "StoreTaggables: Meetup", e.Message); } }
private static string ClearCachedObj(Calinfo calinfo, string cache_dir, string feedurl) { ClearObjFeedInCache(calinfo, cache_dir, feedurl); var obj_blob_name = Utils.MakeCachedFeedObjName(calinfo.id, feedurl); HttpUtils.Wait(2); var es = (ZonedEventStore)ObjectUtils.GetTypedObj<ZonedEventStore>(cache_dir, obj_blob_name); Assert.That(es.events.Count == 0); // verify empty return obj_blob_name; }
private static ZonelessEventStore ProcessEventBriteExample(string example, string source, Calinfo calinfo, Collector collector) { DeleteZonedObjects(calinfo.id); var es = new ZonedEventStore(calinfo, SourceType.eventbrite); collector.CollectEventBrite(es); EventStore.CombineZonedEventStoresToZonelessEventStore(calinfo.id, settings); var zes = new ZonelessEventStore(calinfo).Deserialize(); return(zes); }
private static ZonelessEventStore ProcessUpcomingExample(string example, string source, Calinfo calinfo, Collector collector) { DeleteZonedObjects(calinfo.id); var es = new ZonedEventStore(calinfo, SourceType.upcoming); collector.CollectUpcoming(es, test: true); EventStore.CombineZonedEventStoresToZonelessEventStore(calinfo.id, settings); var zes = new ZonelessEventStore(calinfo).Deserialize(); return zes; }
public static DDay.iCal.Event MakeTmpEvt(Calinfo calinfo, DateTimeWithZone dtstart, DateTimeWithZone dtend, string title, string url, string location, string description, string lat, string lon, bool allday) { DDay.iCal.Event evt = new DDay.iCal.Event(); // for export to the intermediate ics file evt.Summary = title; evt.Url = new Uri(url); if (location != null) evt.Location = location; if (description != null) evt.Description = description; else evt.Description = url; if ( calinfo == null ) MakeGeo(calinfo, evt, lat, lon); else MakeGeo(evt, lat, lon); evt.Start = new iCalDateTime(dtstart.LocalTime); // always local because the final ics file will use vtimezone evt.Start.TZID = calinfo.tzinfo.Id; if (!dtend.Equals(DateTimeWithZone.MinValue(calinfo.tzinfo))) { evt.End = new iCalDateTime(dtend.LocalTime); evt.End.TZID = calinfo.tzinfo.Id; } evt.IsAllDay = allday; evt.UID = Event.MakeEventUid(evt); return evt; }
public EventStore(Calinfo calinfo) { this.id = calinfo.id; this.tzinfo = calinfo.tzinfo; }
public static DDay.iCal.Event MakeTmpEvt(TimeZoneInfo tzinfo, DateTimeWithZone dtstart, DateTimeWithZone dtend, string title, string url, string location, string description, string lat, string lon, bool allday) { var calinfo = new Calinfo(tzinfo); return MakeTmpEvt(calinfo, dtstart, dtend, title, url, location, description, lat, lon, allday); }
private static List<TaggableSource> InitializeTaggables(Calinfo calinfo, string flavor) { List<TaggableSource> taggable_sources; try { taggable_sources = (List<TaggableSource>)ObjectUtils.GetTypedObj<List<TaggableSource>>(calinfo.id, flavor + ".taggables.obj"); } catch { taggable_sources = new List<TaggableSource>(); } return taggable_sources; }
public static string MassageFeedText(Calinfo calinfo, string feedurl, string feedtext, Dictionary<string,string> settings) { // for example, RRULE:FREQ=MONTHLY;COUNT=-45;BYDAY=2SA occurs in some Google Calendars // unable to find a meaning for this in RFC5445, and DDay.iCal rejects it, so I'm removing it for now feedtext = Utils.RemoveNegativeCOUNT(feedtext); // because not needed, and dday.ical doesn't allow legal (but very old) dates // feedtext = GenUtils.RegexReplace(feedtext, "\nCREATED:[^\n]+", ""); feedtext = Utils.RemoveComponent(feedtext, "CREATED"); // because DDay.iCal can't parse ATTENDEE feedtext = Utils.RemoveComponent(feedtext, "ATTENDEE"); // because of issue with http://www.brattleborology.com/calendar/ feedtext = Utils.RemoveComponent(feedtext, "ORGANIZER"); //feedtext = Utils.RemoveComponent(feedtext, "UID"); // do this in GetFeedText so changes don't invalidate otherwise unchanged cached text //feedtext = Utils.RemoveComponent(feedtext, "DTSTAMP"); // because of this: // BEGIN:VEVENT // DESCRIPTION // <- missing colon, iCalcreator 2.4.3 (reported) // DTEND:20120508T160000 feedtext = Utils.AddColonToBarePropnames(feedtext); // because of issues with emich.edu/calendar, umma.museum feedtext = MaybeFixMiswrappedComponent(feedurl, feedtext, settings, "miswrapped_description", "DESCRIPTION"); feedtext = MaybeFixMiswrappedComponent(feedurl, feedtext, settings, "miswrapped_summary", "SUMMARY"); feedtext = MaybeFixMiswrappedComponent(feedurl, feedtext, settings, "miswrapped_location", "LOCATION"); // because of property-name-folding issue https://github.com/dougrday/icalvalid/issues/10 feedtext = Unfold(feedtext); // strip html from summary, description feedtext = Utils.StripTagsFromUnfoldedComponent(feedtext, "SUMMARY"); feedtext = Utils.StripTagsFromUnfoldedComponent(feedtext, "DESCRIPTION"); // workaround https://github.com/dougrday/icalvalid/issues/7 and 8 feedtext = Utils.ChangeDateOnlyUntilToDateTime(feedtext); // handle non-standard X_WR_TIMEZONE if usersetting asked if (calinfo != null && calinfo.use_x_wr_timezone) // null if called from ViewCalendar feedtext = Utils.Handle_X_WR_TIMEZONE(feedtext); feedtext = Utils.AdjustCategories(feedtext); // for now, this only removes unwanted backslashes feedtext = Utils.RemoveComponent(feedtext, "UID"); // don't need these feedtext = Utils.RemoveComponent(feedtext, "DTSTAMP"); return feedtext; }
public ZonelessEventStore(Calinfo calinfo) : base(calinfo) { this.objfile = this.id + ".zoneless.obj"; this.uri = BlobStorage.MakeAzureBlobUri(this.id, this.objfile, false); }
public static string GetFeedTextFromFeedUrl(FeedRegistry fr, Calinfo calinfo, string source, string feedurl, int wait_secs, int max_retries, TimeSpan timeout_secs, Dictionary<string,string> settings, ref bool changed) { HttpWebRequest request; try { var _feedurl = Utils.MaybeChangeWebcalToHttp(feedurl); // original is for feed registry and cache request = (HttpWebRequest)WebRequest.Create(new Uri(_feedurl)); // only modify (if necessary) when actually fetching } catch (Exception e) { GenUtils.LogMsg("warning", "GetFeedTextFromFeedUrl", "cannot use " + feedurl + " : " + e.Message); return String.Empty; } string feedtext = ""; string cached_feed_text = Utils.GetCachedFeedText(feedurl); var response = HttpUtils.RetryHttpRequestExpectingStatus(request, HttpStatusCode.OK, data: null, wait_secs: wait_secs, max_tries: max_retries, timeout_secs: timeout_secs); if (response.status != HttpStatusCode.OK) { var msg = "could not fetch " + source; GenUtils.LogMsg("warning", msg, response.status.ToString()); feedtext = cached_feed_text; } else { feedtext = response.DataAsString(); } if (cached_feed_text.Contains("X-QUOTA-THROTTLED")) GenUtils.LogMsg("warning", "GetFeedTextFromFeed", "cached text contains X-QUOTA-THROTTLED"); if (feedtext != cached_feed_text && feedtext.Contains("X-QUOTA-THROTTLED") == false ) // don't cache if throttled { changed = true; Utils.SaveFeedTextToCache(feedurl, feedtext); } feedtext = MassageFeedText(calinfo, feedurl, feedtext, settings); if (fr != null) EnsureProdId(fr, feedurl, feedtext); return feedtext; }
public static void MakeGeo(Calinfo calinfo, DDay.iCal.Event evt, string lat, string lon) { if (String.IsNullOrEmpty(lat) || string.IsNullOrEmpty(lon)) return; if ( calinfo.hub_enum == HubType.where) { if (evt.GeographicLocation == null) // override with hub's location { try { if (lat == null) // e.g., because called from IcsFromRssPlusXcal lat = calinfo.lat; if (lon == null) lon = calinfo.lon; MakeGeo(evt, lat, lon); } catch (Exception e) { GenUtils.PriorityLogMsg("exception", "AddIcalEvent: " + calinfo.id + " cannot make evt.Geo", e.Message + evt.Summary.ToString()); } } } }
private static ZonelessEventStore ProcessIcalExample(string example, string source, Calinfo calinfo, FeedRegistry fr, Collector collector, bool purge) { DeleteZonedObjects(calinfo.id); if (purge) { Utils.PurgeFeedCacheForHub(calinfo.id); } var feedurl = BlobStorage.MakeAzureBlobUri("admin", example + ".ics", false).ToString(); fr.AddFeed(feedurl, source); var es = new ZonedEventStore(calinfo, SourceType.ical); collector.CollectIcal(fr, es, false); EventStore.CombineZonedEventStoresToZonelessEventStore(calinfo.id, settings); var zes = new ZonelessEventStore(calinfo).Deserialize(); return(zes); }