mirror of
https://github.com/fooflington/selfdefined-checker.git
synced 2025-04-16 06:49:16 +00:00
working poc
This commit is contained in:
commit
7965c41516
33
README.md
Normal file
33
README.md
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
Self-defined checker
|
||||||
|
====================
|
||||||
|
|
||||||
|
Proof-of-concept language checker using the [Self-defined project](https://www.selfdefined.app/).
|
||||||
|
|
||||||
|
Requirements
|
||||||
|
------------
|
||||||
|
|
||||||
|
* J2EE compatible web server (eg. Tomcat)
|
||||||
|
|
||||||
|
Preparation
|
||||||
|
-----------
|
||||||
|
|
||||||
|
1. Clone the repository
|
||||||
|
2. Get the dependencies and ensure they're either in `WEB-INF/lib` or the webserver's shared `lib`:
|
||||||
|
* SQLite JDBC driver (eg. https://bitbucket.org/xerial/sqlite-jdbc/downloads/sqlite-jdbc-3.30.1.jar)
|
||||||
|
* JSON library (eg. http://stleary.github.io/JSON-java/index.html)
|
||||||
|
3. Compile the code (YMMV)
|
||||||
|
```shell
|
||||||
|
cd WEB-INF
|
||||||
|
export LIBPATH=/path/to/shared/java/libraries
|
||||||
|
javac -d classes -classpath src:classes:lib/json-20200518.jar:$LIBPATH/el-api.jar:$LIBPATH/servlet-api.jar:$LIBPATH/sqlite-jdbc.jar src/uk/org/mafoo/selfdefined/Checker.java
|
||||||
|
```
|
||||||
|
4. Build a war file
|
||||||
|
```shell
|
||||||
|
jar -cvf self-defined.war .
|
||||||
|
```
|
||||||
|
5. Deploy! (move the war file to your webservers `/webapps` folder and wait for it to deploy)
|
||||||
|
|
||||||
|
Notes
|
||||||
|
-----
|
||||||
|
|
||||||
|
The included database is build using the data from https://github.com/tatianamac/selfdefined.
|
0
WEB-INF/classes/.keep
Normal file
0
WEB-INF/classes/.keep
Normal file
BIN
WEB-INF/files/defs.db
Normal file
BIN
WEB-INF/files/defs.db
Normal file
Binary file not shown.
0
WEB-INF/lib/.keep
Normal file
0
WEB-INF/lib/.keep
Normal file
176
WEB-INF/src/uk/org/mafoo/selfdefined/Checker.java
Normal file
176
WEB-INF/src/uk/org/mafoo/selfdefined/Checker.java
Normal file
@ -0,0 +1,176 @@
|
|||||||
|
package uk.org.mafoo.selfdefined;
|
||||||
|
|
||||||
|
import javax.servlet.annotation.WebServlet;
|
||||||
|
import javax.management.RuntimeErrorException;
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.annotation.WebServlet;
|
||||||
|
import javax.servlet.http.HttpServlet;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.sql.*;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Enumeration;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.sqlite.*;
|
||||||
|
|
||||||
|
@WebServlet("/Checker")
|
||||||
|
public class Checker extends HttpServlet {
|
||||||
|
|
||||||
|
Connection db;
|
||||||
|
PreparedStatement p_checkWord, p_getWord;
|
||||||
|
String urlBase = "https://www.selfdefined.app/definitions/";
|
||||||
|
|
||||||
|
public void init() throws ServletException {
|
||||||
|
// Do required initialization
|
||||||
|
try {
|
||||||
|
db = DriverManager.getConnection(
|
||||||
|
"jdbc:sqlite:" + getServletContext().getRealPath("/WEB-INF/files/defs.db"));
|
||||||
|
|
||||||
|
p_checkWord = db.prepareStatement("SELECT word, ref FROM words WHERE word LIKE ?");
|
||||||
|
p_getWord = db.prepareStatement("SELECT title, slug, flag_level, flag_text, flag_for FROM definitions WHERE title LIKE ?");
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new RuntimeException("Failed to load database: " + e.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private HashMap<String,String> getWord(String word) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
p_getWord.setString(1, word);
|
||||||
|
ResultSet rs = p_getWord.executeQuery();
|
||||||
|
if(rs.next()) {
|
||||||
|
HashMap<String,String> _return = new HashMap<String,String>();
|
||||||
|
_return.put("word", rs.getString(1));
|
||||||
|
_return.put("slug", rs.getString(2));
|
||||||
|
_return.put("flagLevel", rs.getString(3));
|
||||||
|
_return.put("flagText", rs.getString(4));
|
||||||
|
_return.put("flagFor", rs.getString(5));
|
||||||
|
return _return;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkWord(String word, HashMap<String,String> wordMap, HashMap<String,Integer> wordCounts) {
|
||||||
|
assert(p_checkWord != null);
|
||||||
|
assert(word != null);
|
||||||
|
|
||||||
|
wordCounts.put(word, wordCounts.getOrDefault(word, 0) + 1);
|
||||||
|
|
||||||
|
// Do we already know the answer?
|
||||||
|
if(wordMap.containsKey(word)) {
|
||||||
|
// If so, just increment the wordcount and return
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
p_checkWord.setString(1, word);
|
||||||
|
ResultSet rs = p_checkWord.executeQuery();
|
||||||
|
while(rs.next()) {
|
||||||
|
if(rs.getString(1).equalsIgnoreCase(rs.getString(2))) {
|
||||||
|
wordMap.put(rs.getString(1), null);
|
||||||
|
} else {
|
||||||
|
wordMap.put(rs.getString(1), rs.getString(2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
// FIXME
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Report process(String[] input) {
|
||||||
|
HashMap<String,String> wordMap = new HashMap<String,String>();
|
||||||
|
HashMap<String,Integer> wordCounts = new HashMap<String,Integer>();
|
||||||
|
|
||||||
|
for(String line : input) {
|
||||||
|
for(String word : line.split("\\s+")) {
|
||||||
|
checkWord(word, wordMap, wordCounts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Report report = new Report();
|
||||||
|
for (String word : wordMap.keySet()) {
|
||||||
|
String ref = wordMap.get(word);
|
||||||
|
if(ref == null) ref = word;
|
||||||
|
HashMap<String,String> canonicalWord = getWord(ref);
|
||||||
|
report.add(
|
||||||
|
canonicalWord.get("word"),
|
||||||
|
wordCounts.get(word),
|
||||||
|
canonicalWord.get("flagLevel"),
|
||||||
|
canonicalWord.get("flagText"),
|
||||||
|
canonicalWord.get("flagFor"),
|
||||||
|
urlBase.concat(canonicalWord.get("slug"))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return report;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
||||||
|
String[] vals = req.getParameterValues("input");
|
||||||
|
if(vals != null) {
|
||||||
|
Report r = process(vals);
|
||||||
|
PrintWriter out = resp.getWriter();
|
||||||
|
|
||||||
|
ArrayList<String> acceptHeaders = new ArrayList<String>();
|
||||||
|
for(Enumeration<String> acceptHeaders_e = req.getHeaders("Accept"); acceptHeaders_e.hasMoreElements(); ) {
|
||||||
|
acceptHeaders.add(acceptHeaders_e.nextElement());
|
||||||
|
}
|
||||||
|
if(acceptHeaders.contains("text/json")) {
|
||||||
|
resp.setContentType("text/json");
|
||||||
|
out.println(r.toJSONObject());
|
||||||
|
} else {
|
||||||
|
out.println("<!DOCTYPE html>");
|
||||||
|
out.println("<html>");
|
||||||
|
out.println("<head>");
|
||||||
|
out.println(" <title>Language Checker</title>");
|
||||||
|
out.println(" <link rel=\"stylesheet\" type=\"text/css\" href=\"base.css\" />");
|
||||||
|
out.println(" <link href=\"https://fonts.googleapis.com/css2?family=Fira+Mono:wght@400;500&family=Roboto:wght@500&display=swap\" rel=\"stylesheet\">");
|
||||||
|
out.println("</head>");
|
||||||
|
out.println("<body>");
|
||||||
|
out.println(" <h1>Language checker results</h1>");
|
||||||
|
out.println(r.toHTML());
|
||||||
|
out.println("</body></html>");
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException("No data");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
||||||
|
|
||||||
|
// ArrayList<String> arr = new ArrayList<String>();
|
||||||
|
|
||||||
|
// try {
|
||||||
|
// BufferedReader inputData = req.getReader();
|
||||||
|
// String line;
|
||||||
|
// while((line = inputData.readLine()) != null) {
|
||||||
|
// arr.add(line);
|
||||||
|
// }
|
||||||
|
// } catch (IOException e) {
|
||||||
|
// // FIXME
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if(arr.size() > 0) {
|
||||||
|
// Report r = process((String[]) arr.toArray(new String[0]));
|
||||||
|
// PrintWriter out = resp.getWriter();
|
||||||
|
// out.println(r.toJSONObject());
|
||||||
|
// } else {
|
||||||
|
// throw new RuntimeException("No data");
|
||||||
|
// }
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
public void destroy() {
|
||||||
|
// Close the database
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
62
WEB-INF/src/uk/org/mafoo/selfdefined/Report.java
Normal file
62
WEB-INF/src/uk/org/mafoo/selfdefined/Report.java
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
package uk.org.mafoo.selfdefined;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import org.json.*;
|
||||||
|
|
||||||
|
class Report {
|
||||||
|
|
||||||
|
ArrayList<ReportWord> data;
|
||||||
|
|
||||||
|
public Report() {
|
||||||
|
data = new ArrayList<ReportWord>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(String word, Integer count, String flagLevel, String flagText, String flagFor, String url) {
|
||||||
|
data.add(new ReportWord(word, count, flagLevel, flagText, flagFor, url));
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder s = new StringBuilder();
|
||||||
|
s.append("[");
|
||||||
|
int n = 0;
|
||||||
|
for (ReportWord w : data) {
|
||||||
|
if(n++ > 0) { s.append(","); }
|
||||||
|
s.append(w);
|
||||||
|
}
|
||||||
|
s.append("]");
|
||||||
|
|
||||||
|
return s.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONObject toJSONObject() {
|
||||||
|
JSONArray arr = new JSONArray();
|
||||||
|
for(ReportWord w : data) {
|
||||||
|
arr.put(w.toJSONObject());
|
||||||
|
}
|
||||||
|
|
||||||
|
JSONObject obj = new JSONObject();
|
||||||
|
obj.put("results", arr);
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toHTML() {
|
||||||
|
StringBuilder str = new StringBuilder();
|
||||||
|
str.append("<table border='1'>\n");
|
||||||
|
str.append(" <thead>\n");
|
||||||
|
str.append(" <th>Word</th>\n");
|
||||||
|
str.append(" <th>Count</th>\n");
|
||||||
|
str.append(" <th>Flag Level</th>\n");
|
||||||
|
str.append(" <th>Flag Text</th>\n");
|
||||||
|
str.append(" <th>See-Also</th>\n");
|
||||||
|
str.append(" <th>URL</th>\n");
|
||||||
|
str.append(" </thead>\n");
|
||||||
|
str.append(" <tbody>\n");
|
||||||
|
for(ReportWord w : data) {
|
||||||
|
str.append(w.toHTML());
|
||||||
|
}
|
||||||
|
str.append(" </tbody>\n");
|
||||||
|
str.append("</table>\n");
|
||||||
|
|
||||||
|
return str.toString();
|
||||||
|
}
|
||||||
|
}
|
54
WEB-INF/src/uk/org/mafoo/selfdefined/ReportWord.java
Normal file
54
WEB-INF/src/uk/org/mafoo/selfdefined/ReportWord.java
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
package uk.org.mafoo.selfdefined;
|
||||||
|
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
class ReportWord {
|
||||||
|
String word;
|
||||||
|
Integer count;
|
||||||
|
String flagLevel;
|
||||||
|
String flagText;
|
||||||
|
String flagFor;
|
||||||
|
String url;
|
||||||
|
|
||||||
|
public ReportWord(String word, Integer count, String flagLevel, String flagText, String flagFor, String url) {
|
||||||
|
this.word = word;
|
||||||
|
this.count = count;
|
||||||
|
this.flagLevel = flagLevel;
|
||||||
|
this.flagText = flagText;
|
||||||
|
this.flagFor = flagFor;
|
||||||
|
this.url = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return String.format(
|
||||||
|
"{word=%s,count=%d,flagLevel=%s,flagText=%s,flagFor=%s,url=%s}",
|
||||||
|
word, count, flagLevel, flagText, flagFor, url
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONObject toJSONObject() {
|
||||||
|
JSONObject jo = new JSONObject();
|
||||||
|
jo.put("word", word);
|
||||||
|
jo.put("count", count);
|
||||||
|
jo.put("flagLevel", flagLevel);
|
||||||
|
jo.put("flagText", flagText);
|
||||||
|
jo.put("flagFor", flagFor);
|
||||||
|
jo.put("url", url);
|
||||||
|
|
||||||
|
return jo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toHTML() {
|
||||||
|
StringBuilder str = new StringBuilder();
|
||||||
|
str.append("<tr>\n");
|
||||||
|
str.append(" <td>"); str.append(word); str.append("</td>\n");
|
||||||
|
str.append(" <td>"); str.append(count); str.append("</td>\n");
|
||||||
|
str.append(" <td>"); str.append(flagLevel); str.append("</td>\n");
|
||||||
|
str.append(" <td>"); str.append(flagText); str.append("</td>\n");
|
||||||
|
str.append(" <td>"); str.append(flagFor); str.append("</td>\n");
|
||||||
|
str.append(" <td><a href='"); str.append(url); str.append("'>ref</a></td>\n");
|
||||||
|
str.append("</tr>\n");
|
||||||
|
|
||||||
|
return str.toString();
|
||||||
|
}
|
||||||
|
}
|
21
WEB-INF/web.xml
Normal file
21
WEB-INF/web.xml
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<?xml version="1.0" encoding="ISO-8859-1" ?>
|
||||||
|
|
||||||
|
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
|
||||||
|
version="2.4">
|
||||||
|
|
||||||
|
<display-name>S</display-name>
|
||||||
|
<description>S</description>
|
||||||
|
|
||||||
|
<servlet>
|
||||||
|
<servlet-name>CheckerServlet</servlet-name>
|
||||||
|
<servlet-class>uk.org.mafoo.selfdefined.Checker</servlet-class>
|
||||||
|
</servlet>
|
||||||
|
|
||||||
|
<servlet-mapping>
|
||||||
|
<servlet-name>CheckerServlet</servlet-name>
|
||||||
|
<url-pattern>/c</url-pattern>
|
||||||
|
</servlet-mapping>
|
||||||
|
|
||||||
|
</web-app>
|
22
index.jsp
Normal file
22
index.jsp
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Language Checker</title>
|
||||||
|
<link rel="stylesheet" type="text/css" href="base.css" />
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Fira+Mono:wght@400;500&family=Roboto:wght@500&display=swap" rel="stylesheet">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Language checker</h1>
|
||||||
|
<p>Language checker based on the <a href="https://www.selfdefined.app/">Self Defined</a> project</p>
|
||||||
|
<blockquote>
|
||||||
|
Self-Defined seeks to provide more inclusive, holistic, and fluid definitions to reflect the diverse perspectives of the modern world.
|
||||||
|
|
||||||
|
With the foundation of vocabulary, we can begin to understand lived experiences of people different than us. Words can provide us with a sense of identify and allow us to find kinship through common experiences.
|
||||||
|
</blockquote>
|
||||||
|
<form action="Checker" method="post">
|
||||||
|
<!--<label for="input">Text to be checked</label>-->
|
||||||
|
<textarea id="input" size="25" name="input" rows="20" cols="120" value=""></textarea>
|
||||||
|
<input type="submit" value="Check" />
|
||||||
|
</form>
|
||||||
|
<p>You can also POST to the <tt>/Checker</tt> endpoint specifying <tt>Accept: text/json</tt>.</p>
|
||||||
|
</body>
|
Loading…
x
Reference in New Issue
Block a user