Beispiel #1
0
            private void MaybeCacheView(string view_key, CalendarRenderer.ViewRenderer view_renderer, ElmcityCacheDependency dependency, Dictionary <string, object> render_args)
            {
                if (this.test)
                {
                    return;
                }

                if (this.cr.cache[view_key] == null)
                {
                    var    view_str   = this.cr.RenderDynamicViewWithoutCaching(this.controller.ControllerContext, view_renderer, this.view, this.count, this.from, this.to, this.source, render_args);
                    byte[] view_bytes = Encoding.UTF8.GetBytes(view_str);
                    var    cache      = new AspNetCache(this.controller.HttpContext.Cache);
                    this.controller.InsertIntoCache(cache, view_bytes, dependency, view_key);
                }
            }
            public override void ExecuteResult(ControllerContext context)
            {
                // for dynamic views derived from the static file
                // which is the base object for this id, e.g.:
                //  http://elmcity.blob.core.windows.net/a2cal/a2cal.zoneless.obj
                // cache the base object if uncached
                var base_key = Utils.MakeBaseZonelessUrl(this.id);
                if (this.cr.cache[base_key] == null)
                {
                    var bytes = HttpUtils.FetchUrl(new Uri(base_key)).bytes;
                    //InsertIntoCache(bytes, ElmcityUtils.Configurator.cache_sliding_expiration, dependency: null, key: base_key);
                    var cache = new AspNetCache(this.controller.HttpContext.Cache);
                    this.controller.InsertIntoCache( cache, bytes, dependency: null, key: base_key);
                }

                // uri for static content, e.g.:
                // http://elmcity.blob.core.windows.net/a2cal/a2cal.stats.html
                // http://elmcity.blob.core.windows.net/a2cal/a2cal.search.html
                // these generated files could be served using their blob urls, but
                // here are repackaged into the /services namespace, e.g.:
                // http://elmcity.cloudapp.net/services/a2cal/stats
                // http://elmcity.cloudapp.net/services/a2cal/search

                var blob_uri = BlobStorage.MakeAzureBlobUri(this.id, this.id + "." + this.type, false);

                // cache static content
                var blob_key = blob_uri.ToString();
                if (cacheable_types.Exists(t => t == this.type) && this.cr.cache[blob_key] == null)
                {
                    var bytes = HttpUtils.FetchUrl(blob_uri).bytes;
                    var dependency = new ElmcityCacheDependency(base_key);
                    var cache = new AspNetCache(this.controller.HttpContext.Cache);
                    this.controller.InsertIntoCache(cache, bytes, dependency, base_key);
                }

                var fmt = "{0:yyyyMMddTHHmm}";
                var from_str = string.Format(fmt, this.from);
                var to_str = string.Format(fmt, this.to);

                var test_arg = this.test ? "yes" : "";
                var raw_arg = this.raw ? "yes" : "";
                var view_key = Utils.MakeViewKey(this.id, this.type, this.view, this.count.ToString(), from_str, to_str, this.eventsonly, this.mobile, test:test_arg, raw:raw_arg, style:this.style, theme:this.theme);

                var render_args = new Dictionary<string, object>();

                switch (this.type)
                {
                    case "html":
                        render_args["view"] = this.view;
                        render_args["test"] = this.test;
                        render_args["style"] = this.style;
                        render_args["theme"] = this.theme;
                        render_args["mobile"] = false;
                        render_args["ua"] = "";
                        render_args["css"] = this.cr.calinfo.css;  // need to extract and pass along the default theme name
                        render_args["taglist"] = String.IsNullOrEmpty(this.taglist) ? true : this.taglist.ToLower().StartsWith("n");

                        bool mobile_declared = this.mobile.ToLower().StartsWith("y");

                        bool is_mobile;

                        if (settings["use_mobile_detection"] == "yes")                      // detect or use declaration
                        {
                            bool smartphone_detected = TryDetectSmartPhone(render_args);
                            is_mobile = smartphone_detected || mobile_declared;
                        }
                        else
                            is_mobile = mobile_declared;                                    // use declaration only

                        if ( this.mobile.ToLower().StartsWith("n") )                       // maybe override with refusal
                            is_mobile = false;

                        if (is_mobile)
                        {
                            //this.count = Convert.ToInt32(settings["mobile_event_count"]);  // no, let the renderer reduce the list
                            render_args["mobile_event_count"] = Convert.ToInt32(settings["mobile_event_count"]);
                            render_args["mobile"] = true;
                            this.renderer = new CalendarRenderer.ViewRenderer(cr.RenderHtmlForMobile);
                            view_key = Utils.MakeViewKey(this.id, this.type, this.view, this.count.ToString(), from_str, to_str, eventsonly: "yes", mobile: "yes", test:test_arg, raw:raw_arg, style:this.style, theme:this.theme);
                        }
                        /* for dynamic event paging, not used now
                        else if (this.raw)
                        {
                            this.renderer = new CalendarRenderer.ViewRenderer(cr.RenderHtmlEventsOnlyRaw);
                            render_args["raw_sentinel"] = this.raw_sentinel;
                            view_key = Utils.MakeViewKey(this.id, this.type, this.view, this.count.ToString(), from_str, to_str, eventsonly: null, mobile: null, test:test_arg, raw: raw_arg, style:this.style, theme:this.theme);
                        }*/
                        else if (this.eventsonly == "yes")
                        {
                            this.renderer = new CalendarRenderer.ViewRenderer(cr.RenderHtmlEventsOnly);
                            view_key = Utils.MakeViewKey(this.id, this.type, this.view, this.count.ToString(), from_str, to_str, eventsonly: "yes", mobile: "", test:test_arg, raw:raw_arg, style:this.style, theme:this.theme);
                        }
                        else
                            this.renderer = new CalendarRenderer.ViewRenderer(cr.RenderHtml);

                        //if (is_mobile)
                        //	GenUtils.LogMsg("info", "EventsResult", JsonConvert.SerializeObject(render_args));

                        MaybeCacheView(view_key, this.renderer, new ElmcityCacheDependency(base_key), render_args);

                        this.response_body = cr.RenderDynamicViewWithCaching(context, view_key, this.renderer, this.view, this.count, this.from, this.to, render_args);
                        new ContentResult
                        {
                            ContentType = "text/html",
                            Content = this.response_body,
                            ContentEncoding = UTF8
                        }.ExecuteResult(context);
                        break;

                    case "xml":
                        this.renderer = new CalendarRenderer.ViewRenderer(cr.RenderXml);
                        MaybeCacheView(view_key, this.renderer, new ElmcityCacheDependency(base_key), null);
                        this.response_body = cr.RenderDynamicViewWithCaching(context, view_key, this.renderer, this.view, this.count, this.from, this.to, null);
                        new ContentResult
                        {
                            ContentType = "text/xml",
                            Content = this.response_body,
                            ContentEncoding = UTF8
                        }.ExecuteResult(context);
                        break;

                    case "rss":
                        if (count == 0) count = CalendarAggregator.Configurator.rss_default_items;
                        this.renderer = new CalendarRenderer.ViewRenderer(cr.RenderRss);
                        MaybeCacheView(view_key, this.renderer, new ElmcityCacheDependency(base_key), null);
                        this.response_body = cr.RenderDynamicViewWithCaching(context, view_key, this.renderer, this.view, this.count, this.from, this.to, null);

                        new ContentResult
                        {
                            ContentType = "text/xml",
                            Content = response_body,
                            ContentEncoding = UTF8
                        }.ExecuteResult(context);
                        break;

                    case "json":
                        this.renderer = new CalendarRenderer.ViewRenderer(cr.RenderJson);
                        MaybeCacheView(view_key, this.renderer, new ElmcityCacheDependency(base_key), null);
                        string jcontent = cr.RenderDynamicViewWithCaching(context, view_key, this.renderer, this.view, this.count, this.from, this.to, null);
                        if (this.jsonp != null)
                            jcontent = this.jsonp + "(" + jcontent + ")";
                        new ContentResult
                        {
                            ContentEncoding = UTF8,
                            ContentType = "application/json",
                            Content = jcontent
                        }.ExecuteResult(context);
                        break;

                    case "tags_json":
                        string tjcontent = cr.RenderTagCloudAsJson();
                        if (this.jsonp != null)
                            tjcontent = this.jsonp + "(" + tjcontent + ")";
                        new ContentResult
                        {
                            ContentEncoding = UTF8,
                            ContentType = "application/json",
                            Content = tjcontent,
                        }.ExecuteResult(context);
                        break;

                    case "tags_html":
                        string thcontent = cr.RenderTagCloudAsHtml();
                        new ContentResult
                        {
                            ContentEncoding = UTF8,
                            ContentType = "text/html",
                            Content = thcontent,
                        }.ExecuteResult(context);
                        break;

                    case "stats":
                        blob_uri = BlobStorage.MakeAzureBlobUri(this.id, this.id + ".stats.html",false);
                        //this.response_bytes = (byte[])CacheUtils.RetrieveBlobAndEtagFromServerCacheOrUri(this.cr.cache, blob_uri)["response_body"];
                        this.response_bytes = HttpUtils.FetchUrl(blob_uri).bytes;
                        new ContentResult
                        {
                            ContentEncoding = UTF8,
                            ContentType = "text/html",
                            Content = Encoding.UTF8.GetString(this.response_bytes),
                        }.ExecuteResult(context);
                        break;

                    case "ics":
                        this.renderer = new CalendarRenderer.ViewRenderer(cr.RenderIcs);
                        MaybeCacheView(view_key, this.renderer, new ElmcityCacheDependency(base_key), null);
                        string ics_text = cr.RenderDynamicViewWithCaching(context, view_key, this.renderer, this.view, this.count, this.from, this.to, null);
                        new ContentResult
                        {
                            ContentType = "text/calendar",
                            Content = ics_text,
                            ContentEncoding = UTF8
                        }.ExecuteResult(context);
                        break;

                    case "jswidget":
                        new ContentResult
                        {
                            ContentType = "text/html",
                            Content = cr.RenderJsWidget(),
                            ContentEncoding = UTF8
                        }.ExecuteResult(context);
                        break;

                    case "search":
                        blob_uri = BlobStorage.MakeAzureBlobUri(this.id, this.id + ".search.html",false);
                        this.response_bytes = (byte[])CacheUtils.RetrieveBlobAndEtagFromServerCacheOrUri(this.cr.cache, blob_uri)["response_body"];
                        new ContentResult
                        {
                            ContentType = "text/html",
                            Content = Encoding.UTF8.GetString(this.response_bytes),
                            ContentEncoding = UTF8
                        }.ExecuteResult(context);
                        break;

                    case "today_as_html":
                        new ContentResult
                        {
                            ContentType = "text/html",
                            Content = cr.RenderTodayAsHtml(),
                            ContentEncoding = UTF8
                        }.ExecuteResult(context);
                        break;
                }
            }
