Initial commit
This commit is contained in:
commit
a1ee3cf1b5
11
ShoppingList/.classpath
Normal file
11
ShoppingList/.classpath
Normal file
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="lib" path="lib/commons-lang3-3.9.jar"/>
|
||||
<classpathentry kind="lib" path="lib/mariadb-java-client-2.4.4.jar"/>
|
||||
<classpathentry kind="lib" path="C:/Users/Jens/Documents/Entwicklung/Eclipse workspace/libs/mailapi-1.5.0.jar"/>
|
||||
<classpathentry kind="lib" path="C:/Users/Jens/Documents/Entwicklung/Eclipse workspace/libs/smtp-1.5.0.jar"/>
|
||||
<classpathentry kind="lib" path="C:/Users/Jens/Documents/Entwicklung/Eclipse workspace/libs/activation-1.1.1.wso2v2.jar"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
74
ShoppingList/.gitignore
vendored
Normal file
74
ShoppingList/.gitignore
vendored
Normal file
@ -0,0 +1,74 @@
|
||||
|
||||
# Created by https://www.toptal.com/developers/gitignore/api/eclipse
|
||||
# Edit at https://www.toptal.com/developers/gitignore?templates=eclipse
|
||||
|
||||
### Eclipse ###
|
||||
.metadata
|
||||
bin/
|
||||
tmp/
|
||||
*.tmp
|
||||
*.bak
|
||||
*.swp
|
||||
*~.nib
|
||||
local.properties
|
||||
.settings/
|
||||
.loadpath
|
||||
.recommenders
|
||||
|
||||
# External tool builders
|
||||
.externalToolBuilders/
|
||||
|
||||
# Locally stored "Eclipse launch configurations"
|
||||
*.launch
|
||||
|
||||
# PyDev specific (Python IDE for Eclipse)
|
||||
*.pydevproject
|
||||
|
||||
# CDT-specific (C/C++ Development Tooling)
|
||||
.cproject
|
||||
|
||||
# CDT- autotools
|
||||
.autotools
|
||||
|
||||
# Java annotation processor (APT)
|
||||
.factorypath
|
||||
|
||||
# PDT-specific (PHP Development Tools)
|
||||
.buildpath
|
||||
|
||||
# sbteclipse plugin
|
||||
.target
|
||||
|
||||
# Tern plugin
|
||||
.tern-project
|
||||
|
||||
# TeXlipse plugin
|
||||
.texlipse
|
||||
|
||||
# STS (Spring Tool Suite)
|
||||
.springBeans
|
||||
|
||||
# Code Recommenders
|
||||
.recommenders/
|
||||
|
||||
# Annotation Processing
|
||||
.apt_generated/
|
||||
.apt_generated_test/
|
||||
|
||||
# Scala IDE specific (Scala & Java development for Eclipse)
|
||||
.cache-main
|
||||
.scala_dependencies
|
||||
.worksheet
|
||||
|
||||
# Uncomment this line if you wish to ignore the project description file.
|
||||
# Typically, this file would be tracked if it contains build/dependency configurations:
|
||||
#.project
|
||||
|
||||
### Eclipse Patch ###
|
||||
# Spring Boot Tooling
|
||||
.sts4-cache/
|
||||
|
||||
# End of https://www.toptal.com/developers/gitignore/api/eclipse
|
||||
|
||||
ShoppingListLogFile.txt
|
||||
ShoppingList-settings.ini
|
17
ShoppingList/.project
Normal file
17
ShoppingList/.project
Normal file
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>ShoppingList</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
BIN
ShoppingList/lib/commons-lang3-3.9.jar
Normal file
BIN
ShoppingList/lib/commons-lang3-3.9.jar
Normal file
Binary file not shown.
BIN
ShoppingList/lib/javax.xml.bind.jar
Normal file
BIN
ShoppingList/lib/javax.xml.bind.jar
Normal file
Binary file not shown.
BIN
ShoppingList/lib/mariadb-java-client-2.4.4.jar
Normal file
BIN
ShoppingList/lib/mariadb-java-client-2.4.4.jar
Normal file
Binary file not shown.
@ -0,0 +1,134 @@
|
||||
package com.jens.rhasspy.shoppinglist;
|
||||
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.SQLException;
|
||||
|
||||
public class DatabaseHandler implements Runnable
|
||||
{
|
||||
private static DatabaseHandler instance = null;
|
||||
static final String databaseConnectionEncoding = "utf8";
|
||||
|
||||
Connection conn = null;
|
||||
|
||||
private DatabaseHandler()
|
||||
{
|
||||
}
|
||||
|
||||
public static DatabaseHandler getInstance()
|
||||
{
|
||||
if(instance == null)
|
||||
instance = new DatabaseHandler();
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
public Connection getConnection()
|
||||
{
|
||||
// if(isConnectedToDatabase())
|
||||
// {
|
||||
// // It has occured that the connection was there, but dead due to timeout or whatever
|
||||
// try
|
||||
// {
|
||||
// conn.getSchema();
|
||||
// }
|
||||
// catch (SQLException e)
|
||||
//// if(conn.isValid(5000))
|
||||
// {
|
||||
// Miscellaneous.logEvent("DB connection probably dropped. Reestablishing...");
|
||||
// conn = null;
|
||||
// establishConnection();
|
||||
// }
|
||||
// }
|
||||
|
||||
if(!isConnectedToDatabase())
|
||||
establishConnection(true);
|
||||
|
||||
return this.conn;
|
||||
}
|
||||
|
||||
/** force means that connection is definitely reestablished, even if there seems to be an existing one **/
|
||||
private synchronized void establishConnection(boolean force)
|
||||
{
|
||||
if(conn == null | force)
|
||||
{
|
||||
for(String dbServer : Settings.databaseServerNames)
|
||||
{
|
||||
Miscellaneous.logEvent("Trying to connect to database " + Settings.databaseName + "@" + dbServer + " as " + Settings.databaseUsername + "...", 3);
|
||||
|
||||
// String url = "jdbc:mysql://" + dbServer + ":" + Settings.databasePort + "/";
|
||||
// String driver = "com.mysql.jdbc.Driver";
|
||||
String url = "jdbc:mariadb://" + dbServer + ":" + Settings.databasePort + "/";
|
||||
String driver = "org.mariadb.jdbc.Driver";
|
||||
try
|
||||
{
|
||||
Class.forName(driver).newInstance();
|
||||
conn = DriverManager.getConnection(url + Settings.databaseName + "?characterEncoding=" + databaseConnectionEncoding, Settings.databaseUsername, Settings.databasePassword);
|
||||
Miscellaneous.logEvent("Connected to database.", 3);
|
||||
|
||||
break;
|
||||
}
|
||||
catch (ClassNotFoundException e)
|
||||
{
|
||||
Miscellaneous.logEvent(Settings.languageBlock.get("dbDriverNotFound"), 1);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent(Settings.languageBlock.get("dbCouldNotConnect"), 1);
|
||||
Miscellaneous.logEvent(Diverse.getStackTraceAsString(e), 2);
|
||||
this.conn = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void disconnect()
|
||||
{
|
||||
// TODO: Timeout after which the DB connection is terminated automatically.
|
||||
|
||||
if(conn != null)
|
||||
{
|
||||
Miscellaneous.logEvent("Disconnecting from database.", 3);
|
||||
try
|
||||
{
|
||||
this.conn.close();
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
Miscellaneous.logEvent(Diverse.getStackTraceAsString(e), 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
Miscellaneous.logEvent("Not disconnecting from database because not connected.", 4);
|
||||
|
||||
conn=null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable
|
||||
{
|
||||
disconnect();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
getConnection();
|
||||
}
|
||||
|
||||
public boolean isConnectedToDatabase()
|
||||
{
|
||||
try
|
||||
{
|
||||
if(conn != null && conn.isValid(5000))
|
||||
return true;
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
Miscellaneous.logEvent(Diverse.getStackTraceAsString(e), 1);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
611
ShoppingList/src/com/jens/rhasspy/shoppinglist/Diverse.java
Normal file
611
ShoppingList/src/com/jens/rhasspy/shoppinglist/Diverse.java
Normal file
@ -0,0 +1,611 @@
|
||||
package com.jens.rhasspy.shoppinglist;
|
||||
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringReader;
|
||||
import java.io.StringWriter;
|
||||
import java.io.Writer;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.security.SecureRandom;
|
||||
import java.sql.Time;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.HashMap;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.transform.OutputKeys;
|
||||
import javax.xml.transform.Transformer;
|
||||
import javax.xml.transform.TransformerConfigurationException;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import javax.xml.transform.TransformerFactory;
|
||||
import javax.xml.transform.dom.DOMSource;
|
||||
import javax.xml.transform.stream.StreamResult;
|
||||
import javax.xml.xpath.XPath;
|
||||
import javax.xml.xpath.XPathConstants;
|
||||
import javax.xml.xpath.XPathExpression;
|
||||
import javax.xml.xpath.XPathExpressionException;
|
||||
import javax.xml.xpath.XPathFactory;
|
||||
|
||||
public class Diverse
|
||||
{
|
||||
public final static String networkSeparatorCommunication = ";commSep";
|
||||
public final static String networkSeparatorSettings = ";commSett";
|
||||
|
||||
public static enum cacheObjectsEnum { all, devices, commands, rooms, rules, users, houses, nodes, sensors, userDevices };
|
||||
|
||||
public enum SolarEvent {sunrise, sunset};
|
||||
|
||||
public static final String lineSeparator = System.getProperty("line.separator");
|
||||
|
||||
public static String intToOpenClosed(int value)
|
||||
{
|
||||
if(value == 1)
|
||||
return "closed";
|
||||
else if(value == 0)
|
||||
return "open";
|
||||
else
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
public static String intToWaterYesNo(int value)
|
||||
{
|
||||
if(value == 1)
|
||||
return "water";
|
||||
else if(value == 0)
|
||||
return "dry";
|
||||
else
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
public static String intToSmokeYesNo(int value)
|
||||
{
|
||||
if(value == 1)
|
||||
return "smoke";
|
||||
else if(value == 0)
|
||||
return "no smoke";
|
||||
else
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
public static String getEnabledDisabledString(boolean value)
|
||||
{
|
||||
if(value)
|
||||
return "enabled";
|
||||
else
|
||||
return "disabled";
|
||||
}
|
||||
|
||||
public static Calendar calendarFromLong(long source)
|
||||
{
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTimeInMillis(source);
|
||||
return cal;
|
||||
}
|
||||
|
||||
public static String getOnOffString(boolean value)
|
||||
{
|
||||
if(value)
|
||||
return "on";
|
||||
else
|
||||
return "off";
|
||||
}
|
||||
|
||||
public static String getIniLikeValue(String fullText, String searchObject, String separator)
|
||||
{
|
||||
fullText = fullText.trim();
|
||||
|
||||
if (fullText.toLowerCase().contains(searchObject.toLowerCase()))
|
||||
{
|
||||
if (fullText.toLowerCase().contains(separator.toLowerCase())) // multiple values
|
||||
{
|
||||
int start = fullText.toLowerCase().indexOf(searchObject.toLowerCase() + "=") + searchObject.length() + 1;
|
||||
int end = fullText.toLowerCase().indexOf(separator.toLowerCase(), start);
|
||||
|
||||
if (end == -1) // if the last index in fullText
|
||||
return fullText.substring(start);
|
||||
else
|
||||
return fullText.substring(start, end);
|
||||
}
|
||||
else // only one value
|
||||
{
|
||||
return fullText.substring(fullText.indexOf("=") + 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Miscellaneous.logEvent("Index " + searchObject + " cannot be found in full text.", 5);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static String addOrReplaceIniLikeValue(String fullText, String key, String value, String separator)
|
||||
{
|
||||
fullText = fullText.trim();
|
||||
|
||||
if (fullText.startsWith(key + "=") | fullText.contains(separator + key + "="))
|
||||
{
|
||||
if (fullText.contains(separator)) // multiple values
|
||||
{
|
||||
int start = fullText.indexOf(key + "=") + key.length() + 1;
|
||||
int end = fullText.indexOf(separator, start);
|
||||
|
||||
String oldValue;
|
||||
if (end == -1) // if the last index in fullText
|
||||
oldValue = fullText.substring(start);
|
||||
else
|
||||
oldValue = fullText.substring(start, end);
|
||||
|
||||
return fullText.replace(key + "=" + oldValue, key + "=" + value);
|
||||
}
|
||||
else // only one value
|
||||
{
|
||||
return key + "=" + value;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(fullText.length() > 0)
|
||||
return fullText + separator + key + "=" + value;
|
||||
else
|
||||
return key + "=" + value;
|
||||
}
|
||||
}
|
||||
|
||||
public static String removeIniLikeValue(String fullText, String key, String separator)
|
||||
{
|
||||
fullText = fullText.trim();
|
||||
String toBeRemoved = getIniLikeValue(fullText, key, separator);
|
||||
|
||||
if(toBeRemoved != null && fullText.contains(toBeRemoved))
|
||||
{
|
||||
if(fullText.contains(";"))
|
||||
{
|
||||
if(fullText.contains(";" + toBeRemoved))
|
||||
return fullText.replace(";" + toBeRemoved, "");
|
||||
else
|
||||
return fullText.replace(toBeRemoved + ";", "");
|
||||
}
|
||||
else
|
||||
return "";
|
||||
}
|
||||
else
|
||||
return fullText;
|
||||
}
|
||||
|
||||
public static String updateIniLikeValue(String fullText, String key, String value, String separator)
|
||||
{
|
||||
if (fullText.contains(key))
|
||||
{
|
||||
if (fullText.contains(separator)) // multiple values
|
||||
{
|
||||
String[] lines = fullText.split(separator);
|
||||
for(int i=0; i < lines.length; i++)
|
||||
{
|
||||
if(lines[i].startsWith(key))
|
||||
{
|
||||
int equalsPosition = lines[i].indexOf(key + "=") + key.length() + 1;
|
||||
lines[i] = lines[i].substring(0, equalsPosition) + value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return Diverse.arrayImplode(separator, lines);
|
||||
}
|
||||
else // only one value
|
||||
{
|
||||
return fullText + separator + key + "=" + value;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return fullText + separator + key + "=" + value;
|
||||
}
|
||||
}
|
||||
|
||||
public static int boolToInt(boolean in)
|
||||
{
|
||||
if (in)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static boolean intToBool(int in)
|
||||
{
|
||||
if (in > 0)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
|
||||
// ClientServerSplit.logEvent("Error transforming int to bool.", 3);
|
||||
// return false;
|
||||
}
|
||||
|
||||
public static boolean isNumeric(String stringToCheck)
|
||||
{
|
||||
String character;
|
||||
|
||||
for(int i = 0; i < stringToCheck.length(); i++)
|
||||
{
|
||||
character = stringToCheck.substring(i, i + 1);
|
||||
|
||||
if(!character.matches("[1234567890]") && !character.equals(".") && !character.equals(","))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean arraySearch(String[] haystack, String needle, boolean caseSensitive, boolean matchFullLine)
|
||||
{
|
||||
if(matchFullLine)
|
||||
{
|
||||
if(caseSensitive)
|
||||
{
|
||||
for (String s : haystack)
|
||||
{
|
||||
if (s.equals(needle))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (String s : haystack)
|
||||
{
|
||||
if (s.toLowerCase().equals(needle.toLowerCase()))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(caseSensitive)
|
||||
{
|
||||
for (String s : haystack)
|
||||
{
|
||||
if (s.contains(needle))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (String s : haystack)
|
||||
{
|
||||
if (s.toLowerCase().contains(needle.toLowerCase()))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean arraySearch(ArrayList<String> requestList, String needle, boolean caseSensitive, boolean matchFullLine)
|
||||
{
|
||||
return arraySearch(requestList.toArray(new String[requestList.size()]), needle, caseSensitive, matchFullLine);
|
||||
}
|
||||
|
||||
public static boolean arraySearch(cacheObjectsEnum[] haystack, cacheObjectsEnum needle)
|
||||
{
|
||||
if (needle != null)
|
||||
{
|
||||
for (cacheObjectsEnum c : haystack)
|
||||
{
|
||||
if (c.equals(needle))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
Miscellaneous.logEvent("Needle should not be null in function arraySearch()", 5);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static String arrayImplode(String glue, String... values)
|
||||
{
|
||||
String returnString = "";
|
||||
|
||||
for (String s : values)
|
||||
returnString += s + glue;
|
||||
|
||||
if (returnString.length() > 0)
|
||||
returnString = returnString.substring(0, returnString.length() - glue.length());
|
||||
|
||||
return returnString;
|
||||
}
|
||||
|
||||
public static String arrayImplode(String glue, ArrayList<String> arrayList)
|
||||
{
|
||||
String returnString = "";
|
||||
|
||||
for (Object s : arrayList)
|
||||
returnString += s + glue;
|
||||
|
||||
if (returnString.length() > 0)
|
||||
returnString = returnString.substring(0, returnString.length() - glue.length());
|
||||
|
||||
return returnString;
|
||||
}
|
||||
|
||||
public static String arrayImplode(String glue, Object[] array)
|
||||
{
|
||||
String returnString = "";
|
||||
|
||||
for (Object s : array)
|
||||
returnString += s.toString() + glue;
|
||||
|
||||
if (returnString.length() > 0)
|
||||
returnString = returnString.substring(0, returnString.length() - glue.length());
|
||||
|
||||
return returnString;
|
||||
}
|
||||
|
||||
public static String arrayImplode(String glue, HashMap<String, String> map)
|
||||
{
|
||||
String returnString = "";
|
||||
|
||||
for (String key : map.keySet())
|
||||
returnString += map.get(key) + glue;
|
||||
|
||||
if (returnString.length() > 0)
|
||||
returnString = returnString.substring(0, returnString.length() - glue.length());
|
||||
|
||||
return returnString;
|
||||
}
|
||||
|
||||
public static String getSystemTimezone()
|
||||
{
|
||||
// https://coderanch.com/t/386398/java/System-Timezone
|
||||
TimeZone tz = Calendar.getInstance().getTimeZone();
|
||||
// System.out.println(tz.getDisplayName());// (i.e. Moscow Standard Time)
|
||||
return tz.getID();
|
||||
|
||||
// Should return something like this: Asia/Calcutta
|
||||
}
|
||||
|
||||
public static String createPassword(int length)
|
||||
{
|
||||
final String allowedChars = "0123456789abcdefghijklmnopqrstuvwABCDEFGHIJKLMNOP!§$%&?*+#";
|
||||
SecureRandom random = new SecureRandom();
|
||||
StringBuilder pass = new StringBuilder(length);
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
pass.append(allowedChars.charAt(random.nextInt(allowedChars.length())));
|
||||
}
|
||||
return pass.toString();
|
||||
}
|
||||
|
||||
public static Element getXmlTree(String inputString) throws SAXException, IOException, ParserConfigurationException
|
||||
{
|
||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder builder = factory.newDocumentBuilder();
|
||||
|
||||
// Create a Document from a file or stream
|
||||
/*
|
||||
StringBuilder xmlStringBuilder = new StringBuilder();
|
||||
xmlStringBuilder.append("<?xml version="1.0"?> <class> </class>");
|
||||
ByteArrayInputStream input = new ByteArrayInputStream(xmlStringBuilder.toString().getBytes("UTF-8"));
|
||||
*/
|
||||
// Document doc = builder.parse(input);
|
||||
Document doc = builder.parse(new InputSource(new StringReader(inputString)));
|
||||
|
||||
Element rootElement = doc.getDocumentElement();
|
||||
|
||||
return rootElement;
|
||||
/*
|
||||
// Examine attributes
|
||||
|
||||
//returns specific attribute
|
||||
root.getAttribute("attributeName");
|
||||
|
||||
//returns a Map (table) of names/values
|
||||
root.getAttributes();
|
||||
|
||||
// Examine sub-elements
|
||||
|
||||
//returns a list of subelements of specified name
|
||||
root.getElementsByTagName("subelementName");
|
||||
|
||||
//returns a list of all child nodes
|
||||
root.getChildNodes();
|
||||
*/
|
||||
}
|
||||
|
||||
public static String xmlToString(Node node, boolean omitXmlDeclaration, boolean prettyPrint)
|
||||
{
|
||||
if (node == null)
|
||||
{
|
||||
throw new IllegalArgumentException("node is null.");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// Remove unwanted whitespaces
|
||||
node.normalize();
|
||||
XPath xpath = XPathFactory.newInstance().newXPath();
|
||||
XPathExpression expr = xpath.compile("//text()[normalize-space()='']");
|
||||
NodeList nodeList = (NodeList) expr.evaluate(node, XPathConstants.NODESET);
|
||||
|
||||
for (int i = 0; i < nodeList.getLength(); ++i)
|
||||
{
|
||||
Node nd = nodeList.item(i);
|
||||
nd.getParentNode().removeChild(nd);
|
||||
}
|
||||
|
||||
// Create and setup transformer
|
||||
Transformer transformer = TransformerFactory.newInstance().newTransformer();
|
||||
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
|
||||
|
||||
if (omitXmlDeclaration == true)
|
||||
{
|
||||
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
|
||||
}
|
||||
|
||||
if (prettyPrint == true)
|
||||
{
|
||||
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
|
||||
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
|
||||
}
|
||||
|
||||
// Turn the node into a string
|
||||
StringWriter writer = new StringWriter();
|
||||
transformer.transform(new DOMSource(node), new StreamResult(writer));
|
||||
return writer.toString();
|
||||
}
|
||||
catch (TransformerConfigurationException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
catch (TransformerException e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
catch (XPathExpressionException e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public static String getStackTrace()
|
||||
{
|
||||
StringBuilder trace = new StringBuilder();
|
||||
for (StackTraceElement ste : Thread.currentThread().getStackTrace())
|
||||
trace.append(ste + Diverse.lineSeparator);
|
||||
|
||||
trace.delete(trace.length(), trace.length());
|
||||
|
||||
return trace.toString();
|
||||
}
|
||||
|
||||
public static String getStackTraceAsString(Throwable aThrowable)
|
||||
{
|
||||
Writer result = new StringWriter();
|
||||
PrintWriter printWriter = new PrintWriter(result);
|
||||
aThrowable.printStackTrace(printWriter);
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines a custom format for the stack trace as String.
|
||||
*/
|
||||
public static String getCustomStackTrace(Throwable aThrowable)
|
||||
{
|
||||
//add the class name and any message passed to constructor
|
||||
StringBuilder result = new StringBuilder( "Stacktrace: " );
|
||||
result.append(aThrowable.toString());
|
||||
String NEW_LINE = System.getProperty("line.separator");
|
||||
result.append(NEW_LINE);
|
||||
|
||||
//add each element of the stack trace
|
||||
for (StackTraceElement element : aThrowable.getStackTrace())
|
||||
{
|
||||
result.append(element);
|
||||
result.append(NEW_LINE);
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
public static ArrayList<Element> getSubElements(Node node, String parentName, String childName)
|
||||
{
|
||||
ArrayList<Element> returnList = new ArrayList<Element>();
|
||||
NodeList nodeElements = ((Element)node).getElementsByTagName("houses");
|
||||
for(int i = 0; i < nodeElements.getLength(); i++)
|
||||
{
|
||||
if (nodeElements.item(i).getNodeType() == Node.ELEMENT_NODE)
|
||||
{
|
||||
NodeList childElements = nodeElements.item(i).getChildNodes();
|
||||
for (int j = 0; j < childElements.getLength(); j++)
|
||||
{
|
||||
Element element = (Element) childElements.item(j);
|
||||
// HouseTemplate house = HouseTemplate.fromXmlStringStatic(Diverse.getXmlFull(element));
|
||||
returnList.add(element);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*ArrayList<Element> returnList = new ArrayList<>();
|
||||
|
||||
NodeList children = ((Element)node).getElementsByTagName(parentName);
|
||||
|
||||
for(int i=0; i < children.getLength(); i++)
|
||||
{
|
||||
returnList.add((Element)children.item(i));
|
||||
}*/
|
||||
|
||||
return returnList;
|
||||
}
|
||||
|
||||
public static double round(double value, int places)
|
||||
{
|
||||
if (places < 0) throw new IllegalArgumentException();
|
||||
|
||||
BigDecimal bd = new BigDecimal(Double.toString(value));
|
||||
bd = bd.setScale(places, RoundingMode.HALF_UP);
|
||||
return bd.doubleValue();
|
||||
}
|
||||
|
||||
public static Class getCallerClass()
|
||||
{
|
||||
StackTraceElement[] stElements = Thread.currentThread().getStackTrace();
|
||||
for (int i=1; i<stElements.length; i++)
|
||||
{
|
||||
StackTraceElement ste = stElements[i];
|
||||
if (!ste.getClassName().equals(Diverse.class.getName()) && ste.getClassName().indexOf("java.lang.Thread")!=0)
|
||||
{
|
||||
return ste.getClass().getDeclaringClass();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Class getCallerCallerClassName()
|
||||
{
|
||||
StackTraceElement[] stElements = Thread.currentThread().getStackTrace();
|
||||
String callerClassName = null;
|
||||
for (int i=1; i<stElements.length; i++)
|
||||
{
|
||||
StackTraceElement ste = stElements[i];
|
||||
if (!ste.getClassName().equals(Diverse.class.getName())&& ste.getClassName().indexOf("java.lang.Thread")!=0)
|
||||
{
|
||||
if (callerClassName==null)
|
||||
{
|
||||
callerClassName = ste.getClassName();
|
||||
}
|
||||
else if (!callerClassName.equals(ste.getClassName()))
|
||||
{
|
||||
try
|
||||
{
|
||||
Class returnClass = Class.forName(ste.getClassName());
|
||||
return returnClass;
|
||||
}
|
||||
catch(Exception e)
|
||||
{}
|
||||
// return ste.getClassName();
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static int countOccurences(String input, String needle)
|
||||
{
|
||||
String out = input.replace (needle, "");
|
||||
int lenDiff = input.length () - out.length ();
|
||||
return lenDiff / needle.length();
|
||||
}
|
||||
}
|
@ -0,0 +1,562 @@
|
||||
package com.jens.rhasspy.shoppinglist;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.management.GarbageCollectorMXBean;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.FileHandler;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.mail.Authenticator;
|
||||
import javax.mail.Message;
|
||||
import javax.mail.PasswordAuthentication;
|
||||
import javax.mail.Session;
|
||||
import javax.mail.Transport;
|
||||
import javax.mail.internet.AddressException;
|
||||
import javax.mail.internet.InternetAddress;
|
||||
import javax.mail.internet.MimeMessage;
|
||||
|
||||
public class Miscellaneous
|
||||
{
|
||||
protected static Calendar logDate;
|
||||
static Logger logger = Logger.getLogger(Miscellaneous.class.getName());
|
||||
static FileHandler fileHandler = null;
|
||||
|
||||
|
||||
public static final String genericErrorMessage = "sldaskdm32oierror";
|
||||
|
||||
protected static boolean logCleanerRunning = false;
|
||||
|
||||
static File getLogFileFullPath()
|
||||
{
|
||||
File logFile;
|
||||
File folder = new File(Settings.logFolderPath);
|
||||
|
||||
if((folder.exists() && folder.canWrite()) | folder.mkdir())
|
||||
logFile = new File(folder.getAbsolutePath() + "/" + Settings.logFileName);
|
||||
else
|
||||
logFile = new File(Settings.logFileName);
|
||||
|
||||
// System.out.println("Using " + logFile.getAbsolutePath().toString() + " as log file path.");
|
||||
|
||||
return logFile;
|
||||
}
|
||||
|
||||
public static String formatDate(Date input)
|
||||
{
|
||||
DateFormat sdf = null;
|
||||
SimpleDateFormat fallBackFormatter = new SimpleDateFormat(Settings.dateFormat);
|
||||
|
||||
if(sdf == null && Settings.dateFormat != null)
|
||||
sdf = new SimpleDateFormat(Settings.dateFormat);
|
||||
|
||||
String formattedDate;
|
||||
if(sdf != null)
|
||||
formattedDate = sdf.format(input);
|
||||
else
|
||||
formattedDate = fallBackFormatter.format(input);
|
||||
|
||||
return formattedDate;
|
||||
}
|
||||
|
||||
public static synchronized void logEvent(String eventDescription, int logLevel)
|
||||
{
|
||||
if(logLevel <= Settings.logLevel)
|
||||
{
|
||||
logDate = Calendar.getInstance();
|
||||
|
||||
String formattedDate = Miscellaneous.formatDate(logDate.getTime());
|
||||
|
||||
String callingClass = Thread.currentThread().getStackTrace()[2].getClassName();
|
||||
|
||||
String textToLog = Diverse.lineSeparator + formattedDate + ": " + callingClass + ": " + eventDescription;
|
||||
|
||||
File logFile = getLogFileFullPath();
|
||||
|
||||
if(!logFile.exists())
|
||||
{
|
||||
try
|
||||
{
|
||||
logFile.createNewFile();
|
||||
}
|
||||
catch (IOException e1)
|
||||
{
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Files.write(Paths.get(logFile.toString()), textToLog.getBytes(), StandardOpenOption.APPEND);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
//exception handling left as an exercise for the reader
|
||||
// System.out.println("Error appending to file " + logFile + ": " + Diverse.getStackTraceAsString(e));
|
||||
}
|
||||
|
||||
if(Miscellaneous.isDevelopment())
|
||||
System.out.println(textToLog);
|
||||
|
||||
if(!logCleanerRunning && Math.random() < 0.01) // tidy up with 0,1% probability
|
||||
{
|
||||
logCleanerRunning = true;
|
||||
|
||||
Miscellaneous.logEvent("Cleaning up log file.", 3);
|
||||
|
||||
long maxSizeInBytes = (long)Settings.logMaxSize * 1024 * 1024;
|
||||
|
||||
if(logFile.exists() && logFile.length() > (maxSizeInBytes))
|
||||
{
|
||||
File archivedLogFile = new File(logFile.getAbsolutePath() + "-old");
|
||||
logFile.renameTo(archivedLogFile);
|
||||
Miscellaneous.logEvent("Log renamed to " + archivedLogFile.getAbsolutePath(), 3);
|
||||
}
|
||||
|
||||
Miscellaneous.logEvent("Cleaning up log file finished.", 3);
|
||||
|
||||
logCleanerRunning = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static String getGCStats()
|
||||
{
|
||||
StringBuilder returnString = new StringBuilder();
|
||||
|
||||
long totalGarbageCollections = 0;
|
||||
long garbageCollectionTime = 0;
|
||||
|
||||
for(GarbageCollectorMXBean gc : ManagementFactory.getGarbageCollectorMXBeans())
|
||||
{
|
||||
|
||||
long count = gc.getCollectionCount();
|
||||
|
||||
if(count >= 0) {
|
||||
totalGarbageCollections += count;
|
||||
}
|
||||
|
||||
long time = gc.getCollectionTime();
|
||||
|
||||
if(time >= 0)
|
||||
garbageCollectionTime += time;
|
||||
}
|
||||
|
||||
returnString.append("Total Garbage Collections: " + totalGarbageCollections + Diverse.lineSeparator);
|
||||
returnString.append("Total Garbage Collection Time (ms): " + garbageCollectionTime);
|
||||
|
||||
return returnString.toString();
|
||||
}
|
||||
|
||||
public static class SmtpSimple
|
||||
{
|
||||
/**
|
||||
* Send a single email.
|
||||
*/
|
||||
public boolean sendEmail(String mailServer, int mailServerPor, String encryptionType, boolean useAuthentication, final String username, final String password, String aFromEmailAddr, String aToEmailAddr, String aSubject, String aBody)
|
||||
{
|
||||
// Properties über die Systemeigenschaften anlegen
|
||||
Properties properties = System.getProperties();
|
||||
|
||||
properties.setProperty("mail.smtp.host", mailServer);
|
||||
properties.setProperty("mail.smtp.port", String.valueOf(mailServerPor));
|
||||
|
||||
properties.setProperty("mail.smtp.auth", String.valueOf(useAuthentication));
|
||||
|
||||
/*
|
||||
* final Properties props = new Properties();
|
||||
* props.put("mail.smtp.host", "SMTPHOST");
|
||||
* props.put("mail.smtp.port", "PORTNUMBER");
|
||||
* props.put("mail.transport.protocol","smtp");
|
||||
* props.put("mail.smtp.auth", "true");
|
||||
* props.put("mail.smtp.starttls.enable", "true");
|
||||
* props.put("mail.smtp.tls", "true");
|
||||
* props.put("mail.smtp.ssl.checkserveridentity", "true");
|
||||
*/
|
||||
|
||||
if(encryptionType.equalsIgnoreCase("STARTTLS"))
|
||||
properties.setProperty("mail.smtp.starttls.enable", "true");
|
||||
else if(encryptionType.equalsIgnoreCase("TLS"))
|
||||
properties.put("mail.smtp.tls", "true");
|
||||
else if(encryptionType.equalsIgnoreCase("SSL"))
|
||||
properties.setProperty("mail.smtp.ssl.enable", "true");
|
||||
|
||||
// properties.put("mail.smtp.ssl.checkserveridentity", "false");
|
||||
|
||||
Session session;
|
||||
|
||||
Authenticator auth = new Authenticator()
|
||||
{
|
||||
protected PasswordAuthentication getPasswordAuthentication()
|
||||
{
|
||||
return new PasswordAuthentication(username, password);
|
||||
}
|
||||
};
|
||||
|
||||
if(useAuthentication)
|
||||
session = Session.getDefaultInstance(properties, auth);
|
||||
else
|
||||
session= Session.getDefaultInstance(properties, null);
|
||||
|
||||
// session.setDebug(true);
|
||||
|
||||
MimeMessage message = new MimeMessage(session);
|
||||
try
|
||||
{
|
||||
//the "from" address may be set in code, or set in the
|
||||
//config file under "mail.from" ; here, the latter style is used
|
||||
message.setFrom(new InternetAddress(aFromEmailAddr));
|
||||
message.addRecipient(Message.RecipientType.TO, new InternetAddress(aToEmailAddr));
|
||||
message.setSubject(aSubject);
|
||||
message.setText(aBody);
|
||||
Transport.send(message);
|
||||
return true;
|
||||
}
|
||||
catch (AddressException e)
|
||||
{
|
||||
System.err.println("Cannot send email. " + Diverse.getStackTraceAsString(e));
|
||||
}
|
||||
catch (javax.mail.MessagingException e)
|
||||
{
|
||||
System.err.println("Cannot send email. " + Diverse.getStackTraceAsString(e));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static String readFile(File file)
|
||||
{
|
||||
String content = null;
|
||||
try
|
||||
{
|
||||
FileReader reader = new FileReader(file);
|
||||
char[] chars = new char[(int) file.length()];
|
||||
reader.read(chars);
|
||||
content = new String(chars);
|
||||
reader.close();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
return content;
|
||||
}
|
||||
|
||||
public static double convertCelsiusToFahrenheit(double celsius)
|
||||
{
|
||||
return (celsius * 1.8 + 32);
|
||||
}
|
||||
|
||||
public static double convertFahrenheitToCelsius(double fahrenheit)
|
||||
{
|
||||
return ((fahrenheit - 32)/1.8);
|
||||
}
|
||||
|
||||
public static String downloadWebpage(String urlAddress)
|
||||
{
|
||||
URL url;
|
||||
InputStream is = null;
|
||||
BufferedReader br = null;
|
||||
String line;
|
||||
|
||||
try
|
||||
{
|
||||
url = new URL(urlAddress);
|
||||
is = url.openStream(); // throws an IOException
|
||||
br = new BufferedReader(new InputStreamReader(is));
|
||||
|
||||
StringBuilder returnString = new StringBuilder();
|
||||
|
||||
while ((line = br.readLine()) != null)
|
||||
{
|
||||
// System.out.println(line);
|
||||
returnString.append(line);
|
||||
}
|
||||
|
||||
if(br != null)
|
||||
br.close();
|
||||
|
||||
if (is != null)
|
||||
is.close();
|
||||
|
||||
Miscellaneous.logEvent("Webpage downloaded: " + returnString.toString(), 5);
|
||||
|
||||
return returnString.toString();
|
||||
}
|
||||
catch (MalformedURLException mue)
|
||||
{
|
||||
mue.printStackTrace();
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
ioe.printStackTrace();
|
||||
}
|
||||
finally
|
||||
{
|
||||
try
|
||||
{
|
||||
if(br != null)
|
||||
br.close();
|
||||
|
||||
if (is != null)
|
||||
is.close();
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
// nothing to see here
|
||||
}
|
||||
}
|
||||
|
||||
return genericErrorMessage;
|
||||
}
|
||||
|
||||
public static boolean isDevelopment()
|
||||
{
|
||||
Boolean desenv = null;
|
||||
|
||||
// if (desenv != null)
|
||||
// return desenv;
|
||||
|
||||
try
|
||||
{
|
||||
desenv = new File(".").getCanonicalPath().contains("workspace");
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return desenv;
|
||||
}
|
||||
|
||||
public static String getOnOffStringForBoolean(boolean state)
|
||||
{
|
||||
if(state)
|
||||
return "on";
|
||||
else
|
||||
return "off";
|
||||
}
|
||||
|
||||
// public enum SolarEvent { dawn, sunrise, solarNoon, sunset, dusk };
|
||||
|
||||
/**
|
||||
*
|
||||
* @param commandToExecute
|
||||
* @param timeout
|
||||
* @return Returns an array: 0=exit code, 1=cmdline output
|
||||
*/
|
||||
public static Object[] runExternalApplication(String commandToExecute, long timeout)
|
||||
{
|
||||
/*
|
||||
* Classes stolen from https://github.com/stleary/JSON-java
|
||||
*/
|
||||
|
||||
Miscellaneous.logEvent("Running external application " + commandToExecute + "...", 4);
|
||||
|
||||
Object[] returnObject = new Object[2];
|
||||
|
||||
StringBuilder output = new StringBuilder();
|
||||
String line = null;
|
||||
OutputStream stdin = null;
|
||||
InputStream stderr = null;
|
||||
InputStream stdout = null;
|
||||
|
||||
try
|
||||
{
|
||||
Process process = null;
|
||||
|
||||
process = Runtime.getRuntime().exec(commandToExecute);
|
||||
stdin = process.getOutputStream ();
|
||||
stderr = process.getErrorStream ();
|
||||
stdout = process.getInputStream ();
|
||||
|
||||
// "write" the parms into stdin
|
||||
/*line = "param1" + "\n";
|
||||
stdin.write(line.getBytes() );
|
||||
stdin.flush();
|
||||
|
||||
line = "param2" + "\n";
|
||||
stdin.write(line.getBytes() );
|
||||
stdin.flush();
|
||||
|
||||
line = "param3" + "\n";
|
||||
stdin.write(line.getBytes() );
|
||||
stdin.flush();
|
||||
|
||||
stdin.close(); */
|
||||
|
||||
// clean up if any output in stdout
|
||||
BufferedReader brCleanUp = new BufferedReader (new InputStreamReader (stdout));
|
||||
while ((line = brCleanUp.readLine ()) != null)
|
||||
{
|
||||
Miscellaneous.logEvent ("[Stdout] " + line, 4);
|
||||
output.append(line);
|
||||
}
|
||||
brCleanUp.close();
|
||||
|
||||
// clean up if any output in stderr
|
||||
brCleanUp = new BufferedReader (new InputStreamReader (stderr));
|
||||
while ((line = brCleanUp.readLine ()) != null)
|
||||
{
|
||||
Miscellaneous.logEvent ("[Stderr] " + line, 4);
|
||||
output.append(line);
|
||||
}
|
||||
brCleanUp.close();
|
||||
|
||||
try
|
||||
{
|
||||
// Wait for the process to exit, we want the return code
|
||||
if(timeout > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
if(!process.waitFor(timeout, TimeUnit.MILLISECONDS))
|
||||
{
|
||||
Miscellaneous.logEvent("Timeout of " + String.valueOf(timeout) + " ms reached. Killing check attempt.", 3);
|
||||
process.destroyForcibly();
|
||||
}
|
||||
}
|
||||
catch(NoSuchMethodError e)
|
||||
{
|
||||
process.waitFor();
|
||||
}
|
||||
}
|
||||
else
|
||||
process.waitFor();
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
Miscellaneous.logEvent("Waiting for process failed: " + Diverse.getStackTraceAsString(e), 4);
|
||||
Miscellaneous.logEvent(Diverse.getStackTraceAsString(e), 1);
|
||||
}
|
||||
|
||||
Miscellaneous.logEvent("ReturnCode: " + String.valueOf(process.exitValue()), 4);
|
||||
|
||||
returnObject[0] = process.exitValue();
|
||||
returnObject[1] = output.toString();
|
||||
|
||||
return returnObject;
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
Miscellaneous.logEvent(Diverse.getStackTraceAsString(e), 1);
|
||||
}
|
||||
|
||||
Miscellaneous.logEvent("Error running external application.", 1);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean restartNode()
|
||||
{
|
||||
// return true;
|
||||
return (boolean) runExternalApplication("sudo shutdown -r", 60000)[0];
|
||||
}
|
||||
|
||||
public static boolean isLeapYear(int year)
|
||||
{
|
||||
boolean leap = false;
|
||||
|
||||
if(year % 4 == 0)
|
||||
{
|
||||
if( year % 100 == 0)
|
||||
{
|
||||
// year is divisible by 400, hence the year is a leap year
|
||||
if ( year % 400 == 0)
|
||||
leap = true;
|
||||
else
|
||||
leap = false;
|
||||
}
|
||||
else
|
||||
leap = true;
|
||||
}
|
||||
else
|
||||
leap = false;
|
||||
|
||||
return leap;
|
||||
|
||||
/*if(leap)
|
||||
System.out.println(year + " is a leap year.");
|
||||
else
|
||||
System.out.println(year + " is not a leap year.");*/
|
||||
}
|
||||
|
||||
public static double getStarDate(Calendar when)
|
||||
{
|
||||
int y = when.get(Calendar.YEAR);
|
||||
|
||||
int n = 0;
|
||||
if(Miscellaneous.isLeapYear(y))
|
||||
n = 366;
|
||||
else
|
||||
n = 365;
|
||||
|
||||
int b = 2005;
|
||||
|
||||
long c = 58000;
|
||||
|
||||
int d = when.get(Calendar.DAY_OF_MONTH);
|
||||
|
||||
int m = 0;
|
||||
switch(when.get(Calendar.MONTH))
|
||||
{
|
||||
case Calendar.JANUARY:
|
||||
m = 0;
|
||||
break;
|
||||
case Calendar.FEBRUARY:
|
||||
m = 31;
|
||||
break;
|
||||
case Calendar.MARCH:
|
||||
m = 59;
|
||||
break;
|
||||
case Calendar.APRIL:
|
||||
m = 90;
|
||||
break;
|
||||
case Calendar.MAY:
|
||||
m = 120;
|
||||
break;
|
||||
case Calendar.JUNE:
|
||||
m = 151;
|
||||
break;
|
||||
case Calendar.JULY:
|
||||
m = 181;
|
||||
break;
|
||||
case Calendar.AUGUST:
|
||||
m = 212;
|
||||
break;
|
||||
case Calendar.SEPTEMBER:
|
||||
m = 243;
|
||||
break;
|
||||
case Calendar.OCTOBER:
|
||||
m = 273;
|
||||
break;
|
||||
case Calendar.NOVEMBER:
|
||||
m = 304;
|
||||
break;
|
||||
case Calendar.DECEMBER:
|
||||
m = 334;
|
||||
break;
|
||||
}
|
||||
|
||||
double stardate = c + (1000 * (y-b)) + (1000/n * (m+d-1));
|
||||
|
||||
return stardate;
|
||||
}
|
||||
}
|
194
ShoppingList/src/com/jens/rhasspy/shoppinglist/Product.java
Normal file
194
ShoppingList/src/com/jens/rhasspy/shoppinglist/Product.java
Normal file
@ -0,0 +1,194 @@
|
||||
package com.jens.rhasspy.shoppinglist;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.sql.Types;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class Product
|
||||
{
|
||||
static ArrayList<Product> productCache = null;
|
||||
|
||||
long id;
|
||||
String name;
|
||||
String synonyms;
|
||||
StoreType storeType;
|
||||
|
||||
public long getId()
|
||||
{
|
||||
return id;
|
||||
}
|
||||
public void setId(long id)
|
||||
{
|
||||
this.id = id;
|
||||
}
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
public void setName(String name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getSynonyms()
|
||||
{
|
||||
return synonyms;
|
||||
}
|
||||
public void setSynonyms(String synonyms)
|
||||
{
|
||||
this.synonyms = synonyms;
|
||||
}
|
||||
public static ArrayList<Product> readAllProducts()
|
||||
{
|
||||
if(productCache == null)
|
||||
{
|
||||
try
|
||||
{
|
||||
Connection conn = DatabaseHandler.getInstance().getConnection();
|
||||
|
||||
if(conn == null)
|
||||
Start.exitWithError(Settings.languageBlock.get("dbCouldNotConnect"));
|
||||
|
||||
PreparedStatement preparedStmt = null;
|
||||
|
||||
String query = "SELECT * FROM products";
|
||||
|
||||
preparedStmt = conn.prepareStatement(query);
|
||||
|
||||
Miscellaneous.logEvent(preparedStmt.toString(), 5);
|
||||
|
||||
ResultSet res = preparedStmt.executeQuery();
|
||||
|
||||
productCache = new ArrayList<Product>();
|
||||
|
||||
while (res.next())
|
||||
{
|
||||
Product p = new Product();
|
||||
|
||||
p.setId(res.getLong("id"));
|
||||
p.setName(res.getString("name"));
|
||||
p.setSynonyms(res.getString("synonyms"));
|
||||
|
||||
StoreType st = StoreType.getById(res.getLong("storeTypeId"));
|
||||
p.setStoreType(st);
|
||||
|
||||
productCache.add(p);
|
||||
}
|
||||
|
||||
res.close();
|
||||
preparedStmt.close();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Start.exitWithError(Settings.languageBlock.get("dbCouldNotConnect"));
|
||||
}
|
||||
}
|
||||
|
||||
return productCache;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
return ((Product)obj).getName().equalsIgnoreCase(getName());
|
||||
}
|
||||
|
||||
public static Product getByName(String productName)
|
||||
{
|
||||
for(Product p : readAllProducts())
|
||||
{
|
||||
if(p.getName().equalsIgnoreCase(productName))
|
||||
return p;
|
||||
else if(p.getName().equalsIgnoreCase(productName.replace("-", " ")))
|
||||
return p;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return getName();
|
||||
}
|
||||
|
||||
public static Product getById(long id)
|
||||
{
|
||||
for(Product p : readAllProducts())
|
||||
{
|
||||
if(p.getId() == id)
|
||||
return p;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
public StoreType getStoreType()
|
||||
{
|
||||
return storeType;
|
||||
}
|
||||
public void setStoreType(StoreType storeType)
|
||||
{
|
||||
this.storeType = storeType;
|
||||
}
|
||||
|
||||
public boolean create()
|
||||
{
|
||||
String query = "INSERT INTO nodes (name, synonyms, storeTypeId) VALUES (?, ?, ?)";
|
||||
Connection conn = DatabaseHandler.getInstance().getConnection();
|
||||
PreparedStatement preparedStmt = null;
|
||||
try
|
||||
{
|
||||
preparedStmt = conn.prepareStatement(query, Statement.RETURN_GENERATED_KEYS);
|
||||
|
||||
preparedStmt.setString(1, this.getName());
|
||||
|
||||
if(this.getSynonyms() == null)
|
||||
preparedStmt.setNull(2, Types.VARCHAR);
|
||||
else
|
||||
preparedStmt.setString(2, getSynonyms());
|
||||
|
||||
preparedStmt.setLong(3, getStoreType().getId());
|
||||
|
||||
preparedStmt.executeUpdate();
|
||||
ResultSet rs = preparedStmt.getGeneratedKeys();
|
||||
if (rs.next())
|
||||
{
|
||||
this.setId(rs.getInt(1));
|
||||
Miscellaneous.logEvent("INSERT-ID: " + String.valueOf(this.getId()), 5);
|
||||
|
||||
rs.close();
|
||||
preparedStmt.close();
|
||||
|
||||
Miscellaneous.logEvent("Product has been successfully created.", 2);
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
rs.close();
|
||||
String error = "Insert new product failed.";
|
||||
Miscellaneous.logEvent(error, 1);
|
||||
}
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
Miscellaneous.logEvent(Diverse.getStackTraceAsString(e), 1);
|
||||
}
|
||||
finally
|
||||
{
|
||||
try
|
||||
{
|
||||
if(preparedStmt != null && !preparedStmt.isClosed())
|
||||
preparedStmt.close();
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
118
ShoppingList/src/com/jens/rhasspy/shoppinglist/Settings.java
Normal file
118
ShoppingList/src/com/jens/rhasspy/shoppinglist/Settings.java
Normal file
@ -0,0 +1,118 @@
|
||||
package com.jens.rhasspy.shoppinglist;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
public class Settings
|
||||
{
|
||||
public static Map<String,String> languageBlock = new HashMap<>();
|
||||
|
||||
// Settings from file
|
||||
public static String databaseUsername;
|
||||
public static String databasePassword;
|
||||
public static String databaseName;
|
||||
public static String[] databaseServerNames;
|
||||
public static int databasePort;
|
||||
public static String logFolderPath;
|
||||
public static String notificationFromAddress;
|
||||
public static String[] notificationToAddresses;
|
||||
public static String notificationMailServer;
|
||||
public static int notificationMailServerPort;
|
||||
public static String notificationEncryptionType;
|
||||
public static boolean notificationAuthenticate;
|
||||
public static String notificationUsername;
|
||||
public static String notificationPassword;
|
||||
public static String language;
|
||||
public static int logLevel = 1; // Set a default value as logging is performed before settings can be loaded.
|
||||
|
||||
// Constants not user modifiable.
|
||||
public static final String programName = "ShoppingList";
|
||||
public static final String logFileName = programName + "LogFile.txt";
|
||||
public static final String settingsFileName = programName + "-settings.ini";
|
||||
public static final String dateFormat = "dd.MM.yyyy HH:mm:ss:SSSS";
|
||||
public static final int logMaxSize = 5000; // Set a default value as logging is performed before settings can be loaded.
|
||||
public static final boolean notificationsEnabled = true;
|
||||
public static final int notificationVerbosity = 2;
|
||||
|
||||
public static boolean readSettings()
|
||||
{
|
||||
File sFile = new File(settingsFileName);
|
||||
Miscellaneous.logEvent("Loading settings from " + sFile.getAbsolutePath(), 3);
|
||||
|
||||
Properties prop = new Properties();
|
||||
|
||||
try
|
||||
{
|
||||
// Local settings from settings file
|
||||
prop.load(new FileInputStream(sFile));
|
||||
|
||||
databaseUsername = prop.getProperty("databaseUsername", "error");
|
||||
databasePassword = prop.getProperty("databasePassword", "error");
|
||||
databaseName = prop.getProperty("databaseName", "error");
|
||||
databaseServerNames = prop.getProperty("databaseServerNames", "error").split(",");
|
||||
databasePort = Integer.parseInt(prop.getProperty("databasePort", "error"));
|
||||
logFolderPath = prop.getProperty("logFolderPath", "error");
|
||||
notificationFromAddress = prop.getProperty("notificationFromAddress", "error");
|
||||
notificationToAddresses = prop.getProperty("notificationToAddresses", "error").split(",");
|
||||
notificationMailServer = prop.getProperty("notificationMailServer", "error");
|
||||
notificationMailServerPort = Integer.parseInt(prop.getProperty("notificationMailServerPort", "error"));
|
||||
notificationEncryptionType = prop.getProperty("notificationEncryptionType", "error");
|
||||
notificationAuthenticate = Boolean.parseBoolean(prop.getProperty("notificationEncryptionType", "error"));
|
||||
notificationUsername = prop.getProperty("notificationUsername", "error");
|
||||
notificationPassword = prop.getProperty("notificationPassword", "error");
|
||||
language = prop.getProperty("language", "error");
|
||||
logLevel = Integer.parseInt(prop.getProperty("logLevel", "1"));
|
||||
}
|
||||
catch (FileNotFoundException e)
|
||||
{
|
||||
Start.exitWithError(Settings.languageBlock.get("settingsFileNotFound") + " " + settingsFileName);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
Start.exitWithError(Settings.languageBlock.get("settingsCouldNotBeRead") + " " + settingsFileName);
|
||||
}
|
||||
|
||||
fillLanguageVariable();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void fillLanguageVariable()
|
||||
{
|
||||
if(language != null && language.equalsIgnoreCase("de"))
|
||||
{
|
||||
languageBlock.put("dbCouldNotConnect", "Konnte nicht zur Datenbank verbinden.");
|
||||
languageBlock.put("dbDriverNotFound", "Datenbanktreiber nicht gefunden.");
|
||||
languageBlock.put("settingsFileNotFound", "Konfigurationsdatei nicht gefunden.");
|
||||
languageBlock.put("settingsCouldNotBeRead", "Konfigurationsdatei konnte nicht gelesen werden.");
|
||||
languageBlock.put("noActionDefined", "Keine Aktion angegeben.");
|
||||
languageBlock.put("couldNotCreateList", "Konnte keine Liste anlegen.");
|
||||
languageBlock.put("productNotFound", "Produkt nicht gefunden.");
|
||||
languageBlock.put("couldNotAddProdToList", "Produkt konnte nicht auf die Liste gesetzt werden.");
|
||||
languageBlock.put("noProdSpecified", "Kein Produkt angegeben.");
|
||||
languageBlock.put("couldNotRemoveProdFromList", "Produkt konnte nicht von Liste entfernt werden.");
|
||||
languageBlock.put("couldNotSendList", "Liste konnte nicht verschickt werden.");
|
||||
languageBlock.put("couldNotCreateNewList", "Neue Liste konnte nicht erstellt werden.");
|
||||
}
|
||||
else
|
||||
{
|
||||
languageBlock.put("dbCouldNotConnect", "Could not connect to database.");
|
||||
languageBlock.put("dbDriverNotFound", "Database driver not found.");
|
||||
languageBlock.put("settingsFileNotFound", "Configuration file not found.");
|
||||
languageBlock.put("settingsCouldNotBeRead", "Could not read configuration file.");
|
||||
languageBlock.put("noActionDefined", "No action specified.");
|
||||
languageBlock.put("couldNotCreateList", "Could not create list.");
|
||||
languageBlock.put("productNotFound", "Product not found.");
|
||||
languageBlock.put("couldNotAddProdToList", "Product could not be added to list.");
|
||||
languageBlock.put("noProdSpecified", "No product specified.");
|
||||
languageBlock.put("couldNotRemoveProdFromList", "Product could not be removed from list.");
|
||||
languageBlock.put("couldNotSendList", "List could not be sent.");
|
||||
languageBlock.put("couldNotCreateNewList", "New list could not be created.");
|
||||
}
|
||||
}
|
||||
}
|
254
ShoppingList/src/com/jens/rhasspy/shoppinglist/ShoppingList.java
Normal file
254
ShoppingList/src/com/jens/rhasspy/shoppinglist/ShoppingList.java
Normal file
@ -0,0 +1,254 @@
|
||||
package com.jens.rhasspy.shoppinglist;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
|
||||
public class ShoppingList
|
||||
{
|
||||
long id;
|
||||
Calendar creationTime;
|
||||
String comment;
|
||||
ArrayList<ShoppingListEntry> entries = new ArrayList<>();
|
||||
|
||||
public long getId()
|
||||
{
|
||||
return id;
|
||||
}
|
||||
public void setId(long id)
|
||||
{
|
||||
this.id = id;
|
||||
}
|
||||
public Calendar getCreationTime()
|
||||
{
|
||||
return creationTime;
|
||||
}
|
||||
public void setCreationTime(Calendar creationTime)
|
||||
{
|
||||
this.creationTime = creationTime;
|
||||
}
|
||||
public String getComment()
|
||||
{
|
||||
return comment;
|
||||
}
|
||||
public void setComment(String comment)
|
||||
{
|
||||
this.comment = comment;
|
||||
}
|
||||
|
||||
public boolean create()
|
||||
{
|
||||
PreparedStatement preparedStmt = null;
|
||||
Connection conn = null;
|
||||
try
|
||||
{
|
||||
conn = DatabaseHandler.getInstance().getConnection();
|
||||
|
||||
String parentQuery = "INSERT INTO lists (id, creationTime, comment) VALUES (?, ?, ?)";
|
||||
preparedStmt = conn.prepareStatement(parentQuery, Statement.RETURN_GENERATED_KEYS);
|
||||
|
||||
preparedStmt.setLong(1, this.getId());
|
||||
preparedStmt.setLong(2, this.getCreationTime().getTimeInMillis());
|
||||
if(comment != null)
|
||||
preparedStmt.setString(3, this.getComment());
|
||||
else
|
||||
preparedStmt.setNull(3, java.sql.Types.VARCHAR);
|
||||
|
||||
Miscellaneous.logEvent(preparedStmt.toString(), 5);
|
||||
|
||||
long numAffectedRows = preparedStmt.executeUpdate();
|
||||
Miscellaneous.logEvent("AMOUNT OF UPDATED ROWS: " + numAffectedRows, 5);
|
||||
ResultSet rs = preparedStmt.getGeneratedKeys();
|
||||
if (numAffectedRows > 0)
|
||||
{
|
||||
if (rs.next())
|
||||
{
|
||||
this.setId(rs.getInt(1));
|
||||
rs.close();
|
||||
Miscellaneous.logEvent("INSERT-ID: " + String.valueOf(this.getId()), 5);
|
||||
preparedStmt.close();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent(Diverse.getStackTraceAsString(e), 1);
|
||||
}
|
||||
finally
|
||||
{
|
||||
try
|
||||
{
|
||||
if(preparedStmt != null && !preparedStmt.isClosed())
|
||||
preparedStmt.close();
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static ShoppingList getMostRecentList()
|
||||
{
|
||||
ShoppingList resultList = null;
|
||||
|
||||
PreparedStatement preparedStmt = null;
|
||||
try
|
||||
{
|
||||
Connection conn = DatabaseHandler.getInstance().getConnection();
|
||||
|
||||
String query = "SELECT * FROM lists ORDER BY creationTime DESC LIMIT 0,1";
|
||||
|
||||
preparedStmt = conn.prepareStatement(query);
|
||||
|
||||
Miscellaneous.logEvent(preparedStmt.toString(), 5);
|
||||
|
||||
ResultSet res = preparedStmt.executeQuery();
|
||||
|
||||
if (res.next())
|
||||
{
|
||||
resultList = new ShoppingList();
|
||||
resultList.setId(res.getLong("id"));
|
||||
resultList.setCreationTime(Diverse.calendarFromLong(res.getLong("creationTime")));
|
||||
resultList.setComment(res.getString("comment"));
|
||||
}
|
||||
|
||||
res.close();
|
||||
preparedStmt.close();
|
||||
|
||||
if(resultList == null)
|
||||
resultList = createNewList();
|
||||
|
||||
// Read entries
|
||||
if(resultList.getEntries() == null)
|
||||
resultList.setEntries(new ArrayList<>());
|
||||
resultList.getEntries().clear();
|
||||
|
||||
query = "SELECT * FROM listEntries WHERE listId=?";
|
||||
|
||||
preparedStmt = conn.prepareStatement(query);
|
||||
preparedStmt.setLong(1, resultList.getId());
|
||||
|
||||
Miscellaneous.logEvent(preparedStmt.toString(), 5);
|
||||
|
||||
res = preparedStmt.executeQuery();
|
||||
|
||||
while (res.next())
|
||||
{
|
||||
ShoppingListEntry entry = new ShoppingListEntry();
|
||||
entry.setParentList(resultList);
|
||||
entry.setProduct(Product.getById(res.getLong("productId")));
|
||||
resultList.getEntries().add(entry);
|
||||
}
|
||||
|
||||
res.close();
|
||||
preparedStmt.close();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent(Diverse.getStackTraceAsString(e), 1);
|
||||
}
|
||||
finally
|
||||
{
|
||||
try
|
||||
{
|
||||
if(preparedStmt != null && !preparedStmt.isClosed())
|
||||
preparedStmt.close();
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
if(resultList == null)
|
||||
resultList = createNewList();
|
||||
|
||||
return resultList;
|
||||
}
|
||||
|
||||
public boolean send()
|
||||
{
|
||||
StringBuilder shoppingListString = new StringBuilder();
|
||||
|
||||
if(comment != null)
|
||||
shoppingListString.append("(" + comment + ")" + Diverse.lineSeparator);
|
||||
|
||||
ArrayList<StoreType> storeTypesInUse = new ArrayList<>();
|
||||
for(ShoppingListEntry entry : this.entries)
|
||||
{
|
||||
if(!storeTypesInUse.contains(entry.getProduct().getStoreType()))
|
||||
{
|
||||
storeTypesInUse.add(entry.getProduct().getStoreType());
|
||||
}
|
||||
}
|
||||
|
||||
for(StoreType st : storeTypesInUse)
|
||||
{
|
||||
shoppingListString.append(st.getName() + Diverse.lineSeparator + "=======================" + Diverse.lineSeparator);
|
||||
|
||||
for(ShoppingListEntry entry : this.entries)
|
||||
{
|
||||
if(entry.getProduct().getStoreType().equals(st))
|
||||
shoppingListString.append(entry.getProduct().getName() + Diverse.lineSeparator);
|
||||
}
|
||||
|
||||
shoppingListString.append(Diverse.lineSeparator);
|
||||
}
|
||||
|
||||
Miscellaneous.SmtpSimple smtp = new Miscellaneous.SmtpSimple();
|
||||
try
|
||||
{
|
||||
boolean result = true;
|
||||
for(String address : Settings.notificationToAddresses)
|
||||
{
|
||||
if(!smtp.sendEmail(Settings.notificationMailServer, Settings.notificationMailServerPort, Settings.notificationEncryptionType, Settings.notificationAuthenticate, Settings.notificationUsername, Settings.notificationPassword, Settings.notificationFromAddress, address, "Einkaufsliste", shoppingListString.toString()))
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
|
||||
if(result)
|
||||
{
|
||||
Miscellaneous.logEvent("Successfully sent shopping list to all recipients via server " + Settings.notificationMailServer, 2);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
Miscellaneous.logEvent("Error sending shopping list.", 2);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent("Error sending shopping list: " + Diverse.getStackTraceAsString(e), 2);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public ArrayList<ShoppingListEntry> getEntries()
|
||||
{
|
||||
return entries;
|
||||
}
|
||||
public void setEntries(ArrayList<ShoppingListEntry> entries)
|
||||
{
|
||||
this.entries = entries;
|
||||
}
|
||||
|
||||
public static ShoppingList createNewList()
|
||||
{
|
||||
ShoppingList returnList = new ShoppingList();
|
||||
returnList.setCreationTime(Calendar.getInstance());
|
||||
if(returnList.create())
|
||||
return returnList;
|
||||
else
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "Liste erstellt am " + Miscellaneous.formatDate(getCreationTime().getTime());
|
||||
}
|
||||
}
|
@ -0,0 +1,121 @@
|
||||
package com.jens.rhasspy.shoppinglist;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.Calendar;
|
||||
|
||||
public class ShoppingListEntry
|
||||
{
|
||||
ShoppingList parentList;
|
||||
Product product;
|
||||
|
||||
public ShoppingList getParentList()
|
||||
{
|
||||
return parentList;
|
||||
}
|
||||
|
||||
public void setParentList(ShoppingList parentList)
|
||||
{
|
||||
this.parentList = parentList;
|
||||
}
|
||||
|
||||
public Product getProduct()
|
||||
{
|
||||
return product;
|
||||
}
|
||||
|
||||
public void setProduct(Product product)
|
||||
{
|
||||
this.product = product;
|
||||
}
|
||||
|
||||
public boolean create()
|
||||
{
|
||||
PreparedStatement preparedStmt = null;
|
||||
Connection conn = null;
|
||||
try
|
||||
{
|
||||
conn = DatabaseHandler.getInstance().getConnection();
|
||||
|
||||
String parentQuery = "INSERT IGNORE INTO listEntries (listId, productId) VALUES (?, ?)";
|
||||
preparedStmt = conn.prepareStatement(parentQuery, Statement.RETURN_GENERATED_KEYS);
|
||||
|
||||
preparedStmt.setLong(1, this.getParentList().getId());
|
||||
preparedStmt.setLong(2, this.getProduct().getId());
|
||||
|
||||
Miscellaneous.logEvent(preparedStmt.toString(), 5);
|
||||
|
||||
long numAffectedRows = preparedStmt.executeUpdate();
|
||||
Miscellaneous.logEvent("AMOUNT OF UPDATED ROWS: " + numAffectedRows, 5);
|
||||
ResultSet rs = preparedStmt.getGeneratedKeys();
|
||||
// if (numAffectedRows > 0)
|
||||
// {
|
||||
preparedStmt.close();
|
||||
return true;
|
||||
// }
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent(Diverse.getStackTraceAsString(e), 1);
|
||||
}
|
||||
finally
|
||||
{
|
||||
try
|
||||
{
|
||||
if(preparedStmt != null && !preparedStmt.isClosed())
|
||||
preparedStmt.close();
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean delete()
|
||||
{
|
||||
PreparedStatement preparedStmt = null;
|
||||
Connection conn = null;
|
||||
try
|
||||
{
|
||||
conn = DatabaseHandler.getInstance().getConnection();
|
||||
|
||||
String parentQuery = "DELETE FROM listEntries WHERE listId=? AND productId=?";
|
||||
preparedStmt = conn.prepareStatement(parentQuery, Statement.RETURN_GENERATED_KEYS);
|
||||
|
||||
preparedStmt.setLong(1, this.getParentList().getId());
|
||||
preparedStmt.setLong(2, this.getProduct().getId());
|
||||
|
||||
Miscellaneous.logEvent(preparedStmt.toString(), 5);
|
||||
|
||||
long numAffectedRows = preparedStmt.executeUpdate();
|
||||
Miscellaneous.logEvent("AMOUNT OF UPDATED ROWS: " + numAffectedRows, 5);
|
||||
ResultSet rs = preparedStmt.getGeneratedKeys();
|
||||
// if (numAffectedRows > 0)
|
||||
// {
|
||||
preparedStmt.close();
|
||||
return true;
|
||||
// }
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent(Diverse.getStackTraceAsString(e), 1);
|
||||
}
|
||||
finally
|
||||
{
|
||||
try
|
||||
{
|
||||
if(preparedStmt != null && !preparedStmt.isClosed())
|
||||
preparedStmt.close();
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
228
ShoppingList/src/com/jens/rhasspy/shoppinglist/Start.java
Normal file
228
ShoppingList/src/com/jens/rhasspy/shoppinglist/Start.java
Normal file
@ -0,0 +1,228 @@
|
||||
package com.jens.rhasspy.shoppinglist;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
public class Start
|
||||
{
|
||||
public static void main(String[] args)
|
||||
{
|
||||
String productName = null;
|
||||
String action = null;
|
||||
String filePath = null;
|
||||
|
||||
List<String> argsList = new ArrayList<String>();
|
||||
List<String> optsList = new ArrayList<String>();
|
||||
List<String> doubleOptsList = new ArrayList<String>();
|
||||
for (int i=0; i < args.length; i++)
|
||||
{
|
||||
switch (args[i].charAt(0))
|
||||
{
|
||||
case '-':
|
||||
if (args[i].charAt(1) == '-')
|
||||
{
|
||||
int len = 0;
|
||||
String argstring = args[i].toString();
|
||||
len = argstring.length();
|
||||
// System.out.println("Found double dash with command " + argstring.substring(2, len) );
|
||||
String argName = argstring.substring(2, len);
|
||||
doubleOptsList.add(argName);
|
||||
if(argName.equalsIgnoreCase("shoppingProduct"))
|
||||
productName = args[i+1].replace("\"", "");
|
||||
else if(argName.equalsIgnoreCase("action"))
|
||||
action = args[i+1].replace("\"", "");
|
||||
else if(argName.equalsIgnoreCase("filePath"))
|
||||
filePath = args[i+1].replace("\"", "");
|
||||
}
|
||||
else
|
||||
{
|
||||
// System.out.println("Found dash with command " + args[i].charAt(1) + " and value " + args[i+1] );
|
||||
i= i+1;
|
||||
optsList.add(args[i]);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// System.out.println("Add a default arg." );
|
||||
argsList.add(args[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Settings.readSettings();
|
||||
|
||||
if(action == null)
|
||||
{
|
||||
System.out.println(Settings.languageBlock.get("noActionDefined"));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
switch(action)
|
||||
{
|
||||
case "addToList":
|
||||
if(!StringUtils.isEmpty(productName))
|
||||
{
|
||||
ShoppingList list = ShoppingList.getMostRecentList();
|
||||
Product p = Product.getByName(productName);
|
||||
|
||||
if(list == null)
|
||||
exitWithError(Settings.languageBlock.get("couldNotCreateList"));
|
||||
|
||||
if(p == null)
|
||||
exitWithError(Settings.languageBlock.get("productNotFound") + " " + productName);
|
||||
|
||||
ShoppingListEntry entry = new ShoppingListEntry();
|
||||
entry.setParentList(list);
|
||||
entry.setProduct(p);
|
||||
|
||||
if(entry.create())
|
||||
{
|
||||
DatabaseHandler.getInstance().disconnect();
|
||||
System.exit(0);
|
||||
}
|
||||
else
|
||||
exitWithError(Settings.languageBlock.get("couldNotAddProdToList") + " " + productName);
|
||||
}
|
||||
else
|
||||
System.out.println(Settings.languageBlock.get("noProdSpecified"));
|
||||
break;
|
||||
case "removeFromList":
|
||||
if(!StringUtils.isEmpty(productName))
|
||||
{
|
||||
ShoppingList list = ShoppingList.getMostRecentList();
|
||||
Product p = Product.getByName(productName);
|
||||
|
||||
if(list == null)
|
||||
exitWithError(Settings.languageBlock.get("couldNotCreateList"));
|
||||
|
||||
if(p == null)
|
||||
exitWithError(Settings.languageBlock.get("productNotFound") + " " + productName);
|
||||
|
||||
for(ShoppingListEntry entry : list.getEntries())
|
||||
{
|
||||
if(entry.getProduct().equals(p))
|
||||
{
|
||||
if(entry.delete())
|
||||
{
|
||||
DatabaseHandler.getInstance().disconnect();
|
||||
System.exit(0);
|
||||
}
|
||||
else
|
||||
Miscellaneous.logEvent(Settings.languageBlock.get("couldNotRemoveProdFromList") + " " + productName, 2);
|
||||
}
|
||||
}
|
||||
// If it wasn't on the list - why care?
|
||||
DatabaseHandler.getInstance().disconnect();
|
||||
System.exit(0);
|
||||
}
|
||||
else
|
||||
System.out.println(Settings.languageBlock.get("noProdSpecified"));
|
||||
break;
|
||||
case "sendList":
|
||||
if(ShoppingList.getMostRecentList().send())
|
||||
{
|
||||
// System.out.println("Liste wurde verschickt.");
|
||||
DatabaseHandler.getInstance().disconnect();
|
||||
System.exit(0);
|
||||
}
|
||||
else
|
||||
System.out.println(Settings.languageBlock.get("couldNotSendList"));
|
||||
break;
|
||||
case "resetList":
|
||||
if(ShoppingList.createNewList() != null)
|
||||
{
|
||||
// System.out.println("Neue Liste erstellt");
|
||||
DatabaseHandler.getInstance().disconnect();
|
||||
System.exit(0);
|
||||
}
|
||||
else
|
||||
System.out.println(Settings.languageBlock.get("couldNotCreateNewList"));
|
||||
break;
|
||||
case "importProducts":
|
||||
File importFile = new File(filePath);
|
||||
importFile(importFile);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
exitWithError(null);
|
||||
}
|
||||
|
||||
static void exitWithError(String errorText)
|
||||
{
|
||||
if(!StringUtils.isEmpty(errorText))
|
||||
{
|
||||
System.out.println(errorText);
|
||||
Miscellaneous.logEvent("Exiting with error: " + errorText, 1);
|
||||
}
|
||||
else
|
||||
Miscellaneous.logEvent("Exiting with empty error.", 1);
|
||||
|
||||
DatabaseHandler.getInstance().disconnect();
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
static boolean importFile(File importFile)
|
||||
{
|
||||
try
|
||||
{
|
||||
if(!importFile.exists())
|
||||
exitWithError("File does not exist.");
|
||||
|
||||
if(!importFile.canRead())
|
||||
exitWithError("Cannot read file.");
|
||||
|
||||
String fileContent = Miscellaneous.readFile(importFile).trim();
|
||||
|
||||
if(StringUtils.isEmpty(fileContent))
|
||||
exitWithError("File is empty.");
|
||||
|
||||
int errorCounter = 0;
|
||||
|
||||
outerLoop:
|
||||
for(String line : fileContent.split(Diverse.lineSeparator))
|
||||
{
|
||||
String[] synonyms = line.split(":");
|
||||
String product = synonyms[synonyms.length -1];
|
||||
|
||||
for(Product existingProduct : Product.readAllProducts())
|
||||
{
|
||||
if(existingProduct.getName().equalsIgnoreCase(product))
|
||||
continue outerLoop;
|
||||
}
|
||||
|
||||
Product newProduct = new Product();
|
||||
newProduct.setName(product);
|
||||
newProduct.setStoreType(StoreType.readAllStoreTypes().get(0));
|
||||
|
||||
if(synonyms.length > 1)
|
||||
{
|
||||
String syns = synonyms[0].substring(1, synonyms[0].length()-1);
|
||||
syns = syns.replace("|", ";");
|
||||
newProduct.setSynonyms(syns);
|
||||
}
|
||||
|
||||
if(!newProduct.create())
|
||||
{
|
||||
Miscellaneous.logEvent("Failed to import product " + newProduct.getName(), 1);
|
||||
errorCounter++;
|
||||
}
|
||||
}
|
||||
|
||||
if(errorCounter > 0)
|
||||
System.out.println("Import complete with " + String.valueOf(errorCounter) + ".");
|
||||
else
|
||||
System.out.println("Import complete without errors.");
|
||||
|
||||
return true;
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
@ -0,0 +1,97 @@
|
||||
package com.jens.rhasspy.shoppinglist;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class StoreType
|
||||
{
|
||||
long id;
|
||||
String name;
|
||||
|
||||
static ArrayList<StoreType> storeTypeCache = null;
|
||||
|
||||
public static ArrayList<StoreType> readAllStoreTypes()
|
||||
{
|
||||
if(storeTypeCache == null)
|
||||
{
|
||||
try
|
||||
{
|
||||
storeTypeCache = new ArrayList<StoreType>();
|
||||
|
||||
Connection conn = DatabaseHandler.getInstance().getConnection();
|
||||
PreparedStatement preparedStmt = null;
|
||||
|
||||
String query = "SELECT id, name FROM storeTypes";
|
||||
|
||||
preparedStmt = conn.prepareStatement(query);
|
||||
|
||||
Miscellaneous.logEvent(preparedStmt.toString(), 5);
|
||||
|
||||
ResultSet res = preparedStmt.executeQuery();
|
||||
|
||||
while (res.next())
|
||||
{
|
||||
StoreType st = new StoreType();
|
||||
|
||||
st.setId(res.getLong("id"));
|
||||
st.setName(res.getString("name"));
|
||||
|
||||
storeTypeCache.add(st);
|
||||
}
|
||||
|
||||
res.close();
|
||||
preparedStmt.close();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return storeTypeCache;
|
||||
}
|
||||
|
||||
public long getId()
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id)
|
||||
{
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
return name.equalsIgnoreCase(((StoreType)obj).getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return this.getName();
|
||||
}
|
||||
|
||||
public static StoreType getById(long id)
|
||||
{
|
||||
for(StoreType st : readAllStoreTypes())
|
||||
{
|
||||
if(st.getId() == id)
|
||||
return st;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user