Added support for GIST code presenting.

This commit is contained in:
David Russell 2017-09-04 10:17:47 +07:00
parent 4a31f71c3f
commit 748f8c5733
13 changed files with 225 additions and 76 deletions

View File

@ -2,17 +2,17 @@
* MIT License
*
* Copyright (c) 2016 David Russell
*
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@ -39,6 +39,7 @@ public class GRS {
private final String apiToken;
private final String apiTokenHeader;
private final String rawBase;
private final String gistBase;
private final String branchDelim;
private final boolean isDefault;
@ -49,6 +50,7 @@ public class GRS {
String apiToken,
String apiTokenHeader,
String rawBase,
String gistBase,
String branchDelim,
boolean isDefault) {
@ -59,6 +61,7 @@ public class GRS {
this.apiToken = apiToken;
this.apiTokenHeader = apiTokenHeader;
this.rawBase = rawBase;
this.gistBase = gistBase;
this.branchDelim = branchDelim;
this.isDefault = isDefault;
}
@ -72,13 +75,14 @@ public class GRS {
String apiToken = grsCfg.get("apitoken");
String apiTokenHeader = grsCfg.get("apitokenheader");
String rawBase = grsCfg.get("rawbase");
String gistBase = grsCfg.get("gistbase");
String branchDelim = grsCfg.get("branchdelim");
boolean isDefault = Boolean.parseBoolean(grsCfg.get("default"));
if(name != null && type != null && site != null &&
apiBase != null && rawBase != null) {
return new GRS(name, type, site, apiBase, apiToken,
apiTokenHeader, rawBase, branchDelim, isDefault);
apiTokenHeader, rawBase, gistBase, branchDelim, isDefault);
} else {
return null;
}
@ -91,6 +95,7 @@ public class GRS {
public String getApiToken() { return apiToken; }
public String getApiTokenHeader() { return apiTokenHeader; }
public String getRawBase() { return rawBase; }
public String getGistBase() { return gistBase; }
public String compoundBranch(String branch) {
if(branch != null && branchDelim != null) {
return branch.replaceAll(branchDelim, COMPOUNDED_BRANCH);

View File

@ -2,17 +2,17 @@
* MIT License
*
* Copyright (c) 2016 David Russell
*
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@ -107,7 +107,7 @@ public abstract class GRSService {
}
/*
* Return Raw API path for /user/repo/branch/filename with
* Return Raw API path for /user/repo/branch/filename with
* optional query param used to bypass GRS API caching.
*/
public String raw(PitchParams pp,
@ -127,6 +127,20 @@ public abstract class GRSService {
*/
public abstract String repo(PitchParams pp);
/*
* Return GIST API path for code snippet identified by gid.
*/
public String gist(PitchParams pp, String gid) {
return gist(pp, gid, null);
}
/*
* Return GIST API path for code snippet identified by
* file (fid) on code snippet (gid).
*/
public abstract String gist(PitchParams pp, String gid, String fid);
protected static final String SLASH = "/";
protected static final String NOT_FOUND = "#";
}

View File

@ -2,17 +2,17 @@
* MIT License
*
* Copyright (c) 2016 David Russell
*
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@ -72,6 +72,10 @@ public class BitBucket extends GRSService {
.toString();
}
public String gist(PitchParams pp, String gid, String fid) {
return NOT_FOUND;
}
public static final String TYPE = "bitbucket";
private static final String BITBUCKET_REPO_API = "repositories/";
private static final String BITBUCKET_RAW = "/raw/";

View File

@ -2,17 +2,17 @@
* MIT License
*
* Copyright (c) 2016 David Russell
*
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@ -54,6 +54,10 @@ public class GitBucket extends GitHub {
.toString();
}
public String gist(PitchParams pp, String gid, String fid) {
return NOT_FOUND;
}
public static final String TYPE = "gitbucket";
private static final String GITBUCKET_REPOS_API = "repos/";
private static final String GITBUCKET_RAW_API = "raw/";

View File

@ -2,17 +2,17 @@
* MIT License
*
* Copyright (c) 2016 David Russell
*
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@ -72,6 +72,23 @@ public class GitHub extends GRSService {
.toString();
}
public String gist(PitchParams pp, String gid, String fid) {
GRS grs = grsManager.get(pp);
StringBuffer gistLink = new StringBuffer(grs.getGistBase())
.append(gid)
.append(SLASH)
.append(GITHUB_GIST_RAW);
if(fid != null) {
gistLink = gistLink.append(SLASH).append(fid);
}
return gistLink.toString();
}
public static final String TYPE = "github";
private static final String GITHUB_REPO_API = "repos/";
private static final String GITHUB_GIST_RAW = "raw";
}

View File

@ -2,17 +2,17 @@
* MIT License
*
* Copyright (c) 2016 David Russell
*
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@ -82,6 +82,10 @@ public class GitLab extends GRSService {
return pid;
}
public String gist(PitchParams pp, String gid, String fid) {
return NOT_FOUND;
}
public static final String TYPE = "gitlab";
private static final String GITLAB_PROJECTS_API = "projects/";
private static final String GITLAB_RAW = "/raw/";

View File

@ -2,17 +2,17 @@
* MIT License
*
* Copyright (c) 2016 David Russell
*
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@ -72,6 +72,10 @@ public class Gitea extends GRSService {
.toString();
}
public String gist(PitchParams pp, String gid, String fid) {
return NOT_FOUND;
}
public static final String TYPE = "gitea";
private static final String GITEA_REPO_API = "repos/";
private static final String GITEA_RAW = "/raw/";

View File

@ -2,17 +2,17 @@
* MIT License
*
* Copyright (c) 2016 David Russell
*
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@ -72,6 +72,10 @@ public class Gogs extends GRSService {
.toString();
}
public String gist(PitchParams pp, String gid, String fid) {
return NOT_FOUND;
}
public static final String TYPE = "gogs";
private static final String GOGS_REPO_API = "repos/";
private static final String GOGS_RAW = "/raw/";

View File

@ -707,6 +707,7 @@ public class MarkdownModel implements Markdown {
public static final String DELIM_QUERY_CODE = "code";
public static final String DELIM_QUERY_LANG = "lang";
public static final String DELIM_QUERY_SIZE = "size";
public static final String DELIM_QUERY_FILE = "file";
public static final String MD_LINK_OPEN = "![";
public static final String MD_ANCHOR_OPEN = "[";

View File

@ -79,26 +79,13 @@ public class CodeService {
String code = diskService.asText(pp, SOURCE_CODE);
return buildCodeBlock(mdm.extractCodeDelim(md), code, langHint);
} else {
return buildCodeBlockError(mdm.extractCodeDelim(md),
extractPath(md, mdm));
return buildCodeBlockError(mdm.extractCodeDelim(md), codePath);
}
} catch (Exception gex) {}
return codeBlock;
}
private String extractPath(String md, MarkdownModel mdm) {
String path = null;
try {
String delim = mdm.extractCodeDelim(md);
path = md.substring(delim.length());
} catch (Exception pex) {
log.warn("extractPath: ex={}", pex);
}
return path;
}
private String buildCodeBlock(String delim, String code, String langHint) {
return new StringBuffer(delim)
.append(MarkdownModel.MD_SPACER)
@ -129,7 +116,5 @@ public class CodeService {
"### Code Block Delimiter";
private static final String SOURCE_CODE_NOT_FOUND =
"### Source File Not Found";
private static final String LANG_HINT_OPTION = "&lang=";
private static final String NO_LANG_HINT = "";
}

View File

@ -2,17 +2,17 @@
* MIT License
*
* Copyright (c) 2016 David Russell
*
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE

View File

@ -24,11 +24,16 @@
package com.gitpitch.services;
import com.gitpitch.models.MarkdownModel;
import com.gitpitch.services.DiskService;
import com.gitpitch.services.ImageService;
import com.gitpitch.git.GRS;
import com.gitpitch.git.GRSService;
import com.gitpitch.git.GRSManager;
import com.gitpitch.utils.PitchParams;
import com.gitpitch.utils.DelimParams;
import com.gitpitch.utils.YAMLOptions;
import java.util.*;
import java.nio.file.*;
import javax.inject.*;
import play.Logger;
import play.Logger.ALogger;
@ -41,27 +46,17 @@ public class GISTService {
private final Logger.ALogger log = Logger.of(this.getClass());
/*
* Offline GIST Frags.
*/
private static final String OFFLINE_GIST = "#### GIST Slide Disabled";
private static final String OFFLINE_NOTICE = "#### [ GitPitch Offline ]";
/*
* GIST IFrame Frags (scrolling permitted).
*/
private static final String GIST_DIV_OPEN = "<div data-gist=\"true\" ";
private static final String GIST_DIV_CLASS = "class=\"stretch\">";
private static final String GIST_IFR_OPEN =
"<iframe width=\"100%\" height=\"100%\" src=\"";
private static final String GIST_IFR_CLSE =
"\" frameborder=\"0\" scrolling=\"yes\" allowfullscreen></iframe>";
private static final String GIST_DIV_CLSE = "</div>";
private final GRSManager grsManager;
private final DiskService diskService;
private final ImageService imageService;
@Inject
public GISTService(ImageService imageService) {
public GISTService(GRSManager grsManager,
DiskService diskService,
ImageService imageService) {
this.grsManager = grsManager;
this.diskService = diskService;
this.imageService = imageService;
}
@ -71,6 +66,101 @@ public class GISTService {
YAMLOptions yOpts,
MarkdownModel mdm) {
try {
String gid = dp.get(MarkdownModel.DELIM_QUERY_GIST);
if(backCompat(gid)) {
return buildBackCompat(md, dp, pp, yOpts, mdm);
} else {
String fileHint = dp.get(MarkdownModel.DELIM_QUERY_FILE);
String langHint = dp.get(MarkdownModel.DELIM_QUERY_LANG);
String extractedDelim = mdm.extractGISTDelim(md);
GRS grs = grsManager.get(pp);
GRSService grsService = grsManager.getService(grs);
Path branchPath = diskService.ensure(pp);
String gistLink = grsService.gist(pp, gid, fileHint);
log.debug("build: generated gistLink={}", gistLink);
int downStatus =
diskService.download(pp, branchPath, gistLink,
GIST_CODE, grs.getHeaders());
if(downStatus == 0) {
String code = diskService.asText(pp, GIST_CODE);
return buildCodeBlock(extractedDelim, code, langHint);
} else {
return buildCodeBlockError(extractedDelim, gid, fileHint);
}
}
} catch (Exception gex) {
/*
* Invalid GIST syntax, return clean slide delimiter.
*/
return mdm.extractGISTDelim(md);
}
}
public String offline() {
return new StringBuffer(OFFLINE_GIST).append(MarkdownModel.MD_SPACER)
.append(OFFLINE_NOTICE)
.toString();
}
private String buildCodeBlock(String delim, String code, String langHint) {
return new StringBuffer(delim)
.append(MarkdownModel.MD_SPACER)
.append(MarkdownModel.MD_CODE_BLOCK_OPEN)
.append(langHint)
.append(MarkdownModel.MD_SPACER)
.append(code)
.append(MarkdownModel.MD_SPACER)
.append(MarkdownModel.MD_CODE_BLOCK_CLOSE)
.append(MarkdownModel.MD_SPACER)
.toString();
}
private String buildCodeBlockError(String delim,
String codePath,
String fileHint) {
String filePath = fileHint != null ? fileHint : GIST_DEFAULT_FILE;
filePath = "[ " + filePath + " ]";
return new StringBuffer(delim)
.append(MarkdownModel.MD_SPACER)
.append(GIST_DELIMITER)
.append(MarkdownModel.MD_SPACER)
.append(codePath)
.append(MarkdownModel.MD_SPACER)
.append(filePath)
.append(MarkdownModel.MD_SPACER)
.append(GIST_NOT_FOUND)
.append(MarkdownModel.MD_SPACER)
.toString();
}
private boolean backCompat(String gid) {
return !gid.contains(GIST_ID_DELIM);
}
/*
* Provide backward compatible support for embedding
* GIST within an iframe. This approach has been superceded
* by injecting GIST source into code-blocks.
*/
private String buildBackCompat(String md,
DelimParams dp,
PitchParams pp,
YAMLOptions yOpts,
MarkdownModel mdm) {
try {
String gid = dp.get(MarkdownModel.DELIM_QUERY_GIST);
@ -116,10 +206,26 @@ public class GISTService {
}
public String offline() {
return new StringBuffer(OFFLINE_GIST).append(MarkdownModel.MD_SPACER)
.append(OFFLINE_NOTICE)
.toString();
}
private static final String GIST_CODE = "PITCHME.gist";
private static final String GIST_DELIMITER = "### GIST Delimiter";
private static final String GIST_NOT_FOUND = "### GIST Not Found";
private static final String GIST_ID_DELIM = "/";
private static final String GIST_DEFAULT_FILE = "Default File";
/*
* BackCompat GIST IFrame Frags (scrolling permitted).
*/
private static final String GIST_DIV_OPEN = "<div data-gist=\"true\" ";
private static final String GIST_DIV_CLASS = "class=\"stretch\">";
private static final String GIST_IFR_OPEN =
"<iframe width=\"100%\" height=\"100%\" src=\"";
private static final String GIST_IFR_CLSE =
"\" frameborder=\"0\" scrolling=\"yes\" allowfullscreen></iframe>";
private static final String GIST_DIV_CLSE = "</div>";
/*
* BackCompat Offline GIST Frags.
*/
private static final String OFFLINE_GIST = "#### GIST Slide Disabled";
private static final String OFFLINE_NOTICE = "#### [ GitPitch Offline ]";
}

View File

@ -68,9 +68,9 @@ play.modules {
# https://www.playframework.com/documentation/latest/IDE
# ~~~~~
# Depending on your IDE, you can add a hyperlink for errors that will jump you
# directly to the code location in the IDE in dev mode. The following line makes
# use of the IntelliJ IDEA REST interface:
#play.editor=http://localhost:63342/api/file/?file=%s&line=%s
# directly to the code location in the IDE in dev mode. The following line makes
# use of the IntelliJ IDEA REST interface:
#play.editor=http://localhost:63342/api/file/?file=%s&line=%s
## Internationalisation
# https://www.playframework.com/documentation/latest/JavaI18N
@ -432,7 +432,8 @@ gitpitch {
// apitoken = "token your-github-access-token-here"
apitokenheader = "Authorization"
rawbase = "https://raw.githubusercontent.com/"
branchdelim = "~"
gistbase = "https://gist.githubusercontent.com/"
branchdelim = "~"
default = "true"
}
{
@ -443,7 +444,7 @@ gitpitch {
// apitoken = "your-gitlab-access-token-here"
apitokenheader = "PRIVATE-TOKEN"
rawbase = "https://gitlab.com/"
branchdelim = "~"
branchdelim = "~"
default = "false"
}
{
@ -454,7 +455,7 @@ gitpitch {
// apitoken = "your-bitbucket-access-token-here"
apitokenheader = "Authorization"
rawbase = "https://bitbucket.org/"
branchdelim = "~"
branchdelim = "~"
default = "false"
}
{
@ -466,7 +467,7 @@ gitpitch {
// apitoken = "token your-gitea-app-token-here"
apitokenheader = "Authorization"
rawbase = "http://localhost:3000/"
branchdelim = "~"
branchdelim = "~"
default = "false"
}
{
@ -478,7 +479,7 @@ gitpitch {
apitokenheader = "Authorization"
rawbase = "http://localhost:3000/"
rawbase = "https://try.gogs.io/"
branchdelim = "~"
branchdelim = "~"
default = "false"
}
{
@ -489,7 +490,7 @@ gitpitch {
// apitoken = "token your-gitbucket-access-token-here"
apitokenheader = "Authorization"
rawbase = "http://localhost:8080/"
branchdelim = "~"
branchdelim = "~"
default = "false"
}
]