Beispiel #3
0
            public override void ExecuteResult(ControllerContext context)
            {
                // for dynamic views derived from the static file
                // which is the base object for this id, e.g.:
                //  http://elmcity.blob.core.windows.net/a2cal/a2cal.zoneless.obj
                // cache the base object if uncached
                var base_key = Utils.MakeBaseZonelessUrl(this.id);

                if (this.cr.cache[base_key] == null)
                {
                    var bytes = HttpUtils.FetchUrl(new Uri(base_key)).bytes;
                    //InsertIntoCache(bytes, ElmcityUtils.Configurator.cache_sliding_expiration, dependency: null, key: base_key);
                    var cache = new AspNetCache(this.controller.HttpContext.Cache);
                    this.controller.InsertIntoCache(cache, bytes, dependency: null, key: base_key);
                }

                // uri for static content, e.g.:
                // http://elmcity.blob.core.windows.net/a2cal/a2cal.stats.html
                // http://elmcity.blob.core.windows.net/a2cal/a2cal.search.html
                // these generated files could be served using their blob urls, but
                // here are repackaged into the /services namespace, e.g.:
                // http://elmcity.cloudapp.net/services/a2cal/stats
                // http://elmcity.cloudapp.net/services/a2cal/search

                var blob_uri = BlobStorage.MakeAzureBlobUri(this.id, this.id + "." + this.type, false);

                // cache static content
                var blob_key = blob_uri.ToString();

                if (cacheable_types.Exists(t => t == this.type) && this.cr.cache[blob_key] == null)
                {
                    var bytes      = HttpUtils.FetchUrl(blob_uri).bytes;
                    var dependency = new ElmcityCacheDependency(base_key);
                    var cache      = new AspNetCache(this.controller.HttpContext.Cache);
                    this.controller.InsertIntoCache(cache, bytes, dependency, base_key);
                }

                var fmt      = "{0:yyyyMMddTHHmm}";
                var from_str = string.Format(fmt, this.from);
                var to_str   = string.Format(fmt, this.to);

                var render_args = new Dictionary <string, object>();

                var view_key = Utils.MakeViewKey(this.id, this.type, this.view, this.count.ToString(), from_str, to_str, eventsonly: this.eventsonly, mobile: this.mobile, test: this.test, raw: this.raw, style: this.style, theme: this.theme, taglist: this.taglist, tags: this.tags, template: this.template, jsurl: this.jsurl, days: this.days, bare_events: this.bare_events, hub: this.hub, source: this.source, first: this.first.ToString());

                switch (this.type)
                {
                case "html":
                    render_args["view"]            = this.view;
                    render_args["test"]            = this.test;                   // obsolete?
                    render_args["style"]           = this.style;
                    render_args["theme"]           = this.theme;
                    render_args["mobile_detected"] = false;                             // unused for now
                    render_args["ua"]          = "";
                    render_args["css"]         = this.cr.calinfo.css;                   // need to extract and pass along the default theme name
                    render_args["taglist"]     = this.taglist;
                    render_args["template"]    = this.template;
                    render_args["jsurl"]       = this.jsurl;
                    render_args["bare_events"] = this.bare_events;
                    render_args["hub"]         = this.hub;
                    render_args["first"]       = this.first;
                    render_args["eventsonly"]  = this.eventsonly;

                    if (settings["use_mobile_detection"] == "yes")                                                  // detect or use declaration
                    {
                        this.mobile_detected           = TryDetectSmartPhone(render_args);
                        render_args["mobile_detected"] = this.mobile_detected;
                        this.mobile = this.mobile_detected || this.mobile_declared;
                    }
                    else
                    {
                        this.mobile = this.mobile_declared;                                      // use declaration only
                    }
                    if (this.mobile_refused)                                                     // maybe override with refusal
                    {
                        this.mobile = false;
                    }

                    if (this.mobile)
                    {
                        //this.count = Convert.ToInt32(settings["mobile_event_count"]);  // no, let the renderer reduce the list
                        render_args["mobile_event_count"] = Convert.ToInt32(settings["mobile_event_count"]);
                        this.renderer = new CalendarRenderer.ViewRenderer(cr.RenderHtmlForMobile);
                    }
                    else if (this.eventsonly)
                    {
                        this.renderer = new CalendarRenderer.ViewRenderer(cr.RenderHtmlEventsOnly);
                    }
                    else
                    {
                        this.renderer = new CalendarRenderer.ViewRenderer(cr.RenderHtml);
                    }

                    // update for mobile detection
                    view_key = Utils.MakeViewKey(this.id, this.type, this.view, this.count.ToString(), from_str, to_str, eventsonly: this.eventsonly, mobile: this.mobile, test: this.test, raw: this.raw, style: this.style, theme: this.theme, taglist: this.taglist, tags: this.tags, template: this.template, jsurl: this.jsurl, days: this.days, bare_events: this.bare_events, hub: this.hub, source: this.source, first: this.first.ToString());

                    MaybeCacheView(view_key, this.renderer, new ElmcityCacheDependency(base_key), render_args);

                    this.response_body = cr.RenderDynamicViewWithCaching(context, view_key, this.renderer, this.view, this.count, this.from, this.to, this.source, render_args);

                    // let ajax pull events into pages directly
                    this.controller.HttpContext.Response.Headers["Access-Control-Allow-Origin"] = "*";

                    new ContentResult
                    {
                        ContentType     = "text/html",
                        Content         = this.response_body,
                        ContentEncoding = UTF8
                    }.ExecuteResult(context);
                    break;

                case "xml":
                    this.renderer = new CalendarRenderer.ViewRenderer(cr.RenderXml);
                    MaybeCacheView(view_key, this.renderer, new ElmcityCacheDependency(base_key), null);
                    this.response_body = cr.RenderDynamicViewWithCaching(context, view_key, this.renderer, this.view, this.count, this.from, this.to, this.source, null);
                    new ContentResult
                    {
                        ContentType     = "text/xml",
                        Content         = this.response_body,
                        ContentEncoding = UTF8
                    }.ExecuteResult(context);
                    break;

                case "rss":
                    if (count == 0)
                    {
                        count = CalendarAggregator.Configurator.rss_default_items;
                    }
                    this.renderer = new CalendarRenderer.ViewRenderer(cr.RenderRss);
                    MaybeCacheView(view_key, this.renderer, new ElmcityCacheDependency(base_key), null);
                    this.response_body = cr.RenderDynamicViewWithCaching(context, view_key, this.renderer, this.view, this.count, this.from, this.to, this.source, null);

                    new ContentResult
                    {
                        ContentType     = "text/xml",
                        Content         = response_body,
                        ContentEncoding = UTF8
                    }.ExecuteResult(context);
                    break;

                case "json":
                    this.renderer = new CalendarRenderer.ViewRenderer(cr.RenderJson);
                    MaybeCacheView(view_key, this.renderer, new ElmcityCacheDependency(base_key), null);
                    string jcontent = cr.RenderDynamicViewWithCaching(context, view_key, this.renderer, this.view, this.count, this.from, this.to, this.source, null);
                    if (this.jsonp != null)
                    {
                        jcontent = this.jsonp + "(" + jcontent + ")";
                    }
                    new ContentResult
                    {
                        ContentEncoding = UTF8,
                        ContentType     = "application/json",
                        Content         = jcontent
                    }.ExecuteResult(context);
                    break;

                case "text":
                    this.renderer = new CalendarRenderer.ViewRenderer(cr.RenderText);
                    MaybeCacheView(view_key, this.renderer, new ElmcityCacheDependency(base_key), null);
                    string tcontent = cr.RenderDynamicViewWithCaching(context, view_key, this.renderer, this.view, this.count, this.from, this.to, this.source, null);
                    new ContentResult
                    {
                        ContentEncoding = UTF8,
                        ContentType     = "text/plain",
                        Content         = tcontent
                    }.ExecuteResult(context);
                    break;

                case "csv":
                    this.renderer = new CalendarRenderer.ViewRenderer(cr.RenderCsv);
                    MaybeCacheView(view_key, this.renderer, new ElmcityCacheDependency(base_key), null);
                    string csv = cr.RenderDynamicViewWithCaching(context, view_key, this.renderer, this.view, this.count, this.from, this.to, this.source, null);
                    new ContentResult
                    {
                        ContentEncoding = UTF8,
                        ContentType     = "text/plain",
                        Content         = csv
                    }.ExecuteResult(context);
                    break;

                case "tags_json":
                    string tjcontent = cr.RenderTagCloudAsJson();
                    if (this.jsonp != null)
                    {
                        tjcontent = this.jsonp + "(" + tjcontent + ")";
                    }
                    new ContentResult
                    {
                        ContentEncoding = UTF8,
                        ContentType     = "application/json",
                        Content         = tjcontent,
                    }.ExecuteResult(context);
                    break;

                case "tags_html":
                    string thcontent = cr.RenderTagCloudAsHtml();
                    new ContentResult
                    {
                        ContentEncoding = UTF8,
                        ContentType     = "text/html",
                        Content         = thcontent,
                    }.ExecuteResult(context);
                    break;

                case "stats":
                    blob_uri = BlobStorage.MakeAzureBlobUri(this.id, this.id + ".stats.html", false);
                    //this.response_bytes = (byte[])CacheUtils.RetrieveBlobAndEtagFromServerCacheOrUri(this.cr.cache, blob_uri)["response_body"];
                    this.response_bytes = HttpUtils.FetchUrl(blob_uri).bytes;
                    new ContentResult
                    {
                        ContentEncoding = UTF8,
                        ContentType     = "text/html",
                        Content         = Encoding.UTF8.GetString(this.response_bytes),
                    }.ExecuteResult(context);
                    break;

                case "ics":
                    this.renderer = new CalendarRenderer.ViewRenderer(cr.RenderIcs);
                    MaybeCacheView(view_key, this.renderer, new ElmcityCacheDependency(base_key), null);
                    string ics_text = cr.RenderDynamicViewWithCaching(context, view_key, this.renderer, this.view, this.count, this.from, this.to, this.source, null);
                    new ContentResult
                    {
                        ContentType     = "text/calendar",
                        Content         = ics_text,
                        ContentEncoding = UTF8
                    }.ExecuteResult(context);
                    break;

                case "jswidget":
                    new ContentResult
                    {
                        ContentType     = "text/html",
                        Content         = cr.RenderJsWidget(),
                        ContentEncoding = UTF8
                    }.ExecuteResult(context);
                    break;

                case "today_as_html":
                    new ContentResult
                    {
                        ContentType     = "text/html",
                        Content         = cr.RenderTodayAsHtml(),
                        ContentEncoding = UTF8
                    }.ExecuteResult(context);
                    break;
                }
            }
