-
-
Save rodolfobandeira/dc7fb896197f63b7021b284734026be8 to your computer and use it in GitHub Desktop.
Converts Evernote .enex files to json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.io.File; | |
import java.io.FileNotFoundException; | |
import java.io.FileOutputStream; | |
import java.io.IOException; | |
import java.io.OutputStream; | |
import java.io.OutputStreamWriter; | |
import java.util.EnumSet; | |
import javax.xml.parsers.DocumentBuilderFactory; | |
import javax.xml.parsers.ParserConfigurationException; | |
import org.json.JSONArray; | |
import org.json.JSONException; | |
import org.json.JSONObject; | |
import org.jsoup.Jsoup; | |
import org.jsoup.safety.Whitelist; | |
import org.w3c.dom.Document; | |
import org.w3c.dom.NodeList; | |
import org.xml.sax.SAXException; | |
/** | |
* Modified from: https://github.com/tonca/EvernoteReader | |
* | |
* @author Antonio, aNNiMON | |
*/ | |
public final class EnexToJson { | |
private static enum Options { SIMPLE, RESOURCES, CONSOLE, TEXT }; | |
private static final EnumSet<Options> options = EnumSet.noneOf(Options.class); | |
public static void main(String[] args) { | |
if (args.length == 0) { | |
System.out.println("Usage: java EnexToJson file.enex [options]\n" | |
+ "Options:\n" | |
+ " -s, --simple include only title and content and date\n" | |
+ " -r, --resources include resources to json\n" | |
+ " -c, --console print output to stdout, not json file\n" | |
+ " -t, --text cleans html content\n" | |
); | |
return; | |
} | |
final String enexFile = args[0]; | |
for (int i = 1; i < args.length; i++) { | |
switch (args[i]) { | |
case "-s": | |
case "--simple": | |
options.add(Options.SIMPLE); | |
break; | |
case "-r": | |
case "--resources": | |
options.add(Options.RESOURCES); | |
break; | |
case "-c": | |
case "--console": | |
options.add(Options.CONSOLE); | |
break; | |
case "-t": | |
case "--text": | |
options.add(Options.TEXT); | |
break; | |
} | |
} | |
process(enexFile); | |
} | |
private static void process(String filename) { | |
final File inputFile = new File(filename); | |
final File outputFile = new File(inputFile.getParentFile(), inputFile.getName() + ".json"); | |
try (OutputStreamWriter out = new OutputStreamWriter(createOutputStream(outputFile), "UTF-8")) { | |
final Document document = DocumentBuilderFactory.newInstance() | |
.newDocumentBuilder() | |
.parse(inputFile); | |
if (document.hasChildNodes()) { | |
final JSONArray jsonArray = new JSONArray(); | |
parse(document.getChildNodes(), jsonArray, new JSONObject()); | |
out.append(jsonArray.toString(2)); | |
} | |
out.flush(); | |
} catch (ParserConfigurationException | SAXException | IOException ex) { | |
System.err.println(ex); | |
} | |
} | |
private static OutputStream createOutputStream(File outputFile) throws FileNotFoundException { | |
if (options.contains(Options.CONSOLE)) { | |
return System.out; | |
} else { | |
return new FileOutputStream(outputFile); | |
} | |
} | |
private static void parse(NodeList childNodes, JSONArray notes, JSONObject data) { | |
String content; | |
final int length = childNodes.getLength(); | |
for (int i = 0; i < length; i++) { | |
switch (childNodes.item(i).getNodeName()) { | |
case "title": | |
content = childNodes.item(i).getTextContent(); | |
data.put("title", content); | |
break; | |
case "content": | |
content = childNodes.item(i).getTextContent(); | |
if (options.contains(Options.TEXT)) { | |
content = cleanHtml(content); | |
} | |
data.put("content", content); | |
break; | |
case "created": | |
content = childNodes.item(i).getTextContent(); | |
data.put("created", content); | |
break; | |
case "updated": | |
if (options.contains(Options.SIMPLE)) break; | |
content = childNodes.item(i).getTextContent(); | |
data.put("updated", content); | |
break; | |
case "latitude": | |
if (options.contains(Options.SIMPLE)) break; | |
content = childNodes.item(i).getTextContent(); | |
data.put("latitude", content); | |
break; | |
case "longitude": | |
if (options.contains(Options.SIMPLE)) break; | |
content = childNodes.item(i).getTextContent(); | |
data.put("longitude", content); | |
break; | |
case "altitude": | |
if (options.contains(Options.SIMPLE)) break; | |
content = childNodes.item(i).getTextContent(); | |
data.put("altitude", content); | |
break; | |
case "source": | |
if (options.contains(Options.SIMPLE)) break; | |
content = childNodes.item(i).getTextContent(); | |
data.put("source", content); | |
break; | |
case "source-url": | |
if (options.contains(Options.SIMPLE)) break; | |
content = childNodes.item(i).getTextContent(); | |
data.put("source-url", content); | |
break; | |
case "tag": | |
if (options.contains(Options.SIMPLE)) break; | |
JSONArray tags = createTags(data); | |
content = childNodes.item(i).getTextContent(); | |
JSONObject tag = new JSONObject(); | |
tag.put("tag", content); | |
tags.put(tag); | |
break; | |
case "author": | |
if (options.contains(Options.SIMPLE)) break; | |
content = childNodes.item(i).getTextContent(); | |
data.put("author", content); | |
break; | |
case "resource": | |
if (options.contains(Options.SIMPLE)) break; | |
if (!options.contains(Options.RESOURCES)) break; | |
content = childNodes.item(i).getTextContent(); | |
data.put("resource", content); | |
break; | |
case "note": | |
final JSONObject note = new JSONObject(); | |
parse(childNodes.item(i).getChildNodes(), notes, note); | |
data.put("note", note); | |
notes.put(note); | |
break; | |
case "note-attributes": | |
if (options.contains(Options.SIMPLE)) break; | |
final JSONObject noteAttributes = new JSONObject(); | |
parse(childNodes.item(i).getChildNodes(), notes, noteAttributes); | |
data.put("note-attributes", noteAttributes); | |
break; | |
case "en-export": | |
parse(childNodes.item(i).getChildNodes(), notes, data); | |
break; | |
default: | |
break; | |
} | |
} | |
} | |
private static JSONArray createTags(JSONObject jsonObj) throws JSONException { | |
JSONArray tags; | |
if (jsonObj.has("tags")) { | |
tags = jsonObj.getJSONArray("tags"); | |
} else { | |
tags = new JSONArray(); | |
jsonObj.put("tags", tags); | |
} | |
return tags; | |
} | |
private static String cleanHtml(String content) { | |
return Jsoup.clean(content, Whitelist.none()); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment