In unserer Firma haben wir das lokale PukiWiki betrieben, bevor ich in die Firma eingetreten bin, aber dieses Mal bin ich zu esa.io \ (⁰⊖⁰) / gewechselt. Der Hauptgrund ist, dass ich zu esa gekommen bin, aber ich war auch sehr unzufrieden mit dem On-Premise-Management-Mendokuse und dem Wunsch, Markdown anstelle der Wiki-Notation zu verwenden. Dieser Artikel ist wie ein Arbeitsprotokoll, das die in PukiWiki gespeicherten Artikel schnell auf esa.io migriert. Ich schäme mich, das Migrationsprogramm anzukündigen. Wenn Sie also dasselbe tun möchten, beziehen Sie sich bitte darauf.
https://esa.io/ Einfach ausgedrückt ist es ein Wiki-ähnliches Tool zum Informationsaustausch. Ich mag die Tatsache, dass die Hürden für den Informationsaustausch sehr gering sind und die verschiedenen Funktionen "für juckende Stellen zugänglich", die das Bearbeiten und Verwalten von Artikeln sehr einfach machen. Als ich es tatsächlich in der kostenlosen Testversion verwendet habe, war es eine Serie von "Oh!".
Die Artikel-TXT-Datei wird im Ordner "wiki" auf dem PukiWiki-Server gespeichert. Kopieren Sie diese an den angegebenen Ort. Führen Sie dann das unten stehende Migrationsprogramm aus und los geht's. Das Migrationsprogramm wurde mit Java erstellt.
Holen Sie sich im Voraus ein Zugriffstoken, da es die Web-API von esa verwendet. Sie können es unter "Anwendungen" in den Teameinstellungen im Teil "Persönliche Zugriffstoken" abrufen.
Es ist ein Wegwerfprogramm, also habe ich es mit großer Dynamik gemacht. Ich habe keine Anstrengungen unternommen, um das Lesen zu vereinfachen, daher denke ich, dass es schwierig ist, wenn Sie ein wenig damit spielen möchten. .. .. Wenn Sie etwas wie "Ich weiß nicht, was es hier bedeutet" haben, fragen Sie bitte in den Kommentaren. Bitte ändern Sie den mit ★ gekennzeichneten Teil im Programm entsprechend Ihrer Umgebung, bevor Sie ihn ausführen. Die esa-API ist eine Spezifikation, die in 15 Minuten nur bis zu 75 Mal aufgerufen werden kann. Wenn dieses Limit jedoch überschritten wird, versuche ich zu warten, bis ich sie erneut aufrufen kann.
public class WikiMigrationToEsa
{
private static Client apiClient = ClientBuilder.newClient();
private static MutableList<Pair<Integer, Twin<String>>> documentList = Lists.mutable.empty();
//★ Geben Sie den Ordner an, in dem sich die Wiki-Artikeldateien befinden
private static final String wikiFilePath = "C:\\Users\\hoge\\wiki";
//★esa.io Zugriffstoken
private static final String authorizationKey = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
//★ Teamname
private static final String teamName = "hogehoge";
public static void main(String[] args)
{
//Esa-Wiki-Artikeldateien nacheinander.Post an io
try (final Stream<Path> pathStream = Files.walk(Paths.get(wikiFilePath)))
{
pathStream
.map(path -> path.toFile())
.filter(file -> !file.isDirectory())
.filter(file -> file.getName().toLowerCase().endsWith(".txt"))
.forEach(file -> postWikiFile(file.toPath()));
} catch (final IOException e) {
e.printStackTrace();
return;
}
//Esa-Links im Wiki für gepostete Artikel.Update auf io-Format
patchInnerLink();
}
public static void postWikiFile(Path wikiItemFile)
{
EsaPostItemDto content = new EsaPostItemDto();
content.post = new EsaPostBodyDto();
StringBuilder bodyText = new StringBuilder();
//Titel
String wikiFileName = StringUtils.substringBefore(wikiItemFile.toFile().getName(), ".");
byte[] bytes;
try
{
bytes = Hex.decodeHex(wikiFileName);
} catch (DecoderException e)
{
e.printStackTrace();
return;
}
String itemName = "";
try
{
itemName = new String(bytes, "EUC-JP");
} catch (UnsupportedEncodingException e)
{
e.printStackTrace();
return;
}
//Es wurde ein Problem behoben, bei dem Schrägstriche mit halber Breite in Titeln als Kategorien erkannt wurden
itemName = RegExUtils.replaceAll(itemName, "/", "/");
try (FileInputStream fileInputStream = new FileInputStream(wikiItemFile.toFile());
InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, "EUC-JP");
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
)
{
String lineTmp;
int lineNo = 0;
boolean isCodeBlock = false;
boolean isTable = false;
while ((lineTmp = bufferedReader.readLine()) != null) {
lineNo++;
byte[] lineBytes = lineTmp.getBytes();
String line = new String(lineBytes, "UTF-8");
if(lineNo == 1)
{
if(StringUtils.startsWithIgnoreCase(line, "#freeze"))
{
return;
}
}
if(StringUtils.startsWithIgnoreCase(line, "#ref") || StringUtils.startsWithIgnoreCase(line, "&ref"))
{
String fileName = StringUtils.substringBetween(line, "(", ")");
fileName = RegExUtils.replaceAll(fileName, "(^[^\\.]+\\.[^,]+),.+", "$1");
line = "![" + fileName + "](http://hoge/fuga/index.php?plugin=attach&refer="+URLEncoder.encode(itemName,"EUC-JP")+"&openfile="+URLEncoder.encode(fileName,"EUC-JP")+")";
}
if(!isCodeBlock && StringUtils.startsWith(line, " "))
{
isCodeBlock = true;
bodyText.append("```");
bodyText.append(System.getProperty("line.separator"));
}
if(isCodeBlock)
{
if(StringUtils.startsWith(line, " "))
{
bodyText.append(line);
bodyText.append(System.getProperty("line.separator"));
continue;
}
else
{
bodyText.append("```");
bodyText.append(System.getProperty("line.separator"));
isCodeBlock = false;
}
}
if(!isTable && StringUtils.startsWith(line, "|"))
{
isTable = true;
int columnCount = StringUtils.countMatches(line, "|");
bodyText.append(System.getProperty("line.separator"));
if(StringUtils.endsWith(line, "h"))
{
bodyText.append(StringUtils.substringBeforeLast(line, "h"));
bodyText.append(System.getProperty("line.separator"));
bodyText.append(StringUtils.repeat("|", "-----", columnCount));
bodyText.append(System.getProperty("line.separator"));
continue;
}
else
{
bodyText.append(StringUtils.repeat("|", "header", columnCount));
bodyText.append(System.getProperty("line.separator"));
bodyText.append(StringUtils.repeat("|", "-----", columnCount));
bodyText.append(System.getProperty("line.separator"));
bodyText.append(line);
bodyText.append(System.getProperty("line.separator"));
continue;
}
}
if(isTable)
{
if(StringUtils.startsWith(line, "|"))
{
bodyText.append(line);
bodyText.append(System.getProperty("line.separator"));
continue;
}
else
{
bodyText.append(System.getProperty("line.separator"));
isTable = false;
}
}
line = RegExUtils.replaceAll(line, "\\[#[0-9a-z]+\\]$", "");
line = RegExUtils.replaceAll(line, "^\\*\\*\\*", "### ");
line = RegExUtils.replaceAll(line, "^\\*\\*", "## ");
line = RegExUtils.replaceAll(line, "^\\*", "# ");
line = RegExUtils.replaceAll(line, "^---", " - ");
line = RegExUtils.replaceAll(line, "^--", " - ");
line = RegExUtils.replaceAll(line, "^-", "- ");
line = RegExUtils.replaceAll(line, "^\\+\\+\\+", " 1\\. ");
line = RegExUtils.replaceAll(line, "^\\+\\+", " 1\\. ");
line = RegExUtils.replaceAll(line, "^\\+", "1\\. ");
line = RegExUtils.replaceAll(line, "^\\+", "1\\. ");
line = RegExUtils.replaceAll(line, "''", "\\*\\*");
line = RegExUtils.replaceAll(line, "%%", "~~");
line = RegExUtils.replaceAll(line, "\\[\\[([^\\]^:^>]+)[:|>]([^:^/^\\]]+://[^\\]]+)\\]\\]","\\[$1\\]\\($2\\)");
bodyText.append(line);
bodyText.append(System.getProperty("line.separator"));
}
}
catch (IOException e)
{
e.printStackTrace();
return;
}
content.post.body_md = bodyText.toString();
content.post.name = itemName;
content.post.wip = false;
content.post.message = "Migration aus dem Wiki";
content.post.user = "esa_bot";
Response apiResponse = apiClient.target("https://api.esa.io/v1/teams/" + teamName + "/posts")
.request()
.header("Authorization", "Bearer " + authorizationKey)
.header("Content-Type", "application/json")
.post(Entity.entity(content, MediaType.APPLICATION_JSON));
System.out.println(apiResponse.getStatus());
JSONObject postResponseBody = new JSONObject(apiResponse.readEntity(String.class));
System.out.println("number : " + postResponseBody.getLong("number"));
documentList.add(
Tuples.pair(
postResponseBody.getInt("number")
,Tuples.twin(
itemName
, bodyText.toString()
)
)
);
waitAPILimit(apiResponse);
}
private static void patchInnerLink()
{
Pattern linkPattern = Pattern.compile("(\\[\\[[^\\]^>]+>[^\\]^:^/]+\\]\\]|\\[\\[[^\\]^>]+\\]\\])");
documentList.each(post -> {
Twin<String> postItem = post.getTwo();
Matcher postMatcher = linkPattern.matcher(postItem.getTwo());
StringBuffer sb = new StringBuffer();
while(postMatcher.find())
{
String linkString = postMatcher.group();
//linkString kann einen Alias haben oder nicht, also im Fall eines Alias>Nachher herausnehmen
if(StringUtils.contains(linkString, ">"))
{
linkString = StringUtils.substringAfter(linkString, ">");
}
final String linkItemName = RegExUtils.removeAll(linkString, "\\[|\\]");
Pair<Integer, Twin<String>> linkedItem = documentList.select(post2 -> StringUtils.equals(linkItemName, post2.getTwo().getOne())).getFirst();
if(linkedItem != null)
{
postMatcher.appendReplacement(sb, "[#" + linkedItem.getOne() + ": " + linkItemName + "](/posts/"+linkedItem.getOne()+")");
}
}
postMatcher.appendTail(sb);
EsaPostItemDto content = new EsaPostItemDto();
content.post = new EsaPostBodyDto();
content.post.body_md = sb.toString();
content.post.name = postItem.getOne();
content.post.wip = false;
content.post.message = "Interne Link-Aktualisierung";
content.post.updated_by = "esa_bot";
Response patchResponse = apiClient
.property(HttpUrlConnectorProvider.SET_METHOD_WORKAROUND, true)
.target("https://api.esa.io/v1/teams/" + teamName + "/posts/" + post.getOne())
.request()
.header("Authorization", "Bearer " + authorizationKey)
.header("Content-Type", "application/json")
.method("PATCH", Entity.entity(content, MediaType.APPLICATION_JSON))
;
System.out.println(patchResponse.getStatus());
waitAPILimit(patchResponse);
});
}
private static void waitAPILimit(Response apiResponse)
{
String remaining = apiResponse.getHeaderString("X-RateLimit-Remaining");
System.out.println("X-RateLimit-Remaining : " + remaining);
if(StringUtils.equals(remaining, "0"))
{
System.out.println("X-Rate-Limit-Reset : " + apiResponse.getHeaderString("X-RateLimit-Reset"));
OffsetDateTime reset = OffsetDateTime.ofInstant(Instant.ofEpochSecond(Long.valueOf(apiResponse.getHeaderString("X-RateLimit-Reset"))), ZoneId.systemDefault());
System.out.println("X-Rate-Limit-Reset : " + reset.format(DateTimeFormatter.ISO_DATE_TIME));
//Fügen Sie 1 Minute hinzu, da die Uhr möglicherweise nicht korrekt ist
reset = reset.plusMinutes(1);
while(reset.isAfter(OffsetDateTime.now(ZoneId.systemDefault())))
{
try
{
TimeUnit.MINUTES.sleep(1);
} catch (InterruptedException e)
{
e.printStackTrace();
System.exit(0);
}
}
}
}
}
EsaPostBodyDto.java
public class EsaPostBodyDto
{
public String name;
public String body_md;
public List<String> tags;
public String category;
public boolean wip;
public String message;
public String user;
public String updated_by;
}
EsaPostItemDto.java
public class EsaPostItemDto
{
public EsaPostBodyDto post;
}
pom.xml
<dependencies>
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.3</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<!-- servlet-api -->
<!-- https://mvnrepository.com/artifact/javax.servlet/servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<!-- Apache Commons Lang -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.8</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-codec/commons-codec -->
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.11</version>
</dependency>
<!-- jersey -->
<!-- https://mvnrepository.com/artifact/org.glassfish.jersey.media/jersey-media-json-jackson -->
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.25</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>2.25</version>
</dependency>
<!-- eclipse collections -->
<dependency>
<groupId>org.eclipse.collections</groupId>
<artifactId>eclipse-collections-api</artifactId>
<version>8.0.0</version>
</dependency>
<dependency>
<groupId>org.eclipse.collections</groupId>
<artifactId>eclipse-collections</artifactId>
<version>8.0.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.json/json -->
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20180813</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-library</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>
</dependencies>
Recommended Posts