Beispiel #4
0
            public override void ExecuteResult(ControllerContext context)
            {
                // for dynamic views derived from the static file
                // which is the base object for this id, e.g.:
                //  http://elmcity.blob.core.windows.net/a2cal/a2cal.zoneless.obj
                // cache the base object if uncached
                var base_key = Utils.MakeBaseZonelessUrl(this.id);
                if (this.cr.cache[base_key] == null)
                {
                    var bytes = HttpUtils.FetchUrl(new Uri(base_key)).bytes;
                    //InsertIntoCache(bytes, ElmcityUtils.Configurator.cache_sliding_expiration, dependency: null, key: base_key);
                    var cache = new AspNetCache(this.controller.HttpContext.Cache);
                    this.controller.InsertIntoCache( cache, bytes, dependency: null, key: base_key);
                }

                // uri for static content, e.g.:
                // http://elmcity.blob.core.windows.net/a2cal/a2cal.stats.html
                // http://elmcity.blob.core.windows.net/a2cal/a2cal.search.html
                // these generated files could be served using their blob urls, but
                // here are repackaged into the /services namespace, e.g.:
                // http://elmcity.cloudapp.net/services/a2cal/stats
                // http://elmcity.cloudapp.net/services/a2cal/search

                var blob_uri = BlobStorage.MakeAzureBlobUri(this.id, this.id + "." + this.type, false);

                // cache static content
                var blob_key = blob_uri.ToString();
                if (cacheable_types.Exists(t => t == this.type) && this.cr.cache[blob_key] == null)
                {
                    var bytes = HttpUtils.FetchUrl(blob_uri).bytes;
                    var dependency = new ElmcityCacheDependency(base_key);
                    var cache = new AspNetCache(this.controller.HttpContext.Cache);
                    this.controller.InsertIntoCache(cache, bytes, dependency, base_key);
                }

                var fmt = "{0:yyyyMMddTHHmm}";
                var from_str = string.Format(fmt, this.from);
                var to_str = string.Format(fmt, this.to);

                var render_args = new Dictionary<string, object>();

                var view_key = Utils.MakeViewKey(this.id, this.type, this.view, this.count.ToString(), from_str, to_str, eventsonly: this.eventsonly, mobile: this.mobile, test: this.test, raw: this.raw, style: this.style, theme: this.theme, taglist: this.taglist, tags: this.tags, template: this.template, jsurl: this.jsurl, days: this.days, bare_events: this.bare_events, hub: this.hub, source: this.source, first: this.first.ToString());

                switch (this.type)
                {
                    case "html":
                        render_args["view"] = this.view;
                        render_args["test"] = this.test;  // obsolete?
                        render_args["style"] = this.style;
                        render_args["theme"] = this.theme;
                        render_args["mobile_detected"] = false; // unused for now
                        render_args["ua"] = "";
                        render_args["css"] = this.cr.calinfo.css;  // need to extract and pass along the default theme name
                        render_args["taglist"] = this.taglist;
                        render_args["template"] = this.template;
                        render_args["jsurl"] = this.jsurl;
                        render_args["bare_events"] = this.bare_events;
                        render_args["hub"] = this.hub;
                        render_args["first"] = this.first;
                        render_args["eventsonly"] = this.eventsonly;

                        if (settings["use_mobile_detection"] == "yes")                      // detect or use declaration
                        {
                            this.mobile_detected = TryDetectSmartPhone(render_args);
                            render_args["mobile_detected"] = this.mobile_detected;
                            this.mobile = this.mobile_detected || this.mobile_declared;
                        }
                        else
                            this.mobile = this.mobile_declared;                                    // use declaration only

                        if ( this.mobile_refused )                       // maybe override with refusal
                            this.mobile = false;

                        if (this.mobile)
                        {
                            //this.count = Convert.ToInt32(settings["mobile_event_count"]);  // no, let the renderer reduce the list
                            render_args["mobile_event_count"] = Convert.ToInt32(settings["mobile_event_count"]);
                            this.renderer = new CalendarRenderer.ViewRenderer(cr.RenderHtmlForMobile);
                        }
                        else if (this.eventsonly)
                        {
                            this.renderer = new CalendarRenderer.ViewRenderer(cr.RenderHtmlEventsOnly);
                        }
                        else
                        {
                            this.renderer = new CalendarRenderer.ViewRenderer(cr.RenderHtml);
                        }

                        // update for mobile detection
                        view_key = Utils.MakeViewKey(this.id, this.type, this.view, this.count.ToString(), from_str, to_str, eventsonly: this.eventsonly, mobile: this.mobile, test: this.test, raw: this.raw, style: this.style, theme: this.theme, taglist: this.taglist, tags: this.tags, template: this.template, jsurl: this.jsurl, days: this.days, bare_events: this.bare_events, hub: this.hub, source: this.source, first: this.first.ToString());

                        MaybeCacheView(view_key, this.renderer, new ElmcityCacheDependency(base_key), render_args);

                        this.response_body = cr.RenderDynamicViewWithCaching(context, view_key, this.renderer, this.view, this.count, this.from, this.to, this.source, render_args);

                        // let ajax pull events into pages directly
                        this.controller.HttpContext.Response.Headers["Access-Control-Allow-Origin"] = "*";

                        new ContentResult
                        {
                            ContentType = "text/html",
                            Content = this.response_body,
                            ContentEncoding = UTF8
                        }.ExecuteResult(context);
                        break;

                    case "xml":
                        this.renderer = new CalendarRenderer.ViewRenderer(cr.RenderXml);
                        MaybeCacheView(view_key, this.renderer, new ElmcityCacheDependency(base_key), null);
                        this.response_body = cr.RenderDynamicViewWithCaching(context, view_key, this.renderer, this.view, this.count, this.from, this.to, this.source, null);
                        new ContentResult
                        {
                            ContentType = "text/xml",
                            Content = this.response_body,
                            ContentEncoding = UTF8
                        }.ExecuteResult(context);
                        break;

                    case "rss":
                        if (count == 0) count = CalendarAggregator.Configurator.rss_default_items;
                        this.renderer = new CalendarRenderer.ViewRenderer(cr.RenderRss);
                        MaybeCacheView(view_key, this.renderer, new ElmcityCacheDependency(base_key), null);
                        this.response_body = cr.RenderDynamicViewWithCaching(context, view_key, this.renderer, this.view, this.count, this.from, this.to, this.source, null);

                        new ContentResult
                        {
                            ContentType = "text/xml",
                            Content = response_body,
                            ContentEncoding = UTF8
                        }.ExecuteResult(context);
                        break;

                    case "json":
                        this.renderer = new CalendarRenderer.ViewRenderer(cr.RenderJson);
                        MaybeCacheView(view_key, this.renderer, new ElmcityCacheDependency(base_key), null);
                        string jcontent = cr.RenderDynamicViewWithCaching(context, view_key, this.renderer, this.view, this.count, this.from, this.to, this.source, null);
                        if (this.jsonp != null)
                            jcontent = this.jsonp + "(" + jcontent + ")";
                        new ContentResult
                        {
                            ContentEncoding = UTF8,
                            ContentType = "application/json",
                            Content = jcontent
                        }.ExecuteResult(context);
                        break;

                    case "text":
                        this.renderer = new CalendarRenderer.ViewRenderer(cr.RenderText);
                        MaybeCacheView(view_key, this.renderer, new ElmcityCacheDependency(base_key), null);
                        string tcontent = cr.RenderDynamicViewWithCaching(context, view_key, this.renderer, this.view, this.count, this.from, this.to, this.source, null);
                        new ContentResult
                        {
                            ContentEncoding = UTF8,
                            ContentType = "text/plain",
                            Content = tcontent
                        }.ExecuteResult(context);
                        break;

                    case "csv":
                        this.renderer = new CalendarRenderer.ViewRenderer(cr.RenderCsv);
                        MaybeCacheView(view_key, this.renderer, new ElmcityCacheDependency(base_key), null);
                        string csv = cr.RenderDynamicViewWithCaching(context, view_key, this.renderer, this.view, this.count, this.from, this.to, this.source, null);
                        new ContentResult
                        {
                            ContentEncoding = UTF8,
                            ContentType = "text/plain",
                            Content = csv
                        }.ExecuteResult(context);
                        break;

                    case "tags_json":
                        string tjcontent = cr.RenderTagCloudAsJson();
                        if (this.jsonp != null)
                            tjcontent = this.jsonp + "(" + tjcontent + ")";
                        new ContentResult
                        {
                            ContentEncoding = UTF8,
                            ContentType = "application/json",
                            Content = tjcontent,
                        }.ExecuteResult(context);
                        break;

                    case "tags_html":
                        string thcontent = cr.RenderTagCloudAsHtml();
                        new ContentResult
                        {
                            ContentEncoding = UTF8,
                            ContentType = "text/html",
                            Content = thcontent,
                        }.ExecuteResult(context);
                        break;

                    case "stats":
                        blob_uri = BlobStorage.MakeAzureBlobUri(this.id, this.id + ".stats.html",false);
                        //this.response_bytes = (byte[])CacheUtils.RetrieveBlobAndEtagFromServerCacheOrUri(this.cr.cache, blob_uri)["response_body"];
                        this.response_bytes = HttpUtils.FetchUrl(blob_uri).bytes;
                        new ContentResult
                        {
                            ContentEncoding = UTF8,
                            ContentType = "text/html",
                            Content = Encoding.UTF8.GetString(this.response_bytes),
                        }.ExecuteResult(context);
                        break;

                    case "ics":
                        this.renderer = new CalendarRenderer.ViewRenderer(cr.RenderIcs);
                        MaybeCacheView(view_key, this.renderer, new ElmcityCacheDependency(base_key), null);
                        string ics_text = cr.RenderDynamicViewWithCaching(context, view_key, this.renderer, this.view, this.count, this.from, this.to, this.source, null);
                        new ContentResult
                        {
                            ContentType = "text/calendar",
                            Content = ics_text,
                            ContentEncoding = UTF8
                        }.ExecuteResult(context);
                        break;

                    case "jswidget":
                        new ContentResult
                        {
                            ContentType = "text/html",
                            Content = cr.RenderJsWidget(),
                            ContentEncoding = UTF8
                        }.ExecuteResult(context);
                        break;

                    case "today_as_html":
                        new ContentResult
                        {
                            ContentType = "text/html",
                            Content = cr.RenderTodayAsHtml(),
                            ContentEncoding = UTF8
                        }.ExecuteResult(context);
                        break;
                }
            }