public async Task <object> Any(CreateNotebook request) { if (string.IsNullOrEmpty(request.Lang)) { throw new ArgumentNullException(nameof(request.Lang)); } if (string.IsNullOrEmpty(request.Slug)) { throw new ArgumentNullException(nameof(request.Slug)); } var baseUrl = request.Slug; if (baseUrl.IndexOf("://", StringComparison.Ordinal) == -1) { if (baseUrl.StartsWith("http.") || baseUrl.StartsWith("https.")) { baseUrl = baseUrl.LeftPart('.') + "://" + baseUrl.RightPart('.'); } else { baseUrl = "https://" + baseUrl; } } var requestDto = request.Request; var lang = LangInfoUtils.AssertLangInfo(request.Lang); var notebook = await Sites.CreateNotebookAsync(lang, baseUrl, request.IncludeTypes, requestDto, request.Args); var suffix = requestDto ?? (request.IncludeTypes != null ? request.IncludeTypes.Replace("{", "").Replace("}", "").Replace(".", "").Replace("*", "").Replace(",", "-") : ""); var fileName = request.Name ?? baseUrl.RightPart("://").LeftPart('/').SafeVarRef() + (string.IsNullOrEmpty(suffix) ? "" : "-" + suffix); if (!fileName.EndsWith(".ipynb")) { fileName += ".ipynb"; } var json = notebook.ToJson().IndentJson(); return(new HttpResult(json, "application/x-ipynb+json") { Headers = { [HttpHeaders.ContentDisposition] = $"attachment; {HttpExt.GetDispositionFileName(fileName)}; size={json.Length}; modification-date={DateTime.UtcNow.ToString("R").Replace(",", "")}" } }); }
public async Task <object> Get(GistRef request) { if (string.IsNullOrEmpty(request.Slug)) { throw new ArgumentNullException(nameof(request.Slug)); } if (string.IsNullOrEmpty(request.Lang)) { throw new ArgumentNullException(nameof(request.Lang)); } var lang = LangInfoUtils.AssertLangInfo(request.Lang); var includeTypes = string.IsNullOrEmpty(request.IncludeTypes) ? null : request.IncludeTypes; var requestDto = includeTypes; Dictionary <string, string> args = null; if (includeTypes != null && includeTypes.IndexOf('(') >= 0) { var kvps = includeTypes.RightPart('('); kvps = '{' + kvps.Substring(0, kvps.Length - 1) + '}'; args = kvps.FromJsv <Dictionary <string, string> >(); includeTypes = includeTypes.LeftPart('('); requestDto = includeTypes.LastRightPart(','); //If any includeTypes were given (e.g. tag) use that instead of just Request DTO: if (includeTypes.IndexOf(',') >= 0) { includeTypes = includeTypes.LastLeftPart(','); //Replace URL-friendly brackets with braces includeTypes = includeTypes.Replace('[', '{').Replace(']', '}'); //Treat '*' as All DTOs, i.e. don't limit included DTO Types if (includeTypes == "*") { includeTypes = null; } } else if (!includeTypes.EndsWith(".*")) { includeTypes += ".*"; } } var baseUrl = request.Slug; if (baseUrl.IndexOf("://", StringComparison.Ordinal) == -1) { if (baseUrl.StartsWith("http.") || baseUrl.StartsWith("https.")) { baseUrl = baseUrl.LeftPart('.') + "://" + baseUrl.RightPart('.'); } else { baseUrl = "https://" + baseUrl; } } var key = $"{nameof(GistRef)}:{baseUrl}:{lang.Code}:{request.IncludeTypes??"*"}.gist"; if (request.NoCache == true) { await CacheAsync.RemoveAsync(key); } var gist = await CacheAsync.GetOrCreateAsync(key, TimeSpan.FromMinutes(10), async() => { var site = await Sites.GetSiteAsync(request.Slug); var langInfo = await site.Languages.GetLanguageInfoAsync(request.Lang); var baseUrlTitle = baseUrl.RightPart("://").LeftPart("/"); if (includeTypes != null) { baseUrlTitle += $" {requestDto}"; langInfo = await langInfo.ForRequestAsync(includeTypes); } var langTypesContent = langInfo.Content; var files = new Dictionary <string, GistFile>(); var description = $"{baseUrlTitle} {lang.Name} API"; var meta = site.Metadata.Api; var requestOp = meta.Operations.FirstOrDefault(x => x.Request.Name == requestDto); var authTemplate = requestOp?.RequiresAuth == true ? lang.RequiresAuthTemplate : ""; var types = new List <string> { requestDto ?? "MyRequest" }; if (requestOp != null && args != null) { var props = requestOp.Request.GetFlattenedProperties(meta); foreach (var entry in args) { var prop = props.FirstOrDefault(x => string.Equals(x.Name, entry.Key, StringComparison.OrdinalIgnoreCase)); var propType = prop?.Type != null ? meta.FindType(prop.Type, prop.Namespace) : null; if (propType != null) { types.Add(propType.Name); } } } lang.Files.Each((string k, string v) => { var content = v .Replace("{BASE_URL}", baseUrl) .Replace("{REQUEST}", requestDto ?? "MyRequest") .Replace("{RESPONSE}", lang.GetResponse(requestOp)) .Replace("{TYPES}", string.Join(", ", types)) .Replace("{API_COMMENT}", request.IncludeTypes != null ? "" : lang.LineComment) .Replace("{REQUIRES_AUTH}", authTemplate) .Replace("{DESCRIPTION}", description) .Replace("{INSPECT_VARS}", requestDto != null ? lang.InspectVarsResponse : null); var textCase = site.Metadata.App.JsTextCase != null ? (TextCase)Enum.Parse(typeof(TextCase), site.Metadata.App.JsTextCase, ignoreCase: true) : TextCase.CamelCase; using var jsScope = JsConfig.With(new Config { TextCase = textCase }); { content = args != null ? content.Replace("{REQUEST_BODY}", lang.RequestBody(requestDto, args, meta)) : content.Replace("{REQUEST_BODY}", ""); } var file = new GistFile { Filename = k, Content = content, Type = MimeTypes.PlainText, Raw_Url = new GistRefFile { Slug = request.Slug, Lang = lang.Code, File = k }.ToAbsoluteUri(Request), }; file.Size = file.Content.Length; files[k] = file; }); var langFiles = VirtualFiles.GetDirectory($"files/{lang.Code}"); if (langFiles != null) { foreach (var file in langFiles.GetAllFiles()) { var content = file.ReadAllText(); lang.Files[file.Name] = content; } } var dtoFileName = $"{lang.DtosPathPrefix}dtos.{lang.Ext}"; files[dtoFileName] = new GistFile { Filename = dtoFileName, Content = langTypesContent, Size = langTypesContent.Length, Type = MimeTypes.PlainText, Raw_Url = langInfo.Url, }; var resolvedUrl = Request.IsSecureConnection ? "https://" + Request.AbsoluteUri.RightPart("://") : Request.AbsoluteUri; var to = new GithubGist { Description = description, Created_At = DateTime.UtcNow, Files = files, Public = true, Url = resolvedUrl, Owner = new GithubUser { Id = 76883648, Login = "******", Avatar_Url = "https://avatars2.githubusercontent.com/u/76883648?v=4", Url = "https://api.github.com/users/gistcafe", Html_Url = "https://github.com/gistcafe", Type = "User" } }; var hashCode = new HashCode(); hashCode.Add(to.Description); files.Each(entry => { hashCode.Add(entry.Key); hashCode.Add(entry.Value); }); to.Id = resolvedUrl; return(to); });