[JAVA] Migrer de on-prepukiwiki vers esa.io \ (⁰⊖⁰) /

Aperçu

Dans notre entreprise, nous exploitions le PukiWiki sur site avant de rejoindre l'entreprise, mais cette fois j'ai déménagé vers esa.io \ (⁰⊖⁰) / La raison principale est que je suis entré dans esa, mais j'ai aussi eu beaucoup d'insatisfaction avec la gestion sur site mendokuse et le désir d'utiliser Markdown plutôt que la notation Wiki. Cet article est comme un journal de travail qui migre rapidement les articles stockés dans PukiWiki vers esa.io. J'ai honte d'annoncer le programme de migration, donc si vous voulez faire la même chose, veuillez vous y référer.

Qu'est-ce que esa.io

https://esa.io/ En termes simples, c'est un outil de partage d'informations de type Wiki. J'aime le fait que les obstacles au partage d'informations sont très faibles, et les différentes fonctionnalités «accessibles aux endroits qui piquent» qui facilitent l'édition et la gestion des articles. Quand je l'ai utilisé dans l'essai gratuit, c'était une série de "Oh!".

Je vais bouger \ (⁰⊖⁰) /

Une telle politique

Ce que j'ai abandonné

Procédure de migration

Le fichier txt de l'article est stocké dans le dossier "wiki" sur le serveur PukiWiki. Copiez-le à l'emplacement désigné. Ensuite, exécutez le programme de migration ci-dessous et vous êtes prêt à partir. Le programme de migration a été réalisé avec java.

Puisqu'il utilise l'API Web d'ESA, obtenez un jeton d'accès à l'avance. Vous pouvez l'obtenir depuis "Applications" dans les paramètres de l'équipe, dans la partie "Jetons d'accès personnels".

Programme de migration

C'est un programme jetable, donc je l'ai fait avec une grande dynamique. Je n'ai fait aucun effort pour le rendre plus facile à lire, donc je pense que c'est difficile à faire quand on veut jouer un peu avec. .. .. Si vous avez quelque chose comme "Je ne sais pas ce que cela signifie ici", veuillez demander dans les commentaires. Veuillez changer la partie marquée avec ★ dans le programme en fonction de votre environnement avant de l'exécuter. L'API esa est une spécification qui ne peut être appelée que jusqu'à 75 fois en 15 minutes, mais si cette limite est dépassée, j'essaye d'attendre de pouvoir la rappeler.

Programme principal

public class WikiMigrationToEsa
{
	private static Client apiClient = ClientBuilder.newClient();
	
	private static MutableList<Pair<Integer, Twin<String>>> documentList = Lists.mutable.empty();
	
	//★ Spécifiez le dossier où se trouvent les fichiers de l'article wiki
	private static final String wikiFilePath = "C:\\Users\\hoge\\wiki";
	//★esa.jeton d'accès io
	private static final String authorizationKey = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
	//★ Nom de l'équipe
	private static final String teamName = "hogehoge";
	
	public static void main(String[] args)
	{
		//Les fichiers d'article du wiki Esa un par un.Publier sur 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;
		}
		//Liens Esa dans le wiki pour les articles publiés.Mettre à jour au format io
		patchInnerLink();
	}
	
	public static void postWikiFile(Path wikiItemFile)
	{
		EsaPostItemDto content = new EsaPostItemDto();
		content.post = new EsaPostBodyDto();
		StringBuilder bodyText = new StringBuilder();
		//Titre
		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;
		}
		//Correction d'un problème où les barres obliques demi-largeur dans les titres étaient reconnues comme des catégories
		itemName = RegExUtils.replaceAll(itemName, "/", "&#47;");
		
		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 = "Migrer depuis le 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 peut avoir ou non un alias, donc dans le cas d'un alias>Sortez après
				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 = "Mise à jour du lien interne";
			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));
			//Ajouter 1 minute compte tenu de la possibilité que l'horloge ne soit pas correcte
			reset = reset.plusMinutes(1);
			while(reset.isAfter(OffsetDateTime.now(ZoneId.systemDefault())))
			{
				try
				{
					TimeUnit.MINUTES.sleep(1);
				} catch (InterruptedException e)
				{
					e.printStackTrace();
					System.exit(0);
				}
			}
		}
	}
}

DTO pour exprimer JSON de l'API esa

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;
}

La bibliothèque que vous utilisez

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>

référence

Référence API esa

Recommended Posts

Migrer de on-prepukiwiki vers esa.io \ (⁰⊖⁰) /
Migrer de JUnit 4 vers JUnit 5
Migrer Ubuntu 18.04 LTS du disque dur vers un SSD plus petit
Migrer de Java vers Kotlin côté serveur + Spring-boot
Migrer du client de transport vers le client de niveau supérieur Rest
[Swift, ARKit] Migrer de hitTest obsolète vers raycastQuery
Changements de Java 8 à Java 11
Somme de Java_1 à 100
De Java à Ruby !!
Passé d'iBATIS à MyBatis3
Essayez Spring Boot de 0 à 100.
Migration de Cobol vers JAVA
Passer de slim3-gen à slim3-gen-jsr269
Passer d'AWS à PaizaCloud
Nouvelles fonctionnalités de Java7 à Java8
Connectez-vous de Java à PostgreSQL
Conversion de ○ mois en ○ années ○ mois
Réécriture de l'applet à l'application
Passer de SQLite3 à PostgreSQL
De Java inefficace à Java efficace