diff --git a/vipra-backend/src/main/java/de/vipra/rest/resource/SearchResource.java b/vipra-backend/src/main/java/de/vipra/rest/resource/SearchResource.java index 68a58faba438a728f798e9d378742a2314e5c64e..d3f019918649a0ef64f0eecf28797c4bf98651a1 100644 --- a/vipra-backend/src/main/java/de/vipra/rest/resource/SearchResource.java +++ b/vipra-backend/src/main/java/de/vipra/rest/resource/SearchResource.java @@ -1,8 +1,10 @@ package de.vipra.rest.resource; import java.io.IOException; +import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; +import java.util.Date; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -52,7 +54,7 @@ public class SearchResource { @GET @Produces(MediaType.APPLICATION_JSON) public Response doSearch(@QueryParam("topicModel") String topicModel, @QueryParam("skip") Integer skip, @QueryParam("limit") Integer limit, - @QueryParam("fields") final String fields, @QueryParam("query") final String query, @QueryParam("long") final Long fromDate, + @QueryParam("fields") final String fields, @QueryParam("query") final String query, @QueryParam("from") final Long fromDate, @QueryParam("to") final Long toDate) { final ResponseWrapper<List<ArticleFull>> res = new ResponseWrapper<>(); @@ -93,10 +95,16 @@ public class SearchResource { if (fromDate != null || toDate != null) { final RangeQueryBuilder rqb = QueryBuilders.rangeQuery("date"); - if (fromDate != null) - rqb.from(fromDate); - if (toDate != null) - rqb.to(toDate); + final SimpleDateFormat sdf = new SimpleDateFormat(Constants.DATETIME_FORMAT); + if (fromDate != null) { + final String date = sdf.format(new Date(fromDate)); + rqb.from(date); + } + if (toDate != null) { + final String date = sdf.format(new Date(toDate)); + rqb.to(date); + } + rqb.format(Constants.DATETIME_FORMAT); qb = QueryBuilders.boolQuery().must(qb).must(rqb); } diff --git a/vipra-cmd/runcfg/CMD.launch b/vipra-cmd/runcfg/CMD.launch index 45f808ecda89b079e69151a4741c3781198fce3c..cecae20174f45544c3b10e208bf905112b2f276c 100644 --- a/vipra-cmd/runcfg/CMD.launch +++ b/vipra-cmd/runcfg/CMD.launch @@ -11,7 +11,7 @@ </listAttribute> <stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="org.eclipse.m2e.launchconfig.classpathProvider"/> <stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="de.vipra.cmd.Main"/> -<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-dm test"/> +<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-n test"/> <stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="vipra-cmd"/> <stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.m2e.launchconfig.sourcepathProvider"/> <stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-ea"/> diff --git a/vipra-cmd/src/main/java/de/vipra/cmd/CommandLineOptions.java b/vipra-cmd/src/main/java/de/vipra/cmd/CommandLineOptions.java index d78a3f6ab36c6cc77296bd8a8cbd83cce25c0b48..e849abee437260c7ac1bf1c26410cabd72a8580c 100644 --- a/vipra-cmd/src/main/java/de/vipra/cmd/CommandLineOptions.java +++ b/vipra-cmd/src/main/java/de/vipra/cmd/CommandLineOptions.java @@ -37,9 +37,12 @@ public class CommandLineOptions { .optionalArg(true).build(); public static final Option MODEL = Option.builder("M").longOpt("model").desc("generate topics on models").hasArgs().argName("[models...]") .optionalArg(true).build(); + public static final Option RENAME = Option.builder("n").longOpt("rename").desc("rename selected models").hasArg().argName("[models...]") + .optionalArg(true).build(); public static final Option SELECT = Option.builder("S").longOpt("select").desc("select models").hasArgs().argName("models...").build(); public static final Option BACKUP = Option.builder("B").longOpt("backup").desc("backup data/filebase").hasArg().argName("path").build(); public static final Option RESTORE = Option.builder("R").longOpt("restore").desc("restore data/filebase").hasArg().argName("path").build(); + public static final Option LOG = Option.builder("o").longOpt("out").desc("print output to file").hasArg().optionalArg(true).build(); private final Options options; private CommandLine cmd; @@ -47,7 +50,7 @@ public class CommandLineOptions { public CommandLineOptions() { final Option[] optionsArray = { CLEAR, DEBUG, HELP, INDEX, LIST, REREAD, SILENT, TEST, ALL, CREATE, DELETE, EDIT, PRINT, IMPORT, MODEL, - SELECT, BACKUP, RESTORE, VERSION }; + RENAME, SELECT, BACKUP, RESTORE, VERSION, LOG }; options = new Options(); for (final Option option : optionsArray) options.addOption(option); @@ -240,4 +243,23 @@ public class CommandLineOptions { return hasOption(VERSION); } + public boolean isRename() { + return hasOption(RENAME); + } + + public String[] modelsToRename() { + final String[] models = getOptionValues(RENAME); + if (models != null && models.length > 0) + return models; + return selectedModels(); + } + + public boolean isLog() { + return hasOption(LOG); + } + + public String logPath() { + return getOptionValue(LOG); + } + } 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 58d67fb62f77556dd11c601ebc3a92928af7fdb8..d2a67882a4517e362423f76702150f0baa5ce820 100644 --- a/vipra-cmd/src/main/java/de/vipra/cmd/Main.java +++ b/vipra-cmd/src/main/java/de/vipra/cmd/Main.java @@ -1,5 +1,7 @@ package de.vipra.cmd; +import java.io.File; +import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.ListIterator; @@ -18,9 +20,11 @@ import de.vipra.cmd.option.IndexingCommand; import de.vipra.cmd.option.ListModelsCommand; import de.vipra.cmd.option.ModelingCommand; import de.vipra.cmd.option.PrintModelCommand; +import de.vipra.cmd.option.RenameModelCommand; import de.vipra.cmd.option.RestoreCommand; import de.vipra.cmd.option.TestCommand; import de.vipra.cmd.option.VersionCommand; +import de.vipra.util.Config; import de.vipra.util.ConsoleUtils; import de.vipra.util.LockFile; import de.vipra.util.ex.LockFileException; @@ -75,6 +79,19 @@ public class Main { ConsoleUtils.setSilent(opts.isSilent()); + try { + if (opts.isLog()) { + final String file = opts.logPath(); + if (file == null) + ConsoleUtils.setLogFile(Config.getGenericLogFile()); + else + ConsoleUtils.setLogFile(new File(file)); + } + } catch (IOException e) { + ConsoleUtils.error("cannot use log file: " + e.getMessage()); + return; + } + // commands final List<Command> commands = new ArrayList<>(); @@ -100,6 +117,9 @@ public class Main { if (opts.isCreate()) commands.add(new CreateModelCommand(opts.modelsToCreate())); + if (opts.isRename()) + commands.add(new RenameModelCommand(opts.modelsToRename())); + if (opts.isList()) commands.add(new ListModelsCommand()); diff --git a/vipra-cmd/src/main/java/de/vipra/cmd/option/CreateModelCommand.java b/vipra-cmd/src/main/java/de/vipra/cmd/option/CreateModelCommand.java index 48857552bd1c994f802e9af213463fbe2a3f9571..0c44072fd2f38605b73eb51c15a5d0a837a6c13e 100644 --- a/vipra-cmd/src/main/java/de/vipra/cmd/option/CreateModelCommand.java +++ b/vipra-cmd/src/main/java/de/vipra/cmd/option/CreateModelCommand.java @@ -51,13 +51,12 @@ public class CreateModelCommand implements Command { } for (final String name : names) { - if (name.toLowerCase().equals("all")) - throw new Exception("invalid model name: " + name); + final String msg = config.validModelName(name); + if (msg != null) + throw new Exception(msg); + final File modelDir = new File(config.getDataDirectory(), name); - if (modelDir.exists()) { - ConsoleUtils.info("model already exists: " + name); - continue; - } + if (!modelDir.mkdirs()) throw new Exception("could not create model directory: " + modelDir.getAbsolutePath()); diff --git a/vipra-cmd/src/main/java/de/vipra/cmd/option/RenameModelCommand.java b/vipra-cmd/src/main/java/de/vipra/cmd/option/RenameModelCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..dac38bc986bbf12ab5271c0c540e5288d4dc3b6d --- /dev/null +++ b/vipra-cmd/src/main/java/de/vipra/cmd/option/RenameModelCommand.java @@ -0,0 +1,69 @@ +package de.vipra.cmd.option; + +import java.io.File; + +import org.bson.types.ObjectId; + +import de.vipra.util.Config; +import de.vipra.util.ConsoleUtils; +import de.vipra.util.model.TopicModelConfig; +import de.vipra.util.model.TopicModelFull; +import de.vipra.util.service.MongoService; +import de.vipra.util.service.QueryBuilder; + +public class RenameModelCommand implements Command { + + private final String[] models; + private Config config; + private MongoService<TopicModelFull, ObjectId> dbTopicModels; + + public RenameModelCommand(final String[] models) { + this.models = models; + } + + private void renameModel(final String name) throws Exception { + String newName; + while (true) { + final File oldModelDir = new File(config.getDataDirectory(), name); + final TopicModelFull topicModel = dbTopicModels.getSingle(QueryBuilder.builder().eq("name", name)); + if (!oldModelDir.exists() || topicModel == null) { + ConsoleUtils.error("unknwon topic model: '" + name + "'"); + return; + } + + newName = ConsoleUtils.readString("enter new name for model '" + name + "'"); + final String msg = config.validModelName(newName); + if (msg != null) { + ConsoleUtils.error(msg); + continue; + } + final TopicModelConfig modelConfig = config.getTopicModelConfig(name); + modelConfig.setName(newName); + modelConfig.saveToFile(oldModelDir); + + final File newModelDir = new File(config.getDataDirectory(), newName); + oldModelDir.renameTo(newModelDir); + + topicModel.setName(newName); + topicModel.getModelConfig().setName(newName); + dbTopicModels.replaceSingle(topicModel); + + ConsoleUtils.info("model '" + name + "' renamed to '" + newName + "'"); + break; + } + } + + @Override + public void run() throws Exception { + config = Config.getConfig(); + dbTopicModels = MongoService.getDatabaseService(config, TopicModelFull.class); + for (final String model : models) + renameModel(model); + } + + @Override + public boolean requiresLock() { + return false; + } + +} diff --git a/vipra-ui/app/html/articles/index.html b/vipra-ui/app/html/articles/index.html index 1591a8f894962ddcd85d2e5ef6a5dc26f9ee676c..61662e45884561e9e63dd3eafc154c5d2e1b41ac 100644 --- a/vipra-ui/app/html/articles/index.html +++ b/vipra-ui/app/html/articles/index.html @@ -33,7 +33,7 @@ <sort-dir ng-model="articlesIndexModels.sortdir" /> </span> </div> - <table class="table table-hover table-condensed"> + <table class="table table-hover table-condensed table-fixed"> <tbody> <tr ng-repeat="article in articles"> <td> diff --git a/vipra-ui/app/html/articles/show.html b/vipra-ui/app/html/articles/show.html index 3c39f1ae040b7c70130d6f5cb39a75e6d4edd8b4..7fcb0c155b6f743c064b2bc7254b06c18c383223 100644 --- a/vipra-ui/app/html/articles/show.html +++ b/vipra-ui/app/html/articles/show.html @@ -29,7 +29,9 @@ <tbody> <tr> <th class="infocol">ID</th> - <td ng-bind="::article.id"></td> + <td> + <span class="ellipsis" ng-bind="::article.id"></span> + </td> </tr> <tr> <th>Date</th> @@ -38,10 +40,12 @@ <tr ng-if="article.url"> <th>URL</th> <td> - <a ng-href="{{::article.url}}" target="_blank"> - <i class="fa fa-link"></i> - <span ng-bind="::article.url"></span> - </a> + <span class="ellipsis"> + <a ng-href="{{::article.url}}" target="_blank"> + <i class="fa fa-link"></i> + <span ng-bind="::article.url"></span> + </a> + </span> </td> </tr> <tr> @@ -82,7 +86,7 @@ </div> </div> <h3>Similar articles <info text="Similar articles are determined based on topic share. Higher topic share results in higher share ratio."/></h3> - <table class="table table-bordered table-condensed" ng-show="article.similarArticles.length" ng-cloak> + <table class="table table-bordered table-condensed table-fixed" ng-show="article.similarArticles.length" ng-cloak> <thead> <tr> <th class="infocol" ng-model="articlesShowModels.similarSort" sort-by="share">Share</th> diff --git a/vipra-ui/app/html/entities/articles.html b/vipra-ui/app/html/entities/articles.html index 0c7d5c20a2dfa8a9d8c91c509540b28ca8b6dbd4..6232bdd52f138e8cf61fff57ad3471fae5afa1f7 100644 --- a/vipra-ui/app/html/entities/articles.html +++ b/vipra-ui/app/html/entities/articles.html @@ -34,13 +34,16 @@ <sort-dir ng-model="entitiesArticlesModels.sortdir" /> </span> </div> - <table class="table table-hover table-condensed"> + <table class="table table-hover table-condensed table-fixed"> <tbody> <tr ng-repeat="article in articles"> <td> <article-link article="::article"/> </td> </tr> + <tr ng-show="loadingArticles"> + <td>Loading...</td> + </tr> </tbody> </table> <div class="panel-footer"> diff --git a/vipra-ui/app/html/entities/index.html b/vipra-ui/app/html/entities/index.html index df62bb0c70c2a649c6bc041092d1586b9820dfb9..5cf739fd136182f6d6336abd3a69838616cd1716 100644 --- a/vipra-ui/app/html/entities/index.html +++ b/vipra-ui/app/html/entities/index.html @@ -30,7 +30,7 @@ <sort-dir ng-model="entitiesIndexModels.sortdir" /> </span> </div> - <table class="table table-hover table-condensed"> + <table class="table table-hover table-condensed table-fixed"> <tbody> <tr ng-repeat="entity in entities"> <td> diff --git a/vipra-ui/app/html/index.html b/vipra-ui/app/html/index.html index fa3a10ba4cac539aeb92a86e5e6123ab8b3d3d8f..bae0a628f73caf6aa7fddac3b8b568f4829a63b8 100644 --- a/vipra-ui/app/html/index.html +++ b/vipra-ui/app/html/index.html @@ -6,7 +6,7 @@ <span class="text-logo">VIPRA</span> </div> </div> - <div class="row row-spaced"> + <div class="row"> <div class="col-md-12"> <div ng-class="{'input-group':advancedSearchEnabled}"> <div class="form-group has-feedback"> @@ -19,7 +19,8 @@ </div> </div> </div> - <div class="row row-spaced" ng-show="advancedSearch&&advancedSearchEnabled" ng-cloak> + <div class="row" ng-show="advancedSearch&&advancedSearchEnabled" ng-cloak> + <br> <div class="col-md-6 form-horizontal"> <label for="advFromDate" class="col-sm-2 control-label">From</label> <div class="input-group date col-sm-10" id="advFromDate" bs-datetimepicker ng-model="rootModels.advFromDate"> @@ -40,6 +41,7 @@ </div> </div> <div class="row latest-items" ng-hide="search"> + <br> <div class="col-md-8 text-center"> <h4>Latest articles</h4> <ul class="list-unstyled"> @@ -99,7 +101,7 @@ <p> <span class="text" ng-bind="article.text"></span> <br> - <small class="text-muted" ng-bind-template="{{::article.meta.score.toFixed(3)}} – {{::Vipra.formatDate(article.date)}}" ng-attr-title="Relevance: {{::article.meta.score.toFixed(3)}}, Date: {{::Vipra.formatDate(article.date)}}"></small> + <small class="text-muted" ng-bind-template="{{::article.meta.score.toFixed(3)}} – {{::Vipra.formatDate(article.date)}}" ng-attr-title="Score: {{::article.meta.score.toFixed(3)}}, Date: {{::Vipra.formatDate(article.date)}}"></small> </p> </li> </ul> diff --git a/vipra-ui/app/html/topics/articles.html b/vipra-ui/app/html/topics/articles.html index 0a0b1cc7c6141f72662e063b8f125f224f5a4752..b2272aa0af084441afa1a1401e96944ee0d9bfbf 100644 --- a/vipra-ui/app/html/topics/articles.html +++ b/vipra-ui/app/html/topics/articles.html @@ -34,7 +34,7 @@ <sort-dir ng-model="topicsArticlesModels.sortdir" /> </span> </div> - <table class="table table-hover table-condensed"> + <table class="table table-hover table-condensed table-fixed"> <tbody> <tr ng-repeat="article in articles"> <td> diff --git a/vipra-ui/app/html/topics/index.html b/vipra-ui/app/html/topics/index.html index 2b87cbb096ba8571def6323efeaa03e6f1b672f7..2ffc0069a225a8235f6d9f9cb03b0dd20edcb691 100644 --- a/vipra-ui/app/html/topics/index.html +++ b/vipra-ui/app/html/topics/index.html @@ -32,7 +32,7 @@ <sort-dir ng-model="topicsIndexModels.sortdir" /> </span> </div> - <table class="table table-hover table-condensed"> + <table class="table table-hover table-condensed table-fixed"> <tbody> <tr ng-repeat="topic in topics"> <td> diff --git a/vipra-ui/app/html/words/articles.html b/vipra-ui/app/html/words/articles.html index a3e5d0484397a1c6fc3ad7d8420fd21acf7b83fb..14d2247e70b3332e824d482e9bb6914f3abd34bf 100644 --- a/vipra-ui/app/html/words/articles.html +++ b/vipra-ui/app/html/words/articles.html @@ -34,7 +34,7 @@ <sort-dir ng-model="wordsArticlesModels.sortdir" /> </span> </div> - <table class="table table-hover table-condensed"> + <table class="table table-hover table-condensed table-fixed"> <tbody> <tr ng-repeat="article in articles"> <td> diff --git a/vipra-ui/app/html/words/index.html b/vipra-ui/app/html/words/index.html index d9cf9edbb17cd9a33d1044ca10b7797252cc3409..2f6c91c889e18a2318132f720cde5c6e3d5b924a 100644 --- a/vipra-ui/app/html/words/index.html +++ b/vipra-ui/app/html/words/index.html @@ -30,7 +30,7 @@ <sort-dir ng-model="wordsIndexModels.sortdir" /> </span> </div> - <table class="table table-hover table-condensed"> + <table class="table table-hover table-condensed table-fixed"> <tbody> <tr ng-repeat="word in words"> <td> diff --git a/vipra-ui/app/html/words/topics.html b/vipra-ui/app/html/words/topics.html index 4e8e14cdb86f53f5a5824964d4ba012083d09b79..a4fe2e10835cb788dcb82bf3f6a70f84122d686d 100644 --- a/vipra-ui/app/html/words/topics.html +++ b/vipra-ui/app/html/words/topics.html @@ -33,7 +33,7 @@ <sort-dir ng-model="wordsTopicsModels.sortdir" /> </span> </div> - <table class="table table-hover table-condensed"> + <table class="table table-hover table-condensed table-fixed"> <tbody> <tr ng-repeat="topic in topics"> <td> diff --git a/vipra-ui/app/js/app.js b/vipra-ui/app/js/app.js index 20cdc87d8802be1dec03ff48e8b6cd06c9512a0c..1913324ccaaf6a774b45e46df703c4aa0ce1f77d 100644 --- a/vipra-ui/app/js/app.js +++ b/vipra-ui/app/js/app.js @@ -254,6 +254,12 @@ input.trigger('fileselect', [numFiles, label]); }); + $(document).on('click','.navbar-collapse.in',function(e) { + if($(e.target).is('a') && $(e.target).attr('class') != 'dropdown-toggle') { + $(this).collapse('hide'); + } + }); + $(document).ready(function() { $('.btn-file :file').on('fileselect', function(event, numFiles, label) { var input = $(this).parents('.input-group').find(':text'), diff --git a/vipra-ui/app/js/controllers.js b/vipra-ui/app/js/controllers.js index 2f720f637aa447a36baa9d2dcb05cf05829cd706..397e7b01c659fc95129d08b577fc3790f93e3ecb 100644 --- a/vipra-ui/app/js/controllers.js +++ b/vipra-ui/app/js/controllers.js @@ -189,13 +189,6 @@ }); $scope.showCheatSheet = hotkeys.toggleCheatSheet; - - /* - $scope.$watch('rootModels.topicModel', function() { - if($state.current.name !== 'index') - $state.transitionTo('index'); - }); - */ } ]); @@ -209,7 +202,7 @@ $scope.chooseTopicModel(); $scope.searchResultsStep = 10; - $scope.advancedSearchEnabled = false; + $scope.advancedSearchEnabled = true; $scope.search = $stateParams.q || $scope.search; $scope.$watch('rootModels.topicModel', function() { @@ -1423,7 +1416,7 @@ app.controller('EntitiesArticlesController', ['$scope', '$state', '$stateParams', 'ArticleFactory', function($scope, $state, $stateParams, ArticleFactory) { - $scope.checkTopicModel('entities.articles', function() { + $scope.checkTopicModel('entities.show.articles', function() { $scope.entity = $stateParams.id; $scope.entitiesArticlesModels = { @@ -1434,6 +1427,7 @@ }; $scope.$watchGroup(['entitiesArticlesModels.page', 'entitiesArticlesModels.sortkey', 'entitiesArticlesModels.sortdir'], function() { + $scope.loadingArticles = true; ArticleFactory.query({ skip: ($scope.entitiesArticlesModels.page - 1) * $scope.entitiesArticlesModels.limit, limit: $scope.entitiesArticlesModels.limit, @@ -1444,6 +1438,9 @@ $scope.articles = data; $scope.articlesTotal = headers("V-Total"); $scope.maxPage = Math.ceil($scope.articlesTotal / $scope.entitiesArticlesModels.limit); + $scope.loadingArticles = false; + }, function() { + $scope.loadingArticles = false; }); }); }); @@ -1484,9 +1481,7 @@ }); }; - $scope.$watchGroup(['wordsIndexModels.page', 'wordsIndexModels.sortkey', 'wordsIndexModels.sortdir'], function() { - $scope.reloadWords(); - }); + $scope.$watchGroup(['wordsIndexModels.page', 'wordsIndexModels.sortkey', 'wordsIndexModels.sortdir'], $scope.reloadWords); $scope.$watchGroup(['wordsIndexModels.startChar', 'wordsIndexModels.contains'], function() { if($scope.wordsIndexModels.page !== 1) @@ -1515,7 +1510,7 @@ app.controller('WordsTopicsController', ['$scope', '$state', '$stateParams', 'TopicFactory', function($scope, $state, $stateParams, TopicFactory) { - $scope.checkTopicModel('words.topics', function() { + $scope.checkTopicModel('words.show.topics', function() { $scope.word = $stateParams.id; $scope.wordsTopicsModels = { @@ -1545,7 +1540,7 @@ app.controller('WordsArticlesController', ['$scope', '$state', '$stateParams', 'ArticleFactory', function($scope, $state, $stateParams, ArticleFactory) { - $scope.checkTopicModel('words.articles', function() { + $scope.checkTopicModel('words.show.articles', function() { $scope.word = $stateParams.id; $scope.wordsArticlesModels = { @@ -1622,7 +1617,7 @@ $scope.calculatePages = function() { var pages = [], max = Math.ceil($scope.total / $scope.limit * 1.0), - pad = 4, + pad = 2, start = Math.max($scope.page - pad, 1), end = Math.min(Math.max($scope.page + pad, start + pad * 2), max); for (var i = start; i <= end; i++) { diff --git a/vipra-ui/app/less/app.less b/vipra-ui/app/less/app.less index 10d9f4ac480543d30de3b57f1da3ffbdde971e3b..754b620ac0ea06bef7e88361afc959334f3232b0 100644 --- a/vipra-ui/app/less/app.less +++ b/vipra-ui/app/less/app.less @@ -140,6 +140,12 @@ a:hover { z-index: 2; } } +td { + overflow: hidden; +} +a { + word-break: break-all; +} .initial { float: left; diff --git a/vipra-util/src/main/java/de/vipra/util/CalendarUtils.java b/vipra-util/src/main/java/de/vipra/util/CalendarUtils.java index a999af211286baea238c67bd2195921879d54710..48e2c8e391ba305ea043c82d548374d083721cb1 100644 --- a/vipra-util/src/main/java/de/vipra/util/CalendarUtils.java +++ b/vipra-util/src/main/java/de/vipra/util/CalendarUtils.java @@ -12,7 +12,7 @@ public class CalendarUtils { } public static final int getTrimester(final Calendar c) { - int month = c.get(Calendar.MONTH); + final int month = c.get(Calendar.MONTH); if (month < 4) return 0; if (month < 8) @@ -29,7 +29,7 @@ public class CalendarUtils { * @return the quarter of the calendar month */ public static final int getQuarter(final Calendar c) { - int month = c.get(Calendar.MONTH); + final int month = c.get(Calendar.MONTH); if (month < 3) return 0; if (month < 6) diff --git a/vipra-util/src/main/java/de/vipra/util/Config.java b/vipra-util/src/main/java/de/vipra/util/Config.java index 0d9de6c81f015c76ea1f9abcc68e0126215ffe0f..2fbf5ab715604abb39e3b327196b7ce7cace76e4 100644 --- a/vipra-util/src/main/java/de/vipra/util/Config.java +++ b/vipra-util/src/main/java/de/vipra/util/Config.java @@ -8,6 +8,7 @@ import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import org.apache.commons.io.IOUtils; import org.bson.types.ObjectId; @@ -194,6 +195,16 @@ public class Config { return new File(base, Constants.FILEBASE_DIR); } + /** + * Returns a generic logging directory + * + * @return generic logging directory + */ + public static File getGenericLogFile() { + final File base = PathUtils.tempDir(); + return new File(base, Constants.LOG_FILE); + } + /** * Returns a representation of the used mongodb connection * @@ -280,4 +291,16 @@ public class Config { return instance; } + public String validModelName(String name) throws ConfigException { + name = name.trim().toLowerCase(); + if (name.equals("all")) + return "invalid model name: 'all' is a special name and cannot be used."; + for (final Entry<String, TopicModelConfig> entry : topicModelConfigs.entrySet()) + if (entry.getValue().getName().toLowerCase().equals(name)) + return "model with name '" + name + "' already exists."; + if (new File(getDataDirectory(), name).exists()) + return "model with name '" + name + "' already exists."; + return null; + } + } diff --git a/vipra-util/src/main/java/de/vipra/util/ConsoleUtils.java b/vipra-util/src/main/java/de/vipra/util/ConsoleUtils.java index 089276a528fdc168961cdac9116edb7d5242807e..42240f46ff279c6eb497c7c69fc7536f4b1077a6 100644 --- a/vipra-util/src/main/java/de/vipra/util/ConsoleUtils.java +++ b/vipra-util/src/main/java/de/vipra/util/ConsoleUtils.java @@ -1,6 +1,8 @@ package de.vipra.util; import java.io.BufferedReader; +import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintStream; @@ -19,12 +21,20 @@ public class ConsoleUtils { private static boolean silent = false; private static int pad = 5; private static int lastLineLength = 0; + private static File logFile = null; + private static PrintStream logWriter = null; public static void setSilent(final boolean s) { silent = s; } + public static void setLogFile(final File file) throws IOException { + logFile = file; + logWriter = new PrintStream(new FileOutputStream(logFile, true), true); + } + private static int print(final PrintStream ps, final boolean newLine, final String msg) { + int result = 0; if (!silent) { if (newLine) ps.println(msg); @@ -32,10 +42,12 @@ public class ConsoleUtils { ps.print(msg); if (msg != null) { lastLineLength = msg.length(); - return lastLineLength; + result = lastLineLength; } } - return 0; + if (logWriter != null) + logWriter.println(msg.replaceAll("\u001B\\[[;\\d]*[ -/]*[@-~]", "").replaceAll("\\r", "")); + return result; } private static String label(final String label) { diff --git a/vipra-util/src/main/java/de/vipra/util/Constants.java b/vipra-util/src/main/java/de/vipra/util/Constants.java index ad6495a6f4e4ddb8b402597d99f5fb741f543b68..d23af9f1c498a1d756607045ab69e88ede9535c0 100644 --- a/vipra-util/src/main/java/de/vipra/util/Constants.java +++ b/vipra-util/src/main/java/de/vipra/util/Constants.java @@ -31,6 +31,7 @@ public class Constants { public static final String CONFIG_FILE = "config.json"; public static final String BUILDNUMBER_FILE = "buildNumber.properties"; + public static final String LOG_FILE = "vipra.log"; /* * DATABASE