Initial commit

This commit is contained in:
Jens 2021-02-03 22:49:24 +01:00
commit a1ee3cf1b5
15 changed files with 2421 additions and 0 deletions

11
ShoppingList/.classpath Normal file
View 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
View 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
View 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>

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

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

View 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();
}
}

View File

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

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

View 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.");
}
}
}

View 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());
}
}

View File

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

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

View File

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