diff --git a/ma-impl.sublime-workspace b/ma-impl.sublime-workspace index 12a293e29ec5b63837bfab546db8548fe2b2fa01..01b7a763d8d9090c7061359839b6ef57e3d12f48 100644 --- a/ma-impl.sublime-workspace +++ b/ma-impl.sublime-workspace @@ -279,18 +279,18 @@ "build_varint": "", "command_palette": { - "height": 375.0, - "last_filter": "close", + "height": 231.0, + "last_filter": "insta", "selected_items": [ - [ - "close", - "Project: Close" - ], [ "insta", "Package Control: Install Package" ], + [ + "close", + "Project: Close" + ], [ "synr", "Set Syntax: R" @@ -450,23 +450,54 @@ "expanded_folders": [ "/home/eike/Repositories/fu/ss15/ma/impl", - "/home/eike/Repositories/fu/ss15/ma/impl/vipra-ui" + "/home/eike/Repositories/fu/ss15/ma/impl/vipra-ui/app", + "/home/eike/Repositories/fu/ss15/ma/impl/vipra-ui/app/templates/articles", + "/home/eike/Repositories/fu/ss15/ma/impl/vipra-ui/app/templates/components", + "/home/eike/Repositories/fu/ss15/ma/impl/vm" ], "file_history": [ - "/home/eike/Repositories/fu/ss15/ma/impl/vipra-ui/bower.json", - "/home/eike/Repositories/fu/ss15/ma/impl/vipra-ui/bower_components/ember/ember.js", - "/home/eike/Repositories/fu/ss15/ma/impl/vipra-ui/app/routes/articles.js", - "/home/eike/Repositories/fu/ss15/ma/impl/vipra-ui/package.json", + "/home/eike/Repositories/fu/ss15/ma/impl/vipra-ui/app/components/article-list.js", + "/home/eike/Repositories/fu/ss15/ma/impl/vipra-ui/app/components/text-marker.js", + "/home/eike/Repositories/fu/ss15/ma/impl/vipra-ui/app/components/debounced-input.js", + "/home/eike/Repositories/fu/ss15/ma/impl/vipra-ui/app/components/dynamic-high-charts.js", + "/home/eike/Repositories/fu/ss15/ma/impl/vipra-ui/app/templates/components/text-marker.hbs", + "/home/eike/Repositories/fu/ss15/ma/impl/vipra-ui/app/templates/components/article-list.hbs", + "/home/eike/Repositories/fu/ss15/ma/impl/vipra-ui/app/templates/articles/list.hbs", + "/home/eike/Repositories/fu/ss15/ma/impl/vm/bootstrap.sh", + "/home/eike/Repositories/fu/ss15/ma/impl/vipra-ui/app/adapters/application.js", + "/home/eike/Repositories/fu/ss15/ma/impl/vipra-ui/app/routes/articles/list.js", + "/home/eike/Repositories/fu/ss15/ma/impl/vipra-ui/app/templates/articles/show.hbs", + "/home/eike/Repositories/fu/ss15/ma/impl/vipra-ui/app/components/filter-text.js", + "/home/eike/Repositories/fu/ss15/ma/impl/vm/webapps/test/index.html", + "/home/eike/Repositories/fu/ss15/ma/impl/vipra-ui/app/controllers/articles/list.js", + "/home/eike/Repositories/fu/ss15/ma/impl/vipra-ui/app/router.js", + "/home/eike/Repositories/fu/ss15/ma/impl/vipra-ui/app/index.html", + "/home/eike/Repositories/fu/ss15/ma/impl/vipra-ui/app/components/search-box.js", + "/home/eike/Repositories/fu/ss15/ma/impl/vipra-ui/app/templates/loading.hbs", + "/home/eike/Repositories/fu/ss15/ma/impl/vipra-ui/app/templates/not-found.hbs", "/home/eike/Repositories/fu/ss15/ma/impl/vipra-ui/app/templates/articles.hbs", "/home/eike/Repositories/fu/ss15/ma/impl/vipra-ui/app/models/article.js", - "/home/eike/Repositories/fu/ss15/ma/impl/vipra-ui/app/router.js", - "/home/eike/Repositories/fu/ss15/ma/impl/vipra-ui/app/adapters/application.js", + "/home/eike/Repositories/fu/ss15/ma/impl/vipra-ui/app/templates/index.hbs", + "/home/eike/Repositories/fu/ss15/ma/impl/vipra-ui/app/routes/articles/index.js", + "/home/eike/Repositories/fu/ss15/ma/impl/vipra-ui/app/routes/article.js", + "/home/eike/Repositories/fu/ss15/ma/impl/vipra-ui/app/templates/articles/index.hbs", + "/home/eike/Repositories/fu/ss15/ma/impl/vipra-ui/app/templates/articles/new.hbs", + "/home/eike/Repositories/fu/ss15/ma/impl/vipra-ui/app/routes/article/show.js", + "/home/eike/Repositories/fu/ss15/ma/impl/vipra-ui/app/templates/article.hbs", + "/home/eike/Repositories/fu/ss15/ma/impl/vipra-ui/app/routes/articles.js", + "/home/eike/Repositories/fu/ss15/ma/impl/vipra-ui/app/templates/articles.show.hbs", + "/home/eike/Repositories/fu/ss15/ma/impl/vipra-ui/app/routes/articles.show.js", + "/home/eike/Repositories/fu/ss15/ma/impl/vipra-ui/app/templates/articles/test.hbs", + "/home/eike/Repositories/fu/ss15/ma/impl/vipra-ui/.ember-cli", + "/home/eike/Repositories/fu/ss15/ma/impl/vipra-ui/bower_components/ember-data/ember-data.js", + "/home/eike/Repositories/fu/ss15/ma/impl/vipra-ui/bower_components/ember/ember.js", + "/home/eike/Repositories/fu/ss15/ma/impl/vipra-ui/app/templates/application.hbs", "/home/eike/Repositories/fu/ss15/ma/impl/vipra-ui/app/serializers/application.js", + "/home/eike/Repositories/fu/ss15/ma/impl/vipra-ui/bower.json", + "/home/eike/Repositories/fu/ss15/ma/impl/vipra-ui/bower_components/ember/.bower.json", + "/home/eike/Repositories/fu/ss15/ma/impl/vipra-ui/package.json", "/home/eike/Repositories/fu/ss15/ma/impl/vipra-ui/app/app.js", - "/home/eike/Repositories/fu/ss15/ma/impl/vipra-ui/app/templates/application.hbs", - "/home/eike/Repositories/fu/ss15/ma/impl/vipra-ui/app/templates/index.hbs", - "/home/eike/Repositories/fu/ss15/ma/impl/vm/bootstrap.sh", "/home/eike/Repositories/fu/ss15/ma/doc/thesis/thesis.tex", "/home/eike/Repositories/fu/ss15/ma/impl/Vagrantfile", "/home/eike/Repositories/fu/ss15/ma/impl/tmbs-processor-backend/src/main/scala/de/cochu/tmbs/processor/MongoDBTest.scala", @@ -583,6 +614,7 @@ "case_sensitive": false, "find_history": [ + "json-api", "\"id\":.*?\\n ", "\"id\":.*?\\n", "\"_id\":", @@ -709,8 +741,7 @@ "!important", "images", "url(\"../images/", - "fa-var", - "account.name" + "fa-var" ], "highlight": true, "in_selection": false, diff --git a/vipra-cmd/.classpath b/vipra-cmd/.classpath index 91251671bf896bb25780ea2ddbe38b6248295e34..1d99666bcace8e15a36c9dd09f3d921742acf5c3 100644 --- a/vipra-cmd/.classpath +++ b/vipra-cmd/.classpath @@ -15,5 +15,6 @@ <attribute name="owner.project.facets" value="java"/> </attributes> </classpathentry> + <classpathentry combineaccessrules="false" kind="src" path="/vipra-util"/> <classpathentry kind="output" path="target/classes"/> </classpath> diff --git a/vipra-cmd/.project b/vipra-cmd/.project index 7457abc9569d7378c1550159176d5982a81e3fe9..42d5a8abc4acc1079b7e84ac965c26a5fce2d48c 100644 --- a/vipra-cmd/.project +++ b/vipra-cmd/.project @@ -33,11 +33,4 @@ <nature>org.eclipse.m2e.core.maven2Nature</nature> <nature>org.eclipse.wst.common.project.facet.core.nature</nature> </natures> - <linkedResources> - <link> - <name>src/main/resources/config.properties</name> - <type>1</type> - <locationURI>PARENT-1-PROJECT_LOC/vipra-config/config.properties</locationURI> - </link> - </linkedResources> </projectDescription> diff --git a/vipra-cmd/src/main/java/de/vipra/cmd/Configuration.java b/vipra-cmd/src/main/java/de/vipra/cmd/Configuration.java deleted file mode 100644 index c30776997c935ebb74d0a18dc0674b6399664249..0000000000000000000000000000000000000000 --- a/vipra-cmd/src/main/java/de/vipra/cmd/Configuration.java +++ /dev/null @@ -1,41 +0,0 @@ -package de.vipra.cmd; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Properties; - -public class Configuration extends Properties { - - private static final long serialVersionUID = 1L; - - public static final String DEFAULT_HOST = "localhost"; - public static final int DEFAULT_PORT = 27017; - public static final String DEFAULT_DB = "test"; - - public Configuration() { - this(Thread.currentThread().getContextClassLoader().getResourceAsStream("config.properties")); - } - - public Configuration(InputStream in) { - try { - load(in); - } catch (IOException e) {} - } - - public String getString(String key, String defaultValue) { - return getProperty(key, defaultValue); - } - - public int getInt(String key, int defaultValue) { - try { - return Integer.parseInt(getProperty(key, Integer.toString(defaultValue))); - } catch (NumberFormatException e) { - return defaultValue; - } - } - - public boolean getBool(String key, boolean defaultValue) { - return Boolean.parseBoolean(getProperty(key, Boolean.toString(defaultValue))); - } - -} diff --git a/vipra-cmd/src/main/java/de/vipra/cmd/Main.java b/vipra-cmd/src/main/java/de/vipra/cmd/Main.java index 34ea6ee604935ad706b0a70ea79aee773f4a4bd7..287f10cc6d587c4faeb692770f5cb764982415fe 100644 --- a/vipra-cmd/src/main/java/de/vipra/cmd/Main.java +++ b/vipra-cmd/src/main/java/de/vipra/cmd/Main.java @@ -1,15 +1,22 @@ package de.vipra.cmd; +import java.io.IOException; + import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.CommandLineParser; import org.apache.commons.cli.DefaultParser; import org.apache.commons.cli.ParseException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import de.vipra.cmd.option.ImportOption; +import de.vipra.util.ConfigException; public class Main { - public static void main(String[] args) { + public static final Logger log = LoggerFactory.getLogger(Main.class); + + public static void main(String[] args) throws IOException, ConfigException { CommandLineParser parser = new DefaultParser(); CmdOptions options = new CmdOptions(); try { @@ -25,7 +32,9 @@ public class Main { } } catch (ParseException e) { options.printHelp(); - } catch (ExecutionException e) {} + } catch (ExecutionException e) { + log.error(e.getMessage()); + } } } diff --git a/vipra-cmd/src/main/java/de/vipra/cmd/MongoDB.java b/vipra-cmd/src/main/java/de/vipra/cmd/MongoDB.java deleted file mode 100644 index 9025c1bdad81f7486996bd5275dd1ad908b2c7a6..0000000000000000000000000000000000000000 --- a/vipra-cmd/src/main/java/de/vipra/cmd/MongoDB.java +++ /dev/null @@ -1,45 +0,0 @@ -package de.vipra.cmd; - -import com.mongodb.MongoClient; -import com.mongodb.client.MongoDatabase; - -public class MongoDB { - - private static MongoDB mongo; - - private final MongoClient client; - private final MongoDatabase db; - - private MongoDB(Configuration config) { - String host = config.getString("db.host", Configuration.DEFAULT_HOST); - Integer port = config.getInt("db.port", Configuration.DEFAULT_PORT); - String databaseName = config.getString("db.name", Configuration.DEFAULT_DB); - - client = new MongoClient(host, port); - db = client.getDatabase(databaseName); - } - - public MongoClient getClient() { - return client; - } - - public MongoDatabase getDatabase() { - return db; - } - - public static MongoDB getInstance() { - if (mongo == null) { - Configuration config = new Configuration(); - mongo = new MongoDB(config); - } - return mongo; - } - - public static MongoDB getInstance(Configuration config) { - if (mongo == null) { - mongo = new MongoDB(config); - } - return mongo; - } - -} diff --git a/vipra-cmd/src/main/java/de/vipra/cmd/option/ImportOption.java b/vipra-cmd/src/main/java/de/vipra/cmd/option/ImportOption.java index 25b02a08acb073f9cb1d6b81eabcbc5213a6c5b3..e8a61d32e0215922c526c79193c243b6237b6b0f 100644 --- a/vipra-cmd/src/main/java/de/vipra/cmd/option/ImportOption.java +++ b/vipra-cmd/src/main/java/de/vipra/cmd/option/ImportOption.java @@ -12,15 +12,24 @@ import org.json.simple.parser.JSONParser; import org.json.simple.parser.ParseException; import de.vipra.cmd.ExecutionException; -import de.vipra.cmd.MongoDB; +import de.vipra.util.Config; +import de.vipra.util.ConfigException; +import de.vipra.util.Mongo; public class ImportOption { private ArrayList<File> files = new ArrayList<>(); private JSONParser parser = new JSONParser(); - private MongoDB mongo = MongoDB.getInstance(); + private Config config; + private Mongo mongo; public ImportOption(String[] paths) throws ExecutionException { + try { + config = new Config(); + mongo = Mongo.getInstance(config); + } catch (IOException | ConfigException e) { + throw new ExecutionException(e.getMessage()); + } addPaths(paths); } @@ -70,14 +79,18 @@ public class ImportOption { } private void importArticle(JSONObject obj) { - + // 1. add article to mongodb + // 2. add article to file database + // 4. topic modeling + // 3. index article via elasticsearch, include topics } public void doImport() { for (File file : files) { try { importFile(file); - } catch (Exception e) {} + } catch (Exception e) { + } } } diff --git a/vipra-config/config.properties b/vipra-cmd/src/main/resources/config.properties similarity index 100% rename from vipra-config/config.properties rename to vipra-cmd/src/main/resources/config.properties diff --git a/vipra-rest/.classpath b/vipra-rest/.classpath index 6acf3eeecaebe2d096ef46a44bf6988db916e316..d8728319c5ba6bfc3e74f4b13ce346e356fab451 100644 --- a/vipra-rest/.classpath +++ b/vipra-rest/.classpath @@ -28,10 +28,11 @@ <attribute name="org.eclipse.jst.component.dependency" value="/WEB-INF/lib"/> </attributes> </classpathentry> - <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"> <attributes> - <attribute name="maven.pomderived" value="true"/> + <attribute name="owner.project.facets" value="java"/> </attributes> </classpathentry> + <classpathentry combineaccessrules="false" kind="src" path="/vipra-util"/> <classpathentry kind="output" path="target/classes"/> </classpath> diff --git a/vipra-rest/.project b/vipra-rest/.project index e9151f1e0a91e271e7af97b5faf74f81d3f160bf..e24244ea68a972f817781145661bc0723916096b 100644 --- a/vipra-rest/.project +++ b/vipra-rest/.project @@ -4,6 +4,7 @@ <comment></comment> <projects> <project>vipra-cmd</project> + <project>vipra-util</project> </projects> <buildSpec> <buildCommand> @@ -40,11 +41,4 @@ <nature>org.eclipse.wst.common.project.facet.core.nature</nature> <nature>org.eclipse.wst.jsdt.core.jsNature</nature> </natures> - <linkedResources> - <link> - <name>src/main/resources/config.properties</name> - <type>1</type> - <locationURI>PARENT-1-PROJECT_LOC/vipra-config/config.properties</locationURI> - </link> - </linkedResources> </projectDescription> diff --git a/vipra-rest/.settings/org.eclipse.jdt.core.prefs b/vipra-rest/.settings/org.eclipse.jdt.core.prefs index c07c252bc5d05edd0375e06b1d52f0a921ae65a0..7677f45f763923b768652ded0a1422b2b83c6d77 100644 --- a/vipra-rest/.settings/org.eclipse.jdt.core.prefs +++ b/vipra-rest/.settings/org.eclipse.jdt.core.prefs @@ -1,16 +1,16 @@ eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.compliance=1.7 org.eclipse.jdt.core.compiler.debug.lineNumber=generate org.eclipse.jdt.core.compiler.debug.localVariable=generate org.eclipse.jdt.core.compiler.debug.sourceFile=generate org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning -org.eclipse.jdt.core.compiler.source=1.8 +org.eclipse.jdt.core.compiler.source=1.7 org.eclipse.jdt.core.formatter.align_type_members_on_columns=false org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 diff --git a/vipra-rest/.settings/org.eclipse.wst.common.component b/vipra-rest/.settings/org.eclipse.wst.common.component index bfc7ecd2c55b87f9f307cc7ca345597974f27cb9..df9f1cfb7b6d2d1e0bfd7425e36690f2b9f64b0c 100644 --- a/vipra-rest/.settings/org.eclipse.wst.common.component +++ b/vipra-rest/.settings/org.eclipse.wst.common.component @@ -4,6 +4,9 @@ <wb-resource deploy-path="/" source-path="/src/main/webapp" tag="defaultRootSource"/> <wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/java"/> <wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/resources"/> + <dependent-module archiveName="vipra-util.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/vipra-util/vipra-util"> + <dependency-type>uses</dependency-type> + </dependent-module> <property name="java-output-path" value="/vipra-rest/target/classes"/> <property name="context-root" value="vipra-rest"/> </wb-module> diff --git a/vipra-rest/.settings/org.eclipse.wst.common.project.facet.core.xml b/vipra-rest/.settings/org.eclipse.wst.common.project.facet.core.xml index d59fb58d14dd57692727e9b2e695dd99cd5929ce..984341746468874acc75524c80a2579ccee81217 100644 --- a/vipra-rest/.settings/org.eclipse.wst.common.project.facet.core.xml +++ b/vipra-rest/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -4,5 +4,5 @@ <installed facet="wst.jsdt.web" version="1.0"/> <installed facet="jst.jaxrs" version="2.0"/> <installed facet="jst.web" version="3.1"/> - <installed facet="java" version="1.8"/> + <installed facet="java" version="1.7"/> </faceted-project> diff --git a/vipra-rest/pom.xml b/vipra-rest/pom.xml index 804ffc3676547e48a94e764de5269de75487a2eb..a7b384aa66170c7f9ddcba6c7dadd4da23cb12af 100644 --- a/vipra-rest/pom.xml +++ b/vipra-rest/pom.xml @@ -12,8 +12,8 @@ <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> - <maven.compiler.target>1.8</maven.compiler.target> - <maven.compiler.source>1.8</maven.compiler.source> + <maven.compiler.target>1.7</maven.compiler.target> + <maven.compiler.source>1.7</maven.compiler.source> <jerseyVersion>2.22.1</jerseyVersion> <jettyVersion>9.3.6.v20151106</jettyVersion> <servletVersion>3.1.0</servletVersion> @@ -29,7 +29,7 @@ </dependency> <dependency> <groupId>org.glassfish.jersey.media</groupId> - <!--<artifactId>jersey-media-moxy</artifactId>--> + <!--<artifactId>jersey-media-moxy</artifactId> --> <artifactId>jersey-media-json-jackson</artifactId> <version>${jerseyVersion}</version> </dependency> @@ -43,6 +43,11 @@ <artifactId>jersey-test-framework-provider-simple</artifactId> <version>${jerseyVersion}</version> </dependency> + <dependency> + <groupId>com.github.fge</groupId> + <artifactId>json-patch</artifactId> + <version>1.9</version> + </dependency> <!-- Servlet API --> <dependency> @@ -50,7 +55,7 @@ <artifactId>javax.servlet-api</artifactId> <version>${servletVersion}</version> </dependency> - + <!-- Logging --> <dependency> <groupId>org.apache.logging.log4j</groupId> diff --git a/vipra-rest/src/main/java/de/vipra/rest/Application.java b/vipra-rest/src/main/java/de/vipra/rest/Application.java index 632b4c8fc73b985bd0f7063bf8901f32f276fded..3a105f81c74b4f98258b6d1d2db1b5e3d74412ff 100644 --- a/vipra-rest/src/main/java/de/vipra/rest/Application.java +++ b/vipra-rest/src/main/java/de/vipra/rest/Application.java @@ -6,6 +6,7 @@ import org.glassfish.jersey.server.ResourceConfig; import de.vipra.rest.provider.APIRequestFilter; import de.vipra.rest.provider.CORSResponseFilter; import de.vipra.rest.provider.ObjectMapperProvider; +import de.vipra.rest.provider.PatchReaderInterceptor; public class Application extends ResourceConfig { @@ -15,6 +16,7 @@ public class Application extends ResourceConfig { register(CORSResponseFilter.class); register(ObjectMapperProvider.class); register(APIRequestFilter.class); + register(PatchReaderInterceptor.class); } } diff --git a/vipra-rest/src/main/java/de/vipra/rest/Configuration.java b/vipra-rest/src/main/java/de/vipra/rest/Configuration.java deleted file mode 100644 index 30b9795d6f94592766796724333814ee5d5c6eca..0000000000000000000000000000000000000000 --- a/vipra-rest/src/main/java/de/vipra/rest/Configuration.java +++ /dev/null @@ -1,50 +0,0 @@ -package de.vipra.rest; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Properties; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class Configuration extends Properties { - - public static final Logger log = LoggerFactory.getLogger(Configuration.class); - - private static final long serialVersionUID = 1L; - - public static final String DEFAULT_HOST = "localhost"; - public static final int DEFAULT_PORT = 27017; - public static final String DEFAULT_DB = "test"; - - public Configuration() { - this(Thread.currentThread().getContextClassLoader().getResourceAsStream("config.properties")); - } - - public Configuration(InputStream in) { - if (in == null) { - log.error("configuration file stream not found"); - } else { - try { - load(in); - } catch (IOException e) {} - } - } - - public String getString(String key, String defaultValue) { - return getProperty(key, defaultValue); - } - - public int getInt(String key, int defaultValue) { - try { - return Integer.parseInt(getProperty(key, Integer.toString(defaultValue))); - } catch (NumberFormatException e) { - return defaultValue; - } - } - - public boolean getBool(String key, boolean defaultValue) { - return Boolean.parseBoolean(getProperty(key, Boolean.toString(defaultValue))); - } - -} diff --git a/vipra-rest/src/main/java/de/vipra/rest/MongoDB.java b/vipra-rest/src/main/java/de/vipra/rest/MongoDB.java deleted file mode 100644 index e219cf3934944a5f00d75bf3e2f923ec992159ad..0000000000000000000000000000000000000000 --- a/vipra-rest/src/main/java/de/vipra/rest/MongoDB.java +++ /dev/null @@ -1,45 +0,0 @@ -package de.vipra.rest; - -import com.mongodb.MongoClient; -import com.mongodb.client.MongoDatabase; - -public class MongoDB { - - private static MongoDB mongo; - - private final MongoClient client; - private final MongoDatabase db; - - private MongoDB(Configuration config) { - String host = config.getString("db.host", Configuration.DEFAULT_HOST); - Integer port = config.getInt("db.port", Configuration.DEFAULT_PORT); - String databaseName = config.getString("db.name", Configuration.DEFAULT_DB); - - client = new MongoClient(host, port); - db = client.getDatabase(databaseName); - } - - public MongoClient getClient() { - return client; - } - - public MongoDatabase getDatabase() { - return db; - } - - public static MongoDB getInstance() { - if (mongo == null) { - Configuration config = new Configuration(); - mongo = new MongoDB(config); - } - return mongo; - } - - public static MongoDB getInstance(Configuration config) { - if (mongo == null) { - mongo = new MongoDB(config); - } - return mongo; - } - -} diff --git a/vipra-rest/src/main/java/de/vipra/rest/PATCH.java b/vipra-rest/src/main/java/de/vipra/rest/PATCH.java new file mode 100644 index 0000000000000000000000000000000000000000..78b80504335a3d1dd80a1e8f17f8680477dc984f --- /dev/null +++ b/vipra-rest/src/main/java/de/vipra/rest/PATCH.java @@ -0,0 +1,17 @@ +package de.vipra.rest; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import javax.ws.rs.HttpMethod; +import javax.ws.rs.NameBinding; + +@Target({ ElementType.METHOD, ElementType.TYPE }) +@Retention(RetentionPolicy.RUNTIME) +@HttpMethod("PATCH") +@Documented +@NameBinding +public @interface PATCH {} \ No newline at end of file diff --git a/vipra-rest/src/main/java/de/vipra/rest/provider/ObjectMapperProvider.java b/vipra-rest/src/main/java/de/vipra/rest/provider/ObjectMapperProvider.java index b818a5f9d115f8ca5e9ea65115d6c2f5f6ba9a3c..7678b4b0ff9af5633917e3eeccab46fe0599c2d9 100644 --- a/vipra-rest/src/main/java/de/vipra/rest/provider/ObjectMapperProvider.java +++ b/vipra-rest/src/main/java/de/vipra/rest/provider/ObjectMapperProvider.java @@ -1,5 +1,7 @@ package de.vipra.rest.provider; +import java.text.SimpleDateFormat; + import javax.ws.rs.ext.ContextResolver; import javax.ws.rs.ext.Provider; @@ -9,11 +11,6 @@ import org.slf4j.LoggerFactory; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; -import com.fasterxml.jackson.databind.module.SimpleModule; - -import de.vipra.rest.model.Article; -import de.vipra.rest.serializer.ArticleDeserializer; -import de.vipra.rest.serializer.ArticleSerializer; @Provider public class ObjectMapperProvider implements ContextResolver<ObjectMapper> { @@ -32,14 +29,10 @@ public class ObjectMapperProvider implements ContextResolver<ObjectMapper> { } public static ObjectMapper createDefaultMapper() { - SimpleModule module = new SimpleModule(); - module.addSerializer(Article.class, new ArticleSerializer()); - module.addDeserializer(Article.class, new ArticleDeserializer()); - final ObjectMapper mapper = new ObjectMapper(); mapper.enable(SerializationFeature.INDENT_OUTPUT); mapper.setSerializationInclusion(Include.NON_NULL); - mapper.registerModule(module); + mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")); return mapper; } diff --git a/vipra-rest/src/main/java/de/vipra/rest/provider/PatchReaderInterceptor.java b/vipra-rest/src/main/java/de/vipra/rest/provider/PatchReaderInterceptor.java new file mode 100644 index 0000000000000000000000000000000000000000..ea7f724260cff7dda1443bdb440733c32705a1ba --- /dev/null +++ b/vipra-rest/src/main/java/de/vipra/rest/provider/PatchReaderInterceptor.java @@ -0,0 +1,113 @@ +package de.vipra.rest.provider; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; + +import com.github.fge.jsonpatch.JsonPatch; +import com.github.fge.jsonpatch.JsonPatchException; + +import de.vipra.rest.PATCH; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Method; + +import javax.ws.rs.GET; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.MultivaluedHashMap; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.UriInfo; +import javax.ws.rs.ext.MessageBodyWriter; +import javax.ws.rs.ext.Provider; +import javax.ws.rs.ext.ReaderInterceptor; +import javax.ws.rs.ext.ReaderInterceptorContext; + +import org.glassfish.jersey.message.MessageBodyWorkers; + +@Provider +@PATCH +public class PatchReaderInterceptor implements ReaderInterceptor { + private UriInfo info; + private MessageBodyWorkers workers; + + @Context + public void setInfo(UriInfo info) { + this.info = info; + } + + @Context + public void setWorkers(MessageBodyWorkers workers) { + this.workers = workers; + } + + @Override + public Object aroundReadFrom(ReaderInterceptorContext readerInterceptorContext) + throws IOException, WebApplicationException { + + // Get the resource we are being called on, + // and find the GET method + Object resource = info.getMatchedResources().get(0); + + Method found = null; + for (Method next : resource.getClass().getMethods()) { + if (next.getAnnotation(GET.class) != null) { + found = next; + break; + } + } + + if (found != null) { + + // Invoke the get method to get the state we are trying to patch + // + Object bean; + try { + bean = found.invoke(resource); + } catch (Exception e) { + throw new WebApplicationException(e); + } + + // Convert this object to a an aray of bytes + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + MessageBodyWriter<? super Object> bodyWriter = workers.getMessageBodyWriter(Object.class, bean.getClass(), + new Annotation[0], MediaType.APPLICATION_JSON_TYPE); + + bodyWriter.writeTo(bean, bean.getClass(), bean.getClass(), new Annotation[0], + MediaType.APPLICATION_JSON_TYPE, new MultivaluedHashMap<String, Object>(), baos); + + // Use the Jackson 2.x classes to convert both the incoming patch + // and the current state of the object into a JsonNode / JsonPatch + ObjectMapper mapper = new ObjectMapper(); + JsonNode serverState = mapper.readValue(baos.toByteArray(), JsonNode.class); + JsonNode patchAsNode = mapper.readValue(readerInterceptorContext.getInputStream(), JsonNode.class); + JsonPatch patch = JsonPatch.fromJson(patchAsNode); + + try { + // Apply the patch + JsonNode result = patch.apply(serverState); + + // Stream the result & modify the stream on the + // readerInterceptor + ByteArrayOutputStream resultAsByteArray = new ByteArrayOutputStream(); + mapper.writeValue(resultAsByteArray, result); + readerInterceptorContext.setInputStream(new ByteArrayInputStream(resultAsByteArray.toByteArray())); + + // Pass control back to the Jersey code + return readerInterceptorContext.proceed(); + + } catch (JsonPatchException e) { + throw new WebApplicationException( + Response.serverError().type("text/plain").entity(e.getMessage()).build()); + } + + } else { + throw new IllegalArgumentException("No matching GET method on resource"); + } + + } +} diff --git a/vipra-rest/src/main/java/de/vipra/rest/resource/ArticleResource.java b/vipra-rest/src/main/java/de/vipra/rest/resource/ArticleResource.java index 605a80ea488ed8988e6e6fd471db69ae0cbaabf4..cc3533782018f2f6217c46835ad878861dcddd6a 100644 --- a/vipra-rest/src/main/java/de/vipra/rest/resource/ArticleResource.java +++ b/vipra-rest/src/main/java/de/vipra/rest/resource/ArticleResource.java @@ -1,6 +1,6 @@ package de.vipra.rest.resource; -import java.io.InputStream; +import java.io.IOException; import java.util.ArrayList; import javax.servlet.ServletContext; @@ -19,13 +19,14 @@ import javax.ws.rs.core.Response; import javax.ws.rs.core.UriInfo; import de.vipra.rest.APIMediaType; -import de.vipra.rest.Configuration; import de.vipra.rest.Messages; -import de.vipra.rest.MongoDB; import de.vipra.rest.model.APIError; import de.vipra.rest.model.Article; import de.vipra.rest.model.ResponseWrapper; import de.vipra.rest.service.ArticleService; +import de.vipra.util.Config; +import de.vipra.util.ConfigException; +import de.vipra.util.Mongo; @Path("articles") public class ArticleResource { @@ -35,10 +36,9 @@ public class ArticleResource { final ArticleService service; - public ArticleResource(@Context ServletContext servletContext) { - InputStream is = servletContext.getResourceAsStream("config.properties"); - Configuration config = new Configuration(is); - MongoDB mongo = MongoDB.getInstance(config); + public ArticleResource(@Context ServletContext servletContext) throws ConfigException, IOException { + Config config = new Config(); + Mongo mongo = Mongo.getInstance(config); service = new ArticleService(mongo.getDatabase()); } @@ -88,7 +88,8 @@ public class ArticleResource { @Path("{id}") public Response deleteArticle(@PathParam("id") String id) { long deleted = service.deleteArticle(id); - switch (Math.toIntExact(deleted)) { + int del = deleted > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) deleted; + switch (del) { case 0: ResponseWrapper<Article> res = new ResponseWrapper<>(); res.addError(new APIError(Response.Status.NOT_FOUND, "Article not found", @@ -107,8 +108,9 @@ public class ArticleResource { @Path("{id}") public Response updateArticle(@PathParam("id") String id, Article article) { long updated = service.updateArticle(uri.getAbsolutePath(), article); + int upd = updated > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) updated; ResponseWrapper<Article> res = new ResponseWrapper<>(); - switch (Math.toIntExact(updated)) { + switch (upd) { case 0: res.addError(new APIError(Response.Status.NOT_FOUND, "Article not found", String.format(Messages.NOT_FOUND, "article", id))); diff --git a/vipra-rest/src/main/java/de/vipra/rest/serializer/ArticleDeserializer.java b/vipra-rest/src/main/java/de/vipra/rest/serializer/ArticleDeserializer.java deleted file mode 100644 index 54152e0b54e4209de180e26bd008a4ad9d713d70..0000000000000000000000000000000000000000 --- a/vipra-rest/src/main/java/de/vipra/rest/serializer/ArticleDeserializer.java +++ /dev/null @@ -1,43 +0,0 @@ -package de.vipra.rest.serializer; - -import java.io.IOException; - -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; -import com.fasterxml.jackson.databind.JsonNode; - -import de.vipra.rest.model.Article; - -import static de.vipra.rest.serializer.Helper.*; - -public class ArticleDeserializer extends JsonDeserializer<Article> { - - @Override - public Article deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException { - Article article = null; - - JsonNode node = p.readValueAsTree(); - if (node != null) { - article = new Article(); - if (node.has("id")) - article.setId(getString(node, "id")); - - if (node.has("attributes")) { - JsonNode attrs = node.get("attributes"); - if (attrs.has("title")) - article.setTitle(getString(attrs, "title")); - if (attrs.has("text")) - article.setText(getString(attrs, "text")); - if (attrs.has("url")) - article.setUrl(getString(attrs, "url")); - if (attrs.has("date")) - article.setDate(stringToDate(getString(attrs, "date"))); - } - } - - return article; - } - -} diff --git a/vipra-rest/src/main/java/de/vipra/rest/serializer/ArticleSerializer.java b/vipra-rest/src/main/java/de/vipra/rest/serializer/ArticleSerializer.java deleted file mode 100644 index b5ce97f963540a3da36c73ce26215290d696d2fd..0000000000000000000000000000000000000000 --- a/vipra-rest/src/main/java/de/vipra/rest/serializer/ArticleSerializer.java +++ /dev/null @@ -1,40 +0,0 @@ -package de.vipra.rest.serializer; - -import de.vipra.rest.model.Article; - -import java.io.IOException; - -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.SerializerProvider; - -import static de.vipra.rest.serializer.Helper.*; - -public class ArticleSerializer extends JsonSerializer<Article> { - - @Override - public void serialize(Article value, JsonGenerator gen, SerializerProvider serializers) - throws IOException, JsonProcessingException { - gen.writeStartObject(); - gen.writeStringField("id", value.getId()); - gen.writeStringField("type", value.getType()); - - if (value.getLinks() != null) - gen.writeObjectField("links", value.getLinks()); - - gen.writeObjectFieldStart("attributes"); - if (value.getTitle() != null) - gen.writeStringField("title", value.getTitle()); - if (value.getText() != null) - gen.writeStringField("text", value.getText()); - if (value.getUrl() != null) - gen.writeStringField("url", value.getUrl()); - if (value.getDate() != null) - gen.writeStringField("date", dateToString(value.getDate())); - gen.writeEndObject(); - - gen.writeEndObject(); - } - -} diff --git a/vipra-rest/src/main/java/de/vipra/rest/serializer/Helper.java b/vipra-rest/src/main/java/de/vipra/rest/serializer/Helper.java deleted file mode 100644 index 09dd2d5ded3efa1c0b847c71628408c2edd898c4..0000000000000000000000000000000000000000 --- a/vipra-rest/src/main/java/de/vipra/rest/serializer/Helper.java +++ /dev/null @@ -1,61 +0,0 @@ -package de.vipra.rest.serializer; - -import java.text.DateFormat; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Date; - -import com.fasterxml.jackson.databind.JsonNode; - -public class Helper { - - public static <T> T get(JsonNode node, String name, T defaultValue, Class<T> type) { - if (node == null) { - return defaultValue; - } - node = node.get(name); - if (node == null) { - return defaultValue; - } - switch (type.getSimpleName()) { - case "String": - return type.cast(node.asText()); - case "Integer": - return type.cast(node.asInt()); - case "Long": - return type.cast(node.asLong()); - } - return null; - } - - public static String getString(JsonNode node, String name, String defaultValue) { - return get(node, name, defaultValue, String.class); - } - - public static String getString(JsonNode node, String name) { - return getString(node, name, null); - } - - public static long getLong(JsonNode node, String name, long defaultValue) { - return get(node, name, defaultValue, Long.class); - } - - public static long getLong(JsonNode node, String name) { - return getLong(node, name, 0L); - } - - public static String dateToString(Date date) { - DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); - return df.format(date); - } - - public static Date stringToDate(String source) { - DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); - try { - return df.parse(source); - } catch (ParseException e) { - return null; - } - } - -} diff --git a/vipra-rest/src/main/resources/config.properties b/vipra-rest/src/main/resources/config.properties new file mode 100644 index 0000000000000000000000000000000000000000..07030840d45dd8fed8c2c2d5bff5fe0a54939a4f --- /dev/null +++ b/vipra-rest/src/main/resources/config.properties @@ -0,0 +1,3 @@ +db.host=localhost +db.port=27017 +db.name=test \ No newline at end of file diff --git a/vipra-rest/src/main/resources/log4j2.xml b/vipra-rest/src/main/resources/log4j2.xml index 8abf1b196fcbb49c3df9551ecb1937bd6491200b..871334005580a7821f2a6e7f7c2517ab454b2e17 100644 --- a/vipra-rest/src/main/resources/log4j2.xml +++ b/vipra-rest/src/main/resources/log4j2.xml @@ -6,8 +6,9 @@ </Console> </Appenders> <Loggers> - <Root level="all"> + <Root level="ALL"> <AppenderRef ref="Console" /> </Root> + <Logger name="org.mongodb" level="INFO"/> </Loggers> </Configuration> \ No newline at end of file diff --git a/vipra-rest/src/main/webapp/WEB-INF/web.xml b/vipra-rest/src/main/webapp/WEB-INF/web.xml index dc73bea3b07729290fc992520ea78d71bcc9bd74..3cfd9841c2652280fb1819e4b627b1cfb1c3405d 100644 --- a/vipra-rest/src/main/webapp/WEB-INF/web.xml +++ b/vipra-rest/src/main/webapp/WEB-INF/web.xml @@ -13,6 +13,6 @@ </servlet> <servlet-mapping> <servlet-name>jersey</servlet-name> - <url-pattern>/rest/*</url-pattern> + <url-pattern>/*</url-pattern> </servlet-mapping> </web-app> \ No newline at end of file diff --git a/vipra-rest/src/main/webapp/index.jsp b/vipra-rest/src/main/webapp/index.jsp deleted file mode 100644 index d4fb745c4314a31b867be2d5000cbd268f3d0533..0000000000000000000000000000000000000000 --- a/vipra-rest/src/main/webapp/index.jsp +++ /dev/null @@ -1 +0,0 @@ -<jsp:forward page="rest/application.wadl"/> \ No newline at end of file diff --git a/vipra-ui/.ember-cli b/vipra-ui/.ember-cli index 4d87e572b4b8d4e7ff643158432ade4809e6b568..ee64cfed2a8905dc23506af1060ec80cf887582d 100644 --- a/vipra-ui/.ember-cli +++ b/vipra-ui/.ember-cli @@ -5,6 +5,5 @@ Setting `disableAnalytics` to true will prevent any data from being sent. */ - "disableAnalytics": false, - "liveReload": false + "disableAnalytics": false } diff --git a/vipra-ui/.project b/vipra-ui/.project new file mode 100644 index 0000000000000000000000000000000000000000..6f683a496d89c3c50ed5a40b7db8a94d7cc29afc --- /dev/null +++ b/vipra-ui/.project @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>vipra-ui</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + </buildSpec> + <natures> + </natures> +</projectDescription> diff --git a/vipra-ui/app/adapters/application.js b/vipra-ui/app/adapters/application.js index dff622652d8735502e01e424cba902813697b8b4..701dadac29a043297224620597aa145d32c1a728 100644 --- a/vipra-ui/app/adapters/application.js +++ b/vipra-ui/app/adapters/application.js @@ -1,6 +1,6 @@ import DS from 'ember-data'; export default DS.JSONAPIAdapter.extend({ - host: 'http://localhost:8080', - namespace: 'vipra-rest/rest' + host: `http://${window.location.hostname}:8000`, + namespace: 'vipra-rest' }); diff --git a/vipra-ui/app/components/article-list.js b/vipra-ui/app/components/article-list.js new file mode 100644 index 0000000000000000000000000000000000000000..afa75e431c88c2ffe6b51b07470e0f53a4be44be --- /dev/null +++ b/vipra-ui/app/components/article-list.js @@ -0,0 +1,15 @@ +import Ember from 'ember'; + + export default Ember.Component.extend({ + + filteredArticles: Ember.computed('articles', 'filter', function() { + var keyword = this.get('filter'); + var filtered = this.get('articles'); + if (keyword) { + keyword = keyword.toLowerCase().trim(); + filtered = this.get('articles').filter((item) => item.get('title').toLowerCase().includes(keyword)); + } + return filtered; + }) + + }); diff --git a/vipra-ui/app/components/debounced-input.js b/vipra-ui/app/components/debounced-input.js new file mode 100644 index 0000000000000000000000000000000000000000..5eee646f9195d06d4092541d6033baffb6dc641c --- /dev/null +++ b/vipra-ui/app/components/debounced-input.js @@ -0,0 +1,14 @@ +import Ember from 'ember'; + +export default Ember.TextField.extend({ + debounce: 500, + fireAtStart: false, + + _elementValueDidChange() { + Ember.run.debounce(this, this._setValue, this.debounce, this.fireAtStart); + }, + + _setValue() { + this.set('value', this.$().val()); + } +}); diff --git a/vipra-ui/app/components/dynamic-high-charts.js b/vipra-ui/app/components/dynamic-high-charts.js new file mode 100644 index 0000000000000000000000000000000000000000..730778b19069c2e2471929011d0ae606ad879dec --- /dev/null +++ b/vipra-ui/app/components/dynamic-high-charts.js @@ -0,0 +1,15 @@ +import Ember from 'ember'; +import EmberHighChartsComponent from 'ember-highcharts/components/high-charts'; + +export default EmberHighChartsComponent.extend({ + + redrawChart: function() { + // add redraw logic here. ex: + var chart = this.get('chart'); + var seriesName = this.get('content')[0].name; + chart.series[0].update({ name: seriesName, data: this.get('content')[0].data }, false); + chart.setTitle(null, { text: seriesName }, false); + chart.redraw(); + }.observes('content.@each.isLoaded') + +}); diff --git a/vipra-ui/app/components/text-marker.js b/vipra-ui/app/components/text-marker.js new file mode 100644 index 0000000000000000000000000000000000000000..0e0518bb943456c9325837bd59c848b9f5f4d435 --- /dev/null +++ b/vipra-ui/app/components/text-marker.js @@ -0,0 +1,18 @@ +import Ember from 'ember'; + +export default Ember.Component.extend({ + + setup: function() { + this.updateTextMarker(); + }.on('init'), + + updateTextMarker: function() { + var text = this.get('text'); + var mark = this.get('mark'); + if(mark) { + text = text.replace(new RegExp(mark, 'ig'), '<b>$&</b>'); + } + this.set('marked', text); + }.observes('text', 'mark') + +}); diff --git a/vipra-ui/app/index.html b/vipra-ui/app/index.html index 5262fdc4819ad91fb2ffbe960c2e524b2a120d59..42eed3eb05d7c4f2e784b32e42d5c2a695a5b03f 100644 --- a/vipra-ui/app/index.html +++ b/vipra-ui/app/index.html @@ -3,10 +3,30 @@ <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> - <title>VipraUi</title> + <title>Vipra</title> <meta name="description" content=""> <meta name="viewport" content="width=device-width, initial-scale=1"> + <link rel="apple-touch-icon" sizes="57x57" href="/apple-touch-icon-57x57.png"> + <link rel="apple-touch-icon" sizes="60x60" href="/apple-touch-icon-60x60.png"> + <link rel="apple-touch-icon" sizes="72x72" href="/apple-touch-icon-72x72.png"> + <link rel="apple-touch-icon" sizes="76x76" href="/apple-touch-icon-76x76.png"> + <link rel="apple-touch-icon" sizes="114x114" href="/apple-touch-icon-114x114.png"> + <link rel="apple-touch-icon" sizes="120x120" href="/apple-touch-icon-120x120.png"> + <link rel="apple-touch-icon" sizes="144x144" href="/apple-touch-icon-144x144.png"> + <link rel="apple-touch-icon" sizes="152x152" href="/apple-touch-icon-152x152.png"> + <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon-180x180.png"> + <link rel="icon" type="image/png" href="/favicon-32x32.png" sizes="32x32"> + <link rel="icon" type="image/png" href="/favicon-194x194.png" sizes="194x194"> + <link rel="icon" type="image/png" href="/favicon-96x96.png" sizes="96x96"> + <link rel="icon" type="image/png" href="/android-chrome-192x192.png" sizes="192x192"> + <link rel="icon" type="image/png" href="/favicon-16x16.png" sizes="16x16"> + <link rel="manifest" href="/manifest.json"> + <link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5"> + <meta name="msapplication-TileColor" content="#da532c"> + <meta name="msapplication-TileImage" content="/mstile-144x144.png"> + <meta name="theme-color" content="#ffffff"> + {{content-for 'head'}} <link rel="stylesheet" href="assets/vendor.css"> diff --git a/vipra-ui/app/models/article.js b/vipra-ui/app/models/article.js index 064292d210b840ab925b226cd7d998cb3446996b..0d054ad31aafcc2f4856e01680fc6f74e5887866 100644 --- a/vipra-ui/app/models/article.js +++ b/vipra-ui/app/models/article.js @@ -4,5 +4,5 @@ export default DS.Model.extend({ title: DS.attr(), text: DS.attr(), url: DS.attr(), - date: DS.attr() + date: DS.attr('date') }); diff --git a/vipra-ui/app/router.js b/vipra-ui/app/router.js index 3bf38c00f7ebae4564f82ea90e57bbcdf7c2152b..0a0fb7055747ae093b2b52b9eef98df5277c9fb5 100644 --- a/vipra-ui/app/router.js +++ b/vipra-ui/app/router.js @@ -6,7 +6,11 @@ const Router = Ember.Router.extend({ }); Router.map(function() { - this.route('articles'); + this.route('articles', function() { + this.route('list', { path: '/' }); + this.route('show', { path: '/:article_id' }); + }); + this.route('not-found', { path: '/*:' }); }); export default Router; diff --git a/vipra-ui/app/routes/articles.js b/vipra-ui/app/routes/articles.js deleted file mode 100644 index 2009e33bf38909f55f13f802caced901f0c23e86..0000000000000000000000000000000000000000 --- a/vipra-ui/app/routes/articles.js +++ /dev/null @@ -1,7 +0,0 @@ -import Ember from 'ember'; - -export default Ember.Route.extend({ - model() { - return this.store.findAll('article'); - } -}); diff --git a/vipra-ui/app/routes/articles/list.js b/vipra-ui/app/routes/articles/list.js new file mode 100644 index 0000000000000000000000000000000000000000..81b69808893707a30683a7ef1bfdb15a89be1f73 --- /dev/null +++ b/vipra-ui/app/routes/articles/list.js @@ -0,0 +1,61 @@ +import Ember from 'ember'; + +var chartData = []; +var chartOptions = { + chart: { + zoomType: 'x' + }, + title: { + text: 'Articles per month' + }, + legend: { + enabled: false + }, + xAxis: { + type: 'datetime', + title: { + text: 'Dates' + } + }, + yAxis: { + title: { + text: 'Articles' + } + }, + tooltip: { + headerFormat: '', + pointFormat: '{point.x:%b %Y}: {point.y} article(s)' + } +}; + +export default Ember.Route.extend({ + model() { + return Ember.RSVP.hash({ + articles: this.store.findAll('article'), + chartOptions: chartOptions, + chartData: chartData + }); + }, + + afterModel(model) { + var count = {}; + model.articles.forEach(article => { + var date = article.get('date') + var month = date.getMonth()+1; + var dstr = date.getFullYear() + '-' + (month < 10 ? '0' + month : month); + if(count.hasOwnProperty(dstr)) { + count[dstr][1] += 1; + } else { + count[dstr] = [Date.UTC(date.getFullYear(), month), 1]; + } + }); + var data = []; + for(var key in count) { + data.push(count[key]); + } + model.chartData = [{ + name: 'Articles', + data: data + }]; + } +}); diff --git a/vipra-ui/app/routes/index.js b/vipra-ui/app/routes/not-found.js similarity index 100% rename from vipra-ui/app/routes/index.js rename to vipra-ui/app/routes/not-found.js diff --git a/vipra-ui/app/templates/articles.hbs b/vipra-ui/app/templates/articles.hbs index 35225d4ad2833a0d73a9706b20d4d174a5208d9d..c42a140eac368bb9661e1e5e77fe78ab056bc47c 100644 --- a/vipra-ui/app/templates/articles.hbs +++ b/vipra-ui/app/templates/articles.hbs @@ -1,5 +1,5 @@ <h1>Articles</h1> +{{#link-to 'articles.list'}}All{{/link-to}} +<hr> -{{#each model as |article|}} - <p>{{article.title}}</p> -{{/each}} \ No newline at end of file +{{outlet}} \ No newline at end of file diff --git a/vipra-ui/app/templates/articles/list.hbs b/vipra-ui/app/templates/articles/list.hbs new file mode 100644 index 0000000000000000000000000000000000000000..08f7ccb638bf957b5ca67cc5c53231837aeab3c5 --- /dev/null +++ b/vipra-ui/app/templates/articles/list.hbs @@ -0,0 +1,7 @@ +{{dynamic-high-charts content=model.chartData chartOptions=model.chartOptions}} + +<h2>Found articles</h2> + +{{debounced-input placeholder='Filter' size='50' valueBinding='filter' debounce='150'}} + +{{article-list articles=model.articles filter=filter}} \ No newline at end of file diff --git a/vipra-ui/app/templates/articles/new.hbs b/vipra-ui/app/templates/articles/new.hbs new file mode 100644 index 0000000000000000000000000000000000000000..c1318fddb4debfa78918fc66c95283760fc470cd --- /dev/null +++ b/vipra-ui/app/templates/articles/new.hbs @@ -0,0 +1 @@ +<h2>New article</h2> \ No newline at end of file diff --git a/vipra-ui/app/templates/articles/show.hbs b/vipra-ui/app/templates/articles/show.hbs new file mode 100644 index 0000000000000000000000000000000000000000..a93a42bd788761f32cad7384ca38bef4c132a1e0 --- /dev/null +++ b/vipra-ui/app/templates/articles/show.hbs @@ -0,0 +1,10 @@ +<h2>{{model.title}}</h2> + +<dl> + <dt>Date</dt> + <dd>{{model.date}}</dd> + <dt>URL</dt> + <dd><a href="{{model.url}}">{{model.url}}</a></dd> +</dl> + +{{model.text}} \ No newline at end of file diff --git a/vipra-ui/app/templates/components/article-list.hbs b/vipra-ui/app/templates/components/article-list.hbs new file mode 100644 index 0000000000000000000000000000000000000000..8d3269ffb87a2266baece0abf9056f021d25a6c3 --- /dev/null +++ b/vipra-ui/app/templates/components/article-list.hbs @@ -0,0 +1,5 @@ +<ol> + {{#each filteredArticles as |article|}} + <li>{{#link-to 'articles.show' article.id}}{{text-marker text=article.title mark=filter}}{{/link-to}}</li> + {{/each}} +</ol> \ No newline at end of file diff --git a/vipra-ui/app/templates/components/debounced-input.hbs b/vipra-ui/app/templates/components/debounced-input.hbs new file mode 100644 index 0000000000000000000000000000000000000000..889d9eeadc1012bdf474d7ea123f9bff23e9d8f5 --- /dev/null +++ b/vipra-ui/app/templates/components/debounced-input.hbs @@ -0,0 +1 @@ +{{yield}} diff --git a/vipra-ui/app/templates/components/dynamic-high-charts.hbs b/vipra-ui/app/templates/components/dynamic-high-charts.hbs new file mode 100644 index 0000000000000000000000000000000000000000..889d9eeadc1012bdf474d7ea123f9bff23e9d8f5 --- /dev/null +++ b/vipra-ui/app/templates/components/dynamic-high-charts.hbs @@ -0,0 +1 @@ +{{yield}} diff --git a/vipra-ui/app/templates/components/text-marker.hbs b/vipra-ui/app/templates/components/text-marker.hbs new file mode 100644 index 0000000000000000000000000000000000000000..5fb15880633ca60fd96531b511b79b62127997ba --- /dev/null +++ b/vipra-ui/app/templates/components/text-marker.hbs @@ -0,0 +1 @@ +{{{marked}}} \ No newline at end of file diff --git a/vipra-ui/app/templates/index.hbs b/vipra-ui/app/templates/index.hbs index 2f733f8f8b8ee4c32a20a0335fead9d5619935b6..51b28c7ae97459acfa02b24e3afbe8260ea55896 100644 --- a/vipra-ui/app/templates/index.hbs +++ b/vipra-ui/app/templates/index.hbs @@ -1,3 +1 @@ -<h1>Vipra</h1> - -{{#link-to 'articles'}}Browse articles{{/link-to}} \ No newline at end of file +<h1>Vipra</h1> \ No newline at end of file diff --git a/vipra-ui/app/templates/loading.hbs b/vipra-ui/app/templates/loading.hbs new file mode 100644 index 0000000000000000000000000000000000000000..37d709251262e861315c9da5f955b5600a1c6007 --- /dev/null +++ b/vipra-ui/app/templates/loading.hbs @@ -0,0 +1 @@ +Loading... \ No newline at end of file diff --git a/vipra-ui/app/templates/not-found.hbs b/vipra-ui/app/templates/not-found.hbs new file mode 100644 index 0000000000000000000000000000000000000000..4ca64b93827b10496afabced2f19afef3a6111ed --- /dev/null +++ b/vipra-ui/app/templates/not-found.hbs @@ -0,0 +1,3 @@ +<h1>404 - Not found</h1> + +<p>The requested resource was not found on this server</p> \ No newline at end of file diff --git a/vipra-ui/package.json b/vipra-ui/package.json index 24ae137dc87eb14af2fef82e9c7c0106db5b69c0..fa584f24d50ce25b3c949cb3abc59c4631b3019b 100644 --- a/vipra-ui/package.json +++ b/vipra-ui/package.json @@ -34,6 +34,7 @@ "ember-cli-uglify": "^1.2.0", "ember-data": "1.13.15", "ember-disable-proxy-controllers": "^1.0.1", - "ember-export-application-global": "^1.0.4" + "ember-export-application-global": "^1.0.4", + "ember-highcharts": "0.2.1" } } diff --git a/vipra-ui/public/android-chrome-144x144.png b/vipra-ui/public/android-chrome-144x144.png new file mode 100644 index 0000000000000000000000000000000000000000..a75a06d5e6943aee4c175213f6cf98b03fa3f85c Binary files /dev/null and b/vipra-ui/public/android-chrome-144x144.png differ diff --git a/vipra-ui/public/android-chrome-192x192.png b/vipra-ui/public/android-chrome-192x192.png new file mode 100644 index 0000000000000000000000000000000000000000..38a70604dcb27a9ee3fbf79d71360c5d1bb30def Binary files /dev/null and b/vipra-ui/public/android-chrome-192x192.png differ diff --git a/vipra-ui/public/android-chrome-36x36.png b/vipra-ui/public/android-chrome-36x36.png new file mode 100644 index 0000000000000000000000000000000000000000..fa55583e69edd38b9b9dc4b344610ce40f076014 Binary files /dev/null and b/vipra-ui/public/android-chrome-36x36.png differ diff --git a/vipra-ui/public/android-chrome-48x48.png b/vipra-ui/public/android-chrome-48x48.png new file mode 100644 index 0000000000000000000000000000000000000000..053cc4ed735d16d23ca7f7bfc06b8b419c5da221 Binary files /dev/null and b/vipra-ui/public/android-chrome-48x48.png differ diff --git a/vipra-ui/public/android-chrome-72x72.png b/vipra-ui/public/android-chrome-72x72.png new file mode 100644 index 0000000000000000000000000000000000000000..98c240493437e4f97f0c6e08d10ab1c174d792f2 Binary files /dev/null and b/vipra-ui/public/android-chrome-72x72.png differ diff --git a/vipra-ui/public/android-chrome-96x96.png b/vipra-ui/public/android-chrome-96x96.png new file mode 100644 index 0000000000000000000000000000000000000000..2d2202ca6ba65fba1402708be385110c13ca4606 Binary files /dev/null and b/vipra-ui/public/android-chrome-96x96.png differ diff --git a/vipra-ui/public/apple-touch-icon-114x114.png b/vipra-ui/public/apple-touch-icon-114x114.png new file mode 100644 index 0000000000000000000000000000000000000000..bc2a612c2e7e6a66e1f82d42722943a90e00e25f Binary files /dev/null and b/vipra-ui/public/apple-touch-icon-114x114.png differ diff --git a/vipra-ui/public/apple-touch-icon-120x120.png b/vipra-ui/public/apple-touch-icon-120x120.png new file mode 100644 index 0000000000000000000000000000000000000000..fdaabce77f0024103256d92f819694892752aa5a Binary files /dev/null and b/vipra-ui/public/apple-touch-icon-120x120.png differ diff --git a/vipra-ui/public/apple-touch-icon-144x144.png b/vipra-ui/public/apple-touch-icon-144x144.png new file mode 100644 index 0000000000000000000000000000000000000000..1d46bf72898e7a1d57e584e33166b4ab93ad1913 Binary files /dev/null and b/vipra-ui/public/apple-touch-icon-144x144.png differ diff --git a/vipra-ui/public/apple-touch-icon-152x152.png b/vipra-ui/public/apple-touch-icon-152x152.png new file mode 100644 index 0000000000000000000000000000000000000000..cf4fe5c4d8e00ade403c398bf6354c66dcb6f419 Binary files /dev/null and b/vipra-ui/public/apple-touch-icon-152x152.png differ diff --git a/vipra-ui/public/apple-touch-icon-180x180.png b/vipra-ui/public/apple-touch-icon-180x180.png new file mode 100644 index 0000000000000000000000000000000000000000..9349bc3006cbeae993227c4247526a2f5331bca3 Binary files /dev/null and b/vipra-ui/public/apple-touch-icon-180x180.png differ diff --git a/vipra-ui/public/apple-touch-icon-57x57.png b/vipra-ui/public/apple-touch-icon-57x57.png new file mode 100644 index 0000000000000000000000000000000000000000..404609005a57d079d934aeafb60e9f41c777303d Binary files /dev/null and b/vipra-ui/public/apple-touch-icon-57x57.png differ diff --git a/vipra-ui/public/apple-touch-icon-60x60.png b/vipra-ui/public/apple-touch-icon-60x60.png new file mode 100644 index 0000000000000000000000000000000000000000..69090a0b6c4948749effbb3fe956c3caf72b6154 Binary files /dev/null and b/vipra-ui/public/apple-touch-icon-60x60.png differ diff --git a/vipra-ui/public/apple-touch-icon-72x72.png b/vipra-ui/public/apple-touch-icon-72x72.png new file mode 100644 index 0000000000000000000000000000000000000000..7e41b0928a7ca05b405ed7bce68b8e2099de6e03 Binary files /dev/null and b/vipra-ui/public/apple-touch-icon-72x72.png differ diff --git a/vipra-ui/public/apple-touch-icon-76x76.png b/vipra-ui/public/apple-touch-icon-76x76.png new file mode 100644 index 0000000000000000000000000000000000000000..29d14b903247e28ff96f6ea34bf3a38d50f5482e Binary files /dev/null and b/vipra-ui/public/apple-touch-icon-76x76.png differ diff --git a/vipra-ui/public/apple-touch-icon-precomposed.png b/vipra-ui/public/apple-touch-icon-precomposed.png new file mode 100644 index 0000000000000000000000000000000000000000..4d110e9874af7700780f80bfeec4a287fa6d49b1 Binary files /dev/null and b/vipra-ui/public/apple-touch-icon-precomposed.png differ diff --git a/vipra-ui/public/apple-touch-icon.png b/vipra-ui/public/apple-touch-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..9349bc3006cbeae993227c4247526a2f5331bca3 Binary files /dev/null and b/vipra-ui/public/apple-touch-icon.png differ diff --git a/vipra-ui/public/browserconfig.xml b/vipra-ui/public/browserconfig.xml new file mode 100644 index 0000000000000000000000000000000000000000..65380f3873df0b1efc837c390c3a91bd2c2c6a14 --- /dev/null +++ b/vipra-ui/public/browserconfig.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8"?> +<browserconfig> + <msapplication> + <tile> + <square70x70logo src="/mstile-70x70.png"/> + <square150x150logo src="/mstile-150x150.png"/> + <square310x310logo src="/mstile-310x310.png"/> + <wide310x150logo src="/mstile-310x150.png"/> + <TileColor>#da532c</TileColor> + </tile> + </msapplication> +</browserconfig> diff --git a/vipra-ui/public/favicon-16x16.png b/vipra-ui/public/favicon-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..2142db750ebddec14220299d9b135ef67c086a8a Binary files /dev/null and b/vipra-ui/public/favicon-16x16.png differ diff --git a/vipra-ui/public/favicon-194x194.png b/vipra-ui/public/favicon-194x194.png new file mode 100644 index 0000000000000000000000000000000000000000..21aebd21587c3e1e8ead181661abfd5c63b7520f Binary files /dev/null and b/vipra-ui/public/favicon-194x194.png differ diff --git a/vipra-ui/public/favicon-32x32.png b/vipra-ui/public/favicon-32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..5f02b4eddf4ea6a56bfcd19c8b61a406f99d9129 Binary files /dev/null and b/vipra-ui/public/favicon-32x32.png differ diff --git a/vipra-ui/public/favicon-96x96.png b/vipra-ui/public/favicon-96x96.png new file mode 100644 index 0000000000000000000000000000000000000000..db921e4ed2dcd5d09ed8c3feda59dbecdb4f6493 Binary files /dev/null and b/vipra-ui/public/favicon-96x96.png differ diff --git a/vipra-ui/public/favicon.ico b/vipra-ui/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..5732db6037b1f85a34fb650544f2c844313a2855 Binary files /dev/null and b/vipra-ui/public/favicon.ico differ diff --git a/vipra-ui/public/manifest.json b/vipra-ui/public/manifest.json new file mode 100644 index 0000000000000000000000000000000000000000..fd248ba860774e85815f340dca3d7a91b00fc794 --- /dev/null +++ b/vipra-ui/public/manifest.json @@ -0,0 +1,41 @@ +{ + "name": "Vipra", + "icons": [ + { + "src": "\/android-chrome-36x36.png", + "sizes": "36x36", + "type": "image\/png", + "density": 0.75 + }, + { + "src": "\/android-chrome-48x48.png", + "sizes": "48x48", + "type": "image\/png", + "density": 1 + }, + { + "src": "\/android-chrome-72x72.png", + "sizes": "72x72", + "type": "image\/png", + "density": 1.5 + }, + { + "src": "\/android-chrome-96x96.png", + "sizes": "96x96", + "type": "image\/png", + "density": 2 + }, + { + "src": "\/android-chrome-144x144.png", + "sizes": "144x144", + "type": "image\/png", + "density": 3 + }, + { + "src": "\/android-chrome-192x192.png", + "sizes": "192x192", + "type": "image\/png", + "density": 4 + } + ] +} diff --git a/vipra-ui/public/mstile-144x144.png b/vipra-ui/public/mstile-144x144.png new file mode 100644 index 0000000000000000000000000000000000000000..f8bbf5181ec917852ccc7d485261c378ccbc7585 Binary files /dev/null and b/vipra-ui/public/mstile-144x144.png differ diff --git a/vipra-ui/public/mstile-150x150.png b/vipra-ui/public/mstile-150x150.png new file mode 100644 index 0000000000000000000000000000000000000000..695de5e588f6771411672a7ab77d11ff9f7b19c0 Binary files /dev/null and b/vipra-ui/public/mstile-150x150.png differ diff --git a/vipra-ui/public/mstile-310x150.png b/vipra-ui/public/mstile-310x150.png new file mode 100644 index 0000000000000000000000000000000000000000..31d0d95b73f37cb775eaa1fbe11152400f961d5f Binary files /dev/null and b/vipra-ui/public/mstile-310x150.png differ diff --git a/vipra-ui/public/mstile-310x310.png b/vipra-ui/public/mstile-310x310.png new file mode 100644 index 0000000000000000000000000000000000000000..632930e827817f36965e2402748adef9b9311d96 Binary files /dev/null and b/vipra-ui/public/mstile-310x310.png differ diff --git a/vipra-ui/public/mstile-70x70.png b/vipra-ui/public/mstile-70x70.png new file mode 100644 index 0000000000000000000000000000000000000000..e6ece63cb1b9caa78fc2cebb370e07d9f2e5db04 Binary files /dev/null and b/vipra-ui/public/mstile-70x70.png differ diff --git a/vipra-ui/public/safari-pinned-tab.svg b/vipra-ui/public/safari-pinned-tab.svg new file mode 100644 index 0000000000000000000000000000000000000000..93d972a555c1c94f9e87b83f856d2dfb05b9c5ab --- /dev/null +++ b/vipra-ui/public/safari-pinned-tab.svg @@ -0,0 +1,36 @@ +<?xml version="1.0" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN" + "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> +<svg version="1.0" xmlns="http://www.w3.org/2000/svg" + width="512.000000pt" height="512.000000pt" viewBox="0 0 512.000000 512.000000" + preserveAspectRatio="xMidYMid meet"> +<metadata> +Created by potrace 1.11, written by Peter Selinger 2001-2013 +</metadata> +<g transform="translate(0.000000,512.000000) scale(0.100000,-0.100000)" +fill="#000000" stroke="none"> +<path d="M3010 5110 c-129 -17 -159 -22 -240 -40 -112 -26 -104 -24 -196 -55 +-184 -63 -388 -173 -539 -289 -82 -64 -103 -83 -202 -183 -298 -302 -477 -668 +-537 -1098 -14 -100 -15 -399 -1 -495 28 -199 96 -426 177 -586 l31 -61 -691 +-692 c-559 -559 -700 -705 -731 -759 -167 -282 -60 -647 233 -791 188 -93 409 +-76 576 42 14 10 337 329 718 709 l692 691 98 -46 c170 -80 379 -140 569 -165 +73 -9 367 -9 453 0 266 28 570 135 800 281 169 107 372 290 487 437 213 274 +356 613 399 945 9 72 11 387 3 458 -39 336 -165 653 -374 938 -63 87 -237 269 +-320 336 -155 126 -414 270 -586 327 -107 35 -259 72 -359 86 -97 14 -377 20 +-460 10z m455 -333 c391 -73 703 -251 961 -552 127 -147 236 -347 298 -544 58 +-185 75 -314 71 -526 -4 -161 -6 -176 -36 -305 -43 -185 -95 -316 -188 -472 +-233 -392 -621 -661 -1085 -754 -101 -20 -394 -26 -506 -11 -237 33 -509 142 +-709 285 -122 86 -288 252 -373 372 -121 171 -223 403 -262 596 -8 43 -18 93 +-21 109 -21 104 -8 467 20 554 3 11 8 31 10 43 3 13 15 59 29 103 147 483 534 +879 1016 1039 58 19 116 37 130 40 14 2 50 10 80 16 30 6 80 13 110 17 30 3 +57 7 58 9 10 8 329 -7 397 -19z m-1730 -2814 c70 -85 212 -223 279 -271 20 +-14 36 -28 36 -32 0 -10 -1285 -1295 -1325 -1326 -45 -34 -120 -54 -183 -49 +-100 7 -191 72 -235 165 -31 65 -29 168 4 235 19 38 177 203 680 707 360 361 +659 657 664 657 6 0 42 -39 80 -86z"/> +<path d="M2995 4299 c-351 -67 -642 -288 -800 -607 -39 -80 -80 -197 -89 -256 +-4 -21 -8 -42 -11 -46 -3 -4 -8 -55 -11 -113 -6 -104 -6 -106 19 -131 45 -45 +119 -27 131 32 3 15 8 59 11 99 17 273 178 553 408 712 78 53 219 119 293 136 +10 2 37 9 59 14 45 10 130 20 188 21 72 0 110 74 67 130 -17 23 -26 25 -97 26 +-43 0 -118 -7 -168 -17z"/> +</g> +</svg> diff --git a/vipra-ui/tests/integration/components/article-list-test.js b/vipra-ui/tests/integration/components/article-list-test.js new file mode 100644 index 0000000000000000000000000000000000000000..bcc52965fc674e9690c7834e179c13b38bfe5caf --- /dev/null +++ b/vipra-ui/tests/integration/components/article-list-test.js @@ -0,0 +1,25 @@ +import { moduleForComponent, test } from 'ember-qunit'; +import hbs from 'htmlbars-inline-precompile'; + +moduleForComponent('article-list', 'Integration | Component | article list', { + integration: true +}); + +test('it renders', function(assert) { + + // Set any properties with this.set('myProperty', 'value'); + // Handle any actions with this.on('myAction', function(val) { ... });" + EOL + EOL + + + this.render(hbs`{{article-list}}`); + + assert.equal(this.$().text().trim(), ''); + + // Template block usage:" + EOL + + this.render(hbs` + {{#article-list}} + template block text + {{/article-list}} + `); + + assert.equal(this.$().text().trim(), 'template block text'); +}); diff --git a/vipra-ui/tests/integration/components/debounced-input-test.js b/vipra-ui/tests/integration/components/debounced-input-test.js new file mode 100644 index 0000000000000000000000000000000000000000..323028be87c1069b493b592cbfd34e0f0ee65ea1 --- /dev/null +++ b/vipra-ui/tests/integration/components/debounced-input-test.js @@ -0,0 +1,25 @@ +import { moduleForComponent, test } from 'ember-qunit'; +import hbs from 'htmlbars-inline-precompile'; + +moduleForComponent('debounced-input', 'Integration | Component | debounced input', { + integration: true +}); + +test('it renders', function(assert) { + + // Set any properties with this.set('myProperty', 'value'); + // Handle any actions with this.on('myAction', function(val) { ... });" + EOL + EOL + + + this.render(hbs`{{debounced-input}}`); + + assert.equal(this.$().text().trim(), ''); + + // Template block usage:" + EOL + + this.render(hbs` + {{#debounced-input}} + template block text + {{/debounced-input}} + `); + + assert.equal(this.$().text().trim(), 'template block text'); +}); diff --git a/vipra-ui/tests/integration/components/dynamic-high-charts-test.js b/vipra-ui/tests/integration/components/dynamic-high-charts-test.js new file mode 100644 index 0000000000000000000000000000000000000000..07810b85074cac1214cd04b68efccc4eb6ef1794 --- /dev/null +++ b/vipra-ui/tests/integration/components/dynamic-high-charts-test.js @@ -0,0 +1,25 @@ +import { moduleForComponent, test } from 'ember-qunit'; +import hbs from 'htmlbars-inline-precompile'; + +moduleForComponent('dynamic-high-charts', 'Integration | Component | dynamic high charts', { + integration: true +}); + +test('it renders', function(assert) { + + // Set any properties with this.set('myProperty', 'value'); + // Handle any actions with this.on('myAction', function(val) { ... });" + EOL + EOL + + + this.render(hbs`{{dynamic-high-charts}}`); + + assert.equal(this.$().text().trim(), ''); + + // Template block usage:" + EOL + + this.render(hbs` + {{#dynamic-high-charts}} + template block text + {{/dynamic-high-charts}} + `); + + assert.equal(this.$().text().trim(), 'template block text'); +}); diff --git a/vipra-ui/tests/integration/components/text-marker-test.js b/vipra-ui/tests/integration/components/text-marker-test.js new file mode 100644 index 0000000000000000000000000000000000000000..1af17c61bc9e6b08df64bdaa001f22802d69825a --- /dev/null +++ b/vipra-ui/tests/integration/components/text-marker-test.js @@ -0,0 +1,25 @@ +import { moduleForComponent, test } from 'ember-qunit'; +import hbs from 'htmlbars-inline-precompile'; + +moduleForComponent('text-marker', 'Integration | Component | text marker', { + integration: true +}); + +test('it renders', function(assert) { + + // Set any properties with this.set('myProperty', 'value'); + // Handle any actions with this.on('myAction', function(val) { ... });" + EOL + EOL + + + this.render(hbs`{{text-marker}}`); + + assert.equal(this.$().text().trim(), ''); + + // Template block usage:" + EOL + + this.render(hbs` + {{#text-marker}} + template block text + {{/text-marker}} + `); + + assert.equal(this.$().text().trim(), 'template block text'); +}); diff --git a/vipra-ui/tests/unit/controllers/articles-test.js b/vipra-ui/tests/unit/controllers/articles-test.js new file mode 100644 index 0000000000000000000000000000000000000000..2f09e3a9cfb428f7762f161885385c8da50f5983 --- /dev/null +++ b/vipra-ui/tests/unit/controllers/articles-test.js @@ -0,0 +1,12 @@ +import { moduleFor, test } from 'ember-qunit'; + +moduleFor('controller:articles', 'Unit | Controller | articles', { + // Specify the other units that are required for this test. + // needs: ['controller:foo'] +}); + +// Replace this with your real tests. +test('it exists', function(assert) { + let controller = this.subject(); + assert.ok(controller); +}); diff --git a/vipra-ui/tests/unit/routes/articles-test.js b/vipra-ui/tests/unit/routes/article-test.js similarity index 80% rename from vipra-ui/tests/unit/routes/articles-test.js rename to vipra-ui/tests/unit/routes/article-test.js index 14d8ec8499d5da6db2902c3cb9f547c04b1fc68a..a9185964f142f77bed47257f75926240c781b292 100644 --- a/vipra-ui/tests/unit/routes/articles-test.js +++ b/vipra-ui/tests/unit/routes/article-test.js @@ -1,6 +1,6 @@ import { moduleFor, test } from 'ember-qunit'; -moduleFor('route:articles', 'Unit | Route | articles', { +moduleFor('route:article', 'Unit | Route | article', { // Specify the other units that are required for this test. // needs: ['controller:foo'] }); diff --git a/vipra-ui/tests/unit/routes/not-found-test.js b/vipra-ui/tests/unit/routes/not-found-test.js new file mode 100644 index 0000000000000000000000000000000000000000..2375b9bb75fd6d375431e81f000b518cc2ee6e8c --- /dev/null +++ b/vipra-ui/tests/unit/routes/not-found-test.js @@ -0,0 +1,11 @@ +import { moduleFor, test } from 'ember-qunit'; + +moduleFor('route:not-found', 'Unit | Route | not found', { + // Specify the other units that are required for this test. + // needs: ['controller:foo'] +}); + +test('it exists', function(assert) { + let route = this.subject(); + assert.ok(route); +}); diff --git a/vipra-util/.classpath b/vipra-util/.classpath new file mode 100644 index 0000000000000000000000000000000000000000..d38d831c96760fdab9ce81082bb658d298932a2c --- /dev/null +++ b/vipra-util/.classpath @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="src" path="src/main/java"/> + <classpathentry kind="src" path="src/main/resources"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"> + <attributes> + <attribute name="maven.pomderived" value="true"/> + </attributes> + </classpathentry> + <classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER"> + <attributes> + <attribute name="maven.pomderived" value="true"/> + </attributes> + </classpathentry> + <classpathentry kind="con" path="org.eclipse.jst.j2ee.internal.module.container"/> + <classpathentry kind="output" path="target/classes"/> +</classpath> diff --git a/vipra-util/.gitignore b/vipra-util/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..09e3bc9b241c477ea341af9ee029becad0c2148c --- /dev/null +++ b/vipra-util/.gitignore @@ -0,0 +1,2 @@ +/bin/ +/target/ diff --git a/vipra-util/.project b/vipra-util/.project new file mode 100644 index 0000000000000000000000000000000000000000..7e5c99aad3e63cb25e06c3a8510fc8cea87fdeef --- /dev/null +++ b/vipra-util/.project @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>vipra-util</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.wst.common.project.facet.core.builder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.m2e.core.maven2Builder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.wst.validation.validationbuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.jem.workbench.JavaEMFNature</nature> + <nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature> + <nature>org.eclipse.m2e.core.maven2Nature</nature> + <nature>org.eclipse.jdt.core.javanature</nature> + <nature>org.eclipse.wst.common.project.facet.core.nature</nature> + </natures> +</projectDescription> diff --git a/vipra-util/.settings/org.eclipse.jdt.core.prefs b/vipra-util/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000000000000000000000000000000000000..107056a36e4dc4b53aad1c866f7ff7b82068ddbc --- /dev/null +++ b/vipra-util/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,12 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/vipra-util/.settings/org.eclipse.m2e.core.prefs b/vipra-util/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000000000000000000000000000000000000..f897a7f1cb2389f85fe6381425d29f0a9866fb65 --- /dev/null +++ b/vipra-util/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/vipra-util/.settings/org.eclipse.wst.common.component b/vipra-util/.settings/org.eclipse.wst.common.component new file mode 100644 index 0000000000000000000000000000000000000000..217de769b1c939ce8569041d55e0227a3473b779 --- /dev/null +++ b/vipra-util/.settings/org.eclipse.wst.common.component @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="UTF-8"?><project-modules id="moduleCoreId" project-version="1.5.0"> + <wb-module deploy-name="vipra-util"> + <wb-resource deploy-path="/" source-path="/src/main/java"/> + <wb-resource deploy-path="/" source-path="/src/main/resources"/> + </wb-module> +</project-modules> diff --git a/vipra-util/.settings/org.eclipse.wst.common.project.facet.core.xml b/vipra-util/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 0000000000000000000000000000000000000000..926884d914bf20b850efed694a328543aa498e30 --- /dev/null +++ b/vipra-util/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<faceted-project> + <fixed facet="jst.utility"/> + <fixed facet="java"/> + <installed facet="java" version="1.6"/> + <installed facet="jst.utility" version="1.0"/> +</faceted-project> diff --git a/vipra-util/pom.xml b/vipra-util/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..039cebdc7455794d59bdcd94a576ec29157018db --- /dev/null +++ b/vipra-util/pom.xml @@ -0,0 +1,52 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>de.vipra</groupId> + <artifactId>vipra-util</artifactId> + <version>0.0.1-SNAPSHOT</version> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <log4jVersion>2.4.1</log4jVersion> + </properties> + + <dependencies> + <!-- Logging --> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-api</artifactId> + <version>${log4jVersion}</version> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-core</artifactId> + <version>${log4jVersion}</version> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-slf4j-impl</artifactId> + <version>${log4jVersion}</version> + </dependency> + + <!-- MongoDB Database Adapter --> + <dependency> + <groupId>org.mongodb</groupId> + <artifactId>mongodb-driver</artifactId> + <version>3.0.4</version> + </dependency> + </dependencies> + + <build> + <sourceDirectory>src</sourceDirectory> + <plugins> + <plugin> + <artifactId>maven-compiler-plugin</artifactId> + <version>3.3</version> + <configuration> + <source>1.8</source> + <target>1.8</target> + </configuration> + </plugin> + </plugins> + </build> +</project> \ No newline at end of file diff --git a/vipra-util/src/main/java/META-INF/MANIFEST.MF b/vipra-util/src/main/java/META-INF/MANIFEST.MF new file mode 100644 index 0000000000000000000000000000000000000000..5e9495128c0376427420c4189993b3851770b702 --- /dev/null +++ b/vipra-util/src/main/java/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Class-Path: + diff --git a/vipra-util/src/main/java/de/vipra/util/Config.java b/vipra-util/src/main/java/de/vipra/util/Config.java new file mode 100644 index 0000000000000000000000000000000000000000..f10013558603df1d99bcd1ad622071c508715bdc --- /dev/null +++ b/vipra-util/src/main/java/de/vipra/util/Config.java @@ -0,0 +1,50 @@ +package de.vipra.util; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class Config { + + public static final Logger log = LoggerFactory.getLogger(Config.class); + + private final Properties props = new Properties(); + + public Config() throws IOException, ConfigException { + this(Thread.currentThread().getContextClassLoader().getResourceAsStream("config.properties")); + + } + + public Config(InputStream is) throws IOException, ConfigException { + if (is == null) { + log.error("config file input stream is null"); + throw new ConfigException("config file input stream is null"); + } else { + props.load(is); + } + } + + public String getString(String key) { + return getString(key, null); + } + + public String getString(String key, String defaultValue) { + return props.getProperty(key, defaultValue); + } + + public Integer getInt(String key) { + return getInt(key, null); + } + + public Integer getInt(String key, Integer defaultValue) { + try { + return Integer.parseInt(props.getProperty(key)); + } catch (NumberFormatException e) { + return defaultValue; + } + } + +} diff --git a/vipra-util/src/main/java/de/vipra/util/ConfigException.java b/vipra-util/src/main/java/de/vipra/util/ConfigException.java new file mode 100644 index 0000000000000000000000000000000000000000..d6404572e5f34f137c3e095ca1bb2e71d416ad9d --- /dev/null +++ b/vipra-util/src/main/java/de/vipra/util/ConfigException.java @@ -0,0 +1,11 @@ +package de.vipra.util; + +public class ConfigException extends Exception { + + private static final long serialVersionUID = 1L; + + public ConfigException(String string) { + super(string); + } + +} \ No newline at end of file diff --git a/vipra-util/src/main/java/de/vipra/util/Mongo.java b/vipra-util/src/main/java/de/vipra/util/Mongo.java new file mode 100644 index 0000000000000000000000000000000000000000..73628bd0be1064b622c2860f14b766ba7a671e03 --- /dev/null +++ b/vipra-util/src/main/java/de/vipra/util/Mongo.java @@ -0,0 +1,48 @@ +package de.vipra.util; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.mongodb.MongoClient; +import com.mongodb.client.MongoDatabase; +import de.vipra.util.Config; + +public class Mongo { + + public static final Logger log = LoggerFactory.getLogger(Mongo.class); + + private static Mongo instance; + + private final MongoClient client; + private final MongoDatabase database; + + private Mongo(Config config) throws ConfigException { + String host = config.getString("db.host"); + Integer port = config.getInt("db.port"); + String databaseName = config.getString("db.name"); + + if (host == null || port == null || databaseName == null) { + log.error("host/port/dbname missing in configuration"); + throw new ConfigException("host/port/dbname missing in configuration"); + } + + client = new MongoClient(host, port); + database = client.getDatabase(databaseName); + } + + public MongoClient getClient() { + return client; + } + + public MongoDatabase getDatabase() { + return database; + } + + public static Mongo getInstance(Config config) throws ConfigException { + if (instance == null) { + instance = new Mongo(config); + } + return instance; + } + +} diff --git a/vipra-util/src/main/resources/config.properties b/vipra-util/src/main/resources/config.properties new file mode 100644 index 0000000000000000000000000000000000000000..07030840d45dd8fed8c2c2d5bff5fe0a54939a4f --- /dev/null +++ b/vipra-util/src/main/resources/config.properties @@ -0,0 +1,3 @@ +db.host=localhost +db.port=27017 +db.name=test \ No newline at end of file diff --git a/vipra-util/src/main/resources/log4j2.xml b/vipra-util/src/main/resources/log4j2.xml new file mode 100644 index 0000000000000000000000000000000000000000..871334005580a7821f2a6e7f7c2517ab454b2e17 --- /dev/null +++ b/vipra-util/src/main/resources/log4j2.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Configuration> + <Appenders> + <Console name="Console" target="SYSTEM_OUT"> + <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %logger{36} - %msg%n" /> + </Console> + </Appenders> + <Loggers> + <Root level="ALL"> + <AppenderRef ref="Console" /> + </Root> + <Logger name="org.mongodb" level="INFO"/> + </Loggers> +</Configuration> \ No newline at end of file diff --git a/vm/bootstrap.sh b/vm/bootstrap.sh index 5535f49a5719b7b8165dc745b27926aa3034693d..0b238ae423cec87d95814f685a590923e5f7ff4d 100644 --- a/vm/bootstrap.sh +++ b/vm/bootstrap.sh @@ -96,7 +96,7 @@ mvn -DskipTests -X clean -f ./mahout install # ----------------------------------------------------------------------------- # install elasticsearch -wget https://download.elasticsearch.org/elasticsearch/release/org/elasticsearch/distribution/deb/elasticsearch/2.1.0/elasticsearch-2.1.0.deb +wget https://download.elasticsearch.org/elasticsearch/release/org/elasticsearch/distribution/deb/elasticsearch/2.1.1/elasticsearch-2.1.1.deb gdebi -n elasticsearch-2.1.0.deb rm elasticsearch-2.1.0.deb service start elasticsearch