From 986fd25942682f9708e3d710c015074f4fcb90b5 Mon Sep 17 00:00:00 2001 From: Athou Date: Fri, 8 Aug 2014 16:49:02 +0200 Subject: [PATCH 01/37] removed wicket and tomee, use dropwizard instead. remove wro4j, use gulp instead --- .bowerrc | 3 + .gitignore | 17 +- .openshift/action_hooks/README.md | 3 - .openshift/action_hooks/build | 5 - .openshift/action_hooks/deploy | 5 - .openshift/action_hooks/post_deploy | 4 - .../action_hooks/post_start_jbosseap-6.0 | 14 - .../action_hooks/post_stop_jbosseap-6.0 | 14 - .openshift/action_hooks/pre_build | 5 - .../action_hooks/pre_build_jbosseap-6.0 | 7 - .../action_hooks/pre_start_jbosseap-6.0 | 14 - .openshift/action_hooks/pre_stop_jbosseap-6.0 | 14 - .openshift/config/modules/README | 3 - .openshift/config/standalone.xml | 517 ----- .openshift/cron/README.cron | 22 - .openshift/cron/daily/.gitignore | 0 .openshift/cron/daily/log-cleanup.sh | 7 - .openshift/cron/hourly/.gitignore | 0 .openshift/cron/minutely/.gitignore | 0 .openshift/cron/monthly/.gitignore | 0 .openshift/cron/weekly/README | 16 - .openshift/cron/weekly/chrono.dat | 1 - .openshift/cron/weekly/chronograph | 3 - .openshift/cron/weekly/jobs.allow | 12 - .openshift/cron/weekly/jobs.deny | 7 - .openshift/markers/README | 22 - LICENSE | 31 - README.md | 132 -- bower.json | 30 + conf/setenv.bat | 1 - conf/setenv.sh | 1 - config.yml | 50 + gulp | 2 + gulp.cmd | 3 + gulpfile.js | 73 + package.json | 18 + pom.xml | 711 ++---- src/main/{webapp => app}/app-icon-114.png | Bin src/main/{webapp => app}/app-icon-128.png | Bin src/main/{webapp => app}/app-icon-144.png | Bin src/main/{webapp => app}/app-icon-16.png | Bin src/main/{webapp => app}/app-icon-195.png | Bin src/main/{webapp => app}/app-icon-256.png | Bin src/main/{webapp => app}/app-icon-32.png | Bin src/main/{webapp => app}/app-icon-512.png | Bin src/main/{webapp => app}/app-icon-57.png | Bin src/main/{webapp => app}/app-icon-64.png | Bin src/main/{webapp => app}/app-icon-72.png | Bin src/main/{webapp => app}/app-icon.svg | 0 src/main/{webapp => app}/favicon.ico | Bin .../images/default_favicon.gif | Bin .../images/google_reader_icon.png | Bin src/main/{webapp => app}/images/logo.png | Bin src/main/{webapp => app}/images/logo_2.png | Bin src/main/{webapp => app}/images/preview.jpg | Bin src/main/app/index.html | 73 + src/main/{webapp => app}/js/controllers.js | 2 - src/main/{webapp => app}/js/directives.js | 0 src/main/{webapp => app}/js/filters.js | 0 src/main/{webapp => app}/js/main.js | 0 src/main/{webapp => app}/js/services.js | 0 src/main/{webapp => app}/js/welcome.js | 0 src/main/{webapp => app}/metro-icon-150.png | Bin src/main/{webapp => app}/metro-icon-70.png | Bin src/main/{webapp => app}/sass/app.scss | 3 + .../main/app/sass/base}/.gitkeep | 0 .../sass/components/_admin-panel.scss | 0 .../sass/components/_entry-list.scss | 0 .../sass/components/_help.scss | 0 .../sass/components/_loading-bar.scss | 0 .../sass/components/_subscription-list.scss | 0 .../sass/components/_toolbar.scss | 0 .../app/sass/components/readabilicons.scss | 20 + .../sass/components/zocial.scss} | 6 +- .../{webapp => app}/sass/generic/_misc.scss | 0 .../sass/generic/_scrollbar.scss | 0 .../{webapp => app}/sass/mobile/_mobile.scss | 0 .../sass/themes/_MRACHINI.scss | 0 .../sass/themes/_bootstrap.scss | 0 .../{webapp => app}/sass/themes/_dark.scss | 0 .../sass/themes/_ebraminio.scss | 0 .../{webapp => app}/sass/themes/_svetla.scss | 0 .../{webapp => app}/sass/themes/_test.scss | 0 .../{webapp => app}/sass/themes/_third.scss | 0 .../{webapp => app}/templates/_category.html | 0 .../templates/_feedsearch.html | 0 .../{webapp => app}/templates/_footer.html | 0 .../templates/_metrics.gauge.html | 0 .../templates/_metrics.meter.html | 0 .../{webapp => app}/templates/_shortcuts.html | 0 src/main/{webapp => app}/templates/_tags.html | 0 .../{webapp => app}/templates/_toolbar.html | 0 src/main/{webapp => app}/templates/_tree.html | 0 src/main/{webapp => app}/templates/admin.html | 0 .../templates/admin.metrics.html | 0 .../templates/admin.settings.html | 0 .../templates/admin.useradd.html | 0 .../templates/admin.useredit.html | 0 .../templates/admin.userlist.html | 0 .../templates/feeds.category_details.html | 0 .../templates/feeds.feed_details.html | 0 .../{webapp => app}/templates/feeds.help.html | 0 src/main/{webapp => app}/templates/feeds.html | 0 .../templates/feeds.import.html | 0 .../templates/feeds.new_category.html | 0 .../templates/feeds.subscribe.html | 0 .../templates/feeds.tag_details.html | 0 .../{webapp => app}/templates/feeds.view.html | 0 .../{webapp => app}/templates/profile.html | 0 .../{webapp => app}/templates/settings.html | 0 .../com/commafeed/CommaFeedApplication.java | 182 ++ .../com/commafeed/CommaFeedAuthenticator.java | 21 + .../com/commafeed/CommaFeedConfiguration.java | 105 + .../com/commafeed/backend/HttpGetter.java | 2 +- .../com/commafeed/backend/ScheduledTasks.java | 48 - .../backend/cache/NoopCacheService.java | 5 - .../backend/cache/RedisCacheService.java | 10 +- .../backend/dao/ApplicationSettingsDAO.java | 10 - .../backend/dao/FeedCategoryDAO.java | 81 +- .../com/commafeed/backend/dao/FeedDAO.java | 119 +- .../backend/dao/FeedEntryContentDAO.java | 50 +- .../commafeed/backend/dao/FeedEntryDAO.java | 71 +- .../backend/dao/FeedEntryStatusDAO.java | 166 +- .../backend/dao/FeedEntryTagDAO.java | 37 +- .../backend/dao/FeedSubscriptionDAO.java | 101 +- .../com/commafeed/backend/dao/GenericDAO.java | 166 +- .../com/commafeed/backend/dao/UnitOfWork.java | 60 + .../com/commafeed/backend/dao/UserDAO.java | 63 +- .../commafeed/backend/dao/UserRoleDAO.java | 30 +- .../backend/dao/UserSettingsDAO.java | 27 +- .../{feeds => feed}/FaviconFetcher.java | 11 +- .../backend/{feeds => feed}/FeedFetcher.java | 13 +- .../backend/{feeds => feed}/FeedParser.java | 2 +- .../FeedQueues.java} | 116 +- .../{feeds => feed}/FeedRefreshContext.java | 2 +- .../{feeds => feed}/FeedRefreshExecutor.java | 2 +- .../backend/feed/FeedRefreshTaskGiver.java | 95 + .../{feeds => feed}/FeedRefreshUpdater.java | 101 +- .../{feeds => feed}/FeedRefreshWorker.java | 73 +- .../backend/{feeds => feed}/FeedUtils.java | 22 +- .../backend/{feeds => feed}/FetchedFeed.java | 2 +- .../backend/{feeds => feed}/HtmlEntities.java | 2 +- .../metrics/MetricRegistryProducer.java | 30 - .../backend/model/ApplicationSettings.java | 43 - .../com/commafeed/backend/model/Feed.java | 6 - .../commafeed/backend/model/FeedCategory.java | 8 - .../commafeed/backend/model/FeedEntry.java | 8 +- .../backend/model/FeedEntryContent.java | 6 - .../backend/model/FeedEntryStatus.java | 12 +- .../commafeed/backend/model/FeedEntryTag.java | 6 - .../backend/model/FeedSubscription.java | 9 - .../com/commafeed/backend/model/User.java | 10 +- .../com/commafeed/backend/model/UserRole.java | 6 - .../commafeed/backend/model/UserSettings.java | 8 +- .../commafeed/backend/opml/OPMLExporter.java | 12 +- .../commafeed/backend/opml/OPMLImporter.java | 33 +- .../ApplicationPropertiesService.java | 10 +- .../DatabaseCleaningService.java | 28 +- .../FeedEntryContentService.java | 10 +- .../FeedEntryService.java | 22 +- .../FeedEntryTagService.java | 14 +- .../backend/service/FeedService.java | 32 + .../FeedSubscriptionService.java | 46 +- .../FeedUpdateService.java | 16 +- .../{services => service}/MailService.java | 10 +- .../PasswordEncryptionService.java | 2 +- .../PubSubService.java} | 28 +- .../backend/service/StartupService.java | 127 ++ .../{services => service}/UserService.java | 38 +- .../services/ApplicationSettingsService.java | 60 - .../backend/services/FeedService.java | 41 - .../backend/startup/DatabaseUpdater.java | 76 - .../backend/startup/StartupBean.java | 120 - .../com/commafeed/frontend/APIGenerator.java | 101 - .../frontend/CommaFeedApplication.java | 216 -- .../commafeed/frontend/CommaFeedSession.java | 69 - .../frontend/CommaFeedSessionServices.java | 37 - .../frontend/InterceptingFilter.java | 53 - .../com/commafeed/frontend/SecurityCheck.java | 28 - .../commafeed/frontend/model/Category.java | 20 +- .../com/commafeed/frontend/model/Entries.java | 26 +- .../com/commafeed/frontend/model/Entry.java | 48 +- .../commafeed/frontend/model/FeedCount.java | 4 +- .../commafeed/frontend/model/FeedInfo.java | 4 +- .../commafeed/frontend/model/ServerInfo.java | 7 +- .../commafeed/frontend/model/Settings.java | 28 +- .../frontend/model/Subscription.java | 34 +- .../commafeed/frontend/model/UnreadCount.java | 5 +- .../commafeed/frontend/model/UserModel.java | 24 +- .../model/request/AddCategoryRequest.java | 10 +- .../request/CategoryModificationRequest.java | 14 +- .../model/request/CollapseRequest.java | 10 +- .../model/request/FeedInfoRequest.java | 8 +- .../model/request/FeedMergeRequest.java | 10 +- .../request/FeedModificationRequest.java | 14 +- .../frontend/model/request/IDRequest.java | 8 +- .../frontend/model/request/MarkRequest.java | 14 +- .../model/request/MultipleMarkRequest.java | 8 +- .../request/ProfileModificationRequest.java | 12 +- .../model/request/RegistrationRequest.java | 10 +- .../frontend/model/request/StarRequest.java | 12 +- .../model/request/SubscribeRequest.java | 12 +- .../frontend/model/request/TagRequest.java | 10 +- .../commafeed/frontend/pages/BasePage.html | 56 - .../commafeed/frontend/pages/BasePage.java | 130 -- .../frontend/pages/DemoLoginPage.java | 22 - .../commafeed/frontend/pages/HomePage.html | 12 - .../commafeed/frontend/pages/HomePage.java | 34 - .../commafeed/frontend/pages/LogoutPage.java | 11 - .../pages/NextUnreadRedirectPage.java | 78 - .../pages/PasswordRecoveryCallbackPage.html | 26 - .../pages/PasswordRecoveryCallbackPage.java | 77 - .../frontend/pages/PasswordRecoveryPage.html | 22 - .../frontend/pages/PasswordRecoveryPage.java | 78 - .../commafeed/frontend/pages/TestRssPage.java | 59 - .../commafeed/frontend/pages/WelcomePage.html | 81 - .../commafeed/frontend/pages/WelcomePage.java | 29 - .../com/commafeed/frontend/pages/analytics.js | 13 - .../components/BootstrapFeedbackPanel.java | 49 - .../frontend/pages/components/LoginPanel.html | 28 - .../frontend/pages/components/LoginPanel.java | 34 - .../pages/components/RegisterPanel.html | 25 - .../pages/components/RegisterPanel.java | 94 - .../resources => resource}/AdminREST.java | 182 +- .../resources => resource}/CategoryREST.java | 167 +- .../resources => resource}/EntryREST.java | 69 +- .../resources => resource}/FeedREST.java | 213 +- .../PubSubHubbubCallbackREST.java | 61 +- .../frontend/resource/ServerREST.java | 68 + .../resources => resource}/UserREST.java | 106 +- .../CustomCssUrlRewritingProcessor.java | 18 - .../resources/SassImportProcessor.java | 26 - .../frontend/resources/SassOnlyProcessor.java | 26 - .../resources/TimestampProcessor.java | 26 - .../resources/UserCustomCssReference.java | 37 - .../resources/WroAdditionalProvider.java | 32 - .../frontend/resources/WroListener.java | 22 - .../frontend/resources/WroManagerFactory.java | 22 - .../commafeed/frontend/rest/JsonProvider.java | 95 - .../commafeed/frontend/rest/PrettyPrint.java | 12 - .../frontend/rest/RESTApplication.java | 36 - .../frontend/rest/resources/AbstractREST.java | 150 -- .../frontend/rest/resources/ServerREST.java | 65 - ...InternationalizationDevelopmentFilter.java | 128 -- .../commafeed/frontend/utils/WicketUtils.java | 62 - .../utils/exception/DisplayException.java | 23 - .../utils/exception/DisplayExceptionPage.html | 27 - .../utils/exception/DisplayExceptionPage.java | 38 - src/main/resources/META-INF/persistence.xml | 39 - ...source.processor.support.ProcessorProvider | 1 - .../resources/changelogs/db.changelog-1.0.xml | 2 +- .../resources/changelogs/db.changelog-1.1.xml | 2 +- .../resources/changelogs/db.changelog-1.2.xml | 2 +- .../resources/changelogs/db.changelog-1.3.xml | 2 +- .../resources/changelogs/db.changelog-1.4.xml | 2 +- .../resources/changelogs/db.changelog-1.5.xml | 4 + src/main/resources/i18n/ar.properties | 157 -- src/main/resources/i18n/ca.properties | 156 -- src/main/resources/i18n/cs.properties | 157 -- src/main/resources/i18n/cy.properties | 157 -- src/main/resources/i18n/da.properties | 157 -- src/main/resources/i18n/de.properties | 157 -- src/main/resources/i18n/en.properties | 156 -- src/main/resources/i18n/es.properties | 157 -- src/main/resources/i18n/fa.properties | 157 -- src/main/resources/i18n/fi.properties | 157 -- src/main/resources/i18n/fr.properties | 157 -- src/main/resources/i18n/gl.properties | 157 -- src/main/resources/i18n/glk.properties | 157 -- src/main/resources/i18n/hu.properties | 157 -- src/main/resources/i18n/it.properties | 157 -- src/main/resources/i18n/ja.properties | 157 -- src/main/resources/i18n/ko.properties | 157 -- src/main/resources/i18n/languages.properties | 28 - src/main/resources/i18n/ms.properties | 157 -- src/main/resources/i18n/nb.properties | 157 -- src/main/resources/i18n/nl.properties | 157 -- src/main/resources/i18n/nn.properties | 157 -- src/main/resources/i18n/pl.properties | 157 -- src/main/resources/i18n/pt.properties | 157 -- src/main/resources/i18n/ru.properties | 157 -- src/main/resources/i18n/sk.properties | 157 -- src/main/resources/i18n/sv.properties | 157 -- src/main/resources/i18n/tr.properties | 157 -- src/main/resources/i18n/zh.properties | 157 -- src/main/resources/log4j.properties | 9 - ...db.changelog-master.xml => migrations.xml} | 2 +- src/main/script/HTMLConcat.groovy | 52 - src/main/script/I18nGenerator.groovy | 52 - src/main/tomee/conf/system.properties | 53 - src/main/tomee/conf/tomee.xml | 58 - .../META-INF/jboss-deployment-structure.xml | 7 - src/main/webapp/WEB-INF/beans.xml | 8 - src/main/webapp/WEB-INF/scan.xml | 7 - src/main/webapp/WEB-INF/web.xml | 39 - src/main/webapp/WEB-INF/wro.properties | 18 - src/main/webapp/WEB-INF/wro.xml | 61 - src/main/webapp/api/css/custom.css | 25 - .../webapp/api/css/hightlight.default.css | 135 -- src/main/webapp/api/css/screen.css | 1759 --------------- src/main/webapp/api/images/pet_store_api.png | Bin 824 -> 0 bytes src/main/webapp/api/images/throbber.gif | Bin 9257 -> 0 bytes src/main/webapp/api/images/wordnik_api.png | Bin 980 -> 0 bytes src/main/webapp/api/index.html | 92 - src/main/webapp/api/lib/backbone-min.js | 38 - .../webapp/api/lib/handlebars-1.0.rc.1.js | 1920 ---------------- src/main/webapp/api/lib/highlight.7.3.pack.js | 1 - src/main/webapp/api/lib/jquery-1.8.0.min.js | 2 - src/main/webapp/api/lib/jquery.ba-bbq.min.js | 18 - src/main/webapp/api/lib/jquery.slideto.min.js | 1 - src/main/webapp/api/lib/jquery.wiggle.min.js | 8 - src/main/webapp/api/lib/swagger.js | 767 ------- src/main/webapp/api/lib/underscore-min.js | 32 - src/main/webapp/api/swagger-ui.js | 1990 ----------------- src/main/webapp/api/swagger-ui.min.js | 1 - src/main/webapp/js/template-loader.js | 35 - src/main/webapp/sass/base/.gitkeep | 0 .../loading-bar.0.4.0.min.js | 300 --- .../angular-loading-bar/loading-bar.min.css | 8 - .../css/font-awesome-3.2.1.min.css | 403 ---- .../vendor/fontawesome/font/FontAwesome.otf | Bin 61896 -> 0 bytes .../fontawesome/font/fontawesome-webfont.eot | Bin 37405 -> 0 bytes .../fontawesome/font/fontawesome-webfont.svg | 399 ---- .../fontawesome/font/fontawesome-webfont.ttf | Bin 79076 -> 0 bytes .../fontawesome/font/fontawesome-webfont.woff | Bin 43572 -> 0 bytes .../jqueryui/images/animated-overlay.gif | Bin 1738 -> 0 bytes .../images/ui-bg_flat_0_aaaaaa_40x100.png | Bin 180 -> 0 bytes .../images/ui-bg_flat_75_ffffff_40x100.png | Bin 178 -> 0 bytes .../images/ui-bg_glass_55_fbf9ee_1x400.png | Bin 120 -> 0 bytes .../images/ui-bg_glass_65_ffffff_1x400.png | Bin 105 -> 0 bytes .../images/ui-bg_glass_75_dadada_1x400.png | Bin 111 -> 0 bytes .../images/ui-bg_glass_75_e6e6e6_1x400.png | Bin 110 -> 0 bytes .../images/ui-bg_glass_95_fef1ec_1x400.png | Bin 119 -> 0 bytes .../ui-bg_highlight-soft_75_cccccc_1x100.png | Bin 101 -> 0 bytes .../images/ui-icons_222222_256x240.png | Bin 4369 -> 0 bytes .../images/ui-icons_2e83ff_256x240.png | Bin 4369 -> 0 bytes .../images/ui-icons_454545_256x240.png | Bin 4369 -> 0 bytes .../images/ui-icons_888888_256x240.png | Bin 4369 -> 0 bytes .../images/ui-icons_cd0a0a_256x240.png | Bin 4369 -> 0 bytes .../vendor/jqueryui/jquery-ui.1.10.3.min.js | 12 - .../webapp/vendor/jqueryui/jquery-ui.min.css | 4 - .../readabilicons/css/readabilicons.css | 20 - .../fonts/readabilicons-regular.eot | Bin 4608 -> 0 bytes .../fonts/readabilicons-regular.svg | 47 - .../fonts/readabilicons-regular.ttf | Bin 7300 -> 0 bytes .../fonts/readabilicons-regular.woff | Bin 5280 -> 0 bytes .../webapp/vendor/select2/select2-spinner.gif | Bin 1849 -> 0 bytes .../vendor/select2/select2.3.4.3.min.js | 22 - src/main/webapp/vendor/select2/select2.css | 615 ----- src/main/webapp/vendor/select2/select2.png | Bin 613 -> 0 bytes src/main/webapp/vendor/select2/select2x2.png | Bin 845 -> 0 bytes .../vendor/zocial/zocial-regular-webfont.eot | Bin 32013 -> 0 bytes .../vendor/zocial/zocial-regular-webfont.svg | 151 -- .../vendor/zocial/zocial-regular-webfont.ttf | Bin 47988 -> 0 bytes .../vendor/zocial/zocial-regular-webfont.woff | Bin 34872 -> 0 bytes .../{feeds => feed}/FeedUtilsTest.java | 4 +- src/test/javascript/specs/test.js | 15 - 357 files changed, 2178 insertions(+), 19556 deletions(-) create mode 100644 .bowerrc delete mode 100644 .openshift/action_hooks/README.md delete mode 100755 .openshift/action_hooks/build delete mode 100755 .openshift/action_hooks/deploy delete mode 100755 .openshift/action_hooks/post_deploy delete mode 100755 .openshift/action_hooks/post_start_jbosseap-6.0 delete mode 100755 .openshift/action_hooks/post_stop_jbosseap-6.0 delete mode 100755 .openshift/action_hooks/pre_build delete mode 100755 .openshift/action_hooks/pre_build_jbosseap-6.0 delete mode 100755 .openshift/action_hooks/pre_start_jbosseap-6.0 delete mode 100755 .openshift/action_hooks/pre_stop_jbosseap-6.0 delete mode 100644 .openshift/config/modules/README delete mode 100644 .openshift/config/standalone.xml delete mode 100644 .openshift/cron/README.cron delete mode 100644 .openshift/cron/daily/.gitignore delete mode 100755 .openshift/cron/daily/log-cleanup.sh delete mode 100644 .openshift/cron/hourly/.gitignore delete mode 100644 .openshift/cron/minutely/.gitignore delete mode 100644 .openshift/cron/monthly/.gitignore delete mode 100644 .openshift/cron/weekly/README delete mode 100644 .openshift/cron/weekly/chrono.dat delete mode 100755 .openshift/cron/weekly/chronograph delete mode 100644 .openshift/cron/weekly/jobs.allow delete mode 100644 .openshift/cron/weekly/jobs.deny delete mode 100644 .openshift/markers/README delete mode 100644 LICENSE delete mode 100644 README.md create mode 100644 bower.json delete mode 100644 conf/setenv.bat delete mode 100644 conf/setenv.sh create mode 100644 config.yml create mode 100644 gulp create mode 100644 gulp.cmd create mode 100644 gulpfile.js create mode 100644 package.json rename src/main/{webapp => app}/app-icon-114.png (100%) rename src/main/{webapp => app}/app-icon-128.png (100%) rename src/main/{webapp => app}/app-icon-144.png (100%) rename src/main/{webapp => app}/app-icon-16.png (100%) rename src/main/{webapp => app}/app-icon-195.png (100%) rename src/main/{webapp => app}/app-icon-256.png (100%) rename src/main/{webapp => app}/app-icon-32.png (100%) rename src/main/{webapp => app}/app-icon-512.png (100%) rename src/main/{webapp => app}/app-icon-57.png (100%) rename src/main/{webapp => app}/app-icon-64.png (100%) rename src/main/{webapp => app}/app-icon-72.png (100%) rename src/main/{webapp => app}/app-icon.svg (100%) rename src/main/{webapp => app}/favicon.ico (100%) rename src/main/{webapp => app}/images/default_favicon.gif (100%) rename src/main/{webapp => app}/images/google_reader_icon.png (100%) rename src/main/{webapp => app}/images/logo.png (100%) rename src/main/{webapp => app}/images/logo_2.png (100%) rename src/main/{webapp => app}/images/preview.jpg (100%) create mode 100644 src/main/app/index.html rename src/main/{webapp => app}/js/controllers.js (96%) rename src/main/{webapp => app}/js/directives.js (100%) rename src/main/{webapp => app}/js/filters.js (100%) rename src/main/{webapp => app}/js/main.js (100%) rename src/main/{webapp => app}/js/services.js (100%) rename src/main/{webapp => app}/js/welcome.js (100%) rename src/main/{webapp => app}/metro-icon-150.png (100%) rename src/main/{webapp => app}/metro-icon-70.png (100%) rename src/main/{webapp => app}/sass/app.scss (87%) rename {deployments => src/main/app/sass/base}/.gitkeep (100%) rename src/main/{webapp => app}/sass/components/_admin-panel.scss (100%) rename src/main/{webapp => app}/sass/components/_entry-list.scss (100%) rename src/main/{webapp => app}/sass/components/_help.scss (100%) rename src/main/{webapp => app}/sass/components/_loading-bar.scss (100%) rename src/main/{webapp => app}/sass/components/_subscription-list.scss (100%) rename src/main/{webapp => app}/sass/components/_toolbar.scss (100%) create mode 100644 src/main/app/sass/components/readabilicons.scss rename src/main/{webapp/vendor/zocial/zocial.css => app/sass/components/zocial.scss} (79%) rename src/main/{webapp => app}/sass/generic/_misc.scss (100%) rename src/main/{webapp => app}/sass/generic/_scrollbar.scss (100%) rename src/main/{webapp => app}/sass/mobile/_mobile.scss (100%) rename src/main/{webapp => app}/sass/themes/_MRACHINI.scss (100%) rename src/main/{webapp => app}/sass/themes/_bootstrap.scss (100%) rename src/main/{webapp => app}/sass/themes/_dark.scss (100%) rename src/main/{webapp => app}/sass/themes/_ebraminio.scss (100%) rename src/main/{webapp => app}/sass/themes/_svetla.scss (100%) rename src/main/{webapp => app}/sass/themes/_test.scss (100%) rename src/main/{webapp => app}/sass/themes/_third.scss (100%) rename src/main/{webapp => app}/templates/_category.html (100%) rename src/main/{webapp => app}/templates/_feedsearch.html (100%) rename src/main/{webapp => app}/templates/_footer.html (100%) rename src/main/{webapp => app}/templates/_metrics.gauge.html (100%) rename src/main/{webapp => app}/templates/_metrics.meter.html (100%) rename src/main/{webapp => app}/templates/_shortcuts.html (100%) rename src/main/{webapp => app}/templates/_tags.html (100%) rename src/main/{webapp => app}/templates/_toolbar.html (100%) rename src/main/{webapp => app}/templates/_tree.html (100%) rename src/main/{webapp => app}/templates/admin.html (100%) rename src/main/{webapp => app}/templates/admin.metrics.html (100%) rename src/main/{webapp => app}/templates/admin.settings.html (100%) rename src/main/{webapp => app}/templates/admin.useradd.html (100%) rename src/main/{webapp => app}/templates/admin.useredit.html (100%) rename src/main/{webapp => app}/templates/admin.userlist.html (100%) rename src/main/{webapp => app}/templates/feeds.category_details.html (100%) rename src/main/{webapp => app}/templates/feeds.feed_details.html (100%) rename src/main/{webapp => app}/templates/feeds.help.html (100%) rename src/main/{webapp => app}/templates/feeds.html (100%) rename src/main/{webapp => app}/templates/feeds.import.html (100%) rename src/main/{webapp => app}/templates/feeds.new_category.html (100%) rename src/main/{webapp => app}/templates/feeds.subscribe.html (100%) rename src/main/{webapp => app}/templates/feeds.tag_details.html (100%) rename src/main/{webapp => app}/templates/feeds.view.html (100%) rename src/main/{webapp => app}/templates/profile.html (100%) rename src/main/{webapp => app}/templates/settings.html (100%) create mode 100644 src/main/java/com/commafeed/CommaFeedApplication.java create mode 100644 src/main/java/com/commafeed/CommaFeedAuthenticator.java create mode 100644 src/main/java/com/commafeed/CommaFeedConfiguration.java delete mode 100644 src/main/java/com/commafeed/backend/ScheduledTasks.java delete mode 100644 src/main/java/com/commafeed/backend/dao/ApplicationSettingsDAO.java create mode 100644 src/main/java/com/commafeed/backend/dao/UnitOfWork.java rename src/main/java/com/commafeed/backend/{feeds => feed}/FaviconFetcher.java (95%) rename src/main/java/com/commafeed/backend/{feeds => feed}/FeedFetcher.java (92%) rename src/main/java/com/commafeed/backend/{feeds => feed}/FeedParser.java (96%) rename src/main/java/com/commafeed/backend/{feeds/FeedRefreshTaskGiver.java => feed/FeedQueues.java} (54%) rename src/main/java/com/commafeed/backend/{feeds => feed}/FeedRefreshContext.java (89%) rename src/main/java/com/commafeed/backend/{feeds => feed}/FeedRefreshExecutor.java (95%) create mode 100644 src/main/java/com/commafeed/backend/feed/FeedRefreshTaskGiver.java rename src/main/java/com/commafeed/backend/{feeds => feed}/FeedRefreshUpdater.java (71%) rename src/main/java/com/commafeed/backend/{feeds => feed}/FeedRefreshWorker.java (72%) rename src/main/java/com/commafeed/backend/{feeds => feed}/FeedUtils.java (93%) rename src/main/java/com/commafeed/backend/{feeds => feed}/FetchedFeed.java (91%) rename src/main/java/com/commafeed/backend/{feeds => feed}/HtmlEntities.java (96%) delete mode 100644 src/main/java/com/commafeed/backend/metrics/MetricRegistryProducer.java delete mode 100644 src/main/java/com/commafeed/backend/model/ApplicationSettings.java rename src/main/java/com/commafeed/backend/{services => service}/ApplicationPropertiesService.java (63%) rename src/main/java/com/commafeed/backend/{services => service}/DatabaseCleaningService.java (87%) rename src/main/java/com/commafeed/backend/{services => service}/FeedEntryContentService.java (83%) rename src/main/java/com/commafeed/backend/{services => service}/FeedEntryService.java (87%) rename src/main/java/com/commafeed/backend/{services => service}/FeedEntryTagService.java (84%) create mode 100644 src/main/java/com/commafeed/backend/service/FeedService.java rename src/main/java/com/commafeed/backend/{services => service}/FeedSubscriptionService.java (75%) rename src/main/java/com/commafeed/backend/{services => service}/FeedUpdateService.java (75%) rename src/main/java/com/commafeed/backend/{services => service}/MailService.java (82%) rename src/main/java/com/commafeed/backend/{services => service}/PasswordEncryptionService.java (95%) rename src/main/java/com/commafeed/backend/{pubsubhubbub/SubscriptionHandler.java => service/PubSubService.java} (80%) create mode 100644 src/main/java/com/commafeed/backend/service/StartupService.java rename src/main/java/com/commafeed/backend/{services => service}/UserService.java (81%) delete mode 100644 src/main/java/com/commafeed/backend/services/ApplicationSettingsService.java delete mode 100644 src/main/java/com/commafeed/backend/services/FeedService.java delete mode 100644 src/main/java/com/commafeed/backend/startup/DatabaseUpdater.java delete mode 100644 src/main/java/com/commafeed/backend/startup/StartupBean.java delete mode 100644 src/main/java/com/commafeed/frontend/APIGenerator.java delete mode 100644 src/main/java/com/commafeed/frontend/CommaFeedApplication.java delete mode 100644 src/main/java/com/commafeed/frontend/CommaFeedSession.java delete mode 100644 src/main/java/com/commafeed/frontend/CommaFeedSessionServices.java delete mode 100644 src/main/java/com/commafeed/frontend/InterceptingFilter.java delete mode 100644 src/main/java/com/commafeed/frontend/SecurityCheck.java delete mode 100644 src/main/java/com/commafeed/frontend/pages/BasePage.html delete mode 100644 src/main/java/com/commafeed/frontend/pages/BasePage.java delete mode 100644 src/main/java/com/commafeed/frontend/pages/DemoLoginPage.java delete mode 100644 src/main/java/com/commafeed/frontend/pages/HomePage.html delete mode 100644 src/main/java/com/commafeed/frontend/pages/HomePage.java delete mode 100644 src/main/java/com/commafeed/frontend/pages/LogoutPage.java delete mode 100755 src/main/java/com/commafeed/frontend/pages/NextUnreadRedirectPage.java delete mode 100644 src/main/java/com/commafeed/frontend/pages/PasswordRecoveryCallbackPage.html delete mode 100644 src/main/java/com/commafeed/frontend/pages/PasswordRecoveryCallbackPage.java delete mode 100644 src/main/java/com/commafeed/frontend/pages/PasswordRecoveryPage.html delete mode 100644 src/main/java/com/commafeed/frontend/pages/PasswordRecoveryPage.java delete mode 100644 src/main/java/com/commafeed/frontend/pages/TestRssPage.java delete mode 100644 src/main/java/com/commafeed/frontend/pages/WelcomePage.html delete mode 100644 src/main/java/com/commafeed/frontend/pages/WelcomePage.java delete mode 100644 src/main/java/com/commafeed/frontend/pages/analytics.js delete mode 100644 src/main/java/com/commafeed/frontend/pages/components/BootstrapFeedbackPanel.java delete mode 100644 src/main/java/com/commafeed/frontend/pages/components/LoginPanel.html delete mode 100644 src/main/java/com/commafeed/frontend/pages/components/LoginPanel.java delete mode 100644 src/main/java/com/commafeed/frontend/pages/components/RegisterPanel.html delete mode 100644 src/main/java/com/commafeed/frontend/pages/components/RegisterPanel.java rename src/main/java/com/commafeed/frontend/{rest/resources => resource}/AdminREST.java (52%) rename src/main/java/com/commafeed/frontend/{rest/resources => resource}/CategoryREST.java (76%) rename src/main/java/com/commafeed/frontend/{rest/resources => resource}/EntryREST.java (52%) rename src/main/java/com/commafeed/frontend/{rest/resources => resource}/FeedREST.java (70%) rename src/main/java/com/commafeed/frontend/{rest/resources => resource}/PubSubHubbubCallbackREST.java (68%) create mode 100644 src/main/java/com/commafeed/frontend/resource/ServerREST.java rename src/main/java/com/commafeed/frontend/{rest/resources => resource}/UserREST.java (73%) delete mode 100644 src/main/java/com/commafeed/frontend/resources/CustomCssUrlRewritingProcessor.java delete mode 100644 src/main/java/com/commafeed/frontend/resources/SassImportProcessor.java delete mode 100644 src/main/java/com/commafeed/frontend/resources/SassOnlyProcessor.java delete mode 100644 src/main/java/com/commafeed/frontend/resources/TimestampProcessor.java delete mode 100644 src/main/java/com/commafeed/frontend/resources/UserCustomCssReference.java delete mode 100644 src/main/java/com/commafeed/frontend/resources/WroAdditionalProvider.java delete mode 100644 src/main/java/com/commafeed/frontend/resources/WroListener.java delete mode 100644 src/main/java/com/commafeed/frontend/resources/WroManagerFactory.java delete mode 100644 src/main/java/com/commafeed/frontend/rest/JsonProvider.java delete mode 100644 src/main/java/com/commafeed/frontend/rest/PrettyPrint.java delete mode 100644 src/main/java/com/commafeed/frontend/rest/RESTApplication.java delete mode 100644 src/main/java/com/commafeed/frontend/rest/resources/AbstractREST.java delete mode 100644 src/main/java/com/commafeed/frontend/rest/resources/ServerREST.java delete mode 100644 src/main/java/com/commafeed/frontend/utils/InternationalizationDevelopmentFilter.java delete mode 100644 src/main/java/com/commafeed/frontend/utils/WicketUtils.java delete mode 100644 src/main/java/com/commafeed/frontend/utils/exception/DisplayException.java delete mode 100644 src/main/java/com/commafeed/frontend/utils/exception/DisplayExceptionPage.html delete mode 100644 src/main/java/com/commafeed/frontend/utils/exception/DisplayExceptionPage.java delete mode 100644 src/main/resources/META-INF/persistence.xml delete mode 100644 src/main/resources/META-INF/services/ro.isdc.wro.model.resource.processor.support.ProcessorProvider delete mode 100644 src/main/resources/i18n/ar.properties delete mode 100644 src/main/resources/i18n/ca.properties delete mode 100644 src/main/resources/i18n/cs.properties delete mode 100644 src/main/resources/i18n/cy.properties delete mode 100644 src/main/resources/i18n/da.properties delete mode 100644 src/main/resources/i18n/de.properties delete mode 100644 src/main/resources/i18n/en.properties delete mode 100644 src/main/resources/i18n/es.properties delete mode 100644 src/main/resources/i18n/fa.properties delete mode 100644 src/main/resources/i18n/fi.properties delete mode 100644 src/main/resources/i18n/fr.properties delete mode 100644 src/main/resources/i18n/gl.properties delete mode 100644 src/main/resources/i18n/glk.properties delete mode 100644 src/main/resources/i18n/hu.properties delete mode 100644 src/main/resources/i18n/it.properties delete mode 100644 src/main/resources/i18n/ja.properties delete mode 100644 src/main/resources/i18n/ko.properties delete mode 100644 src/main/resources/i18n/languages.properties delete mode 100644 src/main/resources/i18n/ms.properties delete mode 100644 src/main/resources/i18n/nb.properties delete mode 100644 src/main/resources/i18n/nl.properties delete mode 100644 src/main/resources/i18n/nn.properties delete mode 100644 src/main/resources/i18n/pl.properties delete mode 100644 src/main/resources/i18n/pt.properties delete mode 100644 src/main/resources/i18n/ru.properties delete mode 100644 src/main/resources/i18n/sk.properties delete mode 100644 src/main/resources/i18n/sv.properties delete mode 100644 src/main/resources/i18n/tr.properties delete mode 100644 src/main/resources/i18n/zh.properties delete mode 100644 src/main/resources/log4j.properties rename src/main/resources/{changelogs/db.changelog-master.xml => migrations.xml} (88%) delete mode 100644 src/main/script/HTMLConcat.groovy delete mode 100644 src/main/script/I18nGenerator.groovy delete mode 100644 src/main/tomee/conf/system.properties delete mode 100644 src/main/tomee/conf/tomee.xml delete mode 100644 src/main/webapp/META-INF/jboss-deployment-structure.xml delete mode 100644 src/main/webapp/WEB-INF/beans.xml delete mode 100644 src/main/webapp/WEB-INF/scan.xml delete mode 100644 src/main/webapp/WEB-INF/web.xml delete mode 100644 src/main/webapp/WEB-INF/wro.properties delete mode 100644 src/main/webapp/WEB-INF/wro.xml delete mode 100644 src/main/webapp/api/css/custom.css delete mode 100644 src/main/webapp/api/css/hightlight.default.css delete mode 100644 src/main/webapp/api/css/screen.css delete mode 100644 src/main/webapp/api/images/pet_store_api.png delete mode 100644 src/main/webapp/api/images/throbber.gif delete mode 100644 src/main/webapp/api/images/wordnik_api.png delete mode 100644 src/main/webapp/api/index.html delete mode 100644 src/main/webapp/api/lib/backbone-min.js delete mode 100644 src/main/webapp/api/lib/handlebars-1.0.rc.1.js delete mode 100644 src/main/webapp/api/lib/highlight.7.3.pack.js delete mode 100644 src/main/webapp/api/lib/jquery-1.8.0.min.js delete mode 100644 src/main/webapp/api/lib/jquery.ba-bbq.min.js delete mode 100644 src/main/webapp/api/lib/jquery.slideto.min.js delete mode 100644 src/main/webapp/api/lib/jquery.wiggle.min.js delete mode 100644 src/main/webapp/api/lib/swagger.js delete mode 100644 src/main/webapp/api/lib/underscore-min.js delete mode 100644 src/main/webapp/api/swagger-ui.js delete mode 100644 src/main/webapp/api/swagger-ui.min.js delete mode 100644 src/main/webapp/js/template-loader.js delete mode 100644 src/main/webapp/sass/base/.gitkeep delete mode 100644 src/main/webapp/vendor/angular-loading-bar/loading-bar.0.4.0.min.js delete mode 100644 src/main/webapp/vendor/angular-loading-bar/loading-bar.min.css delete mode 100644 src/main/webapp/vendor/fontawesome/css/font-awesome-3.2.1.min.css delete mode 100644 src/main/webapp/vendor/fontawesome/font/FontAwesome.otf delete mode 100644 src/main/webapp/vendor/fontawesome/font/fontawesome-webfont.eot delete mode 100644 src/main/webapp/vendor/fontawesome/font/fontawesome-webfont.svg delete mode 100644 src/main/webapp/vendor/fontawesome/font/fontawesome-webfont.ttf delete mode 100644 src/main/webapp/vendor/fontawesome/font/fontawesome-webfont.woff delete mode 100644 src/main/webapp/vendor/jqueryui/images/animated-overlay.gif delete mode 100644 src/main/webapp/vendor/jqueryui/images/ui-bg_flat_0_aaaaaa_40x100.png delete mode 100644 src/main/webapp/vendor/jqueryui/images/ui-bg_flat_75_ffffff_40x100.png delete mode 100644 src/main/webapp/vendor/jqueryui/images/ui-bg_glass_55_fbf9ee_1x400.png delete mode 100644 src/main/webapp/vendor/jqueryui/images/ui-bg_glass_65_ffffff_1x400.png delete mode 100644 src/main/webapp/vendor/jqueryui/images/ui-bg_glass_75_dadada_1x400.png delete mode 100644 src/main/webapp/vendor/jqueryui/images/ui-bg_glass_75_e6e6e6_1x400.png delete mode 100644 src/main/webapp/vendor/jqueryui/images/ui-bg_glass_95_fef1ec_1x400.png delete mode 100644 src/main/webapp/vendor/jqueryui/images/ui-bg_highlight-soft_75_cccccc_1x100.png delete mode 100644 src/main/webapp/vendor/jqueryui/images/ui-icons_222222_256x240.png delete mode 100644 src/main/webapp/vendor/jqueryui/images/ui-icons_2e83ff_256x240.png delete mode 100644 src/main/webapp/vendor/jqueryui/images/ui-icons_454545_256x240.png delete mode 100644 src/main/webapp/vendor/jqueryui/images/ui-icons_888888_256x240.png delete mode 100644 src/main/webapp/vendor/jqueryui/images/ui-icons_cd0a0a_256x240.png delete mode 100644 src/main/webapp/vendor/jqueryui/jquery-ui.1.10.3.min.js delete mode 100644 src/main/webapp/vendor/jqueryui/jquery-ui.min.css delete mode 100644 src/main/webapp/vendor/readabilicons/css/readabilicons.css delete mode 100644 src/main/webapp/vendor/readabilicons/fonts/readabilicons-regular.eot delete mode 100644 src/main/webapp/vendor/readabilicons/fonts/readabilicons-regular.svg delete mode 100644 src/main/webapp/vendor/readabilicons/fonts/readabilicons-regular.ttf delete mode 100644 src/main/webapp/vendor/readabilicons/fonts/readabilicons-regular.woff delete mode 100644 src/main/webapp/vendor/select2/select2-spinner.gif delete mode 100644 src/main/webapp/vendor/select2/select2.3.4.3.min.js delete mode 100644 src/main/webapp/vendor/select2/select2.css delete mode 100644 src/main/webapp/vendor/select2/select2.png delete mode 100644 src/main/webapp/vendor/select2/select2x2.png delete mode 100644 src/main/webapp/vendor/zocial/zocial-regular-webfont.eot delete mode 100644 src/main/webapp/vendor/zocial/zocial-regular-webfont.svg delete mode 100644 src/main/webapp/vendor/zocial/zocial-regular-webfont.ttf delete mode 100644 src/main/webapp/vendor/zocial/zocial-regular-webfont.woff rename src/test/java/com/commafeed/backend/{feeds => feed}/FeedUtilsTest.java (95%) delete mode 100644 src/test/javascript/specs/test.js diff --git a/.bowerrc b/.bowerrc new file mode 100644 index 00000000..b1283deb --- /dev/null +++ b/.bowerrc @@ -0,0 +1,3 @@ +{ + "directory": "src/main/app/lib" +} \ No newline at end of file diff --git a/.gitignore b/.gitignore index f53e9dfe..755a3061 100644 --- a/.gitignore +++ b/.gitignore @@ -1,19 +1,18 @@ -#runtime files -commafeed.log -derby.log -data/ -java_pid* - -# Maven build directory +# build directory target -deployments/ROOT.war + +# node +node +node_modules + +# bower +src/main/app/lib # Eclipse files .project .classpath .settings .factorypath -/target # IntelliJ Idea files .idea diff --git a/.openshift/action_hooks/README.md b/.openshift/action_hooks/README.md deleted file mode 100644 index 86ac3ec5..00000000 --- a/.openshift/action_hooks/README.md +++ /dev/null @@ -1,3 +0,0 @@ -For information about which action hooks are supported, consult the OpenShift documentation: - -https://github.com/openshift/origin-server/blob/master/node/README.writing_applications.md diff --git a/.openshift/action_hooks/build b/.openshift/action_hooks/build deleted file mode 100755 index f0861010..00000000 --- a/.openshift/action_hooks/build +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash -# This is a simple build script and will be executed on your CI system if -# available. Otherwise it will execute while your application is stopped -# before the deploy step. This script gets executed directly, so it -# could be python, php, ruby, etc. diff --git a/.openshift/action_hooks/deploy b/.openshift/action_hooks/deploy deleted file mode 100755 index ed5eb993..00000000 --- a/.openshift/action_hooks/deploy +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash -# This deploy hook gets executed after dependencies are resolved and the -# build hook has been run but before the application has been started back -# up again. This script gets executed directly, so it could be python, php, -# ruby, etc. \ No newline at end of file diff --git a/.openshift/action_hooks/post_deploy b/.openshift/action_hooks/post_deploy deleted file mode 100755 index a57d1f58..00000000 --- a/.openshift/action_hooks/post_deploy +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash -# This is a simple post deploy hook executed after your application -# is deployed and started. This script gets executed directly, so -# it could be python, php, ruby, etc. \ No newline at end of file diff --git a/.openshift/action_hooks/post_start_jbosseap-6.0 b/.openshift/action_hooks/post_start_jbosseap-6.0 deleted file mode 100755 index ff0debda..00000000 --- a/.openshift/action_hooks/post_start_jbosseap-6.0 +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/bash - -# The pre_start_cartridge and pre_stop_cartridge hooks are *SOURCED* -# immediately before (re)starting or stopping the specified cartridge. -# They are able to make any desired environment variable changes as -# well as other adjustments to the application environment. - -# The post_start_cartridge and post_stop_cartridge hooks are executed -# immediately after (re)starting or stopping the specified cartridge. - -# Exercise caution when adding commands to these hooks. They can -# prevent your application from stopping cleanly or starting at all. -# Application start and stop is subject to different timeouts -# throughout the system. diff --git a/.openshift/action_hooks/post_stop_jbosseap-6.0 b/.openshift/action_hooks/post_stop_jbosseap-6.0 deleted file mode 100755 index ff0debda..00000000 --- a/.openshift/action_hooks/post_stop_jbosseap-6.0 +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/bash - -# The pre_start_cartridge and pre_stop_cartridge hooks are *SOURCED* -# immediately before (re)starting or stopping the specified cartridge. -# They are able to make any desired environment variable changes as -# well as other adjustments to the application environment. - -# The post_start_cartridge and post_stop_cartridge hooks are executed -# immediately after (re)starting or stopping the specified cartridge. - -# Exercise caution when adding commands to these hooks. They can -# prevent your application from stopping cleanly or starting at all. -# Application start and stop is subject to different timeouts -# throughout the system. diff --git a/.openshift/action_hooks/pre_build b/.openshift/action_hooks/pre_build deleted file mode 100755 index 10cd5446..00000000 --- a/.openshift/action_hooks/pre_build +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash -# This is a simple script and will be executed on your CI system if -# available. Otherwise it will execute while your application is stopped -# before the build step. This script gets executed directly, so it -# could be python, php, ruby, etc. \ No newline at end of file diff --git a/.openshift/action_hooks/pre_build_jbosseap-6.0 b/.openshift/action_hooks/pre_build_jbosseap-6.0 deleted file mode 100755 index 557aa544..00000000 --- a/.openshift/action_hooks/pre_build_jbosseap-6.0 +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash -# This is a simple bash script and will be sourced prior to building -# your application. This script can be used to modify the Maven build -# arguments for non-CI/Jenkins builds by exporting MAVEN_ARGS. The default -# is "clean package -Popenshift -DskipTests" -export MAVEN_ARGS="clean package -Popenshift -Pprod -DskipTests=true" -export MAVEN_OPTS="-Xmx512m -XX:MaxPermSize=128m -Dmaven.artifact.threads=20" \ No newline at end of file diff --git a/.openshift/action_hooks/pre_start_jbosseap-6.0 b/.openshift/action_hooks/pre_start_jbosseap-6.0 deleted file mode 100755 index ff0debda..00000000 --- a/.openshift/action_hooks/pre_start_jbosseap-6.0 +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/bash - -# The pre_start_cartridge and pre_stop_cartridge hooks are *SOURCED* -# immediately before (re)starting or stopping the specified cartridge. -# They are able to make any desired environment variable changes as -# well as other adjustments to the application environment. - -# The post_start_cartridge and post_stop_cartridge hooks are executed -# immediately after (re)starting or stopping the specified cartridge. - -# Exercise caution when adding commands to these hooks. They can -# prevent your application from stopping cleanly or starting at all. -# Application start and stop is subject to different timeouts -# throughout the system. diff --git a/.openshift/action_hooks/pre_stop_jbosseap-6.0 b/.openshift/action_hooks/pre_stop_jbosseap-6.0 deleted file mode 100755 index ff0debda..00000000 --- a/.openshift/action_hooks/pre_stop_jbosseap-6.0 +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/bash - -# The pre_start_cartridge and pre_stop_cartridge hooks are *SOURCED* -# immediately before (re)starting or stopping the specified cartridge. -# They are able to make any desired environment variable changes as -# well as other adjustments to the application environment. - -# The post_start_cartridge and post_stop_cartridge hooks are executed -# immediately after (re)starting or stopping the specified cartridge. - -# Exercise caution when adding commands to these hooks. They can -# prevent your application from stopping cleanly or starting at all. -# Application start and stop is subject to different timeouts -# throughout the system. diff --git a/.openshift/config/modules/README b/.openshift/config/modules/README deleted file mode 100644 index cb69cf94..00000000 --- a/.openshift/config/modules/README +++ /dev/null @@ -1,3 +0,0 @@ -Place your jboss-as7 modules in this directory. This directory is added to the -module path of the jboss-as7 server associated with your application. It has the -same structure as the jboss-as7/modules directory. diff --git a/.openshift/config/standalone.xml b/.openshift/config/standalone.xml deleted file mode 100644 index 12d7f66c..00000000 --- a/.openshift/config/standalone.xml +++ /dev/null @@ -1,517 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - jdbc:mysql://${env.OPENSHIFT_MYSQL_DB_HOST}:${env.OPENSHIFT_MYSQL_DB_PORT}/${env.OPENSHIFT_APP_NAME}?useUnicode=true&characterEncoding=UTF-8 - - mysql - - ${env.OPENSHIFT_MYSQL_DB_USERNAME} - ${env.OPENSHIFT_MYSQL_DB_PASSWORD} - - - - - com.mysql.jdbc.jdbc2.optional.MysqlXADataSource - - - - - - - - - false - - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ${env.OPENSHIFT_GEAR_DNS} - ${env.OPENSHIFT_JBOSSEAP_CLUSTER_PROXY_PORT} - - 7600 - ${env.OPENSHIFT_JBOSSEAP_IP} - - - 3000 - ${env.OPENSHIFT_JBOSSEAP_CLUSTER} - 0 - 1 - - - - - - - - - - org.jgroups.auth.MD5Token - SHA - ${env.OPENSHIFT_APP_UUID} - - - - - - - - - - - - - - - - - - - - - - - - false - false - false - 102400 - 2 - - ${messaging.thread.pool.max.size} - ${messaging.scheduled.thread.pool.max.size} - - - - - - - - - - - - - - - - - - - - - jms.queue.DLQ - jms.queue.ExpiryQueue - 0 - 1000 - 10485760 - BLOCK - 10 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - true - ${env.OPENSHIFT_GEAR_DNS} - 80 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/.openshift/cron/README.cron b/.openshift/cron/README.cron deleted file mode 100644 index aad91380..00000000 --- a/.openshift/cron/README.cron +++ /dev/null @@ -1,22 +0,0 @@ -Run scripts or jobs on a periodic basis -======================================= -Any scripts or jobs added to the minutely, hourly, daily, weekly or monthly -directories will be run on a scheduled basis (frequency is as indicated by the -name of the directory) using run-parts. - -run-parts ignores any files that are hidden or dotfiles (.*) or backup -files (*~ or *,) or named *.{rpmsave,rpmorig,rpmnew,swp,cfsaved} - -The presence of two specially named files jobs.deny and jobs.allow controls -how run-parts executes your scripts/jobs. - jobs.deny ===> Prevents specific scripts or jobs from being executed. - jobs.allow ===> Only execute the named scripts or jobs (all other/non-named - scripts that exist in this directory are ignored). - -The principles of jobs.deny and jobs.allow are the same as those of cron.deny -and cron.allow and are described in detail at: - http://docs.redhat.com/docs/en-US/Red_Hat_Enterprise_Linux/6/html/Deployment_Guide/ch-Automating_System_Tasks.html#s2-autotasks-cron-access - -See: man crontab or above link for more details and see the the weekly/ - directory for an example. - diff --git a/.openshift/cron/daily/.gitignore b/.openshift/cron/daily/.gitignore deleted file mode 100644 index e69de29b..00000000 diff --git a/.openshift/cron/daily/log-cleanup.sh b/.openshift/cron/daily/log-cleanup.sh deleted file mode 100755 index ce79496f..00000000 --- a/.openshift/cron/daily/log-cleanup.sh +++ /dev/null @@ -1,7 +0,0 @@ -if [ $OPENSHIFT_JBOSSAS_LOG_DIR ]; then - rm -rf $OPENSHIFT_JBOSSAS_LOG_DIR/*.log.* -fi - -if [ $OPENSHIFT_JBOSSEAP_LOG_DIR ]; then - rm -rf $OPENSHIFT_JBOSSEAP_LOG_DIR/*.log.* -fi \ No newline at end of file diff --git a/.openshift/cron/hourly/.gitignore b/.openshift/cron/hourly/.gitignore deleted file mode 100644 index e69de29b..00000000 diff --git a/.openshift/cron/minutely/.gitignore b/.openshift/cron/minutely/.gitignore deleted file mode 100644 index e69de29b..00000000 diff --git a/.openshift/cron/monthly/.gitignore b/.openshift/cron/monthly/.gitignore deleted file mode 100644 index e69de29b..00000000 diff --git a/.openshift/cron/weekly/README b/.openshift/cron/weekly/README deleted file mode 100644 index 7c3e659f..00000000 --- a/.openshift/cron/weekly/README +++ /dev/null @@ -1,16 +0,0 @@ -Run scripts or jobs on a weekly basis -===================================== -Any scripts or jobs added to this directory will be run on a scheduled basis -(weekly) using run-parts. - -run-parts ignores any files that are hidden or dotfiles (.*) or backup -files (*~ or *,) or named *.{rpmsave,rpmorig,rpmnew,swp,cfsaved} and handles -the files named jobs.deny and jobs.allow specially. - -In this specific example, the chronograph script is the only script or job file -executed on a weekly basis (due to white-listing it in jobs.allow). And the -README and chrono.dat file are ignored either as a result of being black-listed -in jobs.deny or because they are NOT white-listed in the jobs.allow file. - -For more details, please see ../README.cron file. - diff --git a/.openshift/cron/weekly/chrono.dat b/.openshift/cron/weekly/chrono.dat deleted file mode 100644 index fc4abb87..00000000 --- a/.openshift/cron/weekly/chrono.dat +++ /dev/null @@ -1 +0,0 @@ -Time And Relative D...n In Execution (Open)Shift! diff --git a/.openshift/cron/weekly/chronograph b/.openshift/cron/weekly/chronograph deleted file mode 100755 index 61de949f..00000000 --- a/.openshift/cron/weekly/chronograph +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -echo "`date`: `cat $(dirname \"$0\")/chrono.dat`" diff --git a/.openshift/cron/weekly/jobs.allow b/.openshift/cron/weekly/jobs.allow deleted file mode 100644 index 8d32abc7..00000000 --- a/.openshift/cron/weekly/jobs.allow +++ /dev/null @@ -1,12 +0,0 @@ -# -# Script or job files listed in here (one entry per line) will be -# executed on a weekly-basis. -# -# Example: The chronograph script will be executed weekly but the README -# and chrono.dat files in this directory will be ignored. -# -# The README file is actually ignored due to the entry in the -# jobs.deny which is checked before jobs.allow (this file). -# -chronograph - diff --git a/.openshift/cron/weekly/jobs.deny b/.openshift/cron/weekly/jobs.deny deleted file mode 100644 index 73c94500..00000000 --- a/.openshift/cron/weekly/jobs.deny +++ /dev/null @@ -1,7 +0,0 @@ -# -# Any script or job files listed in here (one entry per line) will NOT be -# executed (read as ignored by run-parts). -# - -README - diff --git a/.openshift/markers/README b/.openshift/markers/README deleted file mode 100644 index 154c7895..00000000 --- a/.openshift/markers/README +++ /dev/null @@ -1,22 +0,0 @@ -Markers -=========== - -Adding marker files to this directory will have the following effects: - -enable_jpda - Will enable the JPDA socket based transport on the java virtual - machine running the JBoss AS 7 application server. This enables - you to remotely debug code running inside the JBoss AS 7 - application server. - -skip_maven_build - Maven build step will be skipped - -force_clean_build - Will start the build process by removing all non -essential Maven dependencies. Any current dependencies specified in -your pom.xml file will then be re-downloaded. - -hot_deploy - Will prevent a JBoss container restart during build/deployment. - Newly build archives will be re-deployed automatically by the - JBoss HDScanner component. - -java7 - Will run JBoss AS7 with Java7 if present. If no marker is present then the - baseline Java version will be used (currently Java6) diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 014a5538..00000000 --- a/LICENSE +++ /dev/null @@ -1,31 +0,0 @@ -Apache License, Version 2.0 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION -1. Definitions. -"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. -"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. -"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. -"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. -"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. -"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. -"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). -"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. -"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." -"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. -2. Grant of Copyright License. -Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. -3. Grant of Patent License. -Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. -4. Redistribution. -You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: -You must give any other recipients of the Work or Derivative Works a copy of this License; and You must cause any modified files to carry prominent notices stating that You changed the files; and You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. -5. Submission of Contributions. -Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. -6. Trademarks. -This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. -7. Disclaimer of Warranty. -Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. -8. Limitation of Liability. -In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. -9. Accepting Warranty or Additional Liability. -While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. -END OF TERMS AND CONDITIONS \ No newline at end of file diff --git a/README.md b/README.md deleted file mode 100644 index a5e20b87..00000000 --- a/README.md +++ /dev/null @@ -1,132 +0,0 @@ -CommaFeed [![Build Status](https://buildhive.cloudbees.com/job/Athou/job/commafeed/badge/icon)](https://buildhive.cloudbees.com/job/Athou/job/commafeed/) -========= -Sources for [CommaFeed.com](http://www.commafeed.com/). - -Google Reader inspired self-hosted RSS reader, based on JAX-RS, Wicket and AngularJS. - -Deploy on your own server (using TomEE, a lightweight JavaEE6 container based on Tomcat) or even in the cloud for free on OpenShift. - -Related open-source projects ----------------------------- - -Android apps: [News+ extension](https://github.com/Athou/commafeed-newsplus) - [Android app](https://github.com/doomrobo/CommaFeed-Android-Reader) - -Browser extensions: [Chrome](https://github.com/Athou/commafeed-chrome) - [Firefox](https://github.com/Athou/commafeed-firefox) - [Opera](https://github.com/Athou/commafeed-opera) - [Safari](https://github.com/Athou/commafeed-safari) - -Deployment on OpenShift ------------------------ - -Hosting an application on OpenShift is free. -At the moment those instructions are not working because the application takes too long to build on OpenShift and causes a timeout. -See [here](http://jasonwryan.com/blog/2013/05/25/greader/) for an alternative method. - -* Create an account on [OpenShift](http://www.openshift.com/). -* Add an application, select `JBoss Enterprise Application Platform 6.0`. -* For the `Public URL` set the name you want (e.g. `commafeed`). -* For the `Source Code` option, click `Change` and set this repository (`https://github.com/Athou/commafeed.git`). -* Click `Create Application`. -* Click `Add cartridge` and select `MySQL`. -* Wait a couple of minutes and access your application. -* The default user is `admin` and the password is `admin`. - -Deployment on your own server ------------------------------ - -For storage, you can either use an embedded HSQLDB database or an external MySQL, PostgreSQL or SQLServer database. -You also need Maven 3.x (and a Java 1.7+ JDK) installed in order to build the application. - -To install maven and openjdk on Ubuntu, issue the following commands - - sudo add-apt-repository ppa:natecarlson/maven3 - sudo apt-get update - sudo apt-get install openjdk-7-jdk maven3 - - # Not required but if you don't, use 'mvn3' instead of 'mvn' for the rest of the instructions. - sudo ln -s /usr/bin/mvn3 /usr/bin/mvn - -On Windows and other operating systems, just download maven 3.x from the [official site](http://maven.apache.org/), extract it somewhere and add the `bin` directory to your `PATH` environment variable. - -Download the sources (it doesn't matter where, you can delete the directory when you're done). -If you don't have git you can download the sources as a zip file from [here](https://github.com/Athou/commafeed/archive/master.zip) - - git clone https://github.com/Athou/commafeed.git - cd commafeed - -Now build the application - - # Embedded HSQL database: - mvn clean package tomee:build -Pprod - - # External MySQL database: - mvn clean package tomee:build -Pprod -Pmysql - - # External PostgreSQL database: - mvn clean package tomee:build -Pprod -Ppgsql - - # External Microsoft SQL Server database: - mvn clean package tomee:build -Pprod -Pmssql - -It will generate a zip file at `target/commafeed.zip` with everything you need to run the application. - -* Create a directory somewhere (e.g. `/opt/commafeed/`) and extract the generated zip inside this directory. -* Create a directory called `logs` (e.g. `/opt/commafeed/logs`) -* Copy the file `conf/setenv.sh` (Linux) or `conf/setenv.bat` (Windows) to `bin/` -* If you don't use the embedded database, create a database in your external database instance, then uncomment the `Resource` element corresponding to the database engine you use from `conf/tomee.xml` and edit the default credentials. -* If you'd like to change the default port (8082), edit `conf/server.xml` and look for ``). -This will generate the file `target/commafeed.war`. Copy this file to your tomee `webapps/` directory. -* The application is online at [http://localhost:8082/commafeed](http://localhost:8082/commafeed). Don't forget to set the public URL in the admin settings. -* The default user is `admin` and the password is `admin`. - -You can use nginx or apache as a proxy http server. Note that when using apache, the `ProxyPreserveHost on` option should be set in your config file. - -Local development ------------------ - -Checkout the code and use maven to build and start a local TomEE instance. - - `mvn clean package tomee:run` - -The application is online at [http://localhost:8082/commafeed](http://localhost:8082/commafeed). Any change to the source code will be applied immediatly. -The default user is `admin` and the password is `admin`. - -Translate CommaFeed into your language --------------------------------------- - -Files for internationalization are located [here](https://github.com/Athou/commafeed/tree/master/src/main/resources/i18n). - -To add a new language, create a new file in that directory. -The name of the file should be the two-letters [ISO-639-1 language code](http://en.wikipedia.org/wiki/List_of_ISO_639-1_codes). -The language has to be referenced in the `languages.properties` file to be picked up. - -When adding new translations, add them in en.properties then run `mvn -e groovy:execute -Pi18n`. It will parse the english file and add placeholders in the other translation files. - -Themes ---------------------- - -To create a theme, create a new file `src/main/webapp/sass/themes/_.scss`. Your styles should be wrapped in a `#theme-` element and use the [SCSS format](http://sass-lang.com/) which is a superset of CSS. - -Don't forget to reference your theme in `src/main/webapp/sass/app.scss` and in `src/main/webapp/js/controllers.js` (look for `$scope.themes`). - -See [_test.scss](https://github.com/Athou/commafeed/blob/master/src/main/webapp/sass/themes/_test.scss) for an example. - - -Copyright and license ---------------------- - -Copyright 2013 CommaFeed. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this work except in compliance with the License. -You may obtain a copy of the License in the LICENSE file, or at: - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/bower.json b/bower.json new file mode 100644 index 00000000..811c83fd --- /dev/null +++ b/bower.json @@ -0,0 +1,30 @@ +{ + "name": "commafeed", + "version": "2.0.0", + "dependencies": { + "jquery": "1.11.0", + "jquery-ui": "1.11", + "jquery-mousewheel": "3.1.12", + "lodash": "2.4.1", + "bootstrap": "3.1.1", + "font-awesome": "3.2.1", + "angular": "1.2.16", + "angular-resource": "1.2.16", + "angular-route": "1.2.16", + "angular-sanitize": "1.2.16", + "angular-touch": "1.2.16", + "angular-animate": "1.2.16", + "angular-ui-router": "0.2.8", + "angular-ui-utils": "0.1.0", + "angular-ui-select2": "0.0.5", + "angular-bootstrap": "0.2.0", + "angular-loading-bar": "0.4.0", + "ngInfiniteScroll": "1.0.0", + "ng-grid": "2.0.6", + "mousetrap": "1.4.6", + "momentjs": "2.6.0", + "device.js": "matthewhudson/device.js#2ae5c775e35ccc837589e5af34e292c54936778c", + "readabilicons": "arc90/readability-readabilicons#34c55561c5b8ec6e90714b50237c06b13cb9d59c", + "zocial": "samcollins/css-social-buttons#1f59ecacde475e563fb6771667597493ec4eecb6" + } +} diff --git a/conf/setenv.bat b/conf/setenv.bat deleted file mode 100644 index d48bf725..00000000 --- a/conf/setenv.bat +++ /dev/null @@ -1 +0,0 @@ -set JAVA_OPTS=-Djava.net.preferIPv4Stack=true -Xmx1024m -XX:MaxPermSize=256m -XX:+CMSClassUnloadingEnabled -XX:+UseConcMarkSweepGC -Djsse.enableSNIExtension=false \ No newline at end of file diff --git a/conf/setenv.sh b/conf/setenv.sh deleted file mode 100644 index 7ad8e3ad..00000000 --- a/conf/setenv.sh +++ /dev/null @@ -1 +0,0 @@ -export JAVA_OPTS="-Djava.net.preferIPv4Stack=true -Xmx1024m -XX:MaxPermSize=256m -XX:+CMSClassUnloadingEnabled -XX:+UseConcMarkSweepGC -Djsse.enableSNIExtension=false" \ No newline at end of file diff --git a/config.yml b/config.yml new file mode 100644 index 00000000..316e53fa --- /dev/null +++ b/config.yml @@ -0,0 +1,50 @@ +app: + publicUrl: http://localhost:8083/ + allowRegistrations: false + googleAnalyticsTrackingCode: + googleClientId: + googleClientSecret: + backgroundThreads: 3 + databaseUpdateThreads: 1 + smtpHost: + smtpPort: + smtpTls: false + smtpUserName: + smtpPassword: + heavyLoad: false + pubsubhubbub: false + imageProxyEnabled: false + queryTimeout: 0 + crawlingPaused: false + keepStatusDays: 0 + refreshIntervalMinutes: 5 + announcement: + +authenticationCachePolicy: maximumSize=10000, expireAfterAccess=10m +database: + driverClass: org.h2.Driver + user: sa + password: sa + url: jdbc:h2:./target/example + properties: + charSet: UTF-8 + # hibernate.dialect: org.hibernate.dialect.PostgreSQLDialect + maxWaitForConnection: 1s + validationQuery: "/* MyApplication Health Check */ SELECT 1" + minSize: 1 + maxSize: 8 + checkConnectionWhileIdle: true + +server: + applicationConnectors: + - type: http + port: 8082 + +logging: + level: WARN + loggers: + com.commafeed: DEBUG + liquibase: INFO + org.hibernate.SQL: ALL + appenders: + - type: console \ No newline at end of file diff --git a/gulp b/gulp new file mode 100644 index 00000000..f02507dc --- /dev/null +++ b/gulp @@ -0,0 +1,2 @@ +#!/bin/sh +"node/node" "node_modules/gulp/bin/gulp.js" "$@" \ No newline at end of file diff --git a/gulp.cmd b/gulp.cmd new file mode 100644 index 00000000..3cfe9dad --- /dev/null +++ b/gulp.cmd @@ -0,0 +1,3 @@ +@echo off +%~dp0node/node node_modules/gulp/bin/gulp.js %* +@echo on \ No newline at end of file diff --git a/gulpfile.js b/gulpfile.js new file mode 100644 index 00000000..61038ca6 --- /dev/null +++ b/gulpfile.js @@ -0,0 +1,73 @@ +var gulp = require('gulp'); +var minifyCSS = require('gulp-minify-css'); +var uglify = require('gulp-uglify'); +var filter = require('gulp-filter'); +var bower = require('gulp-bower'); +var connect = require('gulp-connect'); +var modRewrite = require('connect-modrewrite'); +var sass = require('gulp-sass'); +var useref = require('gulp-useref'); +var templateCache = require('gulp-angular-templatecache'); + +var SRC_DIR = 'src/main/app/'; +var TEMP_DIR = 'target/gulp/' +var BUILD_DIR = 'target/classes/assets/'; + +gulp.task('bower', function() { + return bower(); +}); + +gulp.task('images', function() { + return gulp.src(SRC_DIR + 'images/**/*').pipe(gulp.dest(BUILD_DIR + 'images')); +}); + +gulp.task('sass', function() { + return gulp.src(SRC_DIR + 'sass/app.scss').pipe(sass()).pipe(gulp.dest(TEMP_DIR + 'css')); +}); + +gulp.task('fonts', function() { + gulp.src(SRC_DIR + 'lib/font-awesome/font/fontawesome-webfont.*').pipe(gulp.dest(BUILD_DIR + 'font')); + gulp.src(SRC_DIR + 'lib/readabilicons/webfont/fonts/readabilicons-*').pipe(gulp.dest(BUILD_DIR + 'font')); + return gulp.src(SRC_DIR + 'lib/zocial/css/zocial-regular-*').pipe(gulp.dest(BUILD_DIR + 'font')); +}); + +gulp.task('template-cache', function() { + var options = { + module : 'commafeed.services', + root : 'templates/' + }; + return gulp.src(SRC_DIR + 'templates/**/*.html').pipe(templateCache(options)).pipe(gulp.dest(TEMP_DIR + 'js')); +}); + +gulp.task('build', ['images', 'sass', 'fonts', 'template-cache'], function() { + var assets = useref.assets({ + searchPath : [SRC_DIR, TEMP_DIR] + }); + var jsFilter = filter("**/*.js"); + var cssFilter = filter("**/*.css"); + return gulp.src([SRC_DIR + 'index.html', TEMP_DIR + 'app.css']).pipe(assets) + + .pipe(cssFilter).pipe(minifyCSS()).pipe(cssFilter.restore()) + + .pipe(jsFilter).pipe(uglify()).pipe(jsFilter.restore()) + + .pipe(assets.restore()).pipe(useref()).pipe(gulp.dest(BUILD_DIR)); +}); + +gulp.task('watch', function() { + gulp.watch(SRC_DIR + 'sass/**/*.scss', ['build']); + gulp.watch(SRC_DIR + 'js/**/*.js', ['build']); +}); + +gulp.task('serve', function() { + connect.server({ + root : BUILD_DIR, + port : 8083, + middleware : function() { + return [modRewrite(['^/rest/(.*)$ http://localhost:8082/rest/$1 [P]'])]; + } + }); +}); + +gulp.task('dev', ['build', 'watch', 'serve']); +gulp.task('default', ['build']); \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 00000000..20b74d83 --- /dev/null +++ b/package.json @@ -0,0 +1,18 @@ +{ + "name": "commafeed", + "version": "2.0.0", + "main": "main.js", + "private": true, + "devDependencies": { + "gulp": "3.8.7", + "gulp-minify-css": "0.3.7", + "gulp-uglify": "0.3.1", + "gulp-filter": "1.0.0", + "gulp-bower": "0.0.6", + "gulp-connect": "2.0.6", + "connect-modrewrite": "0.7.7", + "gulp-sass": "0.7.2", + "gulp-useref": "0.6.0", + "gulp-angular-templatecache": "1.3.0" + } +} diff --git a/pom.xml b/pom.xml index aad12378..45f4b8bc 100644 --- a/pom.xml +++ b/pom.xml @@ -1,11 +1,11 @@ - 4.0.0 + 4.0.0 com.commafeed commafeed - 1.5.0-SNAPSHOT - war + 2.0.0 + jar CommaFeed @@ -14,163 +14,26 @@ UTF-8 - false - false - java:openejb/Resource/My DataSource - false - utf8mb4 - com.commafeed.backend.cache.NoopCacheService + 0.7.1 - commafeed src/main/resources true - - src/main/java - - **/* - - - **/*.java - - - org.apache.maven.plugins maven-compiler-plugin 3.1 - 1.6 - 1.6 + 1.7 + 1.7 - - maven-war-plugin - 2.4 - - false - - - ${basedir}/src/main/webapp/WEB-INF - WEB-INF - true - - **/beans.xml - - - - target/generated-sources/api-docs/ - api/api-docs - - **/* - - - - - - - org.apache.openejb.maven - tomee-maven-plugin - 1.5.2 - - 1.6.0 - plus - 8082 - -Xmx1024m -XX:MaxPermSize=512m -XX:+CMSClassUnloadingEnabled - ${project.basedir}/src/main/tomee/conf - true - - 1 - - .class - - - .properties - .html - .js - .css - .scss - - - - org.hibernate:hibernate-entitymanager:4.1.11.Final - org.hibernate:hibernate-core:4.1.11.Final - org.hibernate.common:hibernate-commons-annotations:4.0.1.Final - org.hibernate:hibernate-validator:4.3.1.Final - org.jboss.logging:jboss-logging:3.1.3.GA - org.javassist:javassist:3.15.0-GA - - org.apache.openejb:openejb-bonecp:4.6.0 - com.jolbox:bonecp:0.8.0.RELEASE - com.google.guava:guava:14.0.1 - - dom4j:dom4j:1.6.1 - antlr:antlr:2.7.7 - remove:openjpa- - remove:hsqldb - org.hsqldb:hsqldb:2.3.0 - mysql:mysql-connector-java:5.1.26 - postgresql:postgresql:9.1-901.jdbc4 - net.sourceforge.jtds:jtds:1.3.1 - - org.infinispan:infinispan-core:5.1.4.FINAL - org.hibernate:hibernate-infinispan:4.1.11.Final - org.jgroups:jgroups:3.0.9.Final - org.jboss.marshalling:jboss-marshalling-river:1.3.11.GA - org.jboss.marshalling:jboss-marshalling:1.3.11.GA - org.codehaus.woodstox:woodstox-core-asl:4.1.1 - org.codehaus.woodstox:stax2-api:3.1.1 - org.rhq.helpers:rhq-pluginAnnotations:3.0.4 - org.jboss.logmanager:jboss-logmanager:1.2.2.GA - - - - - org.bsc.maven - maven-processor-plugin - 2.2.3 - - - process - - process - - generate-sources - - - org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor - - target/generated-sources/metamodel - - - - doc - process-classes - - process - - - - com.commafeed.frontend.APIGenerator - - target/generated-sources/api-docs - - - - - - org.hibernate - hibernate-jpamodelgen - 1.3.0.Final - - - pl.project13.maven git-commit-id-plugin @@ -187,6 +50,72 @@ false + + org.apache.maven.plugins + maven-shade-plugin + 1.6 + + true + + + *:* + + META-INF/*.SF + META-INF/*.DSA + META-INF/*.RSA + + + + + + + package + + shade + + + + + + com.commafeed.CommaFeedApplication + + + + + + + + com.github.eirslett + frontend-maven-plugin + 0.0.15 + + + install node and npm + + install-node-and-npm + + generate-resources + + v0.10.30 + 1.3.8 + + + + npm install + + npm + + generate-resources + + + gulp build + + gulp + + generate-resources + + + @@ -194,58 +123,71 @@ org.projectlombok lombok - 1.12.6 + 1.14.4 provided - org.jboss.spec - jboss-javaee-6.0 - 1.0.0.Final - pom - provided + org.slf4j + slf4j-api + 1.7.7 + + + + io.dropwizard + dropwizard-core + ${dropwizard.version} - org.hibernate - hibernate-entitymanager - 4.1.11.Final - provided + io.dropwizard + dropwizard-auth + ${dropwizard.version} + + + io.dropwizard + dropwizard-hibernate + ${dropwizard.version} + + + io.dropwizard + dropwizard-client + ${dropwizard.version} + + + io.dropwizard + dropwizard-migrations + ${dropwizard.version} + + + io.federecio + dropwizard-swagger + 0.5.1 - dom4j - dom4j + jsr311-api + javax.ws.rs + + + javassist + javassist - redis.clients - jedis - 2.2.1 + com.mysema.querydsl + querydsl-apt + 3.4.2 + provided + hibernate - org.liquibase - liquibase-core - 3.1.1 - - - - com.google.guava - guava - 16.0.1 + com.mysema.querydsl + querydsl-jpa + 3.4.2 - commons-beanutils - commons-beanutils - 1.9.1 - - - commons-codec - commons-codec - 1.9 - - - commons-collections - commons-collections - 3.2.1 + com.sun.jersey.contribs + jersey-multipart + 1.18.1 commons-io @@ -253,9 +195,14 @@ 2.4 - commons-lang - commons-lang - 2.6 + commons-collections + commons-collections + 3.2.1 + + + commons-codec + commons-codec + 1.9 org.apache.commons @@ -263,11 +210,15 @@ 2.2 - commons-fileupload - commons-fileupload - 1.3.1 + redis.clients + jedis + 2.2.1 + + + com.sun.mail + javax.mail + 1.5.2 - net.java.dev.rome rome @@ -295,6 +246,11 @@ jdom 1.1.3 + + org.jsoup + jsoup + 1.7.3 + com.googlecode.juniversalchardet juniversalchardet @@ -303,160 +259,33 @@ com.google.gwt gwt-servlet - 2.6.0 + 2.6.1 net.sourceforge.cssparser cssparser - 0.9.13 + 0.9.14 - org.apache.httpcomponents - httpclient - 4.3.3 + com.h2database + h2 + 1.4.181 - org.jsoup - jsoup - 1.7.3 - - - - com.fasterxml.jackson.core - jackson-databind - 2.3.3 + mysql + mysql-connector-java + 5.1.31 - org.slf4j - slf4j-log4j12 - 1.7.7 + postgresql + postgresql + 9.1-901-1.jdbc4 - log4j - log4j - 1.2.17 - - - - org.apache.wicket - wicket-core - 6.14.0 - - - - org.apache.wicket - wicket-auth-roles - 6.14.0 - - - org.apache.wicket - wicket-extensions - 6.14.0 - - - org.apache.wicket - wicket-cdi - 6.14.0 - - - ro.isdc.wro4j - wro4j-extensions - 1.7.5 - - - - com.wordnik - swagger-annotations_2.9.1 - 1.2.5 - - - com.wordnik - swagger-jaxrs_2.9.1 - 1.2.5 - provided - - - - com.codahale.metrics - metrics-core - 3.0.2 - - - com.codahale.metrics - metrics-json - 3.0.2 - - - - org.webjars - lodash - 2.4.1-3 - - - org.webjars - jquery - 1.11.0 - - - org.webjars - bootstrap - 3.1.1 - - - org.webjars - jquery-mousewheel - 3.1.9 - - - org.webjars - angularjs - 1.2.16 - - - org.webjars - angular-ui-router - 0.2.8-2 - - - org.webjars - angular-ui-utils - 0.1.0 - - - org.webjars - ui-select2 - 0.0.5 - - - org.webjars - angular-ui-bootstrap - 0.2.0 - - - org.webjars - mousetrap - 1.4.6 - - - org.webjars - momentjs - 2.6.0 - - - org.webjars - ng-grid - 2.0.7 - - - org.webjars - device.js - 139f208 - - - org.webjars - ngInfiniteScroll - 1.0.0 + net.sourceforge.jtds + jtds + 1.3.1 @@ -466,228 +295,4 @@ test - - - - default - - true - - - - - ro.isdc.wro4j - wro4j-maven-plugin - 1.7.5 - - - js - test - - jshint - - - app - devel,noarg,quotmark,laxcomma,laxbreak - - - - css - test - - csslint - - - app - display-property-grouping,duplicate-properties,compatible-vendor-prefixes,vendor-prefix - - - - - - - - - openshift - - java:jboss/datasources/MysqlDS - utf8 - - - commafeed - - - maven-surefire-plugin - 2.14.1 - - true - - - - maven-war-plugin - 2.4 - - deployments - ROOT - - - - - - - - cache - - true - - - - redis - - com.commafeed.backend.cache.RedisCacheService - - - - mysql - - java:openejb/Resource/MySQL - - - - pgsql - - java:openejb/Resource/PostgreSQL - - - - mssql - - java:openejb/Resource/MSSQL - - - - prod - - - skipTests - - - - ${maven.build.timestamp} - true - false - - - - - org.codehaus.gmaven - gmaven-plugin - 1.5 - - - commons-io - commons-io - 2.4 - - - - - process-classes - - execute - - - - ${basedir}/src/main/webapp/templates - templates/ - ${basedir}/target/generated-sources/angularjs/all-templates.html - ${basedir}/src/main/resources/i18n/ - - - ${basedir}/src/main/script - - - def source = project.properties['source']; - def prefix = - project.properties['prefix']; - def dest = - project.properties['destination']; - def i18n = - project.properties['i18nPath']; - new - HTMLConcat().concat(source, - prefix, dest, i18n); - - - - - - - ro.isdc.wro4j - wro4j-maven-plugin - 1.7.5 - - - - run - - - - - all - ro.isdc.wro.maven.plugin.manager.factory.ConfigurableWroManagerFactory - ${project.build.directory}/${project.build.finalName}/static/ - - - - maven-war-plugin - 2.4 - - - - target/generated-sources/angularjs/ - templates - - **/*.html - - - - - - - - - - i18n - - - - org.codehaus.gmaven - gmaven-plugin - 1.5 - - - commons-io - commons-io - 2.4 - - - - - ${basedir}/src/main/resources/i18n/ - - - ${basedir}/src/main/script - - - def dir = project.properties['dir']; - new - I18nGenerator().generate(dir); - - - - - - - - + \ No newline at end of file diff --git a/src/main/webapp/app-icon-114.png b/src/main/app/app-icon-114.png similarity index 100% rename from src/main/webapp/app-icon-114.png rename to src/main/app/app-icon-114.png diff --git a/src/main/webapp/app-icon-128.png b/src/main/app/app-icon-128.png similarity index 100% rename from src/main/webapp/app-icon-128.png rename to src/main/app/app-icon-128.png diff --git a/src/main/webapp/app-icon-144.png b/src/main/app/app-icon-144.png similarity index 100% rename from src/main/webapp/app-icon-144.png rename to src/main/app/app-icon-144.png diff --git a/src/main/webapp/app-icon-16.png b/src/main/app/app-icon-16.png similarity index 100% rename from src/main/webapp/app-icon-16.png rename to src/main/app/app-icon-16.png diff --git a/src/main/webapp/app-icon-195.png b/src/main/app/app-icon-195.png similarity index 100% rename from src/main/webapp/app-icon-195.png rename to src/main/app/app-icon-195.png diff --git a/src/main/webapp/app-icon-256.png b/src/main/app/app-icon-256.png similarity index 100% rename from src/main/webapp/app-icon-256.png rename to src/main/app/app-icon-256.png diff --git a/src/main/webapp/app-icon-32.png b/src/main/app/app-icon-32.png similarity index 100% rename from src/main/webapp/app-icon-32.png rename to src/main/app/app-icon-32.png diff --git a/src/main/webapp/app-icon-512.png b/src/main/app/app-icon-512.png similarity index 100% rename from src/main/webapp/app-icon-512.png rename to src/main/app/app-icon-512.png diff --git a/src/main/webapp/app-icon-57.png b/src/main/app/app-icon-57.png similarity index 100% rename from src/main/webapp/app-icon-57.png rename to src/main/app/app-icon-57.png diff --git a/src/main/webapp/app-icon-64.png b/src/main/app/app-icon-64.png similarity index 100% rename from src/main/webapp/app-icon-64.png rename to src/main/app/app-icon-64.png diff --git a/src/main/webapp/app-icon-72.png b/src/main/app/app-icon-72.png similarity index 100% rename from src/main/webapp/app-icon-72.png rename to src/main/app/app-icon-72.png diff --git a/src/main/webapp/app-icon.svg b/src/main/app/app-icon.svg similarity index 100% rename from src/main/webapp/app-icon.svg rename to src/main/app/app-icon.svg diff --git a/src/main/webapp/favicon.ico b/src/main/app/favicon.ico similarity index 100% rename from src/main/webapp/favicon.ico rename to src/main/app/favicon.ico diff --git a/src/main/webapp/images/default_favicon.gif b/src/main/app/images/default_favicon.gif similarity index 100% rename from src/main/webapp/images/default_favicon.gif rename to src/main/app/images/default_favicon.gif diff --git a/src/main/webapp/images/google_reader_icon.png b/src/main/app/images/google_reader_icon.png similarity index 100% rename from src/main/webapp/images/google_reader_icon.png rename to src/main/app/images/google_reader_icon.png diff --git a/src/main/webapp/images/logo.png b/src/main/app/images/logo.png similarity index 100% rename from src/main/webapp/images/logo.png rename to src/main/app/images/logo.png diff --git a/src/main/webapp/images/logo_2.png b/src/main/app/images/logo_2.png similarity index 100% rename from src/main/webapp/images/logo_2.png rename to src/main/app/images/logo_2.png diff --git a/src/main/webapp/images/preview.jpg b/src/main/app/images/preview.jpg similarity index 100% rename from src/main/webapp/images/preview.jpg rename to src/main/app/images/preview.jpg diff --git a/src/main/app/index.html b/src/main/app/index.html new file mode 100644 index 00000000..0632ead8 --- /dev/null +++ b/src/main/app/index.html @@ -0,0 +1,73 @@ + + + +CommaFeed + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/webapp/js/controllers.js b/src/main/app/js/controllers.js similarity index 96% rename from src/main/webapp/js/controllers.js rename to src/main/app/js/controllers.js index 01d7e4e9..f7224f44 100644 --- a/src/main/webapp/js/controllers.js +++ b/src/main/app/js/controllers.js @@ -866,7 +866,6 @@ module.controller('FeedListCtrl', [ }); EntryService.mark({ id : entry.id, - feedId : entry.feedId, read : read }); } @@ -892,7 +891,6 @@ module.controller('FeedListCtrl', [ if (!e.read) { entries.push({ id : e.id, - feedId : e.feedId, read : true }); e.read = true; diff --git a/src/main/webapp/js/directives.js b/src/main/app/js/directives.js similarity index 100% rename from src/main/webapp/js/directives.js rename to src/main/app/js/directives.js diff --git a/src/main/webapp/js/filters.js b/src/main/app/js/filters.js similarity index 100% rename from src/main/webapp/js/filters.js rename to src/main/app/js/filters.js diff --git a/src/main/webapp/js/main.js b/src/main/app/js/main.js similarity index 100% rename from src/main/webapp/js/main.js rename to src/main/app/js/main.js diff --git a/src/main/webapp/js/services.js b/src/main/app/js/services.js similarity index 100% rename from src/main/webapp/js/services.js rename to src/main/app/js/services.js diff --git a/src/main/webapp/js/welcome.js b/src/main/app/js/welcome.js similarity index 100% rename from src/main/webapp/js/welcome.js rename to src/main/app/js/welcome.js diff --git a/src/main/webapp/metro-icon-150.png b/src/main/app/metro-icon-150.png similarity index 100% rename from src/main/webapp/metro-icon-150.png rename to src/main/app/metro-icon-150.png diff --git a/src/main/webapp/metro-icon-70.png b/src/main/app/metro-icon-70.png similarity index 100% rename from src/main/webapp/metro-icon-70.png rename to src/main/app/metro-icon-70.png diff --git a/src/main/webapp/sass/app.scss b/src/main/app/sass/app.scss similarity index 87% rename from src/main/webapp/sass/app.scss rename to src/main/app/sass/app.scss index f4dec7b6..aaa20831 100644 --- a/src/main/webapp/sass/app.scss +++ b/src/main/app/sass/app.scss @@ -8,6 +8,9 @@ @import "components/help"; @import "components/loading-bar"; +@import "components/readabilicons"; +@import "components/zocial"; + @import "mobile/mobile"; @import "themes/test"; diff --git a/deployments/.gitkeep b/src/main/app/sass/base/.gitkeep similarity index 100% rename from deployments/.gitkeep rename to src/main/app/sass/base/.gitkeep diff --git a/src/main/webapp/sass/components/_admin-panel.scss b/src/main/app/sass/components/_admin-panel.scss similarity index 100% rename from src/main/webapp/sass/components/_admin-panel.scss rename to src/main/app/sass/components/_admin-panel.scss diff --git a/src/main/webapp/sass/components/_entry-list.scss b/src/main/app/sass/components/_entry-list.scss similarity index 100% rename from src/main/webapp/sass/components/_entry-list.scss rename to src/main/app/sass/components/_entry-list.scss diff --git a/src/main/webapp/sass/components/_help.scss b/src/main/app/sass/components/_help.scss similarity index 100% rename from src/main/webapp/sass/components/_help.scss rename to src/main/app/sass/components/_help.scss diff --git a/src/main/webapp/sass/components/_loading-bar.scss b/src/main/app/sass/components/_loading-bar.scss similarity index 100% rename from src/main/webapp/sass/components/_loading-bar.scss rename to src/main/app/sass/components/_loading-bar.scss diff --git a/src/main/webapp/sass/components/_subscription-list.scss b/src/main/app/sass/components/_subscription-list.scss similarity index 100% rename from src/main/webapp/sass/components/_subscription-list.scss rename to src/main/app/sass/components/_subscription-list.scss diff --git a/src/main/webapp/sass/components/_toolbar.scss b/src/main/app/sass/components/_toolbar.scss similarity index 100% rename from src/main/webapp/sass/components/_toolbar.scss rename to src/main/app/sass/components/_toolbar.scss diff --git a/src/main/app/sass/components/readabilicons.scss b/src/main/app/sass/components/readabilicons.scss new file mode 100644 index 00000000..5e65e7f6 --- /dev/null +++ b/src/main/app/sass/components/readabilicons.scss @@ -0,0 +1,20 @@ +@font-face { + font-family: 'readabilicons'; + src: url('../font/readabilicons-regular.eot'); /* IE9 Compat Modes */ + src: url('../font/readabilicons-regular.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */ + url('../font/readabilicons-regular.woff') format('woff'), /* Modern Browsers */ + url('../font/readabilicons-regular.ttf') format('truetype'), /* Safari, Android, iOS */ + url('../font/readabilicons-regular.svg#readabiliconsregular') format('svg'); /* Legacy iOS */ + font-style: normal; + font-weight: 400; +} + +.icon-couch::before { + content: "\e018"; + font-family: "readabilicons"; + -webkit-font-smoothing: antialiased; + font-size: 21px; + top: 5px; + position: relative; + line-height: 0px; +} \ No newline at end of file diff --git a/src/main/webapp/vendor/zocial/zocial.css b/src/main/app/sass/components/zocial.scss similarity index 79% rename from src/main/webapp/vendor/zocial/zocial.css rename to src/main/app/sass/components/zocial.scss index 724b2657..1583c85d 100644 --- a/src/main/webapp/vendor/zocial/zocial.css +++ b/src/main/app/sass/components/zocial.scss @@ -14,9 +14,9 @@ */ @font-face { font-family: 'zocial'; - src: url('zocial-regular-webfont.eot'), - url('zocial-regular-webfont.woff'), url('zocial-regular-webfont.ttf') - format('truetype'), url('zocial-regular-webfont.svg#zocialregular') + src: url('../font/zocial-regular-webfont.eot'), + url('../font/zocial-regular-webfont.woff'), url('../font/zocial-regular-webfont.ttf') + format('truetype'), url('../font/zocial-regular-webfont.svg#zocialregular') format('svg'); font-weight: normal; font-style: normal; diff --git a/src/main/webapp/sass/generic/_misc.scss b/src/main/app/sass/generic/_misc.scss similarity index 100% rename from src/main/webapp/sass/generic/_misc.scss rename to src/main/app/sass/generic/_misc.scss diff --git a/src/main/webapp/sass/generic/_scrollbar.scss b/src/main/app/sass/generic/_scrollbar.scss similarity index 100% rename from src/main/webapp/sass/generic/_scrollbar.scss rename to src/main/app/sass/generic/_scrollbar.scss diff --git a/src/main/webapp/sass/mobile/_mobile.scss b/src/main/app/sass/mobile/_mobile.scss similarity index 100% rename from src/main/webapp/sass/mobile/_mobile.scss rename to src/main/app/sass/mobile/_mobile.scss diff --git a/src/main/webapp/sass/themes/_MRACHINI.scss b/src/main/app/sass/themes/_MRACHINI.scss similarity index 100% rename from src/main/webapp/sass/themes/_MRACHINI.scss rename to src/main/app/sass/themes/_MRACHINI.scss diff --git a/src/main/webapp/sass/themes/_bootstrap.scss b/src/main/app/sass/themes/_bootstrap.scss similarity index 100% rename from src/main/webapp/sass/themes/_bootstrap.scss rename to src/main/app/sass/themes/_bootstrap.scss diff --git a/src/main/webapp/sass/themes/_dark.scss b/src/main/app/sass/themes/_dark.scss similarity index 100% rename from src/main/webapp/sass/themes/_dark.scss rename to src/main/app/sass/themes/_dark.scss diff --git a/src/main/webapp/sass/themes/_ebraminio.scss b/src/main/app/sass/themes/_ebraminio.scss similarity index 100% rename from src/main/webapp/sass/themes/_ebraminio.scss rename to src/main/app/sass/themes/_ebraminio.scss diff --git a/src/main/webapp/sass/themes/_svetla.scss b/src/main/app/sass/themes/_svetla.scss similarity index 100% rename from src/main/webapp/sass/themes/_svetla.scss rename to src/main/app/sass/themes/_svetla.scss diff --git a/src/main/webapp/sass/themes/_test.scss b/src/main/app/sass/themes/_test.scss similarity index 100% rename from src/main/webapp/sass/themes/_test.scss rename to src/main/app/sass/themes/_test.scss diff --git a/src/main/webapp/sass/themes/_third.scss b/src/main/app/sass/themes/_third.scss similarity index 100% rename from src/main/webapp/sass/themes/_third.scss rename to src/main/app/sass/themes/_third.scss diff --git a/src/main/webapp/templates/_category.html b/src/main/app/templates/_category.html similarity index 100% rename from src/main/webapp/templates/_category.html rename to src/main/app/templates/_category.html diff --git a/src/main/webapp/templates/_feedsearch.html b/src/main/app/templates/_feedsearch.html similarity index 100% rename from src/main/webapp/templates/_feedsearch.html rename to src/main/app/templates/_feedsearch.html diff --git a/src/main/webapp/templates/_footer.html b/src/main/app/templates/_footer.html similarity index 100% rename from src/main/webapp/templates/_footer.html rename to src/main/app/templates/_footer.html diff --git a/src/main/webapp/templates/_metrics.gauge.html b/src/main/app/templates/_metrics.gauge.html similarity index 100% rename from src/main/webapp/templates/_metrics.gauge.html rename to src/main/app/templates/_metrics.gauge.html diff --git a/src/main/webapp/templates/_metrics.meter.html b/src/main/app/templates/_metrics.meter.html similarity index 100% rename from src/main/webapp/templates/_metrics.meter.html rename to src/main/app/templates/_metrics.meter.html diff --git a/src/main/webapp/templates/_shortcuts.html b/src/main/app/templates/_shortcuts.html similarity index 100% rename from src/main/webapp/templates/_shortcuts.html rename to src/main/app/templates/_shortcuts.html diff --git a/src/main/webapp/templates/_tags.html b/src/main/app/templates/_tags.html similarity index 100% rename from src/main/webapp/templates/_tags.html rename to src/main/app/templates/_tags.html diff --git a/src/main/webapp/templates/_toolbar.html b/src/main/app/templates/_toolbar.html similarity index 100% rename from src/main/webapp/templates/_toolbar.html rename to src/main/app/templates/_toolbar.html diff --git a/src/main/webapp/templates/_tree.html b/src/main/app/templates/_tree.html similarity index 100% rename from src/main/webapp/templates/_tree.html rename to src/main/app/templates/_tree.html diff --git a/src/main/webapp/templates/admin.html b/src/main/app/templates/admin.html similarity index 100% rename from src/main/webapp/templates/admin.html rename to src/main/app/templates/admin.html diff --git a/src/main/webapp/templates/admin.metrics.html b/src/main/app/templates/admin.metrics.html similarity index 100% rename from src/main/webapp/templates/admin.metrics.html rename to src/main/app/templates/admin.metrics.html diff --git a/src/main/webapp/templates/admin.settings.html b/src/main/app/templates/admin.settings.html similarity index 100% rename from src/main/webapp/templates/admin.settings.html rename to src/main/app/templates/admin.settings.html diff --git a/src/main/webapp/templates/admin.useradd.html b/src/main/app/templates/admin.useradd.html similarity index 100% rename from src/main/webapp/templates/admin.useradd.html rename to src/main/app/templates/admin.useradd.html diff --git a/src/main/webapp/templates/admin.useredit.html b/src/main/app/templates/admin.useredit.html similarity index 100% rename from src/main/webapp/templates/admin.useredit.html rename to src/main/app/templates/admin.useredit.html diff --git a/src/main/webapp/templates/admin.userlist.html b/src/main/app/templates/admin.userlist.html similarity index 100% rename from src/main/webapp/templates/admin.userlist.html rename to src/main/app/templates/admin.userlist.html diff --git a/src/main/webapp/templates/feeds.category_details.html b/src/main/app/templates/feeds.category_details.html similarity index 100% rename from src/main/webapp/templates/feeds.category_details.html rename to src/main/app/templates/feeds.category_details.html diff --git a/src/main/webapp/templates/feeds.feed_details.html b/src/main/app/templates/feeds.feed_details.html similarity index 100% rename from src/main/webapp/templates/feeds.feed_details.html rename to src/main/app/templates/feeds.feed_details.html diff --git a/src/main/webapp/templates/feeds.help.html b/src/main/app/templates/feeds.help.html similarity index 100% rename from src/main/webapp/templates/feeds.help.html rename to src/main/app/templates/feeds.help.html diff --git a/src/main/webapp/templates/feeds.html b/src/main/app/templates/feeds.html similarity index 100% rename from src/main/webapp/templates/feeds.html rename to src/main/app/templates/feeds.html diff --git a/src/main/webapp/templates/feeds.import.html b/src/main/app/templates/feeds.import.html similarity index 100% rename from src/main/webapp/templates/feeds.import.html rename to src/main/app/templates/feeds.import.html diff --git a/src/main/webapp/templates/feeds.new_category.html b/src/main/app/templates/feeds.new_category.html similarity index 100% rename from src/main/webapp/templates/feeds.new_category.html rename to src/main/app/templates/feeds.new_category.html diff --git a/src/main/webapp/templates/feeds.subscribe.html b/src/main/app/templates/feeds.subscribe.html similarity index 100% rename from src/main/webapp/templates/feeds.subscribe.html rename to src/main/app/templates/feeds.subscribe.html diff --git a/src/main/webapp/templates/feeds.tag_details.html b/src/main/app/templates/feeds.tag_details.html similarity index 100% rename from src/main/webapp/templates/feeds.tag_details.html rename to src/main/app/templates/feeds.tag_details.html diff --git a/src/main/webapp/templates/feeds.view.html b/src/main/app/templates/feeds.view.html similarity index 100% rename from src/main/webapp/templates/feeds.view.html rename to src/main/app/templates/feeds.view.html diff --git a/src/main/webapp/templates/profile.html b/src/main/app/templates/profile.html similarity index 100% rename from src/main/webapp/templates/profile.html rename to src/main/app/templates/profile.html diff --git a/src/main/webapp/templates/settings.html b/src/main/app/templates/settings.html similarity index 100% rename from src/main/webapp/templates/settings.html rename to src/main/app/templates/settings.html diff --git a/src/main/java/com/commafeed/CommaFeedApplication.java b/src/main/java/com/commafeed/CommaFeedApplication.java new file mode 100644 index 00000000..b4a965a6 --- /dev/null +++ b/src/main/java/com/commafeed/CommaFeedApplication.java @@ -0,0 +1,182 @@ +package com.commafeed; + +import io.dropwizard.Application; +import io.dropwizard.assets.AssetsBundle; +import io.dropwizard.auth.CachingAuthenticator; +import io.dropwizard.auth.basic.BasicAuthProvider; +import io.dropwizard.auth.basic.BasicCredentials; +import io.dropwizard.db.DataSourceFactory; +import io.dropwizard.hibernate.HibernateBundle; +import io.dropwizard.migrations.MigrationsBundle; +import io.dropwizard.setup.Bootstrap; +import io.dropwizard.setup.Environment; + +import java.util.Date; + +import org.hibernate.SessionFactory; + +import com.codahale.metrics.MetricRegistry; +import com.commafeed.backend.HttpGetter; +import com.commafeed.backend.cache.CacheService; +import com.commafeed.backend.cache.NoopCacheService; +import com.commafeed.backend.dao.FeedCategoryDAO; +import com.commafeed.backend.dao.FeedDAO; +import com.commafeed.backend.dao.FeedEntryContentDAO; +import com.commafeed.backend.dao.FeedEntryDAO; +import com.commafeed.backend.dao.FeedEntryStatusDAO; +import com.commafeed.backend.dao.FeedEntryTagDAO; +import com.commafeed.backend.dao.FeedSubscriptionDAO; +import com.commafeed.backend.dao.UserDAO; +import com.commafeed.backend.dao.UserRoleDAO; +import com.commafeed.backend.dao.UserSettingsDAO; +import com.commafeed.backend.feed.FaviconFetcher; +import com.commafeed.backend.feed.FeedFetcher; +import com.commafeed.backend.feed.FeedParser; +import com.commafeed.backend.feed.FeedQueues; +import com.commafeed.backend.feed.FeedRefreshTaskGiver; +import com.commafeed.backend.feed.FeedRefreshUpdater; +import com.commafeed.backend.feed.FeedRefreshWorker; +import com.commafeed.backend.model.AbstractModel; +import com.commafeed.backend.model.Feed; +import com.commafeed.backend.model.FeedCategory; +import com.commafeed.backend.model.FeedEntry; +import com.commafeed.backend.model.FeedEntryContent; +import com.commafeed.backend.model.FeedEntryStatus; +import com.commafeed.backend.model.FeedEntryTag; +import com.commafeed.backend.model.FeedSubscription; +import com.commafeed.backend.model.User; +import com.commafeed.backend.model.UserRole; +import com.commafeed.backend.model.UserSettings; +import com.commafeed.backend.opml.OPMLExporter; +import com.commafeed.backend.opml.OPMLImporter; +import com.commafeed.backend.service.ApplicationPropertiesService; +import com.commafeed.backend.service.DatabaseCleaningService; +import com.commafeed.backend.service.FeedEntryContentService; +import com.commafeed.backend.service.FeedEntryService; +import com.commafeed.backend.service.FeedEntryTagService; +import com.commafeed.backend.service.FeedService; +import com.commafeed.backend.service.FeedSubscriptionService; +import com.commafeed.backend.service.FeedUpdateService; +import com.commafeed.backend.service.PasswordEncryptionService; +import com.commafeed.backend.service.PubSubService; +import com.commafeed.backend.service.StartupService; +import com.commafeed.backend.service.UserService; +import com.commafeed.frontend.resource.AdminREST; +import com.commafeed.frontend.resource.CategoryREST; +import com.commafeed.frontend.resource.EntryREST; +import com.commafeed.frontend.resource.FeedREST; +import com.commafeed.frontend.resource.PubSubHubbubCallbackREST; +import com.commafeed.frontend.resource.ServerREST; +import com.commafeed.frontend.resource.UserREST; + +public class CommaFeedApplication extends Application { + + public static final String USERNAME_ADMIN = "admin"; + public static final String USERNAME_DEMO = "demo"; + + public static final Date STARTUP_TIME = new Date(); + + private HibernateBundle hibernateBundle; + private MigrationsBundle migrationsBundle; + + @Override + public void initialize(Bootstrap bootstrap) { + hibernateBundle = new HibernateBundle(AbstractModel.class, Feed.class, FeedCategory.class, FeedEntry.class, + FeedEntryContent.class, FeedEntryStatus.class, FeedEntryTag.class, FeedSubscription.class, User.class, UserRole.class, + UserSettings.class) { + @Override + public DataSourceFactory getDataSourceFactory(CommaFeedConfiguration configuration) { + return configuration.getDatabase(); + } + }; + bootstrap.addBundle(hibernateBundle); + + migrationsBundle = new MigrationsBundle() { + @Override + public DataSourceFactory getDataSourceFactory(CommaFeedConfiguration configuration) { + return configuration.getDatabase(); + } + }; + bootstrap.addBundle(migrationsBundle); + + bootstrap.addBundle(new AssetsBundle("/assets/", "/", "index.html")); + } + + @Override + public void run(CommaFeedConfiguration config, Environment environment) throws Exception { + MetricRegistry metrics = environment.metrics(); + SessionFactory sessionFactory = hibernateBundle.getSessionFactory(); + + // TODO select cache service at runtime from config + CacheService cacheService = new NoopCacheService(); + + FeedCategoryDAO feedCategoryDAO = new FeedCategoryDAO(sessionFactory); + FeedDAO feedDAO = new FeedDAO(sessionFactory); + FeedEntryContentDAO feedEntryContentDAO = new FeedEntryContentDAO(sessionFactory); + FeedEntryDAO feedEntryDAO = new FeedEntryDAO(sessionFactory); + FeedEntryTagDAO feedEntryTagDAO = new FeedEntryTagDAO(sessionFactory); + FeedSubscriptionDAO feedSubscriptionDAO = new FeedSubscriptionDAO(sessionFactory); + UserDAO userDAO = new UserDAO(sessionFactory); + UserRoleDAO userRoleDAO = new UserRoleDAO(sessionFactory); + UserSettingsDAO userSettingsDAO = new UserSettingsDAO(sessionFactory); + FeedEntryStatusDAO feedEntryStatusDAO = new FeedEntryStatusDAO(sessionFactory, feedEntryDAO, feedEntryTagDAO, config); + + FeedQueues queues = new FeedQueues(feedDAO, config, metrics); + + ApplicationPropertiesService applicationPropertiesService = new ApplicationPropertiesService(); + DatabaseCleaningService cleaningService = new DatabaseCleaningService(feedDAO, feedEntryDAO, feedEntryContentDAO, + feedEntryStatusDAO, feedSubscriptionDAO); + FeedEntryContentService feedEntryContentService = new FeedEntryContentService(feedEntryContentDAO); + FeedEntryService feedEntryService = new FeedEntryService(feedSubscriptionDAO, feedEntryDAO, feedEntryStatusDAO, cacheService); + FeedEntryTagService feedEntryTagService = new FeedEntryTagService(feedEntryDAO, feedEntryTagDAO); + FeedService feedService = new FeedService(feedDAO); + FeedSubscriptionService feedSubscriptionService = new FeedSubscriptionService(feedEntryStatusDAO, feedSubscriptionDAO, feedService, + queues, cacheService, config); + FeedUpdateService feedUpdateService = new FeedUpdateService(feedEntryDAO, feedEntryContentService); + PasswordEncryptionService encryptionService = new PasswordEncryptionService(); + PubSubService pubSubService = new PubSubService(config, queues); + UserService userService = new UserService(feedCategoryDAO, userDAO, userSettingsDAO, feedSubscriptionService, encryptionService, + config); + StartupService startupService = new StartupService(sessionFactory, userDAO, userService); + + OPMLImporter opmlImporter = new OPMLImporter(feedCategoryDAO, feedSubscriptionService, cacheService); + OPMLExporter opmlExporter = new OPMLExporter(feedCategoryDAO, feedSubscriptionDAO); + + HttpGetter httpGetter = new HttpGetter(); + FeedParser feedParser = new FeedParser(); + FaviconFetcher faviconFetcher = new FaviconFetcher(httpGetter); + + FeedFetcher feedFetcher = new FeedFetcher(feedParser, httpGetter); + FeedRefreshUpdater feedUpdater = new FeedRefreshUpdater(sessionFactory, feedUpdateService, pubSubService, queues, config, metrics, + feedSubscriptionDAO, cacheService); + FeedRefreshWorker feedWorker = new FeedRefreshWorker(feedUpdater, feedFetcher, queues, config, metrics); + FeedRefreshTaskGiver taskGiver = new FeedRefreshTaskGiver(sessionFactory, queues, feedDAO, feedWorker, config, metrics); + + CachingAuthenticator cachingAuthenticator = new CachingAuthenticator( + environment.metrics(), new CommaFeedAuthenticator(userService), config.getAuthenticationCachePolicy()); + environment.jersey().register(new BasicAuthProvider(cachingAuthenticator, "CommaFeed")); + + environment.jersey().setUrlPattern("/rest/*"); + environment.jersey() + .register(new AdminREST(userDAO, userRoleDAO, userService, encryptionService, cleaningService, config, metrics)); + environment.jersey().register( + new CategoryREST(feedCategoryDAO, feedEntryStatusDAO, feedSubscriptionDAO, feedEntryService, feedSubscriptionService, + cacheService, config)); + environment.jersey().register(new EntryREST(feedEntryTagDAO, feedEntryService, feedEntryTagService)); + environment.jersey().register( + new FeedREST(feedSubscriptionDAO, feedCategoryDAO, feedEntryStatusDAO, faviconFetcher, feedFetcher, feedEntryService, + feedSubscriptionService, queues, opmlImporter, opmlExporter, cacheService, config)); + environment.jersey().register(new PubSubHubbubCallbackREST(feedDAO, feedParser, queues, config, metrics)); + environment.jersey().register(new ServerREST(httpGetter, config, applicationPropertiesService)); + environment.jersey().register(new UserREST(userDAO, userRoleDAO, userSettingsDAO, userService, encryptionService)); + + environment.lifecycle().manage(startupService); + environment.lifecycle().manage(taskGiver); + environment.lifecycle().manage(feedWorker); + environment.lifecycle().manage(feedUpdater); + } + + public static void main(String[] args) throws Exception { + new CommaFeedApplication().run(args); + } +} diff --git a/src/main/java/com/commafeed/CommaFeedAuthenticator.java b/src/main/java/com/commafeed/CommaFeedAuthenticator.java new file mode 100644 index 00000000..4c729e17 --- /dev/null +++ b/src/main/java/com/commafeed/CommaFeedAuthenticator.java @@ -0,0 +1,21 @@ +package com.commafeed; + +import io.dropwizard.auth.AuthenticationException; +import io.dropwizard.auth.Authenticator; +import io.dropwizard.auth.basic.BasicCredentials; +import lombok.RequiredArgsConstructor; + +import com.commafeed.backend.model.User; +import com.commafeed.backend.service.UserService; +import com.google.common.base.Optional; + +@RequiredArgsConstructor +public class CommaFeedAuthenticator implements Authenticator { + + private final UserService userService; + + @Override + public Optional authenticate(final BasicCredentials credentials) throws AuthenticationException { + return Optional.fromNullable(userService.login(credentials.getUsername(), credentials.getPassword())); + } +} diff --git a/src/main/java/com/commafeed/CommaFeedConfiguration.java b/src/main/java/com/commafeed/CommaFeedConfiguration.java new file mode 100644 index 00000000..c71394ea --- /dev/null +++ b/src/main/java/com/commafeed/CommaFeedConfiguration.java @@ -0,0 +1,105 @@ +package com.commafeed; + +import io.dropwizard.Configuration; +import io.dropwizard.db.DataSourceFactory; + +import java.util.Date; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; + +import lombok.Getter; + +import org.apache.commons.lang.time.DateUtils; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.google.common.cache.CacheBuilderSpec; + +@Getter +public class CommaFeedConfiguration extends Configuration { + + @Valid + @NotNull + @JsonProperty("database") + private DataSourceFactory database = new DataSourceFactory(); + + @Valid + @NotNull + @JsonProperty("authenticationCachePolicy") + private CacheBuilderSpec authenticationCachePolicy; + + @Valid + @NotNull + @JsonProperty("app") + private ApplicationSettings applicationSettings; + + @Getter + public static class ApplicationSettings { + @JsonProperty + private String publicUrl; + + @JsonProperty + private boolean allowRegistrations; + + @JsonProperty + private String googleAnalyticsTrackingCode; + + @JsonProperty + private String googleClientId; + + @JsonProperty + private String googleClientSecret; + + @JsonProperty + private int backgroundThreads; + + @JsonProperty + private int databaseUpdateThreads; + + @JsonProperty + private String smtpHost; + + @JsonProperty + private int smtpPort; + + @JsonProperty + private boolean smtpTls; + + @JsonProperty + private String smtpUserName; + + @JsonProperty + private String smtpPassword; + + @JsonProperty + private boolean heavyLoad; + + @JsonProperty + private boolean pubsubhubbub; + + @JsonProperty + private boolean imageProxyEnabled; + + @JsonProperty + private int queryTimeout; + + @JsonProperty + private boolean crawlingPaused; + + @JsonProperty + private int keepStatusDays; + + @JsonProperty + private int refreshIntervalMinutes; + + @JsonProperty + private String announcement; + + public Date getUnreadThreshold() { + int keepStatusDays = getKeepStatusDays(); + return keepStatusDays > 0 ? DateUtils.addDays(new Date(), -1 * keepStatusDays) : null; + } + + } + +} diff --git a/src/main/java/com/commafeed/backend/HttpGetter.java b/src/main/java/com/commafeed/backend/HttpGetter.java index f28e5813..23627321 100644 --- a/src/main/java/com/commafeed/backend/HttpGetter.java +++ b/src/main/java/com/commafeed/backend/HttpGetter.java @@ -15,6 +15,7 @@ import javax.net.ssl.X509TrustManager; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringUtils; import org.apache.http.Consts; import org.apache.http.Header; @@ -42,7 +43,6 @@ import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.impl.client.HttpClients; import org.apache.http.protocol.HttpContext; import org.apache.http.util.EntityUtils; -import org.apache.wicket.util.io.IOUtils; /** * Smart HTTP getter: handles gzip, ssl, last modified and etag headers diff --git a/src/main/java/com/commafeed/backend/ScheduledTasks.java b/src/main/java/com/commafeed/backend/ScheduledTasks.java deleted file mode 100644 index d784585b..00000000 --- a/src/main/java/com/commafeed/backend/ScheduledTasks.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.commafeed.backend; - -import java.util.Date; - -import javax.ejb.Schedule; -import javax.ejb.Stateless; -import javax.ejb.TransactionManagement; -import javax.ejb.TransactionManagementType; -import javax.inject.Inject; - -import com.commafeed.backend.services.ApplicationSettingsService; -import com.commafeed.backend.services.DatabaseCleaningService; - -/** - * Contains all scheduled tasks - * - */ -@Stateless -@TransactionManagement(TransactionManagementType.BEAN) -public class ScheduledTasks { - - @Inject - ApplicationSettingsService applicationSettingsService; - - @Inject - DatabaseCleaningService cleaner; - - /** - * clean old read statuses - */ - @Schedule(hour = "*", persistent = false) - private void cleanupOldStatuses() { - Date threshold = applicationSettingsService.getUnreadThreshold(); - if (threshold != null) { - cleaner.cleanStatusesOlderThan(threshold); - } - } - - /** - * clean feeds without subscriptions, then clean contents without entries - */ - @Schedule(hour = "*", persistent = false) - private void cleanFeedsAndContents() { - cleaner.cleanEntriesWithoutSubscriptions(); - cleaner.cleanFeedsWithoutSubscriptions(); - cleaner.cleanContentsWithoutEntries(); - } -} diff --git a/src/main/java/com/commafeed/backend/cache/NoopCacheService.java b/src/main/java/com/commafeed/backend/cache/NoopCacheService.java index e8755090..4741f5ec 100644 --- a/src/main/java/com/commafeed/backend/cache/NoopCacheService.java +++ b/src/main/java/com/commafeed/backend/cache/NoopCacheService.java @@ -3,17 +3,12 @@ package com.commafeed.backend.cache; import java.util.Collections; import java.util.List; -import javax.enterprise.context.ApplicationScoped; -import javax.enterprise.inject.Alternative; - import com.commafeed.backend.model.Feed; import com.commafeed.backend.model.FeedSubscription; import com.commafeed.backend.model.User; import com.commafeed.frontend.model.Category; import com.commafeed.frontend.model.UnreadCount; -@Alternative -@ApplicationScoped public class NoopCacheService extends CacheService { @Override diff --git a/src/main/java/com/commafeed/backend/cache/RedisCacheService.java b/src/main/java/com/commafeed/backend/cache/RedisCacheService.java index 348671a6..2a50a6b2 100644 --- a/src/main/java/com/commafeed/backend/cache/RedisCacheService.java +++ b/src/main/java/com/commafeed/backend/cache/RedisCacheService.java @@ -4,13 +4,10 @@ import java.util.List; import java.util.Set; import java.util.concurrent.TimeUnit; -import javax.annotation.PostConstruct; -import javax.enterprise.context.ApplicationScoped; -import javax.enterprise.inject.Alternative; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.pool.impl.GenericObjectPool; -import lombok.extern.slf4j.Slf4j; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPoolConfig; @@ -26,8 +23,6 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.collect.Lists; -@Alternative -@ApplicationScoped @Slf4j public class RedisCacheService extends CacheService { @@ -35,8 +30,7 @@ public class RedisCacheService extends CacheService { private JedisPool pool; - @PostConstruct - private void init() { + public RedisCacheService() { JedisPoolConfig config = new JedisPoolConfig(); config.setWhenExhaustedAction(GenericObjectPool.WHEN_EXHAUSTED_GROW); pool = new JedisPool(config, "localhost"); diff --git a/src/main/java/com/commafeed/backend/dao/ApplicationSettingsDAO.java b/src/main/java/com/commafeed/backend/dao/ApplicationSettingsDAO.java deleted file mode 100644 index 97b69973..00000000 --- a/src/main/java/com/commafeed/backend/dao/ApplicationSettingsDAO.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.commafeed.backend.dao; - -import javax.ejb.Stateless; - -import com.commafeed.backend.model.ApplicationSettings; - -@Stateless -public class ApplicationSettingsDAO extends GenericDAO { - -} diff --git a/src/main/java/com/commafeed/backend/dao/FeedCategoryDAO.java b/src/main/java/com/commafeed/backend/dao/FeedCategoryDAO.java index 62a2d8bf..7e26201c 100644 --- a/src/main/java/com/commafeed/backend/dao/FeedCategoryDAO.java +++ b/src/main/java/com/commafeed/backend/dao/FeedCategoryDAO.java @@ -2,91 +2,50 @@ package com.commafeed.backend.dao; import java.util.List; -import javax.ejb.Stateless; -import javax.persistence.NoResultException; -import javax.persistence.criteria.CriteriaQuery; -import javax.persistence.criteria.Join; -import javax.persistence.criteria.Predicate; -import javax.persistence.criteria.Root; - import org.apache.commons.lang.ObjectUtils; +import org.hibernate.SessionFactory; import com.commafeed.backend.model.FeedCategory; -import com.commafeed.backend.model.FeedCategory_; +import com.commafeed.backend.model.QFeedCategory; +import com.commafeed.backend.model.QUser; import com.commafeed.backend.model.User; -import com.commafeed.backend.model.User_; -import com.google.common.collect.Iterables; import com.google.common.collect.Lists; +import com.mysema.query.types.Predicate; -@Stateless public class FeedCategoryDAO extends GenericDAO { - @SuppressWarnings("unchecked") + private QFeedCategory category = QFeedCategory.feedCategory; + + public FeedCategoryDAO(SessionFactory sessionFactory) { + super(sessionFactory); + } + public List findAll(User user) { - - CriteriaQuery query = builder.createQuery(getType()); - Root root = query.from(getType()); - Join userJoin = (Join) root.fetch(FeedCategory_.user); - - query.where(builder.equal(userJoin.get(User_.id), user.getId())); - - return cache(em.createQuery(query)).getResultList(); + return newQuery().from(category).where(category.user.eq(user)).join(category.user, QUser.user).fetch().list(category); } public FeedCategory findById(User user, Long id) { - CriteriaQuery query = builder.createQuery(getType()); - Root root = query.from(getType()); - - Predicate p1 = builder.equal(root.get(FeedCategory_.user).get(User_.id), user.getId()); - Predicate p2 = builder.equal(root.get(FeedCategory_.id), id); - - query.where(p1, p2); - - return Iterables.getFirst(cache(em.createQuery(query)).getResultList(), null); + return newQuery().from(category).where(category.user.eq(user), category.id.eq(id)).uniqueResult(category); } public FeedCategory findByName(User user, String name, FeedCategory parent) { - CriteriaQuery query = builder.createQuery(getType()); - Root root = query.from(getType()); - - List predicates = Lists.newArrayList(); - - predicates.add(builder.equal(root.get(FeedCategory_.user), user)); - predicates.add(builder.equal(root.get(FeedCategory_.name), name)); - + Predicate parentPredicate = null; if (parent == null) { - predicates.add(builder.isNull(root.get(FeedCategory_.parent))); + parentPredicate = category.parent.isNull(); } else { - predicates.add(builder.equal(root.get(FeedCategory_.parent), parent)); + parentPredicate = category.parent.eq(parent); } - - query.where(predicates.toArray(new Predicate[0])); - - FeedCategory category = null; - try { - category = em.createQuery(query).getSingleResult(); - } catch (NoResultException e) { - category = null; - } - return category; + return newQuery().from(category).where(category.user.eq(user), category.name.eq(name), parentPredicate).uniqueResult(category); } public List findByParent(User user, FeedCategory parent) { - CriteriaQuery query = builder.createQuery(getType()); - Root root = query.from(getType()); - - List predicates = Lists.newArrayList(); - - predicates.add(builder.equal(root.get(FeedCategory_.user), user)); + Predicate parentPredicate = null; if (parent == null) { - predicates.add(builder.isNull(root.get(FeedCategory_.parent))); + parentPredicate = category.parent.isNull(); } else { - predicates.add(builder.equal(root.get(FeedCategory_.parent), parent)); + parentPredicate = category.parent.eq(parent); } - - query.where(predicates.toArray(new Predicate[0])); - - return em.createQuery(query).getResultList(); + return newQuery().from(category).where(category.user.eq(user), parentPredicate).list(category); } public List findAllChildrenCategories(User user, FeedCategory parent) { diff --git a/src/main/java/com/commafeed/backend/dao/FeedDAO.java b/src/main/java/com/commafeed/backend/dao/FeedDAO.java index bf2d1254..1afe2b27 100644 --- a/src/main/java/com/commafeed/backend/dao/FeedDAO.java +++ b/src/main/java/com/commafeed/backend/dao/FeedDAO.java @@ -3,104 +3,75 @@ package com.commafeed.backend.dao; import java.util.Date; import java.util.List; -import javax.ejb.Stateless; -import javax.persistence.TypedQuery; -import javax.persistence.criteria.CriteriaQuery; -import javax.persistence.criteria.Join; -import javax.persistence.criteria.JoinType; -import javax.persistence.criteria.Predicate; -import javax.persistence.criteria.Root; -import javax.persistence.criteria.SetJoin; -import javax.persistence.criteria.Subquery; - import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.lang.StringUtils; +import org.hibernate.SessionFactory; -import com.commafeed.backend.feeds.FeedUtils; import com.commafeed.backend.model.Feed; -import com.commafeed.backend.model.FeedSubscription; -import com.commafeed.backend.model.FeedSubscription_; -import com.commafeed.backend.model.Feed_; -import com.commafeed.backend.model.User; -import com.commafeed.backend.model.User_; +import com.commafeed.backend.model.QFeed; +import com.commafeed.backend.model.QFeedSubscription; +import com.commafeed.backend.model.QUser; import com.google.common.collect.Iterables; -import com.google.common.collect.Lists; +import com.mysema.query.BooleanBuilder; +import com.mysema.query.jpa.hibernate.HibernateQuery; +import com.mysema.query.jpa.hibernate.HibernateSubQuery; -@Stateless public class FeedDAO extends GenericDAO { - private List getUpdatablePredicates(CriteriaQuery query, Root root, Date lastLoginThreshold) { + private QFeed feed = QFeed.feed; - List preds = Lists.newArrayList(); - Predicate isNull = builder.isNull(root.get(Feed_.disabledUntil)); - Predicate lessThan = builder.lessThan(root.get(Feed_.disabledUntil), new Date()); - preds.add(builder.or(isNull, lessThan)); - - if (lastLoginThreshold != null) { - Subquery subquery = query.subquery(Long.class); - Root subroot = subquery.from(FeedSubscription.class); - subquery.select(builder.count(subroot.get(FeedSubscription_.id))); - - Join userJoin = subroot.join(FeedSubscription_.user); - Predicate p1 = builder.equal(subroot.get(FeedSubscription_.feed), root); - Predicate p2 = builder.greaterThanOrEqualTo(userJoin.get(User_.lastLogin), lastLoginThreshold); - subquery.where(p1, p2); - - preds.add(builder.exists(subquery)); - } - - return preds; + public FeedDAO(SessionFactory sessionFactory) { + super(sessionFactory); } public Long getUpdatableCount(Date lastLoginThreshold) { - CriteriaQuery query = builder.createQuery(Long.class); - Root root = query.from(getType()); + BooleanBuilder disabledDatePredicate = new BooleanBuilder(); + disabledDatePredicate.or(feed.disabledUntil.isNull()); + disabledDatePredicate.or(feed.disabledUntil.lt(new Date())); - query.select(builder.count(root)); - query.where(getUpdatablePredicates(query, root, lastLoginThreshold).toArray(new Predicate[0])); - - TypedQuery q = em.createQuery(query); - return q.getSingleResult(); + HibernateQuery query = newQuery().from(feed).where(disabledDatePredicate); + if (lastLoginThreshold != null) { + QFeedSubscription sub = QFeedSubscription.feedSubscription; + QUser user = QUser.user; + HibernateSubQuery subquery = new HibernateSubQuery(); + subquery.from(sub).join(sub.user, user).where(sub.feed.eq(feed), user.lastLogin.gt(lastLoginThreshold)); + query.where(subquery.exists()); + } + return query.orderBy(feed.disabledUntil.asc()).count(); } public List findNextUpdatable(int count, Date lastLoginThreshold) { - CriteriaQuery query = builder.createQuery(getType()); - Root root = query.from(getType()); + BooleanBuilder disabledDatePredicate = new BooleanBuilder(); + disabledDatePredicate.or(feed.disabledUntil.isNull()); + disabledDatePredicate.or(feed.disabledUntil.lt(new Date())); - query.where(getUpdatablePredicates(query, root, lastLoginThreshold).toArray(new Predicate[0])); - query.orderBy(builder.asc(root.get(Feed_.disabledUntil))); - - TypedQuery q = em.createQuery(query); - q.setMaxResults(count); - - return q.getResultList(); - } - - public Feed findByUrl(String url) { - - String normalized = FeedUtils.normalizeURL(url); - List feeds = findByField(Feed_.normalizedUrlHash, DigestUtils.sha1Hex(normalized)); - Feed feed = Iterables.getFirst(feeds, null); - if (feed != null && StringUtils.equals(normalized, feed.getNormalizedUrl())) { - return feed; + HibernateQuery query = newQuery().from(feed).where(disabledDatePredicate); + if (lastLoginThreshold != null) { + QFeedSubscription sub = QFeedSubscription.feedSubscription; + QUser user = QUser.user; + HibernateSubQuery subquery = new HibernateSubQuery(); + subquery.from(sub).join(sub.user, user).where(sub.feed.eq(feed), user.lastLogin.gt(lastLoginThreshold)); + query.where(subquery.exists()); } + return query.orderBy(feed.disabledUntil.asc()).limit(count).list(feed); + } + + public Feed findByUrl(String normalizedUrl) { + List feeds = newQuery().from(feed).where(feed.normalizedUrlHash.eq(DigestUtils.sha1Hex(normalizedUrl))).list(feed); + Feed feed = Iterables.getFirst(feeds, null); + if (feed != null && StringUtils.equals(normalizedUrl, feed.getNormalizedUrl())) { + return feed; + } return null; } public List findByTopic(String topic) { - return findByField(Feed_.pushTopicHash, DigestUtils.sha1Hex(topic)); + return newQuery().from(feed).where(feed.pushTopicHash.eq(DigestUtils.sha1Hex(topic))).list(feed); } - + public List findWithoutSubscriptions(int max) { - CriteriaQuery query = builder.createQuery(getType()); - Root root = query.from(getType()); - - SetJoin join = root.join(Feed_.subscriptions, JoinType.LEFT); - query.where(builder.isNull(join.get(FeedSubscription_.id))); - TypedQuery q = em.createQuery(query); - q.setMaxResults(max); - - return q.getResultList(); + QFeedSubscription sub = QFeedSubscription.feedSubscription; + return newQuery().from(feed).leftJoin(feed.subscriptions, sub).where(sub.id.isNull()).limit(max).list(feed); } } diff --git a/src/main/java/com/commafeed/backend/dao/FeedEntryContentDAO.java b/src/main/java/com/commafeed/backend/dao/FeedEntryContentDAO.java index 99f46e60..07250ef8 100644 --- a/src/main/java/com/commafeed/backend/dao/FeedEntryContentDAO.java +++ b/src/main/java/com/commafeed/backend/dao/FeedEntryContentDAO.java @@ -2,52 +2,34 @@ package com.commafeed.backend.dao; import java.util.List; -import javax.ejb.Stateless; -import javax.persistence.TypedQuery; -import javax.persistence.criteria.CriteriaQuery; -import javax.persistence.criteria.Join; -import javax.persistence.criteria.JoinType; -import javax.persistence.criteria.Predicate; -import javax.persistence.criteria.Root; +import org.hibernate.SessionFactory; -import com.commafeed.backend.model.FeedEntry; import com.commafeed.backend.model.FeedEntryContent; -import com.commafeed.backend.model.FeedEntryContent_; -import com.commafeed.backend.model.FeedEntry_; +import com.commafeed.backend.model.QFeedEntry; +import com.commafeed.backend.model.QFeedEntryContent; import com.google.common.collect.Iterables; +import com.mysema.query.types.ConstructorExpression; -@Stateless public class FeedEntryContentDAO extends GenericDAO { + private QFeedEntryContent content = QFeedEntryContent.feedEntryContent; + + public FeedEntryContentDAO(SessionFactory sessionFactory) { + super(sessionFactory); + } + public Long findExisting(String contentHash, String titleHash) { - - CriteriaQuery query = builder.createQuery(Long.class); - Root root = query.from(getType()); - query.select(root.get(FeedEntryContent_.id)); - - Predicate p1 = builder.equal(root.get(FeedEntryContent_.contentHash), contentHash); - Predicate p2 = builder.equal(root.get(FeedEntryContent_.titleHash), titleHash); - - query.where(p1, p2); - TypedQuery q = em.createQuery(query); - limit(q, 0, 1); - return Iterables.getFirst(q.getResultList(), null); - + List list = newQuery().from(content).where(content.contentHash.eq(contentHash), content.titleHash.eq(titleHash)).limit(1) + .list(ConstructorExpression.create(Long.class, content.id)); + return Iterables.getFirst(list, null); } public int deleteWithoutEntries(int max) { - CriteriaQuery query = builder.createQuery(getType()); - Root root = query.from(getType()); - - Join join = root.join(FeedEntryContent_.entries, JoinType.LEFT); - query.where(builder.isNull(join.get(FeedEntry_.id))); - TypedQuery q = em.createQuery(query); - q.setMaxResults(max); - - List list = q.getResultList(); + QFeedEntry entry = QFeedEntry.feedEntry; + List list = newQuery().from(content).leftJoin(content.entries, entry).where(entry.id.isNull()).limit(max) + .list(content); int deleted = list.size(); delete(list); return deleted; - } } diff --git a/src/main/java/com/commafeed/backend/dao/FeedEntryDAO.java b/src/main/java/com/commafeed/backend/dao/FeedEntryDAO.java index e457e962..8b98dc0b 100644 --- a/src/main/java/com/commafeed/backend/dao/FeedEntryDAO.java +++ b/src/main/java/com/commafeed/backend/dao/FeedEntryDAO.java @@ -3,82 +3,47 @@ package com.commafeed.backend.dao; import java.util.Date; import java.util.List; -import javax.ejb.Stateless; -import javax.persistence.TypedQuery; -import javax.persistence.criteria.CriteriaQuery; -import javax.persistence.criteria.Join; -import javax.persistence.criteria.JoinType; -import javax.persistence.criteria.Predicate; -import javax.persistence.criteria.Root; -import javax.persistence.criteria.SetJoin; - import org.apache.commons.codec.digest.DigestUtils; +import org.hibernate.SessionFactory; import com.commafeed.backend.model.Feed; import com.commafeed.backend.model.FeedEntry; -import com.commafeed.backend.model.FeedEntry_; -import com.commafeed.backend.model.FeedSubscription; -import com.commafeed.backend.model.FeedSubscription_; -import com.commafeed.backend.model.Feed_; +import com.commafeed.backend.model.QFeed; +import com.commafeed.backend.model.QFeedEntry; +import com.commafeed.backend.model.QFeedSubscription; import com.google.common.collect.Iterables; +import com.mysema.query.types.ConstructorExpression; -@Stateless public class FeedEntryDAO extends GenericDAO { - public Long findExisting(String guid, Long feedId) { + private QFeedEntry entry = QFeedEntry.feedEntry; - CriteriaQuery query = builder.createQuery(Long.class); - Root root = query.from(getType()); - query.select(root.get(FeedEntry_.id)); + public FeedEntryDAO(SessionFactory sessionFactory) { + super(sessionFactory); + } - Predicate p1 = builder.equal(root.get(FeedEntry_.guidHash), DigestUtils.sha1Hex(guid)); - Predicate p2 = builder.equal(root.get(FeedEntry_.feed).get(Feed_.id), feedId); - - query.where(p1, p2); - - TypedQuery q = em.createQuery(query); - limit(q, 0, 1); - List list = q.getResultList(); + public Long findExisting(String guid, Feed feed) { + List list = newQuery().from(entry).where(entry.guidHash.eq(DigestUtils.sha1Hex(guid)), entry.feed.eq(feed)).limit(1) + .list(ConstructorExpression.create(Long.class, entry.id)); return Iterables.getFirst(list, null); } public List findWithoutSubscriptions(int max) { - CriteriaQuery query = builder.createQuery(getType()); - Root root = query.from(getType()); - - Join feedJoin = root.join(FeedEntry_.feed); - SetJoin subJoin = feedJoin.join(Feed_.subscriptions, JoinType.LEFT); - query.where(builder.isNull(subJoin.get(FeedSubscription_.id))); - TypedQuery q = em.createQuery(query); - q.setMaxResults(max); - - return q.getResultList(); + QFeed feed = QFeed.feed; + QFeedSubscription sub = QFeedSubscription.feedSubscription; + return newQuery().from(entry).join(entry.feed, feed).leftJoin(feed.subscriptions, sub).where(sub.id.isNull()).limit(max) + .list(entry); } public int delete(Feed feed, int max) { - - CriteriaQuery query = builder.createQuery(getType()); - Root root = query.from(getType()); - - query.where(builder.equal(root.get(FeedEntry_.feed), feed)); - TypedQuery q = em.createQuery(query); - q.setMaxResults(max); - - List list = q.getResultList(); + List list = newQuery().from(entry).where(entry.feed.eq(feed)).limit(max).list(entry); int deleted = list.size(); delete(list); return deleted; } public int delete(Date olderThan, int max) { - CriteriaQuery query = builder.createQuery(getType()); - Root root = query.from(getType()); - query.where(builder.lessThan(root.get(FeedEntry_.inserted), olderThan)); - - TypedQuery q = em.createQuery(query); - q.setMaxResults(max); - List list = q.getResultList(); - + List list = newQuery().from(entry).where(entry.inserted.lt(olderThan)).limit(max).list(entry); int deleted = list.size(); delete(list); return deleted; diff --git a/src/main/java/com/commafeed/backend/dao/FeedEntryStatusDAO.java b/src/main/java/com/commafeed/backend/dao/FeedEntryStatusDAO.java index 12780b6f..3f7fc7ec 100644 --- a/src/main/java/com/commafeed/backend/dao/FeedEntryStatusDAO.java +++ b/src/main/java/com/commafeed/backend/dao/FeedEntryStatusDAO.java @@ -5,18 +5,10 @@ import java.util.Date; import java.util.List; import java.util.Map; -import javax.ejb.Stateless; -import javax.inject.Inject; -import javax.persistence.Query; -import javax.persistence.TypedQuery; -import javax.persistence.criteria.CriteriaQuery; -import javax.persistence.criteria.Path; -import javax.persistence.criteria.Predicate; -import javax.persistence.criteria.Root; - import org.apache.commons.lang.StringUtils; -import org.apache.commons.lang3.builder.CompareToBuilder; +import org.apache.commons.lang.builder.CompareToBuilder; import org.hibernate.Criteria; +import org.hibernate.SessionFactory; import org.hibernate.criterion.Conjunction; import org.hibernate.criterion.Disjunction; import org.hibernate.criterion.MatchMode; @@ -27,33 +19,44 @@ import org.hibernate.criterion.Restrictions; import org.hibernate.sql.JoinType; import org.hibernate.transform.Transformers; +import com.commafeed.CommaFeedConfiguration; import com.commafeed.backend.FixedSizeSortedSet; import com.commafeed.backend.model.FeedEntry; -import com.commafeed.backend.model.FeedEntryContent_; import com.commafeed.backend.model.FeedEntryStatus; -import com.commafeed.backend.model.FeedEntryStatus_; import com.commafeed.backend.model.FeedEntryTag; -import com.commafeed.backend.model.FeedEntryTag_; -import com.commafeed.backend.model.FeedEntry_; import com.commafeed.backend.model.FeedSubscription; import com.commafeed.backend.model.Models; +import com.commafeed.backend.model.QFeedEntry; +import com.commafeed.backend.model.QFeedEntryContent; +import com.commafeed.backend.model.QFeedEntryStatus; +import com.commafeed.backend.model.QFeedEntryTag; import com.commafeed.backend.model.User; import com.commafeed.backend.model.UserSettings.ReadingOrder; -import com.commafeed.backend.services.ApplicationSettingsService; import com.commafeed.frontend.model.UnreadCount; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.common.collect.Ordering; +import com.mysema.query.jpa.hibernate.HibernateQuery; -@Stateless public class FeedEntryStatusDAO extends GenericDAO { private static final String ALIAS_STATUS = "status"; private static final String ALIAS_ENTRY = "entry"; private static final String ALIAS_TAG = "tag"; - @Inject - FeedEntryTagDAO feedEntryTagDAO; + private FeedEntryDAO feedEntryDAO; + private FeedEntryTagDAO feedEntryTagDAO; + private CommaFeedConfiguration config; + + private QFeedEntryStatus status = QFeedEntryStatus.feedEntryStatus; + + public FeedEntryStatusDAO(SessionFactory sessionFactory, FeedEntryDAO feedEntryDAO, FeedEntryTagDAO feedEntryTagDAO, + CommaFeedConfiguration config) { + super(sessionFactory); + this.feedEntryDAO = feedEntryDAO; + this.feedEntryTagDAO = feedEntryTagDAO; + this.config = config; + } private static final Comparator STATUS_COMPARATOR_DESC = new Comparator() { @Override @@ -61,34 +64,21 @@ public class FeedEntryStatusDAO extends GenericDAO { CompareToBuilder builder = new CompareToBuilder(); builder.append(o2.getEntryUpdated(), o1.getEntryUpdated()); builder.append(o2.getId(), o1.getId()); - return builder.build(); + return builder.toComparison(); }; }; private static final Comparator STATUS_COMPARATOR_ASC = Ordering.from(STATUS_COMPARATOR_DESC).reverse(); - @Inject - ApplicationSettingsService applicationSettingsService; - public FeedEntryStatus getStatus(User user, FeedSubscription sub, FeedEntry entry) { - - CriteriaQuery query = builder.createQuery(getType()); - Root root = query.from(getType()); - - Predicate p1 = builder.equal(root.get(FeedEntryStatus_.entry), entry); - Predicate p2 = builder.equal(root.get(FeedEntryStatus_.subscription), sub); - - query.where(p1, p2); - - List statuses = em.createQuery(query).getResultList(); + List statuses = newQuery().from(status).where(status.entry.eq(entry), status.subscription.eq(sub)).list(status); FeedEntryStatus status = Iterables.getFirst(statuses, null); - return handleStatus(user, status, sub, entry); } private FeedEntryStatus handleStatus(User user, FeedEntryStatus status, FeedSubscription sub, FeedEntry entry) { if (status == null) { - Date unreadThreshold = applicationSettingsService.getUnreadThreshold(); + Date unreadThreshold = config.getApplicationSettings().getUnreadThreshold(); boolean read = unreadThreshold == null ? false : entry.getUpdated().before(unreadThreshold); status = new FeedEntryStatus(user, sub, entry); status.setRead(read); @@ -106,27 +96,20 @@ public class FeedEntryStatusDAO extends GenericDAO { } public List findStarred(User user, Date newerThan, int offset, int limit, ReadingOrder order, boolean includeContent) { - - CriteriaQuery query = builder.createQuery(getType()); - Root root = query.from(getType()); - - List predicates = Lists.newArrayList(); - - predicates.add(builder.equal(root.get(FeedEntryStatus_.user), user)); - predicates.add(builder.equal(root.get(FeedEntryStatus_.starred), true)); - + HibernateQuery query = newQuery().from(status).where(status.user.eq(user), status.starred.isTrue()); if (newerThan != null) { - predicates.add(builder.greaterThanOrEqualTo(root.get(FeedEntryStatus_.entryInserted), newerThan)); + query.where(status.entryInserted.gt(newerThan)); } - - query.where(predicates.toArray(new Predicate[0])); - orderStatusesBy(query, root, order); + if (order == ReadingOrder.asc) { + query.orderBy(status.entryUpdated.asc(), status.id.asc()); + } else { + query.orderBy(status.entryUpdated.desc(), status.id.desc()); + } - TypedQuery q = em.createQuery(query); - limit(q, offset, limit); - setTimeout(q); - List statuses = q.getResultList(); + query.offset(offset).limit(limit).setTimeout(config.getApplicationSettings().getQueryTimeout()); + + List statuses = query.list(status); for (FeedEntryStatus status : statuses) { status = handleStatus(user, status, status.getSubscription(), status.getEntry()); status = fetchTags(user, status); @@ -134,62 +117,66 @@ public class FeedEntryStatusDAO extends GenericDAO { return lazyLoadContent(includeContent, statuses); } - private Criteria buildSearchCriteria(User user, FeedSubscription sub, boolean unreadOnly, String keywords, Date newerThan, int offset, int limit, - ReadingOrder order, Date last, String tag) { - Criteria criteria = getSession().createCriteria(FeedEntry.class, ALIAS_ENTRY); + private Criteria buildSearchCriteria(User user, FeedSubscription sub, boolean unreadOnly, String keywords, Date newerThan, int offset, + int limit, ReadingOrder order, Date last, String tag) { + QFeedEntry entry = QFeedEntry.feedEntry; + QFeedEntryContent content = QFeedEntryContent.feedEntryContent; + QFeedEntryStatus status = QFeedEntryStatus.feedEntryStatus; + QFeedEntryTag entryTag = QFeedEntryTag.feedEntryTag; - criteria.add(Restrictions.eq(FeedEntry_.feed.getName(), sub.getFeed())); + Criteria criteria = currentSession().createCriteria(FeedEntry.class, ALIAS_ENTRY); + criteria.add(Restrictions.eq(entry.feed.getMetadata().getName(), sub.getFeed())); if (keywords != null) { - Criteria contentJoin = criteria.createCriteria(FeedEntry_.content.getName(), "content", JoinType.INNER_JOIN); + Criteria contentJoin = criteria.createCriteria(entry.content.getMetadata().getName(), "content", JoinType.INNER_JOIN); for (String keyword : StringUtils.split(keywords)) { Disjunction or = Restrictions.disjunction(); - or.add(Restrictions.ilike(FeedEntryContent_.content.getName(), keyword, MatchMode.ANYWHERE)); - or.add(Restrictions.ilike(FeedEntryContent_.title.getName(), keyword, MatchMode.ANYWHERE)); + or.add(Restrictions.ilike(content.content.getMetadata().getName(), keyword, MatchMode.ANYWHERE)); + or.add(Restrictions.ilike(content.title.getMetadata().getName(), keyword, MatchMode.ANYWHERE)); contentJoin.add(or); } } - Criteria statusJoin = criteria.createCriteria(FeedEntry_.statuses.getName(), ALIAS_STATUS, JoinType.LEFT_OUTER_JOIN, - Restrictions.eq(FeedEntryStatus_.subscription.getName(), sub)); + Criteria statusJoin = criteria.createCriteria(entry.statuses.getMetadata().getName(), ALIAS_STATUS, JoinType.LEFT_OUTER_JOIN, + Restrictions.eq(status.subscription.getMetadata().getName(), sub)); if (unreadOnly && tag == null) { Disjunction or = Restrictions.disjunction(); - or.add(Restrictions.isNull(FeedEntryStatus_.read.getName())); - or.add(Restrictions.eq(FeedEntryStatus_.read.getName(), false)); + or.add(Restrictions.isNull(status.read.getMetadata().getName())); + or.add(Restrictions.eq(status.read.getMetadata().getName(), false)); statusJoin.add(or); - Date unreadThreshold = applicationSettingsService.getUnreadThreshold(); + Date unreadThreshold = config.getApplicationSettings().getUnreadThreshold(); if (unreadThreshold != null) { - criteria.add(Restrictions.ge(FeedEntry_.updated.getName(), unreadThreshold)); + criteria.add(Restrictions.ge(entry.updated.getMetadata().getName(), unreadThreshold)); } } if (tag != null) { Conjunction and = Restrictions.conjunction(); - and.add(Restrictions.eq(FeedEntryTag_.user.getName(), user)); - and.add(Restrictions.eq(FeedEntryTag_.name.getName(), tag)); - criteria.createCriteria(FeedEntry_.tags.getName(), ALIAS_TAG, JoinType.INNER_JOIN, and); + and.add(Restrictions.eq(entryTag.user.getMetadata().getName(), user)); + and.add(Restrictions.eq(entryTag.name.getMetadata().getName(), tag)); + criteria.createCriteria(entry.tags.getMetadata().getName(), ALIAS_TAG, JoinType.INNER_JOIN, and); } if (newerThan != null) { - criteria.add(Restrictions.ge(FeedEntry_.inserted.getName(), newerThan)); + criteria.add(Restrictions.ge(entry.inserted.getMetadata().getName(), newerThan)); } if (last != null) { if (order == ReadingOrder.desc) { - criteria.add(Restrictions.gt(FeedEntry_.updated.getName(), last)); + criteria.add(Restrictions.gt(entry.updated.getMetadata().getName(), last)); } else { - criteria.add(Restrictions.lt(FeedEntry_.updated.getName(), last)); + criteria.add(Restrictions.lt(entry.updated.getMetadata().getName(), last)); } } if (order != null) { if (order == ReadingOrder.asc) { - criteria.addOrder(Order.asc(FeedEntry_.updated.getName())).addOrder(Order.asc(FeedEntry_.id.getName())); + criteria.addOrder(Order.asc(entry.updated.getMetadata().getName())).addOrder(Order.asc(entry.id.getMetadata().getName())); } else { - criteria.addOrder(Order.desc(FeedEntry_.updated.getName())).addOrder(Order.desc(FeedEntry_.id.getName())); + criteria.addOrder(Order.desc(entry.updated.getMetadata().getName())).addOrder(Order.desc(entry.id.getMetadata().getName())); } } if (offset > -1) { @@ -198,7 +185,7 @@ public class FeedEntryStatusDAO extends GenericDAO { if (limit > -1) { criteria.setMaxResults(limit); } - int timeout = applicationSettingsService.get().getQueryTimeout(); + int timeout = config.getApplicationSettings().getQueryTimeout(); if (timeout > 0) { // hibernate timeout is in seconds, jpa timeout is in millis criteria.setTimeout(timeout / 1000); @@ -255,7 +242,7 @@ public class FeedEntryStatusDAO extends GenericDAO { statuses = Lists.newArrayList(); for (FeedEntryStatus placeholder : placeholders) { Long statusId = placeholder.getId(); - FeedEntry entry = em.find(FeedEntry.class, placeholder.getEntry().getId()); + FeedEntry entry = feedEntryDAO.findById(placeholder.getEntry().getId()); FeedEntryStatus status = handleStatus(user, statusId == null ? null : findById(statusId), placeholder.getSubscription(), entry); status = fetchTags(user, status); @@ -272,7 +259,7 @@ public class FeedEntryStatusDAO extends GenericDAO { Criteria criteria = buildSearchCriteria(user, subscription, true, null, null, -1, -1, null, null, null); ProjectionList projection = Projections.projectionList(); projection.add(Projections.rowCount(), "count"); - projection.add(Projections.max(FeedEntry_.updated.getName()), "updated"); + projection.add(Projections.max(QFeedEntry.feedEntry.updated.getMetadata().getName()), "updated"); criteria.setProjection(projection); criteria.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP); List> list = criteria.list(); @@ -294,35 +281,8 @@ public class FeedEntryStatusDAO extends GenericDAO { return results; } - private void orderStatusesBy(CriteriaQuery query, Path statusJoin, ReadingOrder order) { - orderBy(query, statusJoin.get(FeedEntryStatus_.entryUpdated), statusJoin.get(FeedEntryStatus_.id), order); - } - - private void orderBy(CriteriaQuery query, Path date, Path id, ReadingOrder order) { - if (order != null) { - if (order == ReadingOrder.asc) { - query.orderBy(builder.asc(date), builder.asc(id)); - } else { - query.orderBy(builder.desc(date), builder.desc(id)); - } - } - } - - protected void setTimeout(Query query) { - setTimeout(query, applicationSettingsService.get().getQueryTimeout()); - } - public List getOldStatuses(Date olderThan, int limit) { - CriteriaQuery query = builder.createQuery(getType()); - Root root = query.from(getType()); - - Predicate p1 = builder.lessThan(root.get(FeedEntryStatus_.entryInserted), olderThan); - Predicate p2 = builder.isFalse(root.get(FeedEntryStatus_.starred)); - - query.where(p1, p2); - TypedQuery q = em.createQuery(query); - q.setMaxResults(limit); - return q.getResultList(); + return newQuery().from(status).where(status.entryInserted.lt(olderThan), status.starred.isFalse()).limit(limit).list(status); } } diff --git a/src/main/java/com/commafeed/backend/dao/FeedEntryTagDAO.java b/src/main/java/com/commafeed/backend/dao/FeedEntryTagDAO.java index 82981656..516c8ce0 100644 --- a/src/main/java/com/commafeed/backend/dao/FeedEntryTagDAO.java +++ b/src/main/java/com/commafeed/backend/dao/FeedEntryTagDAO.java @@ -2,42 +2,27 @@ package com.commafeed.backend.dao; import java.util.List; -import javax.ejb.Stateless; -import javax.persistence.criteria.CriteriaQuery; -import javax.persistence.criteria.Predicate; -import javax.persistence.criteria.Root; +import org.hibernate.SessionFactory; import com.commafeed.backend.model.FeedEntry; import com.commafeed.backend.model.FeedEntryTag; -import com.commafeed.backend.model.FeedEntryTag_; -import com.commafeed.backend.model.FeedEntry_; +import com.commafeed.backend.model.QFeedEntryTag; import com.commafeed.backend.model.User; -import com.commafeed.backend.model.User_; +import com.mysema.query.types.ConstructorExpression; -@Stateless public class FeedEntryTagDAO extends GenericDAO { + private QFeedEntryTag tag = QFeedEntryTag.feedEntryTag; + + public FeedEntryTagDAO(SessionFactory sessionFactory) { + super(sessionFactory); + } + public List findByUser(User user) { - CriteriaQuery query = builder.createQuery(String.class); - Root root = query.from(getType()); - query.select(root.get(FeedEntryTag_.name)); - query.distinct(true); - - Predicate p1 = builder.equal(root.get(FeedEntryTag_.user).get(User_.id), user.getId()); - query.where(p1); - - return cache(em.createQuery(query)).getResultList(); + return newQuery().from(tag).where(tag.user.eq(user)).distinct().list(ConstructorExpression.create(String.class, tag.name)); } public List findByEntry(User user, FeedEntry entry) { - CriteriaQuery query = builder.createQuery(getType()); - Root root = query.from(getType()); - - Predicate p1 = builder.equal(root.get(FeedEntryTag_.user).get(User_.id), user.getId()); - Predicate p2 = builder.equal(root.get(FeedEntryTag_.entry).get(FeedEntry_.id), entry.getId()); - - query.where(p1, p2); - - return cache(em.createQuery(query)).getResultList(); + return newQuery().from(tag).where(tag.user.eq(user), tag.entry.eq(entry)).list(tag); } } diff --git a/src/main/java/com/commafeed/backend/dao/FeedSubscriptionDAO.java b/src/main/java/com/commafeed/backend/dao/FeedSubscriptionDAO.java index f0c875b9..60e9877d 100644 --- a/src/main/java/com/commafeed/backend/dao/FeedSubscriptionDAO.java +++ b/src/main/java/com/commafeed/backend/dao/FeedSubscriptionDAO.java @@ -2,110 +2,59 @@ package com.commafeed.backend.dao; import java.util.List; -import javax.ejb.Stateless; -import javax.persistence.criteria.CriteriaQuery; -import javax.persistence.criteria.JoinType; -import javax.persistence.criteria.Predicate; -import javax.persistence.criteria.Root; +import org.hibernate.SessionFactory; import com.commafeed.backend.model.Feed; import com.commafeed.backend.model.FeedCategory; -import com.commafeed.backend.model.FeedCategory_; import com.commafeed.backend.model.FeedSubscription; -import com.commafeed.backend.model.FeedSubscription_; -import com.commafeed.backend.model.Feed_; import com.commafeed.backend.model.Models; +import com.commafeed.backend.model.QFeedSubscription; import com.commafeed.backend.model.User; -import com.commafeed.backend.model.User_; import com.google.common.base.Function; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; +import com.mysema.query.jpa.hibernate.HibernateQuery; -@Stateless public class FeedSubscriptionDAO extends GenericDAO { + private QFeedSubscription sub = QFeedSubscription.feedSubscription; + + public FeedSubscriptionDAO(SessionFactory sessionFactory) { + super(sessionFactory); + } + public FeedSubscription findById(User user, Long id) { - CriteriaQuery query = builder.createQuery(getType()); - Root root = query.from(getType()); - - Predicate p1 = builder.equal(root.get(FeedSubscription_.user).get(User_.id), user.getId()); - Predicate p2 = builder.equal(root.get(FeedSubscription_.id), id); - - root.fetch(FeedSubscription_.feed, JoinType.LEFT); - root.fetch(FeedSubscription_.category, JoinType.LEFT); - - query.where(p1, p2); - - FeedSubscription sub = Iterables.getFirst(cache(em.createQuery(query)).getResultList(), null); - initRelations(sub); - return sub; + List subs = newQuery().from(sub).where(sub.user.eq(user), sub.id.eq(id)).leftJoin(sub.feed).fetch() + .leftJoin(sub.category).fetch().list(sub); + return initRelations(Iterables.getFirst(subs, null)); } public List findByFeed(Feed feed) { - CriteriaQuery query = builder.createQuery(getType()); - Root root = query.from(getType()); - - query.where(builder.equal(root.get(FeedSubscription_.feed), feed)); - List list = cache(em.createQuery(query)).getResultList(); - return list; + return newQuery().from(sub).where(sub.feed.eq(feed)).list(sub); } public FeedSubscription findByFeed(User user, Feed feed) { - - CriteriaQuery query = builder.createQuery(getType()); - Root root = query.from(getType()); - - Predicate p1 = builder.equal(root.get(FeedSubscription_.user).get(User_.id), user.getId()); - Predicate p2 = builder.equal(root.get(FeedSubscription_.feed).get(Feed_.id), feed.getId()); - - root.fetch(FeedSubscription_.feed, JoinType.LEFT); - root.fetch(FeedSubscription_.category, JoinType.LEFT); - - query.where(p1, p2); - - FeedSubscription sub = Iterables.getFirst(cache(em.createQuery(query)).getResultList(), null); - initRelations(sub); - return sub; + List subs = newQuery().from(sub).where(sub.user.eq(user), sub.feed.eq(feed)).list(sub); + return initRelations(Iterables.getFirst(subs, null)); } public List findAll(User user) { - - CriteriaQuery query = builder.createQuery(getType()); - Root root = query.from(getType()); - - root.fetch(FeedSubscription_.feed, JoinType.LEFT); - root.fetch(FeedSubscription_.category, JoinType.LEFT); - - query.where(builder.equal(root.get(FeedSubscription_.user).get(User_.id), user.getId())); - - List list = cache(em.createQuery(query)).getResultList(); - initRelations(list); - return list; + List subs = newQuery().from(sub).where(sub.user.eq(user)).leftJoin(sub.feed).fetch().leftJoin(sub.category) + .fetch().list(sub); + return initRelations(subs); } public List findByCategory(User user, FeedCategory category) { - - CriteriaQuery query = builder.createQuery(getType()); - Root root = query.from(getType()); - - Predicate p1 = builder.equal(root.get(FeedSubscription_.user).get(User_.id), user.getId()); - Predicate p2 = null; + HibernateQuery query = newQuery().from(sub).where(sub.user.eq(user)); if (category == null) { - p2 = builder.isNull(root.get(FeedSubscription_.category)); + query.where(sub.category.isNull()); } else { - p2 = builder.equal(root.get(FeedSubscription_.category).get(FeedCategory_.id), category.getId()); - + query.where(sub.category.eq(category)); } - - query.where(p1, p2); - - List list = cache(em.createQuery(query)).getResultList(); - initRelations(list); - return list; + return initRelations(query.list(sub)); } public List findByCategories(User user, List categories) { - List categoryIds = Lists.transform(categories, new Function() { @Override public Long apply(FeedCategory input) { @@ -122,16 +71,18 @@ public class FeedSubscriptionDAO extends GenericDAO { return subscriptions; } - private void initRelations(List list) { + private List initRelations(List list) { for (FeedSubscription sub : list) { initRelations(sub); } + return list; } - private void initRelations(FeedSubscription sub) { + private FeedSubscription initRelations(FeedSubscription sub) { if (sub != null) { Models.initialize(sub.getFeed()); Models.initialize(sub.getCategory()); } + return sub; } } diff --git a/src/main/java/com/commafeed/backend/dao/GenericDAO.java b/src/main/java/com/commafeed/backend/dao/GenericDAO.java index 51076386..f773fd79 100644 --- a/src/main/java/com/commafeed/backend/dao/GenericDAO.java +++ b/src/main/java/com/commafeed/backend/dao/GenericDAO.java @@ -1,160 +1,59 @@ package com.commafeed.backend.dao; -import java.util.Arrays; +import io.dropwizard.hibernate.AbstractDAO; + import java.util.Collection; -import java.util.List; -import javax.annotation.PostConstruct; -import javax.persistence.EntityManager; -import javax.persistence.PersistenceContext; -import javax.persistence.TypedQuery; -import javax.persistence.criteria.CriteriaBuilder; -import javax.persistence.criteria.CriteriaQuery; -import javax.persistence.criteria.Root; -import javax.persistence.metamodel.Attribute; - -import org.hibernate.Query; -import org.hibernate.Session; +import org.hibernate.SessionFactory; import com.commafeed.backend.model.AbstractModel; -import com.google.common.reflect.TypeToken; +import com.mysema.query.jpa.hibernate.HibernateQuery; -@SuppressWarnings("serial") -public abstract class GenericDAO { +public abstract class GenericDAO extends AbstractDAO { - private TypeToken type = new TypeToken(getClass()) { - }; - - @PersistenceContext - protected EntityManager em; - - protected CriteriaBuilder builder; - - @PostConstruct - public void init() { - builder = em.getCriteriaBuilder(); + public GenericDAO(SessionFactory sessionFactory) { + super(sessionFactory); } - public Session getSession() { - Session session = em.unwrap(Session.class); - return session; + protected HibernateQuery newQuery() { + return new HibernateQuery(currentSession()); } - public void saveOrUpdate(Collection models) { - Session session = getSession(); - int i = 1; - for (AbstractModel model : models) { - session.saveOrUpdate(model); - if (i % 50 == 0) { - session.flush(); - session.clear(); - } + public void saveOrUpdate(T model) { + persist(model); + } + + public void saveOrUpdate(Collection models) { + for (T model : models) { + persist(model); } } - public void saveOrUpdate(AbstractModel... models) { - saveOrUpdate(Arrays.asList(models)); + public void merge(T model) { + currentSession().merge(model); } - public void delete(AbstractModel object) { - if (object != null) { - object = em.merge(object); - em.remove(object); - } - } - - public int delete(Collection objects) { - for (AbstractModel object : objects) { - delete(object); - } - return objects.size(); - } - - public void deleteById(Long id) { - Object ref = em.getReference(getType(), id); - if (ref != null) { - em.remove(ref); + public void merge(Collection models) { + for (T model : models) { + merge(model); } } public T findById(Long id) { - T t = em.find(getType(), id); - return t; + return get(id); } - public List findAll() { - CriteriaQuery query = builder.createQuery(getType()); - query.from(getType()); - return em.createQuery(query).getResultList(); - } - - public List findAll(int startIndex, int count) { - CriteriaQuery query = builder.createQuery(getType()); - query.from(getType()); - TypedQuery q = em.createQuery(query); - q.setMaxResults(count); - q.setFirstResult(startIndex); - return q.getResultList(); - } - - public List findAll(int startIndex, int count, String orderBy, boolean asc) { - - CriteriaQuery query = builder.createQuery(getType()); - Root root = query.from(getType()); - - if (asc) { - query.orderBy(builder.asc(root.get(orderBy))); - } else { - query.orderBy(builder.desc(root.get(orderBy))); - } - - TypedQuery q = em.createQuery(query); - q.setMaxResults(count); - q.setFirstResult(startIndex); - return q.getResultList(); - } - - public long getCount() { - CriteriaBuilder builder = em.getCriteriaBuilder(); - CriteriaQuery query = builder.createQuery(Long.class); - Root root = query.from(getType()); - query.select(builder.count(root)); - return em.createQuery(query).getSingleResult(); - } - - protected List findByField(Attribute field, V value) { - return findByField(field, value, false); - } - - protected List findByField(Attribute field, V value, boolean cache) { - CriteriaQuery query = builder.createQuery(getType()); - Root root = query.from(getType()); - - query.where(builder.equal(root.get(field.getName()), value)); - TypedQuery q = em.createQuery(query); - if (cache) { - cache(q); - } - return em.createQuery(query).getResultList(); - } - - protected void limit(TypedQuery query, int offset, int limit) { - if (offset > -1) { - query.setFirstResult(offset); - } - if (limit > -1) { - query.setMaxResults(limit); + public void delete(T object) { + if (object != null) { + currentSession().delete(object); } } - protected TypedQuery readOnly(TypedQuery query) { - query.unwrap(Query.class).setReadOnly(true); - return query; - } - - protected TypedQuery cache(TypedQuery query) { - query.unwrap(Query.class).setCacheable(true); - return query; + public int delete(Collection objects) { + for (T object : objects) { + delete(object); + } + return objects.size(); } protected void setTimeout(javax.persistence.Query query, int queryTimeout) { @@ -162,9 +61,4 @@ public abstract class GenericDAO { query.setHint("javax.persistence.query.timeout", queryTimeout); } } - - @SuppressWarnings("unchecked") - protected Class getType() { - return (Class) type.getRawType(); - } } diff --git a/src/main/java/com/commafeed/backend/dao/UnitOfWork.java b/src/main/java/com/commafeed/backend/dao/UnitOfWork.java new file mode 100644 index 00000000..27f8d347 --- /dev/null +++ b/src/main/java/com/commafeed/backend/dao/UnitOfWork.java @@ -0,0 +1,60 @@ +package com.commafeed.backend.dao; + +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.Transaction; +import org.hibernate.context.internal.ManagedSessionContext; + +public abstract class UnitOfWork { + + private SessionFactory sessionFactory; + + public UnitOfWork(SessionFactory sessionFactory) { + this.sessionFactory = sessionFactory; + } + + protected abstract T runInSession() throws Exception; + + public T run() { + final Session session = sessionFactory.openSession(); + if (ManagedSessionContext.hasBind(sessionFactory)) { + throw new IllegalStateException("Already in a unit of work!"); + } + T t = null; + try { + ManagedSessionContext.bind(session); + session.beginTransaction(); + try { + t = runInSession(); + commitTransaction(session); + } catch (Exception e) { + rollbackTransaction(session); + this. rethrow(e); + } + } finally { + session.close(); + ManagedSessionContext.unbind(sessionFactory); + } + return t; + } + + private void rollbackTransaction(Session session) { + final Transaction txn = session.getTransaction(); + if (txn != null && txn.isActive()) { + txn.rollback(); + } + } + + private void commitTransaction(Session session) { + final Transaction txn = session.getTransaction(); + if (txn != null && txn.isActive()) { + txn.commit(); + } + } + + @SuppressWarnings("unchecked") + private void rethrow(Exception e) throws E { + throw (E) e; + } + +} diff --git a/src/main/java/com/commafeed/backend/dao/UserDAO.java b/src/main/java/com/commafeed/backend/dao/UserDAO.java index 0a9b24e7..a9ab20c5 100644 --- a/src/main/java/com/commafeed/backend/dao/UserDAO.java +++ b/src/main/java/com/commafeed/backend/dao/UserDAO.java @@ -1,68 +1,27 @@ package com.commafeed.backend.dao; -import javax.ejb.Stateless; -import javax.persistence.NoResultException; -import javax.persistence.TypedQuery; -import javax.persistence.criteria.CriteriaQuery; -import javax.persistence.criteria.Root; - -import org.apache.commons.lang3.StringUtils; +import org.hibernate.SessionFactory; +import com.commafeed.backend.model.QUser; import com.commafeed.backend.model.User; -import com.commafeed.backend.model.User_; -@Stateless public class UserDAO extends GenericDAO { + private QUser user = QUser.user; + + public UserDAO(SessionFactory sessionFactory) { + super(sessionFactory); + } + public User findByName(String name) { - - CriteriaQuery query = builder.createQuery(getType()); - Root root = query.from(getType()); - query.where(builder.equal(builder.lower(root.get(User_.name)), name.toLowerCase())); - TypedQuery q = em.createQuery(query); - cache(q); - - User user = null; - try { - user = q.getSingleResult(); - } catch (NoResultException e) { - user = null; - } - return user; + return newQuery().from(user).where(user.name.equalsIgnoreCase(name)).uniqueResult(user); } public User findByApiKey(String key) { - CriteriaQuery query = builder.createQuery(getType()); - Root root = query.from(getType()); - query.where(builder.equal(root.get(User_.apiKey), key)); - TypedQuery q = em.createQuery(query); - cache(q); - - User user = null; - try { - user = q.getSingleResult(); - } catch (NoResultException e) { - user = null; - } - return user; + return newQuery().from(user).where(user.apiKey.equalsIgnoreCase(key)).uniqueResult(user); } public User findByEmail(String email) { - if (StringUtils.isBlank(email)) { - return null; - } - CriteriaQuery query = builder.createQuery(getType()); - Root root = query.from(getType()); - query.where(builder.equal(root.get(User_.email), email)); - TypedQuery q = em.createQuery(query); - - User user = null; - try { - user = q.getSingleResult(); - } catch (NoResultException e) { - user = null; - } - return user; + return newQuery().from(user).where(user.email.equalsIgnoreCase(email)).uniqueResult(user); } - } diff --git a/src/main/java/com/commafeed/backend/dao/UserRoleDAO.java b/src/main/java/com/commafeed/backend/dao/UserRoleDAO.java index b4336a22..348c5954 100644 --- a/src/main/java/com/commafeed/backend/dao/UserRoleDAO.java +++ b/src/main/java/com/commafeed/backend/dao/UserRoleDAO.java @@ -3,38 +3,28 @@ package com.commafeed.backend.dao; import java.util.List; import java.util.Set; -import javax.ejb.Stateless; -import javax.persistence.criteria.CriteriaQuery; -import javax.persistence.criteria.JoinType; -import javax.persistence.criteria.Root; +import org.hibernate.SessionFactory; +import com.commafeed.backend.model.QUserRole; import com.commafeed.backend.model.User; import com.commafeed.backend.model.UserRole; import com.commafeed.backend.model.UserRole.Role; -import com.commafeed.backend.model.UserRole_; -import com.commafeed.backend.model.User_; import com.google.common.collect.Sets; -@Stateless public class UserRoleDAO extends GenericDAO { - @Override + private QUserRole role = QUserRole.userRole; + + public UserRoleDAO(SessionFactory sessionFactory) { + super(sessionFactory); + } + public List findAll() { - CriteriaQuery query = builder.createQuery(getType()); - Root root = query.from(getType()); - query.distinct(true); - - root.fetch(UserRole_.user, JoinType.LEFT); - - return em.createQuery(query).getResultList(); + return newQuery().from(role).leftJoin(role.user).fetch().distinct().list(role); } public List findAll(User user) { - CriteriaQuery query = builder.createQuery(getType()); - Root root = query.from(getType()); - - query.where(builder.equal(root.get(UserRole_.user).get(User_.id), user.getId())); - return cache(em.createQuery(query)).getResultList(); + return newQuery().from(role).where(role.user.eq(user)).distinct().list(role); } public Set findRoles(User user) { diff --git a/src/main/java/com/commafeed/backend/dao/UserSettingsDAO.java b/src/main/java/com/commafeed/backend/dao/UserSettingsDAO.java index 9c43586a..ac484dd8 100644 --- a/src/main/java/com/commafeed/backend/dao/UserSettingsDAO.java +++ b/src/main/java/com/commafeed/backend/dao/UserSettingsDAO.java @@ -1,31 +1,18 @@ package com.commafeed.backend.dao; -import javax.ejb.Stateless; -import javax.persistence.NoResultException; -import javax.persistence.criteria.CriteriaQuery; -import javax.persistence.criteria.Root; +import org.hibernate.SessionFactory; +import org.hibernate.criterion.Restrictions; import com.commafeed.backend.model.User; import com.commafeed.backend.model.UserSettings; -import com.commafeed.backend.model.UserSettings_; -import com.commafeed.backend.model.User_; -@Stateless public class UserSettingsDAO extends GenericDAO { + public UserSettingsDAO(SessionFactory sessionFactory) { + super(sessionFactory); + } + public UserSettings findByUser(User user) { - - CriteriaQuery query = builder.createQuery(getType()); - Root root = query.from(getType()); - - query.where(builder.equal(root.get(UserSettings_.user).get(User_.id), user.getId())); - - UserSettings settings = null; - try { - settings = cache(em.createQuery(query)).getSingleResult(); - } catch (NoResultException e) { - settings = null; - } - return settings; + return uniqueResult(criteria().add(Restrictions.eq("user", user))); } } diff --git a/src/main/java/com/commafeed/backend/feeds/FaviconFetcher.java b/src/main/java/com/commafeed/backend/feed/FaviconFetcher.java similarity index 95% rename from src/main/java/com/commafeed/backend/feeds/FaviconFetcher.java rename to src/main/java/com/commafeed/backend/feed/FaviconFetcher.java index cc243ddd..bd592de4 100644 --- a/src/main/java/com/commafeed/backend/feeds/FaviconFetcher.java +++ b/src/main/java/com/commafeed/backend/feed/FaviconFetcher.java @@ -1,13 +1,12 @@ -package com.commafeed.backend.feeds; +package com.commafeed.backend.feed; import java.util.Arrays; import java.util.List; -import javax.inject.Inject; - +import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang.StringUtils; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.select.Elements; @@ -20,6 +19,7 @@ import com.commafeed.backend.HttpGetter.HttpResult; * */ @Slf4j +@AllArgsConstructor public class FaviconFetcher { private static long MIN_ICON_LENGTH = 100; @@ -30,8 +30,7 @@ public class FaviconFetcher { "text/ico", "application/ico", "image/x-ms-bmp", "image/x-bmp", "image/gif", "image/png", "image/jpeg"); private static List ICON_MIMETYPE_BLACKLIST = Arrays.asList("application/xml", "text/html"); - @Inject - HttpGetter getter; + private final HttpGetter getter; public byte[] fetch(String url) { diff --git a/src/main/java/com/commafeed/backend/feeds/FeedFetcher.java b/src/main/java/com/commafeed/backend/feed/FeedFetcher.java similarity index 92% rename from src/main/java/com/commafeed/backend/feeds/FeedFetcher.java rename to src/main/java/com/commafeed/backend/feed/FeedFetcher.java index 822225a1..9754488e 100644 --- a/src/main/java/com/commafeed/backend/feeds/FeedFetcher.java +++ b/src/main/java/com/commafeed/backend/feed/FeedFetcher.java @@ -1,10 +1,9 @@ -package com.commafeed.backend.feeds; +package com.commafeed.backend.feed; import java.io.IOException; import java.util.Date; -import javax.inject.Inject; - +import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.codec.binary.StringUtils; @@ -21,13 +20,11 @@ import com.commafeed.backend.model.Feed; import com.sun.syndication.io.FeedException; @Slf4j +@AllArgsConstructor public class FeedFetcher { - @Inject - FeedParser parser; - - @Inject - HttpGetter getter; + private final FeedParser parser; + private final HttpGetter getter; public FetchedFeed fetch(String feedUrl, boolean extractFeedUrlFromHtml, String lastModified, String eTag, Date lastPublishedDate, String lastContentHash) throws FeedException, ClientProtocolException, IOException, NotModifiedException { diff --git a/src/main/java/com/commafeed/backend/feeds/FeedParser.java b/src/main/java/com/commafeed/backend/feed/FeedParser.java similarity index 96% rename from src/main/java/com/commafeed/backend/feeds/FeedParser.java rename to src/main/java/com/commafeed/backend/feed/FeedParser.java index f74284cb..549abedd 100644 --- a/src/main/java/com/commafeed/backend/feeds/FeedParser.java +++ b/src/main/java/com/commafeed/backend/feed/FeedParser.java @@ -1,4 +1,4 @@ -package com.commafeed.backend.feeds; +package com.commafeed.backend.feed; import java.io.StringReader; import java.text.DateFormat; diff --git a/src/main/java/com/commafeed/backend/feeds/FeedRefreshTaskGiver.java b/src/main/java/com/commafeed/backend/feed/FeedQueues.java similarity index 54% rename from src/main/java/com/commafeed/backend/feeds/FeedRefreshTaskGiver.java rename to src/main/java/com/commafeed/backend/feed/FeedQueues.java index cffb76f4..2cb72f7f 100644 --- a/src/main/java/com/commafeed/backend/feeds/FeedRefreshTaskGiver.java +++ b/src/main/java/com/commafeed/backend/feed/FeedQueues.java @@ -1,71 +1,41 @@ -package com.commafeed.backend.feeds; +package com.commafeed.backend.feed; import java.util.Date; import java.util.List; import java.util.Map; import java.util.Queue; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; -import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; -import lombok.extern.slf4j.Slf4j; - import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.lang.time.DateUtils; import com.codahale.metrics.Gauge; import com.codahale.metrics.Meter; import com.codahale.metrics.MetricRegistry; +import com.commafeed.CommaFeedConfiguration; import com.commafeed.backend.dao.FeedDAO; import com.commafeed.backend.model.Feed; -import com.commafeed.backend.services.ApplicationSettingsService; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Queues; -/** - * Infinite loop fetching feeds from the database and queuing them to the {@link FeedRefreshWorker} pool. Also handles feed database updates - * at the end of the cycle through {@link #giveBack(Feed)}. - * - */ -@ApplicationScoped -@Slf4j -public class FeedRefreshTaskGiver { +public class FeedQueues { - @Inject - FeedDAO feedDAO; - - @Inject - ApplicationSettingsService applicationSettingsService; - - @Inject - MetricRegistry metrics; - - @Inject - FeedRefreshWorker worker; - - private int backgroundThreads; + private final FeedDAO feedDAO; + private final CommaFeedConfiguration config; private Queue addQueue = Queues.newConcurrentLinkedQueue(); private Queue takeQueue = Queues.newConcurrentLinkedQueue(); private Queue giveBackQueue = Queues.newConcurrentLinkedQueue(); - private ExecutorService executor; - - private Meter feedRefreshed; - private Meter threadWaited; private Meter refill; - @PostConstruct - public void init() { - backgroundThreads = applicationSettingsService.get().getBackgroundThreads(); - executor = Executors.newFixedThreadPool(1); - feedRefreshed = metrics.meter(MetricRegistry.name(getClass(), "feedRefreshed")); - threadWaited = metrics.meter(MetricRegistry.name(getClass(), "threadWaited")); + @Inject + public FeedQueues(FeedDAO feedDAO, CommaFeedConfiguration config, MetricRegistry metrics) { + this.config = config; + this.feedDAO = feedDAO; + refill = metrics.meter(MetricRegistry.name(getClass(), "refill")); metrics.register(MetricRegistry.name(getClass(), "addQueue"), new Gauge() { @Override @@ -87,56 +57,10 @@ public class FeedRefreshTaskGiver { }); } - @PreDestroy - public void shutdown() { - executor.shutdownNow(); - while (!executor.isTerminated()) { - try { - Thread.sleep(100); - } catch (InterruptedException e) { - log.error("interrupted while waiting for threads to finish."); - } - } - } - - public void start() { - log.info("starting feed refresh task giver"); - executor.execute(new Runnable() { - @Override - public void run() { - try { - // sleeping for a little while, let everything settle - Thread.sleep(60000); - } catch (InterruptedException e) { - log.error("interrupted while sleeping"); - } - while (!executor.isShutdown()) { - try { - FeedRefreshContext context = take(); - if (context != null) { - feedRefreshed.mark(); - worker.updateFeed(context); - } else { - log.debug("nothing to do, sleeping for 15s"); - threadWaited.mark(); - try { - Thread.sleep(15000); - } catch (InterruptedException e) { - log.error("interrupted while sleeping"); - } - } - } catch (Exception e) { - log.error(e.getMessage(), e); - } - } - } - }); - } - /** * take a feed from the refresh queue */ - private FeedRefreshContext take() { + public synchronized FeedRefreshContext take() { FeedRefreshContext context = takeQueue.poll(); if (context == null) { @@ -146,15 +70,11 @@ public class FeedRefreshTaskGiver { return context; } - public Long getUpdatableCount() { - return feedDAO.getUpdatableCount(getLastLoginThreshold()); - } - /** * add a feed to the refresh queue */ public void add(Feed feed, boolean urgent) { - int refreshInterval = applicationSettingsService.get().getRefreshIntervalMinutes(); + int refreshInterval = config.getApplicationSettings().getRefreshIntervalMinutes(); if (feed.getLastUpdated() == null || feed.getLastUpdated().before(DateUtils.addMinutes(new Date(), -1 * refreshInterval))) { addQueue.add(new FeedRefreshContext(feed, urgent)); } @@ -167,7 +87,7 @@ public class FeedRefreshTaskGiver { refill.mark(); List contexts = Lists.newArrayList(); - int batchSize = Math.min(100, 3 * backgroundThreads); + int batchSize = Math.min(100, 3 * config.getApplicationSettings().getBackgroundThreads()); // add feeds we got from the add() method int addQueueSize = addQueue.size(); @@ -176,7 +96,7 @@ public class FeedRefreshTaskGiver { } // add feeds that are up to refresh from the database - if (!applicationSettingsService.get().isCrawlingPaused()) { + if (!config.getApplicationSettings().isCrawlingPaused()) { int count = batchSize - contexts.size(); if (count > 0) { List feeds = feedDAO.findNextUpdatable(count, getLastLoginThreshold()); @@ -186,12 +106,12 @@ public class FeedRefreshTaskGiver { } } - // set the disabledDate to now as we use the disabledDate in feedDAO to decide what to refresh next. We also use a map to remove + // set the disabledDate as we use it in feedDAO to decide what to refresh next. We also use a map to remove // duplicates. Map map = Maps.newLinkedHashMap(); for (FeedRefreshContext context : contexts) { Feed feed = context.getFeed(); - feed.setDisabledUntil(new Date()); + feed.setDisabledUntil(DateUtils.addMinutes(new Date(), config.getApplicationSettings().getRefreshIntervalMinutes())); map.put(feed.getId(), context); } @@ -210,7 +130,7 @@ public class FeedRefreshTaskGiver { for (FeedRefreshContext context : map.values()) { feeds.add(context.getFeed()); } - feedDAO.saveOrUpdate(feeds); + feedDAO.merge(feeds); } /** @@ -225,7 +145,7 @@ public class FeedRefreshTaskGiver { } private Date getLastLoginThreshold() { - if (applicationSettingsService.get().isHeavyLoad()) { + if (config.getApplicationSettings().isHeavyLoad()) { return DateUtils.addDays(new Date(), -30); } else { return null; diff --git a/src/main/java/com/commafeed/backend/feeds/FeedRefreshContext.java b/src/main/java/com/commafeed/backend/feed/FeedRefreshContext.java similarity index 89% rename from src/main/java/com/commafeed/backend/feeds/FeedRefreshContext.java rename to src/main/java/com/commafeed/backend/feed/FeedRefreshContext.java index 5627a67c..f2769b64 100644 --- a/src/main/java/com/commafeed/backend/feeds/FeedRefreshContext.java +++ b/src/main/java/com/commafeed/backend/feed/FeedRefreshContext.java @@ -1,4 +1,4 @@ -package com.commafeed.backend.feeds; +package com.commafeed.backend.feed; import java.util.List; diff --git a/src/main/java/com/commafeed/backend/feeds/FeedRefreshExecutor.java b/src/main/java/com/commafeed/backend/feed/FeedRefreshExecutor.java similarity index 95% rename from src/main/java/com/commafeed/backend/feeds/FeedRefreshExecutor.java rename to src/main/java/com/commafeed/backend/feed/FeedRefreshExecutor.java index 13718c26..b1f7f597 100644 --- a/src/main/java/com/commafeed/backend/feeds/FeedRefreshExecutor.java +++ b/src/main/java/com/commafeed/backend/feed/FeedRefreshExecutor.java @@ -1,4 +1,4 @@ -package com.commafeed.backend.feeds; +package com.commafeed.backend.feed; import java.util.concurrent.LinkedBlockingDeque; import java.util.concurrent.RejectedExecutionHandler; diff --git a/src/main/java/com/commafeed/backend/feed/FeedRefreshTaskGiver.java b/src/main/java/com/commafeed/backend/feed/FeedRefreshTaskGiver.java new file mode 100644 index 00000000..73b8952f --- /dev/null +++ b/src/main/java/com/commafeed/backend/feed/FeedRefreshTaskGiver.java @@ -0,0 +1,95 @@ +package com.commafeed.backend.feed; + +import io.dropwizard.lifecycle.Managed; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import javax.inject.Inject; + +import lombok.extern.slf4j.Slf4j; + +import org.hibernate.SessionFactory; + +import com.codahale.metrics.Meter; +import com.codahale.metrics.MetricRegistry; +import com.commafeed.CommaFeedConfiguration; +import com.commafeed.backend.dao.FeedDAO; +import com.commafeed.backend.dao.UnitOfWork; + +/** + * Infinite loop fetching feeds from @FeedQueues and queuing them to the {@link FeedRefreshWorker} pool. + * + */ +@Slf4j +public class FeedRefreshTaskGiver implements Managed { + + private final SessionFactory sessionFactory; + private final FeedQueues queues; + private final FeedRefreshWorker worker; + + private ExecutorService executor; + + private Meter feedRefreshed; + private Meter threadWaited; + + @Inject + public FeedRefreshTaskGiver(SessionFactory sessionFactory, FeedQueues queues, FeedDAO feedDAO, FeedRefreshWorker worker, + CommaFeedConfiguration config, MetricRegistry metrics) { + this.sessionFactory = sessionFactory; + this.queues = queues; + this.worker = worker; + + executor = Executors.newFixedThreadPool(1); + feedRefreshed = metrics.meter(MetricRegistry.name(getClass(), "feedRefreshed")); + threadWaited = metrics.meter(MetricRegistry.name(getClass(), "threadWaited")); + } + + @Override + public void stop() { + executor.shutdownNow(); + while (!executor.isTerminated()) { + try { + Thread.sleep(100); + } catch (InterruptedException e) { + log.error("interrupted while waiting for threads to finish."); + } + } + } + + @Override + public void start() { + log.info("starting feed refresh task giver"); + executor.execute(new Runnable() { + @Override + public void run() { + while (!executor.isShutdown()) { + try { + FeedRefreshContext context = new UnitOfWork(sessionFactory) { + @Override + protected FeedRefreshContext runInSession() throws Exception { + FeedRefreshContext context = queues.take(); + if (context != null) { + feedRefreshed.mark(); + worker.updateFeed(context); + } + return context; + } + }.run(); + if (context == null) { + log.debug("nothing to do, sleeping for 15s"); + threadWaited.mark(); + try { + Thread.sleep(15000); + } catch (InterruptedException e) { + log.error("interrupted while sleeping"); + } + } + } catch (Exception e) { + log.error(e.getMessage(), e); + } + } + } + }); + } +} diff --git a/src/main/java/com/commafeed/backend/feeds/FeedRefreshUpdater.java b/src/main/java/com/commafeed/backend/feed/FeedRefreshUpdater.java similarity index 71% rename from src/main/java/com/commafeed/backend/feeds/FeedRefreshUpdater.java rename to src/main/java/com/commafeed/backend/feed/FeedRefreshUpdater.java index a809d2b5..6fef2e48 100644 --- a/src/main/java/com/commafeed/backend/feeds/FeedRefreshUpdater.java +++ b/src/main/java/com/commafeed/backend/feed/FeedRefreshUpdater.java @@ -1,4 +1,6 @@ -package com.commafeed.backend.feeds; +package com.commafeed.backend.feed; + +import io.dropwizard.lifecycle.Managed; import java.util.Arrays; import java.util.Date; @@ -7,67 +9,42 @@ import java.util.List; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Lock; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; -import javax.enterprise.context.ApplicationScoped; -import javax.inject.Inject; - import lombok.extern.slf4j.Slf4j; import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang.StringUtils; -import org.apache.commons.lang3.time.DateUtils; +import org.apache.commons.lang.time.DateUtils; +import org.hibernate.SessionFactory; import com.codahale.metrics.Meter; import com.codahale.metrics.MetricRegistry; +import com.commafeed.CommaFeedConfiguration; +import com.commafeed.CommaFeedConfiguration.ApplicationSettings; import com.commafeed.backend.cache.CacheService; -import com.commafeed.backend.dao.FeedDAO; -import com.commafeed.backend.dao.FeedEntryDAO; import com.commafeed.backend.dao.FeedSubscriptionDAO; -import com.commafeed.backend.feeds.FeedRefreshExecutor.Task; -import com.commafeed.backend.model.ApplicationSettings; +import com.commafeed.backend.dao.UnitOfWork; +import com.commafeed.backend.feed.FeedRefreshExecutor.Task; import com.commafeed.backend.model.Feed; import com.commafeed.backend.model.FeedEntry; import com.commafeed.backend.model.FeedEntryContent; import com.commafeed.backend.model.FeedSubscription; import com.commafeed.backend.model.User; -import com.commafeed.backend.pubsubhubbub.SubscriptionHandler; -import com.commafeed.backend.services.ApplicationSettingsService; -import com.commafeed.backend.services.FeedUpdateService; +import com.commafeed.backend.service.FeedUpdateService; +import com.commafeed.backend.service.PubSubService; import com.google.common.collect.Lists; import com.google.common.util.concurrent.Striped; -@ApplicationScoped @Slf4j -public class FeedRefreshUpdater { +public class FeedRefreshUpdater implements Managed { - @Inject - FeedUpdateService feedUpdateService; - - @Inject - SubscriptionHandler handler; - - @Inject - FeedRefreshTaskGiver taskGiver; - - @Inject - FeedDAO feedDAO; - - @Inject - ApplicationSettingsService applicationSettingsService; - - @Inject - MetricRegistry metrics; - - @Inject - FeedSubscriptionDAO feedSubscriptionDAO; - - @Inject - FeedEntryDAO feedEntryDAO; - - @Inject - CacheService cache; + private final SessionFactory sessionFactory; + private final FeedUpdateService feedUpdateService; + private final PubSubService pubSubService; + private final FeedQueues queues; + private final CommaFeedConfiguration config; + private final FeedSubscriptionDAO feedSubscriptionDAO; + private final CacheService cache; private FeedRefreshExecutor pool; private Striped locks; @@ -77,9 +54,18 @@ public class FeedRefreshUpdater { private Meter feedUpdated; private Meter entryInserted; - @PostConstruct - public void init() { - ApplicationSettings settings = applicationSettingsService.get(); + public FeedRefreshUpdater(SessionFactory sessionFactory, FeedUpdateService feedUpdateService, PubSubService pubSubService, + FeedQueues queues, CommaFeedConfiguration config, MetricRegistry metrics, FeedSubscriptionDAO feedSubscriptionDAO, + CacheService cache) { + this.sessionFactory = sessionFactory; + this.feedUpdateService = feedUpdateService; + this.pubSubService = pubSubService; + this.queues = queues; + this.config = config; + this.feedSubscriptionDAO = feedSubscriptionDAO; + this.cache = cache; + + ApplicationSettings settings = config.getApplicationSettings(); int threads = Math.max(settings.getDatabaseUpdateThreads(), 1); pool = new FeedRefreshExecutor("feed-refresh-updater", threads, Math.min(50 * threads, 1000), metrics); locks = Striped.lazyWeakLock(threads * 100000); @@ -90,8 +76,12 @@ public class FeedRefreshUpdater { entryInserted = metrics.meter(MetricRegistry.name(getClass(), "entryInserted")); } - @PreDestroy - public void shutdown() { + @Override + public void start() throws Exception { + } + + @Override + public void stop() throws Exception { pool.shutdown(); } @@ -109,6 +99,16 @@ public class FeedRefreshUpdater { @Override public void run() { + new UnitOfWork(sessionFactory) { + @Override + protected Void runInSession() throws Exception { + internalRun(); + return null; + } + }.run(); + } + + public void internalRun() { boolean ok = true; Feed feed = context.getFeed(); List entries = context.getEntries(); @@ -151,7 +151,7 @@ public class FeedRefreshUpdater { } } - if (applicationSettingsService.get().isPubsubhubbub()) { + if (config.getApplicationSettings().isPubsubhubbub()) { handlePubSub(feed); } if (!ok) { @@ -159,7 +159,7 @@ public class FeedRefreshUpdater { feed.setDisabledUntil(new Date(0)); } feedUpdated.mark(); - taskGiver.giveBack(feed); + queues.giveBack(feed); } @Override @@ -218,10 +218,11 @@ public class FeedRefreshUpdater { new Thread() { @Override public void run() { - handler.subscribe(feed); + pubSubService.subscribe(feed); } }.start(); } } } + } diff --git a/src/main/java/com/commafeed/backend/feeds/FeedRefreshWorker.java b/src/main/java/com/commafeed/backend/feed/FeedRefreshWorker.java similarity index 72% rename from src/main/java/com/commafeed/backend/feeds/FeedRefreshWorker.java rename to src/main/java/com/commafeed/backend/feed/FeedRefreshWorker.java index f1c2bfa4..b846d10e 100644 --- a/src/main/java/com/commafeed/backend/feeds/FeedRefreshWorker.java +++ b/src/main/java/com/commafeed/backend/feed/FeedRefreshWorker.java @@ -1,62 +1,53 @@ -package com.commafeed.backend.feeds; +package com.commafeed.backend.feed; + +import io.dropwizard.lifecycle.Managed; import java.util.Date; import java.util.List; -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; -import javax.enterprise.context.ApplicationScoped; -import javax.inject.Inject; - import lombok.extern.slf4j.Slf4j; import org.apache.commons.codec.digest.DigestUtils; +import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.time.DateUtils; -import org.apache.commons.lang3.ObjectUtils; -import org.apache.commons.lang3.StringUtils; import com.codahale.metrics.MetricRegistry; +import com.commafeed.CommaFeedConfiguration; import com.commafeed.backend.HttpGetter.NotModifiedException; -import com.commafeed.backend.feeds.FeedRefreshExecutor.Task; -import com.commafeed.backend.model.ApplicationSettings; +import com.commafeed.backend.feed.FeedRefreshExecutor.Task; import com.commafeed.backend.model.Feed; import com.commafeed.backend.model.FeedEntry; -import com.commafeed.backend.services.ApplicationSettingsService; +import com.google.common.base.Optional; /** * Calls {@link FeedFetcher} and handles its outcome * */ -@ApplicationScoped @Slf4j -public class FeedRefreshWorker { +public class FeedRefreshWorker implements Managed { - @Inject - FeedRefreshUpdater feedRefreshUpdater; + private final FeedRefreshUpdater feedRefreshUpdater; + private final FeedFetcher fetcher; + private final FeedQueues queues; + private final CommaFeedConfiguration config; + private final FeedRefreshExecutor pool; - @Inject - FeedFetcher fetcher; - - @Inject - FeedRefreshTaskGiver taskGiver; - - @Inject - MetricRegistry metrics; - - @Inject - ApplicationSettingsService applicationSettingsService; - - private FeedRefreshExecutor pool; - - @PostConstruct - private void init() { - ApplicationSettings settings = applicationSettingsService.get(); - int threads = settings.getBackgroundThreads(); + public FeedRefreshWorker(FeedRefreshUpdater feedRefreshUpdater, FeedFetcher fetcher, FeedQueues queues, CommaFeedConfiguration config, + MetricRegistry metrics) { + this.feedRefreshUpdater = feedRefreshUpdater; + this.fetcher = fetcher; + this.config = config; + this.queues = queues; + int threads = config.getApplicationSettings().getBackgroundThreads(); pool = new FeedRefreshExecutor("feed-refresh-worker", threads, Math.min(20 * threads, 1000), metrics); } - @PreDestroy - public void shutdown() { + @Override + public void start() throws Exception { + } + + @Override + public void stop() throws Exception { pool.shutdown(); } @@ -85,16 +76,16 @@ public class FeedRefreshWorker { private void update(FeedRefreshContext context) { Feed feed = context.getFeed(); - int refreshInterval = applicationSettingsService.get().getRefreshIntervalMinutes(); + int refreshInterval = config.getApplicationSettings().getRefreshIntervalMinutes(); Date disabledUntil = DateUtils.addMinutes(new Date(), refreshInterval); try { - String url = ObjectUtils.firstNonNull(feed.getUrlAfterRedirect(), feed.getUrl()); + String url = Optional.fromNullable(feed.getUrlAfterRedirect()).or(feed.getUrl()); FetchedFeed fetchedFeed = fetcher.fetch(url, false, feed.getLastModifiedHeader(), feed.getEtagHeader(), feed.getLastPublishedDate(), feed.getLastContentHash()); // stops here if NotModifiedException or any other exception is thrown List entries = fetchedFeed.getEntries(); - if (applicationSettingsService.get().isHeavyLoad()) { + if (config.getApplicationSettings().isHeavyLoad()) { disabledUntil = FeedUtils.buildDisabledUntil(fetchedFeed.getFeed().getLastEntryDate(), fetchedFeed.getFeed() .getAverageEntryInterval(), disabledUntil); } @@ -122,14 +113,14 @@ public class FeedRefreshWorker { } catch (NotModifiedException e) { log.debug("Feed not modified : {} - {}", feed.getUrl(), e.getMessage()); - if (applicationSettingsService.get().isHeavyLoad()) { + if (config.getApplicationSettings().isHeavyLoad()) { disabledUntil = FeedUtils.buildDisabledUntil(feed.getLastEntryDate(), feed.getAverageEntryInterval(), disabledUntil); } feed.setErrorCount(0); feed.setMessage(e.getMessage()); feed.setDisabledUntil(disabledUntil); - taskGiver.giveBack(feed); + queues.giveBack(feed); } catch (Exception e) { String message = "Unable to refresh feed " + feed.getUrl() + " : " + e.getMessage(); log.debug(e.getClass().getName() + " " + message, e); @@ -138,7 +129,7 @@ public class FeedRefreshWorker { feed.setMessage(message); feed.setDisabledUntil(FeedUtils.buildDisabledUntil(feed.getErrorCount())); - taskGiver.giveBack(feed); + queues.giveBack(feed); } } diff --git a/src/main/java/com/commafeed/backend/feeds/FeedUtils.java b/src/main/java/com/commafeed/backend/feed/FeedUtils.java similarity index 93% rename from src/main/java/com/commafeed/backend/feeds/FeedUtils.java rename to src/main/java/com/commafeed/backend/feed/FeedUtils.java index f2be6a7a..daa1b986 100644 --- a/src/main/java/com/commafeed/backend/feeds/FeedUtils.java +++ b/src/main/java/com/commafeed/backend/feed/FeedUtils.java @@ -1,4 +1,4 @@ -package com.commafeed.backend.feeds; +package com.commafeed.backend.feed; import java.io.StringReader; import java.net.MalformedURLException; @@ -15,9 +15,8 @@ import lombok.extern.slf4j.Slf4j; import org.apache.commons.codec.binary.Base64; import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.StringUtils; -import org.apache.commons.lang3.time.DateUtils; +import org.apache.commons.lang.time.DateUtils; import org.apache.commons.math.stat.descriptive.SummaryStatistics; -import org.apache.wicket.request.UrlUtils; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.nodes.Document.OutputSettings; @@ -129,10 +128,10 @@ public class FeedUtils { } return encoding; } - - public static String replaceHtmlEntitiesWithNumericEntities(String source){ + + public static String replaceHtmlEntitiesWithNumericEntities(String source) { String result = source; - for(String entity : HtmlEntities.NUMERIC_MAPPING.keySet()){ + for (String entity : HtmlEntities.NUMERIC_MAPPING.keySet()) { result = result.replace(entity, HtmlEntities.NUMERIC_MAPPING.get(entity)); } return result; @@ -422,7 +421,7 @@ public class FeedUtils { return url; } - String baseUrl = (feedLink == null || UrlUtils.isRelative(feedLink)) ? feedUrl : feedLink; + String baseUrl = (feedLink == null || isRelative(feedLink)) ? feedUrl : feedLink; if (baseUrl == null) { return url; @@ -439,6 +438,15 @@ public class FeedUtils { return result; } + public static boolean isRelative(final String url) { + // the regex means "doesn't start with 'scheme://'" + if ((url != null) && (url.startsWith("/") == false) && (!url.matches("^\\w+\\:\\/\\/.*")) && !(url.startsWith("#"))) { + return true; + } else { + return false; + } + } + public static String getFaviconUrl(FeedSubscription subscription, String publicUrl) { return removeTrailingSlash(publicUrl) + "/rest/feed/favicon/" + subscription.getId(); } diff --git a/src/main/java/com/commafeed/backend/feeds/FetchedFeed.java b/src/main/java/com/commafeed/backend/feed/FetchedFeed.java similarity index 91% rename from src/main/java/com/commafeed/backend/feeds/FetchedFeed.java rename to src/main/java/com/commafeed/backend/feed/FetchedFeed.java index ae0148be..e538b686 100644 --- a/src/main/java/com/commafeed/backend/feeds/FetchedFeed.java +++ b/src/main/java/com/commafeed/backend/feed/FetchedFeed.java @@ -1,4 +1,4 @@ -package com.commafeed.backend.feeds; +package com.commafeed.backend.feed; import java.util.List; diff --git a/src/main/java/com/commafeed/backend/feeds/HtmlEntities.java b/src/main/java/com/commafeed/backend/feed/HtmlEntities.java similarity index 96% rename from src/main/java/com/commafeed/backend/feeds/HtmlEntities.java rename to src/main/java/com/commafeed/backend/feed/HtmlEntities.java index 608d7152..686bde10 100644 --- a/src/main/java/com/commafeed/backend/feeds/HtmlEntities.java +++ b/src/main/java/com/commafeed/backend/feed/HtmlEntities.java @@ -1,4 +1,4 @@ -package com.commafeed.backend.feeds; +package com.commafeed.backend.feed; import java.util.Collections; import java.util.Map; diff --git a/src/main/java/com/commafeed/backend/metrics/MetricRegistryProducer.java b/src/main/java/com/commafeed/backend/metrics/MetricRegistryProducer.java deleted file mode 100644 index 408a426c..00000000 --- a/src/main/java/com/commafeed/backend/metrics/MetricRegistryProducer.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.commafeed.backend.metrics; - -import javax.annotation.PostConstruct; -import javax.enterprise.context.ApplicationScoped; -import javax.enterprise.inject.Produces; - -import lombok.extern.slf4j.Slf4j; - -import com.codahale.metrics.JmxReporter; -import com.codahale.metrics.MetricRegistry; - -@ApplicationScoped -@Slf4j -public class MetricRegistryProducer { - - private MetricRegistry registry; - - @PostConstruct - private void init() { - log.info("initializing metrics registry"); - registry = new MetricRegistry(); - JmxReporter.forRegistry(registry).build().start(); - log.info("metrics registry initialized"); - } - - @Produces - public MetricRegistry produceMetricsRegistry() { - return registry; - } -} diff --git a/src/main/java/com/commafeed/backend/model/ApplicationSettings.java b/src/main/java/com/commafeed/backend/model/ApplicationSettings.java deleted file mode 100644 index 7d015166..00000000 --- a/src/main/java/com/commafeed/backend/model/ApplicationSettings.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.commafeed.backend.model; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Table; - -import lombok.Getter; -import lombok.Setter; - -import org.apache.log4j.Level; - -@Entity -@Table(name = "APPLICATIONSETTINGS") -@SuppressWarnings("serial") -@Getter -@Setter -public class ApplicationSettings extends AbstractModel { - - private String publicUrl; - private boolean allowRegistrations = false; - private String googleAnalyticsTrackingCode; - private String googleClientId; - private String googleClientSecret; - private int backgroundThreads = 3; - private int databaseUpdateThreads = 1; - private String smtpHost; - private int smtpPort; - private boolean smtpTls; - private String smtpUserName; - private String smtpPassword; - private boolean heavyLoad; - private boolean pubsubhubbub; - private boolean feedbackButton = true; - private String logLevel = Level.INFO.toString(); - private boolean imageProxyEnabled; - private int queryTimeout; - private boolean crawlingPaused; - private int keepStatusDays = 0; - private int refreshIntervalMinutes = 5; - @Column(length = 255) - private String announcement; - -} diff --git a/src/main/java/com/commafeed/backend/model/Feed.java b/src/main/java/com/commafeed/backend/model/Feed.java index 51771b7c..8c15a670 100644 --- a/src/main/java/com/commafeed/backend/model/Feed.java +++ b/src/main/java/com/commafeed/backend/model/Feed.java @@ -3,7 +3,6 @@ package com.commafeed.backend.model; import java.util.Date; import java.util.Set; -import javax.persistence.Cacheable; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; @@ -15,14 +14,9 @@ import javax.persistence.TemporalType; import lombok.Getter; import lombok.Setter; -import org.hibernate.annotations.Cache; -import org.hibernate.annotations.CacheConcurrencyStrategy; - @Entity @Table(name = "FEEDS") @SuppressWarnings("serial") -@Cacheable -@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL) @Getter @Setter public class Feed extends AbstractModel { diff --git a/src/main/java/com/commafeed/backend/model/FeedCategory.java b/src/main/java/com/commafeed/backend/model/FeedCategory.java index 8ef1bc35..e16b53e0 100644 --- a/src/main/java/com/commafeed/backend/model/FeedCategory.java +++ b/src/main/java/com/commafeed/backend/model/FeedCategory.java @@ -2,7 +2,6 @@ package com.commafeed.backend.model; import java.util.Set; -import javax.persistence.Cacheable; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; @@ -14,14 +13,9 @@ import javax.persistence.Table; import lombok.Getter; import lombok.Setter; -import org.hibernate.annotations.Cache; -import org.hibernate.annotations.CacheConcurrencyStrategy; - @Entity @Table(name = "FEEDCATEGORIES") @SuppressWarnings("serial") -@Cacheable -@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL) @Getter @Setter public class FeedCategory extends AbstractModel { @@ -31,11 +25,9 @@ public class FeedCategory extends AbstractModel { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(nullable = false) - @Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL) private User user; @ManyToOne(fetch = FetchType.LAZY) - @Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL) private FeedCategory parent; @OneToMany(mappedBy = "parent") diff --git a/src/main/java/com/commafeed/backend/model/FeedEntry.java b/src/main/java/com/commafeed/backend/model/FeedEntry.java index 3d8532bf..68061118 100644 --- a/src/main/java/com/commafeed/backend/model/FeedEntry.java +++ b/src/main/java/com/commafeed/backend/model/FeedEntry.java @@ -3,7 +3,6 @@ package com.commafeed.backend.model; import java.util.Date; import java.util.Set; -import javax.persistence.Cacheable; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; @@ -19,14 +18,9 @@ import javax.persistence.TemporalType; import lombok.Getter; import lombok.Setter; -import org.hibernate.annotations.Cache; -import org.hibernate.annotations.CacheConcurrencyStrategy; - @Entity @Table(name = "FEEDENTRIES") @SuppressWarnings("serial") -@Cacheable -@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL) @Getter @Setter public class FeedEntry extends AbstractModel { @@ -55,7 +49,7 @@ public class FeedEntry extends AbstractModel { @OneToMany(mappedBy = "entry", cascade = CascadeType.REMOVE) private Set statuses; - + @OneToMany(mappedBy = "entry", cascade = CascadeType.REMOVE) private Set tags; diff --git a/src/main/java/com/commafeed/backend/model/FeedEntryContent.java b/src/main/java/com/commafeed/backend/model/FeedEntryContent.java index 40f80f71..a1398b7d 100644 --- a/src/main/java/com/commafeed/backend/model/FeedEntryContent.java +++ b/src/main/java/com/commafeed/backend/model/FeedEntryContent.java @@ -2,7 +2,6 @@ package com.commafeed.backend.model; import java.util.Set; -import javax.persistence.Cacheable; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Lob; @@ -12,14 +11,9 @@ import javax.persistence.Table; import lombok.Getter; import lombok.Setter; -import org.hibernate.annotations.Cache; -import org.hibernate.annotations.CacheConcurrencyStrategy; - @Entity @Table(name = "FEEDENTRYCONTENTS") @SuppressWarnings("serial") -@Cacheable -@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL) @Getter @Setter public class FeedEntryContent extends AbstractModel { diff --git a/src/main/java/com/commafeed/backend/model/FeedEntryStatus.java b/src/main/java/com/commafeed/backend/model/FeedEntryStatus.java index 023b75c1..bafe6e52 100644 --- a/src/main/java/com/commafeed/backend/model/FeedEntryStatus.java +++ b/src/main/java/com/commafeed/backend/model/FeedEntryStatus.java @@ -3,7 +3,6 @@ package com.commafeed.backend.model; import java.util.Date; import java.util.List; -import javax.persistence.Cacheable; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; @@ -19,19 +18,16 @@ import javax.persistence.Transient; import lombok.Getter; import lombok.Setter; -import org.hibernate.annotations.Cache; -import org.hibernate.annotations.CacheConcurrencyStrategy; - import com.google.common.collect.Lists; @Entity @Table(name = "FEEDENTRYSTATUSES") @SuppressWarnings("serial") -@Cacheable -@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL) @Getter @Setter -@NamedQueries(@NamedQuery(name="Statuses.deleteOld", query="delete from FeedEntryStatus s where s.entryInserted < :date and s.starred = false")) +@NamedQueries(@NamedQuery( + name = "Statuses.deleteOld", + query = "delete from FeedEntryStatus s where s.entryInserted < :date and s.starred = false")) public class FeedEntryStatus extends AbstractModel { @ManyToOne(fetch = FetchType.LAZY) @@ -48,7 +44,7 @@ public class FeedEntryStatus extends AbstractModel { @Transient private boolean markable; - + @Transient private List tags = Lists.newArrayList(); diff --git a/src/main/java/com/commafeed/backend/model/FeedEntryTag.java b/src/main/java/com/commafeed/backend/model/FeedEntryTag.java index 76a12aed..ddf33ac7 100644 --- a/src/main/java/com/commafeed/backend/model/FeedEntryTag.java +++ b/src/main/java/com/commafeed/backend/model/FeedEntryTag.java @@ -1,6 +1,5 @@ package com.commafeed.backend.model; -import javax.persistence.Cacheable; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; @@ -11,14 +10,9 @@ import javax.persistence.Table; import lombok.Getter; import lombok.Setter; -import org.hibernate.annotations.Cache; -import org.hibernate.annotations.CacheConcurrencyStrategy; - @Entity @Table(name = "FEEDENTRYTAGS") @SuppressWarnings("serial") -@Cacheable -@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL) @Getter @Setter public class FeedEntryTag extends AbstractModel { diff --git a/src/main/java/com/commafeed/backend/model/FeedSubscription.java b/src/main/java/com/commafeed/backend/model/FeedSubscription.java index 9f2db975..363665eb 100644 --- a/src/main/java/com/commafeed/backend/model/FeedSubscription.java +++ b/src/main/java/com/commafeed/backend/model/FeedSubscription.java @@ -2,7 +2,6 @@ package com.commafeed.backend.model; import java.util.Set; -import javax.persistence.Cacheable; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; @@ -15,33 +14,25 @@ import javax.persistence.Table; import lombok.Getter; import lombok.Setter; -import org.hibernate.annotations.Cache; -import org.hibernate.annotations.CacheConcurrencyStrategy; - @Entity @Table(name = "FEEDSUBSCRIPTIONS") @SuppressWarnings("serial") -@Cacheable -@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL) @Getter @Setter public class FeedSubscription extends AbstractModel { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(nullable = false) - @Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL) private User user; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(nullable = false) - @Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL) private Feed feed; @Column(length = 128, nullable = false) private String title; @ManyToOne(fetch = FetchType.LAZY) - @Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL) private FeedCategory category; @OneToMany(mappedBy = "subscription", cascade = CascadeType.REMOVE) diff --git a/src/main/java/com/commafeed/backend/model/User.java b/src/main/java/com/commafeed/backend/model/User.java index 20cb6ddb..1b69d57e 100644 --- a/src/main/java/com/commafeed/backend/model/User.java +++ b/src/main/java/com/commafeed/backend/model/User.java @@ -3,7 +3,6 @@ package com.commafeed.backend.model; import java.util.Date; import java.util.Set; -import javax.persistence.Cacheable; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; @@ -16,23 +15,20 @@ import javax.persistence.TemporalType; import lombok.Getter; import lombok.Setter; -import org.hibernate.annotations.Cache; -import org.hibernate.annotations.CacheConcurrencyStrategy; +import org.hibernate.annotations.Cascade; import com.google.common.collect.Sets; @Entity @Table(name = "USERS") @SuppressWarnings("serial") -@Cacheable -@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL) @Getter @Setter public class User extends AbstractModel { @Column(length = 32, nullable = false, unique = true) private String name; - + @Column(length = 255, unique = true) private String email; @@ -61,6 +57,8 @@ public class User extends AbstractModel { private Date recoverPasswordTokenDate; @OneToMany(mappedBy = "user", cascade = { CascadeType.PERSIST, CascadeType.REMOVE }) + @Cascade({ org.hibernate.annotations.CascadeType.PERSIST, org.hibernate.annotations.CascadeType.SAVE_UPDATE, + org.hibernate.annotations.CascadeType.REMOVE }) private Set roles = Sets.newHashSet(); @OneToMany(mappedBy = "user", fetch = FetchType.LAZY, cascade = CascadeType.REMOVE) diff --git a/src/main/java/com/commafeed/backend/model/UserRole.java b/src/main/java/com/commafeed/backend/model/UserRole.java index e0cfbc26..bed925d5 100644 --- a/src/main/java/com/commafeed/backend/model/UserRole.java +++ b/src/main/java/com/commafeed/backend/model/UserRole.java @@ -1,6 +1,5 @@ package com.commafeed.backend.model; -import javax.persistence.Cacheable; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.EnumType; @@ -13,14 +12,9 @@ import javax.persistence.Table; import lombok.Getter; import lombok.Setter; -import org.hibernate.annotations.Cache; -import org.hibernate.annotations.CacheConcurrencyStrategy; - @Entity @Table(name = "USERROLES") @SuppressWarnings("serial") -@Cacheable -@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL) @Getter @Setter public class UserRole extends AbstractModel { diff --git a/src/main/java/com/commafeed/backend/model/UserSettings.java b/src/main/java/com/commafeed/backend/model/UserSettings.java index 7f66d049..70ee4418 100644 --- a/src/main/java/com/commafeed/backend/model/UserSettings.java +++ b/src/main/java/com/commafeed/backend/model/UserSettings.java @@ -1,6 +1,5 @@ package com.commafeed.backend.model; -import javax.persistence.Cacheable; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.EnumType; @@ -14,14 +13,9 @@ import javax.persistence.Table; import lombok.Getter; import lombok.Setter; -import org.hibernate.annotations.Cache; -import org.hibernate.annotations.CacheConcurrencyStrategy; - @Entity @Table(name = "USERSETTINGS") @SuppressWarnings("serial") -@Cacheable -@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL) @Getter @Setter public class UserSettings extends AbstractModel { @@ -69,7 +63,7 @@ public class UserSettings extends AbstractModel { @Column(name = "scroll_speed") private int scrollSpeed; - + private boolean email; private boolean gmail; private boolean facebook; diff --git a/src/main/java/com/commafeed/backend/opml/OPMLExporter.java b/src/main/java/com/commafeed/backend/opml/OPMLExporter.java index 309a1c9d..93287580 100644 --- a/src/main/java/com/commafeed/backend/opml/OPMLExporter.java +++ b/src/main/java/com/commafeed/backend/opml/OPMLExporter.java @@ -3,8 +3,7 @@ package com.commafeed.backend.opml; import java.util.Date; import java.util.List; -import javax.ejb.Stateless; -import javax.inject.Inject; +import lombok.AllArgsConstructor; import com.commafeed.backend.dao.FeedCategoryDAO; import com.commafeed.backend.dao.FeedSubscriptionDAO; @@ -15,14 +14,11 @@ import com.sun.syndication.feed.opml.Attribute; import com.sun.syndication.feed.opml.Opml; import com.sun.syndication.feed.opml.Outline; -@Stateless +@AllArgsConstructor public class OPMLExporter { - @Inject - FeedCategoryDAO feedCategoryDAO; - - @Inject - FeedSubscriptionDAO feedSubscriptionDAO; + private final FeedCategoryDAO feedCategoryDAO; + private final FeedSubscriptionDAO feedSubscriptionDAO; @SuppressWarnings("unchecked") public Opml export(User user) { diff --git a/src/main/java/com/commafeed/backend/opml/OPMLImporter.java b/src/main/java/com/commafeed/backend/opml/OPMLImporter.java index dffa7780..7dd8e30c 100644 --- a/src/main/java/com/commafeed/backend/opml/OPMLImporter.java +++ b/src/main/java/com/commafeed/backend/opml/OPMLImporter.java @@ -3,12 +3,6 @@ package com.commafeed.backend.opml; import java.io.StringReader; import java.util.List; -import javax.ejb.Asynchronous; -import javax.ejb.Stateless; -import javax.ejb.TransactionAttribute; -import javax.ejb.TransactionAttributeType; -import javax.inject.Inject; - import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections.CollectionUtils; @@ -16,37 +10,36 @@ import org.apache.commons.lang.StringUtils; import com.commafeed.backend.cache.CacheService; import com.commafeed.backend.dao.FeedCategoryDAO; -import com.commafeed.backend.feeds.FeedUtils; +import com.commafeed.backend.feed.FeedUtils; import com.commafeed.backend.model.FeedCategory; import com.commafeed.backend.model.User; -import com.commafeed.backend.services.FeedSubscriptionService; -import com.commafeed.backend.services.FeedSubscriptionService.FeedSubscriptionException; +import com.commafeed.backend.service.FeedSubscriptionService; +import com.commafeed.backend.service.FeedSubscriptionService.FeedSubscriptionException; import com.sun.syndication.feed.opml.Opml; import com.sun.syndication.feed.opml.Outline; import com.sun.syndication.io.WireFeedInput; -@Stateless -@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED) @Slf4j public class OPMLImporter { - @Inject - FeedSubscriptionService feedSubscriptionService; + private FeedCategoryDAO feedCategoryDAO; + private FeedSubscriptionService feedSubscriptionService; + private CacheService cache; - @Inject - FeedCategoryDAO feedCategoryDAO; - - @Inject - CacheService cache; + public OPMLImporter(FeedCategoryDAO feedCategoryDAO, FeedSubscriptionService feedSubscriptionService, CacheService cache) { + super(); + this.feedCategoryDAO = feedCategoryDAO; + this.feedSubscriptionService = feedSubscriptionService; + this.cache = cache; + } @SuppressWarnings("unchecked") - @Asynchronous public void importOpml(User user, String xml) { xml = xml.substring(xml.indexOf('<')); WireFeedInput input = new WireFeedInput(); try { Opml feed = (Opml) input.build(new StringReader(xml)); - List outlines = (List) feed.getOutlines(); + List outlines = feed.getOutlines(); for (Outline outline : outlines) { handleOutline(user, outline, null); } diff --git a/src/main/java/com/commafeed/backend/services/ApplicationPropertiesService.java b/src/main/java/com/commafeed/backend/service/ApplicationPropertiesService.java similarity index 63% rename from src/main/java/com/commafeed/backend/services/ApplicationPropertiesService.java rename to src/main/java/com/commafeed/backend/service/ApplicationPropertiesService.java index fc24b8f2..cd12c872 100644 --- a/src/main/java/com/commafeed/backend/services/ApplicationPropertiesService.java +++ b/src/main/java/com/commafeed/backend/service/ApplicationPropertiesService.java @@ -1,4 +1,4 @@ -package com.commafeed.backend.services; +package com.commafeed.backend.service; import java.util.ResourceBundle; @@ -6,13 +6,7 @@ public class ApplicationPropertiesService { private ResourceBundle bundle; - private static ApplicationPropertiesService INSTANCE = new ApplicationPropertiesService(); - - public static ApplicationPropertiesService get() { - return INSTANCE; - } - - private ApplicationPropertiesService() { + public ApplicationPropertiesService() { bundle = ResourceBundle.getBundle("application"); } diff --git a/src/main/java/com/commafeed/backend/services/DatabaseCleaningService.java b/src/main/java/com/commafeed/backend/service/DatabaseCleaningService.java similarity index 87% rename from src/main/java/com/commafeed/backend/services/DatabaseCleaningService.java rename to src/main/java/com/commafeed/backend/service/DatabaseCleaningService.java index 21239b8f..49cf21f2 100644 --- a/src/main/java/com/commafeed/backend/services/DatabaseCleaningService.java +++ b/src/main/java/com/commafeed/backend/service/DatabaseCleaningService.java @@ -1,4 +1,4 @@ -package com.commafeed.backend.services; +package com.commafeed.backend.service; import java.util.Calendar; import java.util.Collections; @@ -6,8 +6,7 @@ import java.util.Date; import java.util.List; import java.util.concurrent.TimeUnit; -import javax.inject.Inject; - +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import com.commafeed.backend.dao.FeedDAO; @@ -25,28 +24,17 @@ import com.commafeed.backend.model.FeedSubscription; * */ @Slf4j +@RequiredArgsConstructor public class DatabaseCleaningService { private static final int BATCH_SIZE = 100; - @Inject - FeedDAO feedDAO; + private final FeedDAO feedDAO; + private final FeedEntryDAO feedEntryDAO; + private final FeedEntryContentDAO feedEntryContentDAO; + private final FeedEntryStatusDAO feedEntryStatusDAO; + private final FeedSubscriptionDAO feedSubscriptionDAO; - @Inject - FeedEntryDAO feedEntryDAO; - - @Inject - FeedSubscriptionDAO feedSubscriptionDAO; - - @Inject - FeedEntryContentDAO feedEntryContentDAO; - - @Inject - FeedEntryStatusDAO feedEntryStatusDAO; - - @Inject - ApplicationSettingsService applicationSettingsService; - public long cleanEntriesWithoutSubscriptions() { log.info("cleaning entries without subscriptions"); long total = 0; diff --git a/src/main/java/com/commafeed/backend/services/FeedEntryContentService.java b/src/main/java/com/commafeed/backend/service/FeedEntryContentService.java similarity index 83% rename from src/main/java/com/commafeed/backend/services/FeedEntryContentService.java rename to src/main/java/com/commafeed/backend/service/FeedEntryContentService.java index ad86406f..8d63b073 100644 --- a/src/main/java/com/commafeed/backend/services/FeedEntryContentService.java +++ b/src/main/java/com/commafeed/backend/service/FeedEntryContentService.java @@ -1,18 +1,18 @@ -package com.commafeed.backend.services; +package com.commafeed.backend.service; -import javax.inject.Inject; +import lombok.RequiredArgsConstructor; import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.lang.StringUtils; import com.commafeed.backend.dao.FeedEntryContentDAO; -import com.commafeed.backend.feeds.FeedUtils; +import com.commafeed.backend.feed.FeedUtils; import com.commafeed.backend.model.FeedEntryContent; +@RequiredArgsConstructor public class FeedEntryContentService { - @Inject - FeedEntryContentDAO feedEntryContentDAO; + private final FeedEntryContentDAO feedEntryContentDAO; /** * this is NOT thread-safe diff --git a/src/main/java/com/commafeed/backend/services/FeedEntryService.java b/src/main/java/com/commafeed/backend/service/FeedEntryService.java similarity index 87% rename from src/main/java/com/commafeed/backend/services/FeedEntryService.java rename to src/main/java/com/commafeed/backend/service/FeedEntryService.java index f8a5cb56..0b644151 100644 --- a/src/main/java/com/commafeed/backend/services/FeedEntryService.java +++ b/src/main/java/com/commafeed/backend/service/FeedEntryService.java @@ -1,10 +1,9 @@ -package com.commafeed.backend.services; +package com.commafeed.backend.service; import java.util.Date; import java.util.List; -import javax.ejb.Stateless; -import javax.inject.Inject; +import lombok.RequiredArgsConstructor; import com.commafeed.backend.cache.CacheService; import com.commafeed.backend.dao.FeedEntryDAO; @@ -16,20 +15,13 @@ import com.commafeed.backend.model.FeedSubscription; import com.commafeed.backend.model.User; import com.google.common.collect.Lists; -@Stateless +@RequiredArgsConstructor public class FeedEntryService { - @Inject - FeedEntryStatusDAO feedEntryStatusDAO; - - @Inject - FeedSubscriptionDAO feedSubscriptionDAO; - - @Inject - FeedEntryDAO feedEntryDAO; - - @Inject - CacheService cache; + private final FeedSubscriptionDAO feedSubscriptionDAO; + private final FeedEntryDAO feedEntryDAO; + private final FeedEntryStatusDAO feedEntryStatusDAO; + private final CacheService cache; public void markEntry(User user, Long entryId, boolean read) { diff --git a/src/main/java/com/commafeed/backend/services/FeedEntryTagService.java b/src/main/java/com/commafeed/backend/service/FeedEntryTagService.java similarity index 84% rename from src/main/java/com/commafeed/backend/services/FeedEntryTagService.java rename to src/main/java/com/commafeed/backend/service/FeedEntryTagService.java index 9eccea24..f902aad8 100644 --- a/src/main/java/com/commafeed/backend/services/FeedEntryTagService.java +++ b/src/main/java/com/commafeed/backend/service/FeedEntryTagService.java @@ -1,10 +1,9 @@ -package com.commafeed.backend.services; +package com.commafeed.backend.service; import java.util.List; import java.util.Map; -import javax.ejb.Stateless; -import javax.inject.Inject; +import lombok.RequiredArgsConstructor; import com.commafeed.backend.dao.FeedEntryDAO; import com.commafeed.backend.dao.FeedEntryTagDAO; @@ -15,14 +14,11 @@ import com.google.common.base.Function; import com.google.common.collect.Lists; import com.google.common.collect.Maps; -@Stateless +@RequiredArgsConstructor public class FeedEntryTagService { - @Inject - FeedEntryDAO feedEntryDAO; - - @Inject - FeedEntryTagDAO feedEntryTagDAO; + private final FeedEntryDAO feedEntryDAO; + private final FeedEntryTagDAO feedEntryTagDAO; public void updateTags(User user, Long entryId, List tagNames) { FeedEntry entry = feedEntryDAO.findById(entryId); diff --git a/src/main/java/com/commafeed/backend/service/FeedService.java b/src/main/java/com/commafeed/backend/service/FeedService.java new file mode 100644 index 00000000..d2c71cce --- /dev/null +++ b/src/main/java/com/commafeed/backend/service/FeedService.java @@ -0,0 +1,32 @@ +package com.commafeed.backend.service; + +import java.util.Date; + +import lombok.RequiredArgsConstructor; + +import org.apache.commons.codec.digest.DigestUtils; + +import com.commafeed.backend.dao.FeedDAO; +import com.commafeed.backend.feed.FeedUtils; +import com.commafeed.backend.model.Feed; + +@RequiredArgsConstructor +public class FeedService { + + private final FeedDAO feedDAO; + + public synchronized Feed findOrCreate(String url) { + String normalized = FeedUtils.normalizeURL(url); + Feed feed = feedDAO.findByUrl(normalized); + if (feed == null) { + feed = new Feed(); + feed.setUrl(url); + feed.setNormalizedUrl(normalized); + feed.setNormalizedUrlHash(DigestUtils.sha1Hex(normalized)); + feed.setDisabledUntil(new Date(0)); + feedDAO.saveOrUpdate(feed); + } + return feed; + } + +} diff --git a/src/main/java/com/commafeed/backend/services/FeedSubscriptionService.java b/src/main/java/com/commafeed/backend/service/FeedSubscriptionService.java similarity index 75% rename from src/main/java/com/commafeed/backend/services/FeedSubscriptionService.java rename to src/main/java/com/commafeed/backend/service/FeedSubscriptionService.java index 79db77e3..1d77b668 100644 --- a/src/main/java/com/commafeed/backend/services/FeedSubscriptionService.java +++ b/src/main/java/com/commafeed/backend/service/FeedSubscriptionService.java @@ -1,21 +1,19 @@ -package com.commafeed.backend.services; +package com.commafeed.backend.service; import java.util.List; import java.util.Map; -import javax.ejb.ApplicationException; -import javax.inject.Inject; - +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang.StringUtils; +import com.commafeed.CommaFeedConfiguration; import com.commafeed.backend.cache.CacheService; -import com.commafeed.backend.dao.FeedEntryDAO; import com.commafeed.backend.dao.FeedEntryStatusDAO; import com.commafeed.backend.dao.FeedSubscriptionDAO; -import com.commafeed.backend.feeds.FeedRefreshTaskGiver; -import com.commafeed.backend.feeds.FeedUtils; +import com.commafeed.backend.feed.FeedQueues; +import com.commafeed.backend.feed.FeedUtils; import com.commafeed.backend.model.Feed; import com.commafeed.backend.model.FeedCategory; import com.commafeed.backend.model.FeedSubscription; @@ -25,40 +23,26 @@ import com.commafeed.frontend.model.UnreadCount; import com.google.common.collect.Maps; @Slf4j +@RequiredArgsConstructor public class FeedSubscriptionService { @SuppressWarnings("serial") - @ApplicationException public static class FeedSubscriptionException extends RuntimeException { public FeedSubscriptionException(String msg) { super(msg); } } - @Inject - FeedService feedService; - - @Inject - FeedEntryDAO feedEntryDAO; - - @Inject - FeedEntryStatusDAO feedEntryStatusDAO; - - @Inject - FeedSubscriptionDAO feedSubscriptionDAO; - - @Inject - ApplicationSettingsService applicationSettingsService; - - @Inject - FeedRefreshTaskGiver taskGiver; - - @Inject - CacheService cache; + private final FeedEntryStatusDAO feedEntryStatusDAO; + private final FeedSubscriptionDAO feedSubscriptionDAO; + private final FeedService feedService; + private final FeedQueues queues; + private final CacheService cache; + private final CommaFeedConfiguration config; public Feed subscribe(User user, String url, String title, FeedCategory category) { - final String pubUrl = applicationSettingsService.get().getPublicUrl(); + final String pubUrl = config.getApplicationSettings().getPublicUrl(); if (StringUtils.isBlank(pubUrl)) { throw new FeedSubscriptionException("Public URL of this CommaFeed instance is not set"); } @@ -79,7 +63,7 @@ public class FeedSubscriptionService { sub.setTitle(FeedUtils.truncate(title, 128)); feedSubscriptionDAO.saveOrUpdate(sub); - taskGiver.add(feed, false); + queues.add(feed, false); cache.invalidateUserRootCategory(user); return feed; } @@ -99,7 +83,7 @@ public class FeedSubscriptionService { List subs = feedSubscriptionDAO.findAll(user); for (FeedSubscription sub : subs) { Feed feed = sub.getFeed(); - taskGiver.add(feed, true); + queues.add(feed, true); } } diff --git a/src/main/java/com/commafeed/backend/services/FeedUpdateService.java b/src/main/java/com/commafeed/backend/service/FeedUpdateService.java similarity index 75% rename from src/main/java/com/commafeed/backend/services/FeedUpdateService.java rename to src/main/java/com/commafeed/backend/service/FeedUpdateService.java index 9c06b9a8..6aa9ed5f 100644 --- a/src/main/java/com/commafeed/backend/services/FeedUpdateService.java +++ b/src/main/java/com/commafeed/backend/service/FeedUpdateService.java @@ -1,9 +1,8 @@ -package com.commafeed.backend.services; +package com.commafeed.backend.service; import java.util.Date; -import javax.ejb.Stateless; -import javax.inject.Inject; +import lombok.AllArgsConstructor; import org.apache.commons.codec.digest.DigestUtils; @@ -12,21 +11,18 @@ import com.commafeed.backend.model.Feed; import com.commafeed.backend.model.FeedEntry; import com.commafeed.backend.model.FeedEntryContent; -@Stateless +@AllArgsConstructor public class FeedUpdateService { - @Inject - FeedEntryDAO feedEntryDAO; - - @Inject - FeedEntryContentService feedEntryContentService; + private final FeedEntryDAO feedEntryDAO; + private final FeedEntryContentService feedEntryContentService; /** * this is NOT thread-safe */ public boolean addEntry(Feed feed, FeedEntry entry) { - Long existing = feedEntryDAO.findExisting(entry.getGuid(), feed.getId()); + Long existing = feedEntryDAO.findExisting(entry.getGuid(), feed); if (existing != null) { return false; } diff --git a/src/main/java/com/commafeed/backend/services/MailService.java b/src/main/java/com/commafeed/backend/service/MailService.java similarity index 82% rename from src/main/java/com/commafeed/backend/services/MailService.java rename to src/main/java/com/commafeed/backend/service/MailService.java index e48a7a5c..929309f5 100644 --- a/src/main/java/com/commafeed/backend/services/MailService.java +++ b/src/main/java/com/commafeed/backend/service/MailService.java @@ -1,4 +1,4 @@ -package com.commafeed.backend.services; +package com.commafeed.backend.service; import java.io.Serializable; import java.util.Properties; @@ -12,7 +12,8 @@ import javax.mail.Transport; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeMessage; -import com.commafeed.backend.model.ApplicationSettings; +import com.commafeed.CommaFeedConfiguration; +import com.commafeed.CommaFeedConfiguration.ApplicationSettings; import com.commafeed.backend.model.User; /** @@ -23,11 +24,11 @@ import com.commafeed.backend.model.User; public class MailService implements Serializable { @Inject - ApplicationSettingsService applicationSettingsService; + CommaFeedConfiguration config; public void sendMail(User user, String subject, String content) throws Exception { - ApplicationSettings settings = applicationSettingsService.get(); + ApplicationSettings settings = config.getApplicationSettings(); final String username = settings.getSmtpUserName(); final String password = settings.getSmtpPassword(); @@ -41,6 +42,7 @@ public class MailService implements Serializable { props.put("mail.smtp.port", "" + settings.getSmtpPort()); Session session = Session.getInstance(props, new Authenticator() { + @Override protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(username, password); } diff --git a/src/main/java/com/commafeed/backend/services/PasswordEncryptionService.java b/src/main/java/com/commafeed/backend/service/PasswordEncryptionService.java similarity index 95% rename from src/main/java/com/commafeed/backend/services/PasswordEncryptionService.java rename to src/main/java/com/commafeed/backend/service/PasswordEncryptionService.java index ff81bff3..48f7736f 100644 --- a/src/main/java/com/commafeed/backend/services/PasswordEncryptionService.java +++ b/src/main/java/com/commafeed/backend/service/PasswordEncryptionService.java @@ -1,4 +1,4 @@ -package com.commafeed.backend.services; +package com.commafeed.backend.service; import java.io.Serializable; import java.security.NoSuchAlgorithmException; diff --git a/src/main/java/com/commafeed/backend/pubsubhubbub/SubscriptionHandler.java b/src/main/java/com/commafeed/backend/service/PubSubService.java similarity index 80% rename from src/main/java/com/commafeed/backend/pubsubhubbub/SubscriptionHandler.java rename to src/main/java/com/commafeed/backend/service/PubSubService.java index b4c50608..f8d5594f 100644 --- a/src/main/java/com/commafeed/backend/pubsubhubbub/SubscriptionHandler.java +++ b/src/main/java/com/commafeed/backend/service/PubSubService.java @@ -1,12 +1,13 @@ -package com.commafeed.backend.pubsubhubbub; +package com.commafeed.backend.service; import java.util.List; -import javax.inject.Inject; import javax.ws.rs.core.MediaType; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringUtils; import org.apache.http.HttpHeaders; import org.apache.http.NameValuePair; @@ -16,14 +17,13 @@ import org.apache.http.client.methods.HttpPost; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.message.BasicNameValuePair; import org.apache.http.util.EntityUtils; -import org.apache.wicket.util.io.IOUtils; +import com.commafeed.CommaFeedConfiguration; import com.commafeed.backend.HttpGetter; -import com.commafeed.backend.feeds.FeedRefreshTaskGiver; -import com.commafeed.backend.feeds.FeedUtils; +import com.commafeed.backend.feed.FeedQueues; +import com.commafeed.backend.feed.FeedUtils; import com.commafeed.backend.model.Feed; -import com.commafeed.backend.services.ApplicationSettingsService; -import com.commafeed.frontend.rest.resources.PubSubHubbubCallbackREST; +import com.commafeed.frontend.resource.PubSubHubbubCallbackREST; import com.google.common.collect.Lists; /** @@ -31,13 +31,11 @@ import com.google.common.collect.Lists; * */ @Slf4j -public class SubscriptionHandler { +@RequiredArgsConstructor +public class PubSubService { - @Inject - ApplicationSettingsService applicationSettingsService; - - @Inject - FeedRefreshTaskGiver taskGiver; + private final CommaFeedConfiguration config; + private final FeedQueues queues; public void subscribe(Feed feed) { @@ -51,7 +49,7 @@ public class SubscriptionHandler { String hub = feed.getPushHub(); String topic = feed.getPushTopic(); - String publicUrl = FeedUtils.removeTrailingSlash(applicationSettingsService.get().getPublicUrl()); + String publicUrl = FeedUtils.removeTrailingSlash(config.getApplicationSettings().getPublicUrl()); log.debug("sending new pubsub subscription to {} for {}", hub, topic); @@ -81,7 +79,7 @@ public class SubscriptionHandler { if (code == 400 && StringUtils.contains(message, pushpressError)) { String[] tokens = message.split(" "); feed.setPushTopic(tokens[tokens.length - 1]); - taskGiver.giveBack(feed); + queues.giveBack(feed); log.debug("handled pushpress subfeed {} : {}", topic, feed.getPushTopic()); } else { throw new Exception("Unexpected response code: " + code + " " + response.getStatusLine().getReasonPhrase() + " - " diff --git a/src/main/java/com/commafeed/backend/service/StartupService.java b/src/main/java/com/commafeed/backend/service/StartupService.java new file mode 100644 index 00000000..56e9d087 --- /dev/null +++ b/src/main/java/com/commafeed/backend/service/StartupService.java @@ -0,0 +1,127 @@ +package com.commafeed.backend.service; + +import io.dropwizard.lifecycle.Managed; + +import java.sql.Connection; +import java.util.Arrays; + +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.sql.DataSource; + +import liquibase.Liquibase; +import liquibase.database.Database; +import liquibase.database.DatabaseFactory; +import liquibase.database.core.PostgresDatabase; +import liquibase.database.jvm.JdbcConnection; +import liquibase.resource.ClassLoaderResourceAccessor; +import liquibase.resource.ResourceAccessor; +import liquibase.structure.DatabaseObject; +import lombok.extern.slf4j.Slf4j; + +import org.hibernate.SessionFactory; +import org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl; +import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider; +import org.hibernate.internal.SessionFactoryImpl; + +import com.commafeed.CommaFeedApplication; +import com.commafeed.backend.dao.UnitOfWork; +import com.commafeed.backend.dao.UserDAO; +import com.commafeed.backend.model.UserRole.Role; + +@Slf4j +public class StartupService implements Managed { + + private SessionFactory sessionFactory; + private UserDAO userDAO; + private UserService userService; + + public StartupService(SessionFactory sessionFactory, UserDAO userDAO, UserService userService) { + this.sessionFactory = sessionFactory; + this.userDAO = userDAO; + this.userService = userService; + } + + @Override + public void start() throws Exception { + updateSchema(); + new UnitOfWork(sessionFactory) { + @Override + protected Void runInSession() throws Exception { + if (userDAO.findByName(CommaFeedApplication.USERNAME_ADMIN) == null) { + initialData(); + } + return null; + } + }.run(); + } + + private void updateSchema() { + try { + Context context = null; + Connection connection = null; + try { + Thread currentThread = Thread.currentThread(); + ClassLoader classLoader = currentThread.getContextClassLoader(); + ResourceAccessor accessor = new ClassLoaderResourceAccessor(classLoader); + + context = new InitialContext(); + DataSource dataSource = getDataSource(sessionFactory); + connection = dataSource.getConnection(); + JdbcConnection jdbcConnection = new JdbcConnection(connection); + + Database database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(jdbcConnection); + + if (database instanceof PostgresDatabase) { + database = new PostgresDatabase() { + @Override + public String escapeObjectName(String objectName, Class objectType) { + return objectName; + } + }; + database.setConnection(jdbcConnection); + } + + Liquibase liq = new Liquibase("migrations.xml", accessor, database); + liq.update("prod"); + } finally { + if (context != null) { + context.close(); + } + if (connection != null) { + connection.close(); + } + } + + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private void initialData() { + log.info("Populating database with default values"); + try { + userService.register(CommaFeedApplication.USERNAME_ADMIN, "admin", "admin@commafeed.com", Arrays.asList(Role.ADMIN, Role.USER), + true); + userService.register(CommaFeedApplication.USERNAME_DEMO, "demo", "demo@commafeed.com", Arrays.asList(Role.USER), true); + } catch (Exception e) { + log.error(e.getMessage(), e); + } + } + + @Override + public void stop() throws Exception { + + } + + private static DataSource getDataSource(SessionFactory sessionFactory) { + if (sessionFactory instanceof SessionFactoryImpl) { + ConnectionProvider cp = ((SessionFactoryImpl) sessionFactory).getConnectionProvider(); + if (cp instanceof DatasourceConnectionProviderImpl) { + return ((DatasourceConnectionProviderImpl) cp).getDataSource(); + } + } + return null; + } + +} diff --git a/src/main/java/com/commafeed/backend/services/UserService.java b/src/main/java/com/commafeed/backend/service/UserService.java similarity index 81% rename from src/main/java/com/commafeed/backend/services/UserService.java rename to src/main/java/com/commafeed/backend/service/UserService.java index 7fdb2295..14e2aa6b 100644 --- a/src/main/java/com/commafeed/backend/services/UserService.java +++ b/src/main/java/com/commafeed/backend/service/UserService.java @@ -1,18 +1,17 @@ -package com.commafeed.backend.services; +package com.commafeed.backend.service; import java.util.Collection; import java.util.Date; import java.util.UUID; -import javax.ejb.Stateless; -import javax.inject.Inject; +import lombok.RequiredArgsConstructor; import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.time.DateUtils; +import com.commafeed.CommaFeedConfiguration; import com.commafeed.backend.dao.FeedCategoryDAO; -import com.commafeed.backend.dao.FeedEntryStatusDAO; import com.commafeed.backend.dao.UserDAO; import com.commafeed.backend.dao.UserSettingsDAO; import com.commafeed.backend.model.User; @@ -20,29 +19,16 @@ import com.commafeed.backend.model.UserRole; import com.commafeed.backend.model.UserRole.Role; import com.google.common.base.Preconditions; -@Stateless +@RequiredArgsConstructor public class UserService { - @Inject - UserDAO userDAO; + private final FeedCategoryDAO feedCategoryDAO; + private final UserDAO userDAO; + private final UserSettingsDAO userSettingsDAO; - @Inject - FeedEntryStatusDAO feedEntryStatusDAO; - - @Inject - FeedCategoryDAO feedCategoryDAO; - - @Inject - UserSettingsDAO userSettingsDAO; - - @Inject - PasswordEncryptionService encryptionService; - - @Inject - ApplicationSettingsService applicationSettingsService; - - @Inject - FeedSubscriptionService feedSubscriptionService; + private final FeedSubscriptionService feedSubscriptionService; + private final PasswordEncryptionService encryptionService; + private final CommaFeedConfiguration config; public User login(String name, String password) { if (name == null || password == null) { @@ -63,7 +49,7 @@ public class UserService { user.setLastLogin(now); saveUser = true; } - if (applicationSettingsService.get().isHeavyLoad() + if (config.getApplicationSettings().isHeavyLoad() && (user.getLastFullRefresh() == null || user.getLastFullRefresh().before(DateUtils.addMinutes(now, -30)))) { user.setLastFullRefresh(now); saveUser = true; @@ -89,7 +75,7 @@ public class UserService { Preconditions.checkNotNull(password); if (!forceRegistration) { - Preconditions.checkState(applicationSettingsService.get().isAllowRegistrations(), + Preconditions.checkState(config.getApplicationSettings().isAllowRegistrations(), "Registrations are closed on this CommaFeed instance"); Preconditions.checkNotNull(email); diff --git a/src/main/java/com/commafeed/backend/services/ApplicationSettingsService.java b/src/main/java/com/commafeed/backend/services/ApplicationSettingsService.java deleted file mode 100644 index bf49a053..00000000 --- a/src/main/java/com/commafeed/backend/services/ApplicationSettingsService.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.commafeed.backend.services; - -import java.util.Date; -import java.util.Enumeration; - -import javax.annotation.PostConstruct; -import javax.enterprise.context.ApplicationScoped; -import javax.inject.Inject; - -import org.apache.commons.lang.time.DateUtils; -import org.apache.log4j.Level; -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; - -import com.commafeed.backend.dao.ApplicationSettingsDAO; -import com.commafeed.backend.model.ApplicationSettings; -import com.google.common.collect.Iterables; - -@ApplicationScoped -public class ApplicationSettingsService { - - @Inject - ApplicationSettingsDAO applicationSettingsDAO; - - private ApplicationSettings settings; - - @PostConstruct - private void init() { - settings = Iterables.getFirst(applicationSettingsDAO.findAll(), null); - } - - public ApplicationSettings get() { - return settings; - } - - public void save(ApplicationSettings settings) { - applicationSettingsDAO.saveOrUpdate(settings); - this.settings = settings; - applyLogLevel(); - } - - public Date getUnreadThreshold() { - int keepStatusDays = get().getKeepStatusDays(); - return keepStatusDays > 0 ? DateUtils.addDays(new Date(), -1 * keepStatusDays) : null; - } - - @SuppressWarnings("unchecked") - public void applyLogLevel() { - String logLevel = get().getLogLevel(); - Level level = Level.toLevel(logLevel); - - Enumeration loggers = LogManager.getCurrentLoggers(); - while (loggers.hasMoreElements()) { - Logger logger = loggers.nextElement(); - if (logger.getName().startsWith("com.commafeed")) { - logger.setLevel(level); - } - } - } -} diff --git a/src/main/java/com/commafeed/backend/services/FeedService.java b/src/main/java/com/commafeed/backend/services/FeedService.java deleted file mode 100644 index 334d179a..00000000 --- a/src/main/java/com/commafeed/backend/services/FeedService.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.commafeed.backend.services; - -import java.util.Date; - -import javax.ejb.Lock; -import javax.ejb.LockType; -import javax.ejb.Singleton; -import javax.inject.Inject; - -import org.apache.commons.codec.digest.DigestUtils; - -import com.commafeed.backend.dao.FeedDAO; -import com.commafeed.backend.dao.FeedSubscriptionDAO; -import com.commafeed.backend.feeds.FeedUtils; -import com.commafeed.backend.model.Feed; - -@Singleton -public class FeedService { - - @Inject - FeedDAO feedDAO; - - @Inject - FeedSubscriptionDAO feedSubscriptionDAO; - - @Lock(LockType.WRITE) - public Feed findOrCreate(String url) { - Feed feed = feedDAO.findByUrl(url); - if (feed == null) { - String normalized = FeedUtils.normalizeURL(url); - feed = new Feed(); - feed.setUrl(url); - feed.setNormalizedUrl(normalized); - feed.setNormalizedUrlHash(DigestUtils.sha1Hex(normalized)); - feed.setDisabledUntil(new Date(0)); - feedDAO.saveOrUpdate(feed); - } - return feed; - } - -} diff --git a/src/main/java/com/commafeed/backend/startup/DatabaseUpdater.java b/src/main/java/com/commafeed/backend/startup/DatabaseUpdater.java deleted file mode 100644 index 1bdd1e24..00000000 --- a/src/main/java/com/commafeed/backend/startup/DatabaseUpdater.java +++ /dev/null @@ -1,76 +0,0 @@ -package com.commafeed.backend.startup; - -import java.sql.Connection; - -import javax.ejb.Stateless; -import javax.ejb.TransactionManagement; -import javax.ejb.TransactionManagementType; -import javax.naming.Context; -import javax.naming.InitialContext; -import javax.sql.DataSource; - -import liquibase.Liquibase; -import liquibase.database.Database; -import liquibase.database.DatabaseFactory; -import liquibase.database.core.PostgresDatabase; -import liquibase.database.jvm.JdbcConnection; -import liquibase.resource.ClassLoaderResourceAccessor; -import liquibase.resource.ResourceAccessor; -import liquibase.structure.DatabaseObject; - -import com.commafeed.backend.services.ApplicationPropertiesService; - -/** - * Executes needed liquibase database schema upgrades - * - */ -@Stateless -@TransactionManagement(TransactionManagementType.BEAN) -public class DatabaseUpdater { - - public void update() { - ApplicationPropertiesService properties = ApplicationPropertiesService.get(); - String datasourceName = properties.getDatasource(); - try { - Context context = null; - Connection connection = null; - try { - Thread currentThread = Thread.currentThread(); - ClassLoader classLoader = currentThread.getContextClassLoader(); - ResourceAccessor accessor = new ClassLoaderResourceAccessor(classLoader); - - context = new InitialContext(); - DataSource dataSource = (DataSource) context.lookup(datasourceName); - connection = dataSource.getConnection(); - JdbcConnection jdbcConnection = new JdbcConnection(connection); - - Database database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(jdbcConnection); - - if (database instanceof PostgresDatabase) { - database = new PostgresDatabase() { - @Override - public String escapeObjectName(String objectName, Class objectType) { - return objectName; - } - }; - database.setConnection(jdbcConnection); - } - - Liquibase liq = new Liquibase("changelogs/db.changelog-master.xml", accessor, database); - liq.update("prod"); - } finally { - if (context != null) { - context.close(); - } - if (connection != null) { - connection.close(); - } - } - - } catch (Exception e) { - throw new RuntimeException(e); - } - - } - -} diff --git a/src/main/java/com/commafeed/backend/startup/StartupBean.java b/src/main/java/com/commafeed/backend/startup/StartupBean.java deleted file mode 100644 index 77e47b06..00000000 --- a/src/main/java/com/commafeed/backend/startup/StartupBean.java +++ /dev/null @@ -1,120 +0,0 @@ -package com.commafeed.backend.startup; - -import java.io.InputStream; -import java.io.InputStreamReader; -import java.util.Arrays; -import java.util.Map; -import java.util.Properties; - -import javax.annotation.PostConstruct; -import javax.ejb.ConcurrencyManagement; -import javax.ejb.ConcurrencyManagementType; -import javax.ejb.Singleton; -import javax.ejb.Startup; -import javax.inject.Inject; - -import lombok.extern.slf4j.Slf4j; - -import org.apache.commons.io.IOUtils; - -import com.commafeed.backend.dao.ApplicationSettingsDAO; -import com.commafeed.backend.feeds.FeedRefreshTaskGiver; -import com.commafeed.backend.model.ApplicationSettings; -import com.commafeed.backend.model.UserRole.Role; -import com.commafeed.backend.services.ApplicationSettingsService; -import com.commafeed.backend.services.UserService; -import com.google.common.collect.Maps; - -/** - * Starting point of the application - * - */ -@Startup -@Singleton -@ConcurrencyManagement(ConcurrencyManagementType.BEAN) -@Slf4j -public class StartupBean { - - public static final String USERNAME_ADMIN = "admin"; - public static final String USERNAME_DEMO = "demo"; - - @Inject - DatabaseUpdater databaseUpdater; - - @Inject - ApplicationSettingsDAO applicationSettingsDAO; - - @Inject - UserService userService; - - @Inject - FeedRefreshTaskGiver taskGiver; - - @Inject - ApplicationSettingsService applicationSettingsService; - - private long startupTime; - private Map supportedLanguages = Maps.newHashMap(); - - @PostConstruct - private void init() { - - startupTime = System.currentTimeMillis(); - - // update database schema - databaseUpdater.update(); - - if (applicationSettingsDAO.getCount() == 0) { - // import initial data - initialData(); - } - applicationSettingsService.applyLogLevel(); - - initSupportedLanguages(); - - // start fetching feeds - taskGiver.start(); - } - - private void initSupportedLanguages() { - Properties props = new Properties(); - InputStream is = null; - try { - is = getClass().getResourceAsStream("/i18n/languages.properties"); - props.load(new InputStreamReader(is, "UTF-8")); - } catch (Exception e) { - log.error(e.getMessage(), e); - } finally { - IOUtils.closeQuietly(is); - } - for (Object key : props.keySet()) { - supportedLanguages.put(key.toString(), props.getProperty(key.toString())); - } - } - - /** - * create default users - */ - private void initialData() { - log.info("Populating database with default values"); - - ApplicationSettings settings = new ApplicationSettings(); - settings.setAnnouncement("Set the Public URL in the admin section!"); - applicationSettingsService.save(settings); - - try { - userService.register(USERNAME_ADMIN, "admin", "admin@commafeed.com", Arrays.asList(Role.ADMIN, Role.USER), true); - userService.register(USERNAME_DEMO, "demo", "demo@commafeed.com", Arrays.asList(Role.USER), true); - } catch (Exception e) { - log.error(e.getMessage(), e); - } - } - - public long getStartupTime() { - return startupTime; - } - - public Map getSupportedLanguages() { - return supportedLanguages; - } -} diff --git a/src/main/java/com/commafeed/frontend/APIGenerator.java b/src/main/java/com/commafeed/frontend/APIGenerator.java deleted file mode 100644 index d84e9375..00000000 --- a/src/main/java/com/commafeed/frontend/APIGenerator.java +++ /dev/null @@ -1,101 +0,0 @@ -package com.commafeed.frontend; - -import java.io.OutputStream; -import java.util.Set; - -import javax.annotation.processing.AbstractProcessor; -import javax.annotation.processing.RoundEnvironment; -import javax.annotation.processing.SupportedAnnotationTypes; -import javax.annotation.processing.SupportedOptions; -import javax.lang.model.element.Element; -import javax.lang.model.element.TypeElement; -import javax.tools.Diagnostic.Kind; -import javax.tools.FileObject; -import javax.tools.StandardLocation; - -import org.apache.commons.lang.StringUtils; -import org.apache.wicket.util.io.IOUtils; - -import com.commafeed.frontend.model.Entries; -import com.commafeed.frontend.model.request.MarkRequest; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.wordnik.swagger.annotations.Api; -import com.wordnik.swagger.core.Documentation; -import com.wordnik.swagger.core.DocumentationEndPoint; -import com.wordnik.swagger.core.SwaggerSpec; -import com.wordnik.swagger.core.util.TypeUtil; -import com.wordnik.swagger.jaxrs.HelpApi; -import com.wordnik.swagger.jaxrs.JaxrsApiReader; - -@SupportedAnnotationTypes("com.wordnik.swagger.annotations.Api") -@SupportedOptions("outputDirectory") -public class APIGenerator extends AbstractProcessor { - - @Override - public boolean process(Set annotations, RoundEnvironment roundEnv) { - try { - return processInternal(annotations, roundEnv); - } catch (Exception e) { - e.printStackTrace(); - processingEnv.getMessager().printMessage(Kind.ERROR, e.getMessage()); - } - return false; - } - - private boolean processInternal(Set annotations, RoundEnvironment roundEnv) throws Exception { - JaxrsApiReader.setFormatString(""); - TypeUtil.addAllowablePackage(Entries.class.getPackage().getName()); - TypeUtil.addAllowablePackage(MarkRequest.class.getPackage().getName()); - - String apiVersion = "1.0"; - String swaggerVersion = SwaggerSpec.version(); - String basePath = "../rest"; - - Documentation doc = new Documentation(); - for (Element element : roundEnv.getElementsAnnotatedWith(Api.class)) { - TypeElement type = (TypeElement) element; - String fqn = type.getQualifiedName().toString(); - Class resource = Class.forName(fqn); - - Api api = resource.getAnnotation(Api.class); - String apiPath = api.value(); - - Documentation apiDoc = JaxrsApiReader.read(resource, apiVersion, swaggerVersion, basePath, apiPath); - apiDoc = new HelpApi(null).filterDocs(apiDoc, null, null, null, null); - - apiDoc.setSwaggerVersion(swaggerVersion); - apiDoc.setApiVersion(apiVersion); - write(apiDoc.getResourcePath(), apiDoc, element); - - doc.addApi(new DocumentationEndPoint(api.value(), api.description())); - - } - doc.setSwaggerVersion(swaggerVersion); - doc.setApiVersion(apiVersion); - - write(doc.getResourcePath(), doc, null); - - return true; - } - - private void write(String resourcePath, Object doc, Element element) throws Exception { - String fileName = StringUtils.defaultString(resourcePath, "resources"); - fileName = StringUtils.removeStart(fileName, "/"); - - FileObject resource = null; - try { - resource = processingEnv.getFiler().createResource(StandardLocation.SOURCE_OUTPUT, "", fileName, element); - } catch (Exception e) { - // already processed - } - if (resource != null) { - OutputStream os = resource.openOutputStream(); - try { - IOUtils.write(new ObjectMapper().writeValueAsString(doc), os, "UTF-8"); - } finally { - IOUtils.closeQuietly(os); - } - } - - } -} diff --git a/src/main/java/com/commafeed/frontend/CommaFeedApplication.java b/src/main/java/com/commafeed/frontend/CommaFeedApplication.java deleted file mode 100644 index 512cda44..00000000 --- a/src/main/java/com/commafeed/frontend/CommaFeedApplication.java +++ /dev/null @@ -1,216 +0,0 @@ -package com.commafeed.frontend; - -import javax.enterprise.inject.spi.BeanManager; -import javax.inject.Inject; -import javax.naming.InitialContext; -import javax.naming.NamingException; -import javax.servlet.http.Cookie; - -import lombok.extern.slf4j.Slf4j; - -import org.apache.commons.lang.StringUtils; -import org.apache.wicket.Application; -import org.apache.wicket.Component; -import org.apache.wicket.IRequestCycleProvider; -import org.apache.wicket.Page; -import org.apache.wicket.RuntimeConfigurationType; -import org.apache.wicket.Session; -import org.apache.wicket.ajax.AjaxRequestTarget; -import org.apache.wicket.authentication.strategy.DefaultAuthenticationStrategy; -import org.apache.wicket.authorization.Action; -import org.apache.wicket.authorization.IAuthorizationStrategy; -import org.apache.wicket.authroles.authentication.AbstractAuthenticatedWebSession; -import org.apache.wicket.authroles.authentication.AuthenticatedWebApplication; -import org.apache.wicket.authroles.authorization.strategies.role.Roles; -import org.apache.wicket.cdi.CdiConfiguration; -import org.apache.wicket.cdi.CdiContainer; -import org.apache.wicket.cdi.ConversationPropagation; -import org.apache.wicket.core.request.handler.PageProvider; -import org.apache.wicket.core.request.handler.RenderPageRequestHandler; -import org.apache.wicket.core.request.handler.RenderPageRequestHandler.RedirectPolicy; -import org.apache.wicket.markup.head.IHeaderResponse; -import org.apache.wicket.markup.head.filter.JavaScriptFilteredIntoFooterHeaderResponse; -import org.apache.wicket.markup.html.IHeaderResponseDecorator; -import org.apache.wicket.markup.html.WebPage; -import org.apache.wicket.request.IRequestHandler; -import org.apache.wicket.request.Request; -import org.apache.wicket.request.Response; -import org.apache.wicket.request.Url; -import org.apache.wicket.request.UrlRenderer; -import org.apache.wicket.request.component.IRequestableComponent; -import org.apache.wicket.request.cycle.AbstractRequestCycleListener; -import org.apache.wicket.request.cycle.RequestCycle; -import org.apache.wicket.request.cycle.RequestCycleContext; -import org.apache.wicket.util.cookies.CookieUtils; - -import com.commafeed.backend.services.ApplicationPropertiesService; -import com.commafeed.backend.services.ApplicationSettingsService; -import com.commafeed.frontend.pages.DemoLoginPage; -import com.commafeed.frontend.pages.HomePage; -import com.commafeed.frontend.pages.LogoutPage; -import com.commafeed.frontend.pages.NextUnreadRedirectPage; -import com.commafeed.frontend.pages.PasswordRecoveryCallbackPage; -import com.commafeed.frontend.pages.PasswordRecoveryPage; -import com.commafeed.frontend.pages.WelcomePage; -import com.commafeed.frontend.utils.WicketUtils; -import com.commafeed.frontend.utils.exception.DisplayExceptionPage; - -@Slf4j -public class CommaFeedApplication extends AuthenticatedWebApplication { - - @Inject - ApplicationSettingsService applicationSettingsService; - - public CommaFeedApplication() { - super(); - boolean prod = ApplicationPropertiesService.get().isProduction(); - setConfigurationType(prod ? RuntimeConfigurationType.DEPLOYMENT : RuntimeConfigurationType.DEVELOPMENT); - } - - @Override - protected void init() { - super.init(); - setupInjection(); - setupSecurity(); - - mountPage("welcome", WelcomePage.class); - mountPage("demo", DemoLoginPage.class); - - mountPage("recover", PasswordRecoveryPage.class); - mountPage("recover2", PasswordRecoveryCallbackPage.class); - - mountPage("logout", LogoutPage.class); - mountPage("error", DisplayExceptionPage.class); - - mountPage("next", NextUnreadRedirectPage.class); - - getMarkupSettings().setStripWicketTags(true); - getMarkupSettings().setCompressWhitespace(true); - getMarkupSettings().setDefaultMarkupEncoding("UTF-8"); - - setHeaderResponseDecorator(new IHeaderResponseDecorator() { - @Override - public IHeaderResponse decorate(IHeaderResponse response) { - return new JavaScriptFilteredIntoFooterHeaderResponse(response, "footer-container"); - } - }); - - getRequestCycleListeners().add(new AbstractRequestCycleListener() { - @Override - public IRequestHandler onException(RequestCycle cycle, Exception ex) { - AjaxRequestTarget target = cycle.find(AjaxRequestTarget.class); - // redirect to the error page if ajax request, render error on current page otherwise - RedirectPolicy policy = target == null ? RedirectPolicy.NEVER_REDIRECT : RedirectPolicy.AUTO_REDIRECT; - return new RenderPageRequestHandler(new PageProvider(new DisplayExceptionPage(ex)), policy); - } - }); - - setRequestCycleProvider(new IRequestCycleProvider() { - @Override - public RequestCycle get(RequestCycleContext context) { - return new RequestCycle(context) { - @Override - protected UrlRenderer newUrlRenderer() { - return new UrlRenderer(getRequest()) { - @Override - public String renderUrl(Url url) { - // override wicket's relative-to-absolute url conversion with what we know is the correct protocol - String publicUrl = applicationSettingsService.get().getPublicUrl(); - if (StringUtils.isNotBlank(publicUrl)) { - Url parsed = Url.parse(publicUrl); - url.setProtocol(parsed.getProtocol()); - url.setPort(parsed.getPort()); - } - return super.renderUrl(url); - } - }; - } - }; - } - }); - } - - private void setupSecurity() { - getSecuritySettings().setAuthenticationStrategy(new DefaultAuthenticationStrategy("LoggedIn") { - - private CookieUtils cookieUtils = null; - - @Override - protected CookieUtils getCookieUtils() { - - if (cookieUtils == null) { - cookieUtils = new CookieUtils() { - @Override - protected void initializeCookie(Cookie cookie) { - super.initializeCookie(cookie); - cookie.setHttpOnly(true); - } - }; - } - return cookieUtils; - } - }); - getSecuritySettings().setAuthorizationStrategy(new IAuthorizationStrategy() { - - @Override - public boolean isInstantiationAuthorized(Class componentClass) { - boolean authorized = true; - - boolean restricted = componentClass.isAnnotationPresent(SecurityCheck.class); - if (restricted) { - SecurityCheck annotation = componentClass.getAnnotation(SecurityCheck.class); - Roles roles = CommaFeedSession.get().getRoles(); - authorized = roles.hasAnyRole(new Roles(annotation.value().name())); - } - return authorized; - } - - @Override - public boolean isActionAuthorized(Component component, Action action) { - return true; - } - }); - } - - @Override - public Class getHomePage() { - return HomePage.class; - } - - protected void setupInjection() { - try { - BeanManager beanManager = (BeanManager) new InitialContext().lookup("java:comp/BeanManager"); - CdiContainer container = new CdiConfiguration(beanManager).setPropagation(ConversationPropagation.NONE).configure(this); - container.getNonContextualManager().inject(this); - } catch (NamingException e) { - log.warn("Could not locate bean manager. CDI is disabled."); - } - } - - @Override - public void restartResponseAtSignInPage() { - // preserve https if it was set - RequestCycle.get().getUrlRenderer().setBaseUrl(Url.parse(WicketUtils.getClientFullUrl())); - super.restartResponseAtSignInPage(); - } - - @Override - public Session newSession(Request request, Response response) { - return new CommaFeedSession(request); - } - - @Override - protected Class getSignInPageClass() { - return WelcomePage.class; - } - - @Override - protected Class getWebSessionClass() { - return CommaFeedSession.class; - } - - public static CommaFeedApplication get() { - - return (CommaFeedApplication) Application.get(); - } -} diff --git a/src/main/java/com/commafeed/frontend/CommaFeedSession.java b/src/main/java/com/commafeed/frontend/CommaFeedSession.java deleted file mode 100644 index 40393a1e..00000000 --- a/src/main/java/com/commafeed/frontend/CommaFeedSession.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.commafeed.frontend; - -import java.util.Set; - -import lombok.Getter; - -import org.apache.wicket.Session; -import org.apache.wicket.authroles.authentication.AuthenticatedWebSession; -import org.apache.wicket.authroles.authorization.strategies.role.Roles; -import org.apache.wicket.request.Request; - -import com.commafeed.backend.model.User; -import com.commafeed.backend.model.UserRole.Role; -import com.google.common.collect.Sets; - -public class CommaFeedSession extends AuthenticatedWebSession { - - private static final long serialVersionUID = 1L; - - private User user; - private Roles roles = new Roles(); - - @Getter(lazy = true) - private final CommaFeedSessionServices services = newServices(); - - public CommaFeedSession(Request request) { - super(request); - } - - public User getUser() { - return user; - } - - public static CommaFeedSession get() { - return (CommaFeedSession) Session.get(); - } - - @Override - public Roles getRoles() { - return roles; - } - - @Override - public boolean authenticate(String userName, String password) { - User user = getServices().getUserService().login(userName, password); - setUser(user); - return user != null; - } - - public void setUser(User user) { - if (user == null) { - this.user = null; - this.roles = new Roles(); - } else { - - Set roleSet = Sets.newHashSet(); - for (Role role : getServices().getUserRoleDAO().findRoles(user)) { - roleSet.add(role.name()); - } - this.user = user; - this.roles = new Roles(roleSet.toArray(new String[0])); - } - } - - private CommaFeedSessionServices newServices() { - return new CommaFeedSessionServices(); - } - -} diff --git a/src/main/java/com/commafeed/frontend/CommaFeedSessionServices.java b/src/main/java/com/commafeed/frontend/CommaFeedSessionServices.java deleted file mode 100644 index 62bcbb59..00000000 --- a/src/main/java/com/commafeed/frontend/CommaFeedSessionServices.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.commafeed.frontend; - -import javax.inject.Inject; - -import org.apache.wicket.Component; - -import com.commafeed.backend.dao.UserRoleDAO; -import com.commafeed.backend.services.UserService; - -// extend Component in order to benefit from injection -public class CommaFeedSessionServices extends Component { - - private static final long serialVersionUID = 1L; - - @Inject - UserService userService; - - @Inject - UserRoleDAO userRoleDAO; - - public CommaFeedSessionServices() { - super("services"); - } - - public UserService getUserService() { - return userService; - } - - public UserRoleDAO getUserRoleDAO() { - return userRoleDAO; - } - - @Override - protected void onRender() { - // do nothing - } -} diff --git a/src/main/java/com/commafeed/frontend/InterceptingFilter.java b/src/main/java/com/commafeed/frontend/InterceptingFilter.java deleted file mode 100644 index b92e3473..00000000 --- a/src/main/java/com/commafeed/frontend/InterceptingFilter.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.commafeed.frontend; - -import java.io.IOException; - -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.annotation.WebFilter; -import javax.servlet.http.HttpServletResponse; - -@WebFilter(urlPatterns = "/*") -public class InterceptingFilter implements Filter { - - private static final String HEADER_CORS = "Access-Control-Allow-Origin"; - private static final String HEADER_CORS_VALUE = "*"; - private static final String HEADER_CORS_METHODS = "Access-Control-Allow-Methods"; - private static final String HEADER_CORS_METHODS_VALUE = "POST, GET, OPTIONS"; - private static final String HEADER_CORS_MAXAGE = "Access-Control-Max-Age"; - private static final String HEADER_CORS_MAXAGE_VALUE = "2592000"; - private static final String HEADER_CORS_ALLOW_HEADERS = "Access-Control-Allow-Headers"; - private static final String HEADER_CORS_ALLOW_HEADERS_VALUE = "Authorization"; - private static final String HEADER_CORS_ALLOW_CREDENTIALS = "Access-Control-Allow-Credentials"; - private static final String HEADER_CORS_ALLOW_CREDENTIALS_VALUE = "true"; - - private static final String HEADER_X_UA_COMPATIBLE = "X-UA-Compatible"; - private static final String HEADER_X_UA_COMPATIBLE_VALUE = "IE=Edge,chrome=1"; - - @Override - public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { - HttpServletResponse resp = (HttpServletResponse) response; - resp.addHeader(HEADER_CORS, HEADER_CORS_VALUE); - resp.addHeader(HEADER_CORS_METHODS, HEADER_CORS_METHODS_VALUE); - resp.addHeader(HEADER_CORS_MAXAGE, HEADER_CORS_MAXAGE_VALUE); - resp.addHeader(HEADER_CORS_ALLOW_HEADERS, HEADER_CORS_ALLOW_HEADERS_VALUE); - resp.addHeader(HEADER_CORS_ALLOW_CREDENTIALS, HEADER_CORS_ALLOW_CREDENTIALS_VALUE); - - resp.addHeader(HEADER_X_UA_COMPATIBLE, HEADER_X_UA_COMPATIBLE_VALUE); - - chain.doFilter(request, response); - } - - @Override - public void init(FilterConfig filterConfig) throws ServletException { - } - - @Override - public void destroy() { - } - -} diff --git a/src/main/java/com/commafeed/frontend/SecurityCheck.java b/src/main/java/com/commafeed/frontend/SecurityCheck.java deleted file mode 100644 index e389008a..00000000 --- a/src/main/java/com/commafeed/frontend/SecurityCheck.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.commafeed.frontend; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Inherited; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import javax.enterprise.util.Nonbinding; -import javax.interceptor.InterceptorBinding; - -import com.commafeed.backend.model.UserRole.Role; - -@Inherited -@InterceptorBinding -@Target({ ElementType.TYPE, ElementType.METHOD }) -@Retention(RetentionPolicy.RUNTIME) -public @interface SecurityCheck { - - /** - * Roles needed. - */ - @Nonbinding - Role value() default Role.USER; - - @Nonbinding - boolean apiKeyAllowed() default false; -} \ No newline at end of file diff --git a/src/main/java/com/commafeed/frontend/model/Category.java b/src/main/java/com/commafeed/frontend/model/Category.java index 2d1b47cb..000a0520 100644 --- a/src/main/java/com/commafeed/frontend/model/Category.java +++ b/src/main/java/com/commafeed/frontend/model/Category.java @@ -6,32 +6,32 @@ import java.util.List; import lombok.Data; import com.google.common.collect.Lists; -import com.wordnik.swagger.annotations.ApiClass; -import com.wordnik.swagger.annotations.ApiProperty; +import com.wordnik.swagger.annotations.ApiModel; +import com.wordnik.swagger.annotations.ApiModelProperty; @SuppressWarnings("serial") -@ApiClass("Entry details") +@ApiModel("Entry details") @Data public class Category implements Serializable { - @ApiProperty("category id") + @ApiModelProperty("category id") private String id; - @ApiProperty("parent category id") + @ApiModelProperty("parent category id") private String parentId; - @ApiProperty("category id") + @ApiModelProperty("category id") private String name; - @ApiProperty("category children categories") + @ApiModelProperty("category children categories") private List children = Lists.newArrayList(); - @ApiProperty("category feeds") + @ApiModelProperty("category feeds") private List feeds = Lists.newArrayList(); - @ApiProperty("wether the category is expanded or collapsed") + @ApiModelProperty("wether the category is expanded or collapsed") private boolean expanded; - @ApiProperty("position of the category in the list") + @ApiModelProperty("position of the category in the list") private Integer position; } \ No newline at end of file diff --git a/src/main/java/com/commafeed/frontend/model/Entries.java b/src/main/java/com/commafeed/frontend/model/Entries.java index bd3a878d..b79d33ab 100644 --- a/src/main/java/com/commafeed/frontend/model/Entries.java +++ b/src/main/java/com/commafeed/frontend/model/Entries.java @@ -6,42 +6,42 @@ import java.util.List; import lombok.Data; import com.google.common.collect.Lists; -import com.wordnik.swagger.annotations.ApiClass; -import com.wordnik.swagger.annotations.ApiProperty; +import com.wordnik.swagger.annotations.ApiModel; +import com.wordnik.swagger.annotations.ApiModelProperty; @SuppressWarnings("serial") -@ApiClass("List of entries with some metadata") +@ApiModel("List of entries with some metadata") @Data public class Entries implements Serializable { - @ApiProperty("name of the feed or the category requested") + @ApiModelProperty("name of the feed or the category requested") private String name; - @ApiProperty("error or warning message") + @ApiModelProperty("error or warning message") private String message; - @ApiProperty("times the server tried to refresh the feed and failed") + @ApiModelProperty("times the server tried to refresh the feed and failed") private int errorCount; - @ApiProperty("URL of the website, extracted from the feed") + @ApiModelProperty("URL of the website, extracted from the feed") private String feedLink; - @ApiProperty("list generation timestamp") + @ApiModelProperty("list generation timestamp") private long timestamp; - @ApiProperty("if the query has more elements") + @ApiModelProperty("if the query has more elements") private boolean hasMore; - @ApiProperty("the requested offset") + @ApiModelProperty("the requested offset") private int offset; - @ApiProperty("the requested limit") + @ApiModelProperty("the requested limit") private int limit; - @ApiProperty("list of entries") + @ApiModelProperty("list of entries") private List entries = Lists.newArrayList(); - @ApiProperty("if true, the unread flag was ignored in the request, all entries are returned regardless of their read status") + @ApiModelProperty("if true, the unread flag was ignored in the request, all entries are returned regardless of their read status") private boolean ignoredReadStatus; } diff --git a/src/main/java/com/commafeed/frontend/model/Entry.java b/src/main/java/com/commafeed/frontend/model/Entry.java index bcbc9c74..b9d28d3a 100644 --- a/src/main/java/com/commafeed/frontend/model/Entry.java +++ b/src/main/java/com/commafeed/frontend/model/Entry.java @@ -7,7 +7,7 @@ import java.util.List; import lombok.Data; -import com.commafeed.backend.feeds.FeedUtils; +import com.commafeed.backend.feed.FeedUtils; import com.commafeed.backend.model.FeedEntry; import com.commafeed.backend.model.FeedEntryContent; import com.commafeed.backend.model.FeedEntryStatus; @@ -17,11 +17,11 @@ import com.google.common.collect.Lists; import com.sun.syndication.feed.synd.SyndContentImpl; import com.sun.syndication.feed.synd.SyndEntry; import com.sun.syndication.feed.synd.SyndEntryImpl; -import com.wordnik.swagger.annotations.ApiClass; -import com.wordnik.swagger.annotations.ApiProperty; +import com.wordnik.swagger.annotations.ApiModel; +import com.wordnik.swagger.annotations.ApiModelProperty; @SuppressWarnings("serial") -@ApiClass("Entry details") +@ApiModel("Entry details") @Data public class Entry implements Serializable { @@ -78,63 +78,63 @@ public class Entry implements Serializable { return entry; } - @ApiProperty("entry id") + @ApiModelProperty("entry id") private String id; - @ApiProperty("entry guid") + @ApiModelProperty("entry guid") private String guid; - @ApiProperty("entry title") + @ApiModelProperty("entry title") private String title; - @ApiProperty("entry content") + @ApiModelProperty("entry content") private String content; - @ApiProperty("wether entry content and title are rtl") + @ApiModelProperty("wether entry content and title are rtl") private boolean rtl; - @ApiProperty("entry author") + @ApiModelProperty("entry author") private String author; - @ApiProperty("entry enclosure url, if any") + @ApiModelProperty("entry enclosure url, if any") private String enclosureUrl; - @ApiProperty("entry enclosure mime type, if any") + @ApiModelProperty("entry enclosure mime type, if any") private String enclosureType; - @ApiProperty("entry publication date") + @ApiModelProperty("entry publication date") private Date date; - @ApiProperty("entry insertion date in the database") + @ApiModelProperty("entry insertion date in the database") private Date insertedDate; - @ApiProperty("feed id") + @ApiModelProperty("feed id") private String feedId; - @ApiProperty("feed name") + @ApiModelProperty("feed name") private String feedName; - @ApiProperty("this entry's feed url") + @ApiModelProperty("this entry's feed url") private String feedUrl; - @ApiProperty("this entry's website url") + @ApiModelProperty("this entry's website url") private String feedLink; - @ApiProperty(value = "The favicon url to use for this feed") + @ApiModelProperty(value = "The favicon url to use for this feed") private String iconUrl; - @ApiProperty("entry url") + @ApiModelProperty("entry url") private String url; - @ApiProperty("read sttaus") + @ApiModelProperty("read sttaus") private boolean read; - @ApiProperty("starred status") + @ApiModelProperty("starred status") private boolean starred; - @ApiProperty("wether the entry is still markable (old entry statuses are discarded)") + @ApiModelProperty("wether the entry is still markable (old entry statuses are discarded)") private boolean markable; - @ApiProperty("tags") + @ApiModelProperty("tags") private List tags; } diff --git a/src/main/java/com/commafeed/frontend/model/FeedCount.java b/src/main/java/com/commafeed/frontend/model/FeedCount.java index 0039ccff..2f1ba048 100644 --- a/src/main/java/com/commafeed/frontend/model/FeedCount.java +++ b/src/main/java/com/commafeed/frontend/model/FeedCount.java @@ -7,9 +7,9 @@ import lombok.Data; import com.commafeed.backend.model.Feed; import com.google.common.collect.Lists; -import com.wordnik.swagger.annotations.ApiClass; +import com.wordnik.swagger.annotations.ApiModel; -@ApiClass("Feed count") +@ApiModel("Feed count") @Data public class FeedCount implements Serializable { diff --git a/src/main/java/com/commafeed/frontend/model/FeedInfo.java b/src/main/java/com/commafeed/frontend/model/FeedInfo.java index 0074e72a..26ff914a 100644 --- a/src/main/java/com/commafeed/frontend/model/FeedInfo.java +++ b/src/main/java/com/commafeed/frontend/model/FeedInfo.java @@ -4,10 +4,10 @@ import java.io.Serializable; import lombok.Data; -import com.wordnik.swagger.annotations.ApiClass; +import com.wordnik.swagger.annotations.ApiModel; @SuppressWarnings("serial") -@ApiClass("Feed details") +@ApiModel("Feed details") @Data public class FeedInfo implements Serializable { diff --git a/src/main/java/com/commafeed/frontend/model/ServerInfo.java b/src/main/java/com/commafeed/frontend/model/ServerInfo.java index 89724eee..4be01543 100644 --- a/src/main/java/com/commafeed/frontend/model/ServerInfo.java +++ b/src/main/java/com/commafeed/frontend/model/ServerInfo.java @@ -1,21 +1,18 @@ package com.commafeed.frontend.model; import java.io.Serializable; -import java.util.Map; import lombok.Data; -import com.google.common.collect.Maps; -import com.wordnik.swagger.annotations.ApiClass; +import com.wordnik.swagger.annotations.ApiModel; @SuppressWarnings("serial") -@ApiClass("Server infos") +@ApiModel("Server infos") @Data public class ServerInfo implements Serializable { private String announcement; private String version; private String gitCommit; - private Map supportedLanguages = Maps.newHashMap(); } diff --git a/src/main/java/com/commafeed/frontend/model/Settings.java b/src/main/java/com/commafeed/frontend/model/Settings.java index 615333d5..46e42e64 100644 --- a/src/main/java/com/commafeed/frontend/model/Settings.java +++ b/src/main/java/com/commafeed/frontend/model/Settings.java @@ -4,41 +4,41 @@ import java.io.Serializable; import lombok.Data; -import com.wordnik.swagger.annotations.ApiClass; -import com.wordnik.swagger.annotations.ApiProperty; +import com.wordnik.swagger.annotations.ApiModel; +import com.wordnik.swagger.annotations.ApiModelProperty; @SuppressWarnings("serial") -@ApiClass("User settings") +@ApiModel("User settings") @Data public class Settings implements Serializable { - @ApiProperty(value = "user's preferred language, english if none") + @ApiModelProperty(value = "user's preferred language, english if none") private String language; - @ApiProperty(value = "user reads all entries or unread entries only", allowableValues = "all,unread", required = true) + @ApiModelProperty(value = "user reads all entries or unread entries only", allowableValues = "all,unread", required = true) private String readingMode; - @ApiProperty(value = "user reads entries in ascending or descending order", allowableValues = "asc,desc", required = true) + @ApiModelProperty(value = "user reads entries in ascending or descending order", allowableValues = "asc,desc", required = true) private String readingOrder; - @ApiProperty(value = "user viewing mode, either title-only or expande view", allowableValues = "title,expanded", required = true) + @ApiModelProperty(value = "user viewing mode, either title-only or expande view", allowableValues = "title,expanded", required = true) private String viewMode; - @ApiProperty(value = "user wants category and feeds with no unread entries shown", required = true) + @ApiModelProperty(value = "user wants category and feeds with no unread entries shown", required = true) private boolean showRead; - @ApiProperty(value = "In expanded view, scroll through entries mark them as read", required = true) + @ApiModelProperty(value = "In expanded view, scroll through entries mark them as read", required = true) private boolean scrollMarks; - @ApiProperty(value = "user's selected theme") + @ApiModelProperty(value = "user's selected theme") private String theme; - @ApiProperty(value = "user's custom css for the website") + @ApiModelProperty(value = "user's custom css for the website") private String customCss; - - @ApiProperty(value = "user's preferred scroll speed when navigating between entries") + + @ApiModelProperty(value = "user's preferred scroll speed when navigating between entries") private int scrollSpeed; - + private boolean email; private boolean gmail; private boolean facebook; diff --git a/src/main/java/com/commafeed/frontend/model/Subscription.java b/src/main/java/com/commafeed/frontend/model/Subscription.java index 605eeb99..a395b184 100644 --- a/src/main/java/com/commafeed/frontend/model/Subscription.java +++ b/src/main/java/com/commafeed/frontend/model/Subscription.java @@ -5,15 +5,15 @@ import java.util.Date; import lombok.Data; -import com.commafeed.backend.feeds.FeedUtils; +import com.commafeed.backend.feed.FeedUtils; import com.commafeed.backend.model.Feed; import com.commafeed.backend.model.FeedCategory; import com.commafeed.backend.model.FeedSubscription; -import com.wordnik.swagger.annotations.ApiClass; -import com.wordnik.swagger.annotations.ApiProperty; +import com.wordnik.swagger.annotations.ApiModel; +import com.wordnik.swagger.annotations.ApiModelProperty; @SuppressWarnings("serial") -@ApiClass("User information") +@ApiModel("User information") @Data public class Subscription implements Serializable { @@ -38,43 +38,43 @@ public class Subscription implements Serializable { return sub; } - @ApiProperty(value = "subscription id", required = true) + @ApiModelProperty(value = "subscription id", required = true) private Long id; - @ApiProperty(value = "subscription name", required = true) + @ApiModelProperty(value = "subscription name", required = true) private String name; - @ApiProperty(value = "error message while fetching the feed", required = true) + @ApiModelProperty(value = "error message while fetching the feed", required = true) private String message; - @ApiProperty(value = "error count", required = true) + @ApiModelProperty(value = "error count", required = true) private int errorCount; - @ApiProperty(value = "last time the feed was refreshed", required = true) + @ApiModelProperty(value = "last time the feed was refreshed", required = true) private Date lastRefresh; - @ApiProperty(value = "next time the feed refresh is planned, null if refresh is already queued", required = true) + @ApiModelProperty(value = "next time the feed refresh is planned, null if refresh is already queued", required = true) private Date nextRefresh; - @ApiProperty(value = "this subscription's feed url", required = true) + @ApiModelProperty(value = "this subscription's feed url", required = true) private String feedUrl; - @ApiProperty(value = "this subscription's website url", required = true) + @ApiModelProperty(value = "this subscription's website url", required = true) private String feedLink; - @ApiProperty(value = "The favicon url to use for this feed") + @ApiModelProperty(value = "The favicon url to use for this feed") private String iconUrl; - @ApiProperty(value = "unread count", required = true) + @ApiModelProperty(value = "unread count", required = true) private long unread; - @ApiProperty(value = "category id") + @ApiModelProperty(value = "category id") private String categoryId; - @ApiProperty("position of the subscription's in the list") + @ApiModelProperty("position of the subscription's in the list") private Integer position; - @ApiProperty("date of the newest item") + @ApiModelProperty("date of the newest item") private Date newestItemTime; } \ No newline at end of file diff --git a/src/main/java/com/commafeed/frontend/model/UnreadCount.java b/src/main/java/com/commafeed/frontend/model/UnreadCount.java index 83b05274..3cb0620b 100644 --- a/src/main/java/com/commafeed/frontend/model/UnreadCount.java +++ b/src/main/java/com/commafeed/frontend/model/UnreadCount.java @@ -5,10 +5,10 @@ import java.util.Date; import lombok.Data; -import com.wordnik.swagger.annotations.ApiClass; +import com.wordnik.swagger.annotations.ApiModel; @SuppressWarnings("serial") -@ApiClass("Unread count") +@ApiModel("Unread count") @Data public class UnreadCount implements Serializable { @@ -17,7 +17,6 @@ public class UnreadCount implements Serializable { private Date newestItemTime; public UnreadCount() { - } public UnreadCount(long feedId, long unreadCount, Date newestItemTime) { diff --git a/src/main/java/com/commafeed/frontend/model/UserModel.java b/src/main/java/com/commafeed/frontend/model/UserModel.java index 55843d16..0753a6d8 100644 --- a/src/main/java/com/commafeed/frontend/model/UserModel.java +++ b/src/main/java/com/commafeed/frontend/model/UserModel.java @@ -5,39 +5,39 @@ import java.util.Date; import lombok.Data; -import com.wordnik.swagger.annotations.ApiClass; -import com.wordnik.swagger.annotations.ApiProperty; +import com.wordnik.swagger.annotations.ApiModel; +import com.wordnik.swagger.annotations.ApiModelProperty; @SuppressWarnings("serial") -@ApiClass("User information") +@ApiModel("User information") @Data public class UserModel implements Serializable { - @ApiProperty(value = "user id", required = true) + @ApiModelProperty(value = "user id", required = true) private Long id; - @ApiProperty(value = "user name", required = true) + @ApiModelProperty(value = "user name", required = true) private String name; - @ApiProperty("user email, if any") + @ApiModelProperty("user email, if any") private String email; - @ApiProperty("api key") + @ApiModelProperty("api key") private String apiKey; - @ApiProperty(value = "user password, never returned by the api") + @ApiModelProperty(value = "user password, never returned by the api") private String password; - @ApiProperty(value = "account status") + @ApiModelProperty(value = "account status") private boolean enabled; - @ApiProperty(value = "account creation date") + @ApiModelProperty(value = "account creation date") private Date created; - @ApiProperty(value = "last login date") + @ApiModelProperty(value = "last login date") private Date lastLogin; - @ApiProperty(value = "user is admin") + @ApiModelProperty(value = "user is admin") private boolean admin; } diff --git a/src/main/java/com/commafeed/frontend/model/request/AddCategoryRequest.java b/src/main/java/com/commafeed/frontend/model/request/AddCategoryRequest.java index b70ef297..24ff9373 100644 --- a/src/main/java/com/commafeed/frontend/model/request/AddCategoryRequest.java +++ b/src/main/java/com/commafeed/frontend/model/request/AddCategoryRequest.java @@ -4,18 +4,18 @@ import java.io.Serializable; import lombok.Data; -import com.wordnik.swagger.annotations.ApiClass; -import com.wordnik.swagger.annotations.ApiProperty; +import com.wordnik.swagger.annotations.ApiModel; +import com.wordnik.swagger.annotations.ApiModelProperty; @SuppressWarnings("serial") -@ApiClass("Add Category Request") +@ApiModel("Add Category Request") @Data public class AddCategoryRequest implements Serializable { - @ApiProperty(value = "name", required = true) + @ApiModelProperty(value = "name", required = true) private String name; - @ApiProperty(value = "parent category id, if any") + @ApiModelProperty(value = "parent category id, if any") private String parentId; } diff --git a/src/main/java/com/commafeed/frontend/model/request/CategoryModificationRequest.java b/src/main/java/com/commafeed/frontend/model/request/CategoryModificationRequest.java index 42a69494..ef34156a 100644 --- a/src/main/java/com/commafeed/frontend/model/request/CategoryModificationRequest.java +++ b/src/main/java/com/commafeed/frontend/model/request/CategoryModificationRequest.java @@ -4,24 +4,24 @@ import java.io.Serializable; import lombok.Data; -import com.wordnik.swagger.annotations.ApiClass; -import com.wordnik.swagger.annotations.ApiProperty; +import com.wordnik.swagger.annotations.ApiModel; +import com.wordnik.swagger.annotations.ApiModelProperty; @SuppressWarnings("serial") -@ApiClass("Category modification request") +@ApiModel("Category modification request") @Data public class CategoryModificationRequest implements Serializable { - @ApiProperty(value = "id", required = true) + @ApiModelProperty(value = "id", required = true) private Long id; - @ApiProperty(value = "new name, null if not changed") + @ApiModelProperty(value = "new name, null if not changed") private String name; - @ApiProperty(value = "new parent category id") + @ApiModelProperty(value = "new parent category id") private String parentId; - @ApiProperty(value = "new display position, null if not changed") + @ApiModelProperty(value = "new display position, null if not changed") private Integer position; } diff --git a/src/main/java/com/commafeed/frontend/model/request/CollapseRequest.java b/src/main/java/com/commafeed/frontend/model/request/CollapseRequest.java index 66263b0e..ab24f6b7 100644 --- a/src/main/java/com/commafeed/frontend/model/request/CollapseRequest.java +++ b/src/main/java/com/commafeed/frontend/model/request/CollapseRequest.java @@ -4,18 +4,18 @@ import java.io.Serializable; import lombok.Data; -import com.wordnik.swagger.annotations.ApiClass; -import com.wordnik.swagger.annotations.ApiProperty; +import com.wordnik.swagger.annotations.ApiModel; +import com.wordnik.swagger.annotations.ApiModelProperty; @SuppressWarnings("serial") -@ApiClass("Mark Request") +@ApiModel("Mark Request") @Data public class CollapseRequest implements Serializable { - @ApiProperty(value = "category id", required = true) + @ApiModelProperty(value = "category id", required = true) private Long id; - @ApiProperty(value = "collapse", required = true) + @ApiModelProperty(value = "collapse", required = true) private boolean collapse; } diff --git a/src/main/java/com/commafeed/frontend/model/request/FeedInfoRequest.java b/src/main/java/com/commafeed/frontend/model/request/FeedInfoRequest.java index 9da780e6..9936c0d7 100644 --- a/src/main/java/com/commafeed/frontend/model/request/FeedInfoRequest.java +++ b/src/main/java/com/commafeed/frontend/model/request/FeedInfoRequest.java @@ -4,15 +4,15 @@ import java.io.Serializable; import lombok.Data; -import com.wordnik.swagger.annotations.ApiClass; -import com.wordnik.swagger.annotations.ApiProperty; +import com.wordnik.swagger.annotations.ApiModel; +import com.wordnik.swagger.annotations.ApiModelProperty; @SuppressWarnings("serial") -@ApiClass("Feed information request") +@ApiModel("Feed information request") @Data public class FeedInfoRequest implements Serializable { - @ApiProperty(value = "feed url", required = true) + @ApiModelProperty(value = "feed url", required = true) private String url; } diff --git a/src/main/java/com/commafeed/frontend/model/request/FeedMergeRequest.java b/src/main/java/com/commafeed/frontend/model/request/FeedMergeRequest.java index 735cfb6e..7f0792c9 100644 --- a/src/main/java/com/commafeed/frontend/model/request/FeedMergeRequest.java +++ b/src/main/java/com/commafeed/frontend/model/request/FeedMergeRequest.java @@ -5,18 +5,18 @@ import java.util.List; import lombok.Data; -import com.wordnik.swagger.annotations.ApiClass; -import com.wordnik.swagger.annotations.ApiProperty; +import com.wordnik.swagger.annotations.ApiModel; +import com.wordnik.swagger.annotations.ApiModelProperty; @SuppressWarnings("serial") -@ApiClass("Feed merge Request") +@ApiModel("Feed merge Request") @Data public class FeedMergeRequest implements Serializable { - @ApiProperty(value = "merge into this feed", required = true) + @ApiModelProperty(value = "merge into this feed", required = true) private Long intoFeedId; - @ApiProperty(value = "id of the feeds to merge", required = true) + @ApiModelProperty(value = "id of the feeds to merge", required = true) private List feedIds; } diff --git a/src/main/java/com/commafeed/frontend/model/request/FeedModificationRequest.java b/src/main/java/com/commafeed/frontend/model/request/FeedModificationRequest.java index c25c73c1..c8b44876 100644 --- a/src/main/java/com/commafeed/frontend/model/request/FeedModificationRequest.java +++ b/src/main/java/com/commafeed/frontend/model/request/FeedModificationRequest.java @@ -4,24 +4,24 @@ import java.io.Serializable; import lombok.Data; -import com.wordnik.swagger.annotations.ApiClass; -import com.wordnik.swagger.annotations.ApiProperty; +import com.wordnik.swagger.annotations.ApiModel; +import com.wordnik.swagger.annotations.ApiModelProperty; @SuppressWarnings("serial") -@ApiClass("Feed modification request") +@ApiModel("Feed modification request") @Data public class FeedModificationRequest implements Serializable { - @ApiProperty(value = "id", required = true) + @ApiModelProperty(value = "id", required = true) private Long id; - @ApiProperty(value = "new name, null if not changed") + @ApiModelProperty(value = "new name, null if not changed") private String name; - @ApiProperty(value = "new parent category id") + @ApiModelProperty(value = "new parent category id") private String categoryId; - @ApiProperty(value = "new display position, null if not changed") + @ApiModelProperty(value = "new display position, null if not changed") private Integer position; } diff --git a/src/main/java/com/commafeed/frontend/model/request/IDRequest.java b/src/main/java/com/commafeed/frontend/model/request/IDRequest.java index 40563896..88d7f338 100644 --- a/src/main/java/com/commafeed/frontend/model/request/IDRequest.java +++ b/src/main/java/com/commafeed/frontend/model/request/IDRequest.java @@ -4,15 +4,15 @@ import java.io.Serializable; import lombok.Data; -import com.wordnik.swagger.annotations.ApiClass; -import com.wordnik.swagger.annotations.ApiProperty; +import com.wordnik.swagger.annotations.ApiModel; +import com.wordnik.swagger.annotations.ApiModelProperty; @SuppressWarnings("serial") -@ApiClass +@ApiModel @Data public class IDRequest implements Serializable { - @ApiProperty + @ApiModelProperty private Long id; } diff --git a/src/main/java/com/commafeed/frontend/model/request/MarkRequest.java b/src/main/java/com/commafeed/frontend/model/request/MarkRequest.java index 2e477690..fa12fd0d 100644 --- a/src/main/java/com/commafeed/frontend/model/request/MarkRequest.java +++ b/src/main/java/com/commafeed/frontend/model/request/MarkRequest.java @@ -5,26 +5,26 @@ import java.util.List; import lombok.Data; -import com.wordnik.swagger.annotations.ApiClass; -import com.wordnik.swagger.annotations.ApiProperty; +import com.wordnik.swagger.annotations.ApiModel; +import com.wordnik.swagger.annotations.ApiModelProperty; @SuppressWarnings("serial") -@ApiClass("Mark Request") +@ApiModel("Mark Request") @Data public class MarkRequest implements Serializable { - @ApiProperty(value = "entry id, category id, 'all' or 'starred'", required = true) + @ApiModelProperty(value = "entry id, category id, 'all' or 'starred'", required = true) private String id; - @ApiProperty(value = "mark as read or unread") + @ApiModelProperty(value = "mark as read or unread") private boolean read; - @ApiProperty( + @ApiModelProperty( value = "only entries older than this, pass the timestamp you got from the entry list to prevent marking an entry that was not retrieved", required = false) private Long olderThan; - @ApiProperty(value = "if marking a category or 'all', exclude those subscriptions from the marking", required = false) + @ApiModelProperty(value = "if marking a category or 'all', exclude those subscriptions from the marking", required = false) private List excludedSubscriptions; } diff --git a/src/main/java/com/commafeed/frontend/model/request/MultipleMarkRequest.java b/src/main/java/com/commafeed/frontend/model/request/MultipleMarkRequest.java index a87509af..706b065d 100644 --- a/src/main/java/com/commafeed/frontend/model/request/MultipleMarkRequest.java +++ b/src/main/java/com/commafeed/frontend/model/request/MultipleMarkRequest.java @@ -5,15 +5,15 @@ import java.util.List; import lombok.Data; -import com.wordnik.swagger.annotations.ApiClass; -import com.wordnik.swagger.annotations.ApiProperty; +import com.wordnik.swagger.annotations.ApiModel; +import com.wordnik.swagger.annotations.ApiModelProperty; @SuppressWarnings("serial") -@ApiClass("Multiple Mark Request") +@ApiModel("Multiple Mark Request") @Data public class MultipleMarkRequest implements Serializable { - @ApiProperty(value = "list of mark requests", required = true) + @ApiModelProperty(value = "list of mark requests", required = true) private List requests; } diff --git a/src/main/java/com/commafeed/frontend/model/request/ProfileModificationRequest.java b/src/main/java/com/commafeed/frontend/model/request/ProfileModificationRequest.java index a40d834c..e60e7841 100644 --- a/src/main/java/com/commafeed/frontend/model/request/ProfileModificationRequest.java +++ b/src/main/java/com/commafeed/frontend/model/request/ProfileModificationRequest.java @@ -4,21 +4,21 @@ import java.io.Serializable; import lombok.Data; -import com.wordnik.swagger.annotations.ApiClass; -import com.wordnik.swagger.annotations.ApiProperty; +import com.wordnik.swagger.annotations.ApiModel; +import com.wordnik.swagger.annotations.ApiModelProperty; @SuppressWarnings("serial") -@ApiClass("Profile modification request") +@ApiModel("Profile modification request") @Data public class ProfileModificationRequest implements Serializable { - @ApiProperty(value = "changes email of the user, if specified") + @ApiModelProperty(value = "changes email of the user, if specified") private String email; - @ApiProperty(value = "changes password of the user, if specified") + @ApiModelProperty(value = "changes password of the user, if specified") private String password; - @ApiProperty(value = "generate a new api key") + @ApiModelProperty(value = "generate a new api key") private boolean newApiKey; } diff --git a/src/main/java/com/commafeed/frontend/model/request/RegistrationRequest.java b/src/main/java/com/commafeed/frontend/model/request/RegistrationRequest.java index 00b67075..a307ee90 100644 --- a/src/main/java/com/commafeed/frontend/model/request/RegistrationRequest.java +++ b/src/main/java/com/commafeed/frontend/model/request/RegistrationRequest.java @@ -4,19 +4,21 @@ import java.io.Serializable; import lombok.Data; -import com.wordnik.swagger.annotations.ApiProperty; +import com.wordnik.swagger.annotations.ApiModel; +import com.wordnik.swagger.annotations.ApiModelProperty; @SuppressWarnings("serial") @Data +@ApiModel public class RegistrationRequest implements Serializable { - @ApiProperty(value = "username, between 3 and 32 characters", required = true) + @ApiModelProperty(value = "username, between 3 and 32 characters", required = true) private String name; - @ApiProperty(value = "password, minimum 6 characters", required = true) + @ApiModelProperty(value = "password, minimum 6 characters", required = true) private String password; - @ApiProperty(value = "email address for password recovery", required = true) + @ApiModelProperty(value = "email address for password recovery", required = true) private String email; } diff --git a/src/main/java/com/commafeed/frontend/model/request/StarRequest.java b/src/main/java/com/commafeed/frontend/model/request/StarRequest.java index e81e9bd0..0661ed75 100644 --- a/src/main/java/com/commafeed/frontend/model/request/StarRequest.java +++ b/src/main/java/com/commafeed/frontend/model/request/StarRequest.java @@ -4,21 +4,21 @@ import java.io.Serializable; import lombok.Data; -import com.wordnik.swagger.annotations.ApiClass; -import com.wordnik.swagger.annotations.ApiProperty; +import com.wordnik.swagger.annotations.ApiModel; +import com.wordnik.swagger.annotations.ApiModelProperty; @SuppressWarnings("serial") -@ApiClass("Star Request") +@ApiModel("Star Request") @Data public class StarRequest implements Serializable { - @ApiProperty(value = "id", required = true) + @ApiModelProperty(value = "id", required = true) private String id; - @ApiProperty(value = "feed id", required = true) + @ApiModelProperty(value = "feed id", required = true) private Long feedId; - @ApiProperty(value = "starred or not") + @ApiModelProperty(value = "starred or not") private boolean starred; } diff --git a/src/main/java/com/commafeed/frontend/model/request/SubscribeRequest.java b/src/main/java/com/commafeed/frontend/model/request/SubscribeRequest.java index cc4c07e3..485b5e0d 100644 --- a/src/main/java/com/commafeed/frontend/model/request/SubscribeRequest.java +++ b/src/main/java/com/commafeed/frontend/model/request/SubscribeRequest.java @@ -4,21 +4,21 @@ import java.io.Serializable; import lombok.Data; -import com.wordnik.swagger.annotations.ApiClass; -import com.wordnik.swagger.annotations.ApiProperty; +import com.wordnik.swagger.annotations.ApiModel; +import com.wordnik.swagger.annotations.ApiModelProperty; @SuppressWarnings("serial") -@ApiClass("Subscription request") +@ApiModel("Subscription request") @Data public class SubscribeRequest implements Serializable { - @ApiProperty(value = "url of the feed", required = true) + @ApiModelProperty(value = "url of the feed", required = true) private String url; - @ApiProperty(value = "name of the feed for the user", required = true) + @ApiModelProperty(value = "name of the feed for the user", required = true) private String title; - @ApiProperty(value = "id of the user category to place the feed in") + @ApiModelProperty(value = "id of the user category to place the feed in") private String categoryId; } diff --git a/src/main/java/com/commafeed/frontend/model/request/TagRequest.java b/src/main/java/com/commafeed/frontend/model/request/TagRequest.java index eb4b87f1..0ea1e8e2 100644 --- a/src/main/java/com/commafeed/frontend/model/request/TagRequest.java +++ b/src/main/java/com/commafeed/frontend/model/request/TagRequest.java @@ -5,18 +5,18 @@ import java.util.List; import lombok.Data; -import com.wordnik.swagger.annotations.ApiClass; -import com.wordnik.swagger.annotations.ApiProperty; +import com.wordnik.swagger.annotations.ApiModel; +import com.wordnik.swagger.annotations.ApiModelProperty; @SuppressWarnings("serial") -@ApiClass("Tag Request") +@ApiModel("Tag Request") @Data public class TagRequest implements Serializable { - @ApiProperty(value = "entry id", required = true) + @ApiModelProperty(value = "entry id", required = true) private Long entryId; - @ApiProperty(value = "tags") + @ApiModelProperty(value = "tags") private List tags; } diff --git a/src/main/java/com/commafeed/frontend/pages/BasePage.html b/src/main/java/com/commafeed/frontend/pages/BasePage.html deleted file mode 100644 index 87b77fea..00000000 --- a/src/main/java/com/commafeed/frontend/pages/BasePage.html +++ /dev/null @@ -1,56 +0,0 @@ - - - -CommaFeed - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/java/com/commafeed/frontend/pages/BasePage.java b/src/main/java/com/commafeed/frontend/pages/BasePage.java deleted file mode 100644 index 4d6eeefc..00000000 --- a/src/main/java/com/commafeed/frontend/pages/BasePage.java +++ /dev/null @@ -1,130 +0,0 @@ -package com.commafeed.frontend.pages; - -import java.util.Map; - -import javax.inject.Inject; - -import org.apache.commons.lang.StringUtils; -import org.apache.wicket.AttributeModifier; -import org.apache.wicket.RuntimeConfigurationType; -import org.apache.wicket.markup.head.CssHeaderItem; -import org.apache.wicket.markup.head.IHeaderResponse; -import org.apache.wicket.markup.head.JavaScriptHeaderItem; -import org.apache.wicket.markup.head.filter.HeaderResponseContainer; -import org.apache.wicket.markup.html.TransparentWebMarkupContainer; -import org.apache.wicket.markup.html.WebMarkupContainer; -import org.apache.wicket.markup.html.WebPage; - -import com.commafeed.backend.dao.FeedCategoryDAO; -import com.commafeed.backend.dao.FeedDAO; -import com.commafeed.backend.dao.FeedEntryDAO; -import com.commafeed.backend.dao.FeedEntryStatusDAO; -import com.commafeed.backend.dao.FeedSubscriptionDAO; -import com.commafeed.backend.dao.UserDAO; -import com.commafeed.backend.dao.UserRoleDAO; -import com.commafeed.backend.dao.UserSettingsDAO; -import com.commafeed.backend.model.ApplicationSettings; -import com.commafeed.backend.model.User; -import com.commafeed.backend.model.UserSettings; -import com.commafeed.backend.services.ApplicationSettingsService; -import com.commafeed.backend.services.MailService; -import com.commafeed.backend.startup.StartupBean; -import com.commafeed.frontend.CommaFeedSession; -import com.commafeed.frontend.utils.WicketUtils; -import com.google.common.collect.Maps; - -@SuppressWarnings("serial") -public abstract class BasePage extends WebPage { - - @Inject - protected FeedDAO feedDAO; - - @Inject - StartupBean startupBean; - - @Inject - protected FeedSubscriptionDAO feedSubscriptionDAO; - - @Inject - protected FeedCategoryDAO feedCategoryDAO; - - @Inject - protected FeedEntryDAO feedEntryDAO; - - @Inject - protected FeedEntryStatusDAO feedEntryStatusDAO; - - @Inject - protected UserDAO userDAO; - - @Inject - protected UserSettingsDAO userSettingsDAO; - - @Inject - protected UserRoleDAO userRoleDAO; - - @Inject - MailService mailService; - - @Inject - ApplicationSettingsService applicationSettingsService; - - private ApplicationSettings settings; - - public BasePage() { - - String lang = "en"; - String theme = "default"; - User user = CommaFeedSession.get().getUser(); - if (user != null) { - UserSettings settings = userSettingsDAO.findByUser(user); - if (settings != null) { - lang = settings.getLanguage() == null ? "en" : settings.getLanguage(); - theme = settings.getTheme() == null ? "default" : settings.getTheme(); - } - } - - add(new TransparentWebMarkupContainer("html").setMarkupId("theme-" + theme).add(new AttributeModifier("lang", lang))); - - settings = applicationSettingsService.get(); - add(new HeaderResponseContainer("footer-container", "footer-container")); - add(new WebMarkupContainer("uservoice") { - @Override - protected void onConfigure() { - super.onConfigure(); - setVisibilityAllowed(settings.isFeedbackButton()); - } - }); - } - - @Override - public void renderHead(IHeaderResponse response) { - super.renderHead(response); - - if (getApplication().getConfigurationType() == RuntimeConfigurationType.DEPLOYMENT) { - long startupTime = startupBean.getStartupTime(); - String suffix = "?" + startupTime; - response.render(JavaScriptHeaderItem.forUrl("static/all.js" + suffix)); - response.render(CssHeaderItem.forUrl("static/all.css" + suffix)); - } else { - response.render(JavaScriptHeaderItem.forUrl("wro/lib.js")); - response.render(CssHeaderItem.forUrl("wro/lib.css")); - response.render(CssHeaderItem.forUrl("wro/app.css")); - - response.render(JavaScriptHeaderItem.forUrl("js/welcome.js")); - response.render(JavaScriptHeaderItem.forUrl("js/main.js")); - response.render(JavaScriptHeaderItem.forUrl("js/controllers.js")); - response.render(JavaScriptHeaderItem.forUrl("js/directives.js")); - response.render(JavaScriptHeaderItem.forUrl("js/filters.js")); - response.render(JavaScriptHeaderItem.forUrl("js/services.js")); - - } - - if (StringUtils.isNotBlank(settings.getGoogleAnalyticsTrackingCode())) { - Map vars = Maps.newHashMap(); - vars.put("trackingCode", settings.getGoogleAnalyticsTrackingCode()); - WicketUtils.loadJS(response, BasePage.class, "analytics", vars); - } - - } -} diff --git a/src/main/java/com/commafeed/frontend/pages/DemoLoginPage.java b/src/main/java/com/commafeed/frontend/pages/DemoLoginPage.java deleted file mode 100644 index a61ca868..00000000 --- a/src/main/java/com/commafeed/frontend/pages/DemoLoginPage.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.commafeed.frontend.pages; - -import javax.inject.Inject; - -import org.apache.wicket.markup.html.WebPage; - -import com.commafeed.backend.services.UserService; -import com.commafeed.backend.startup.StartupBean; -import com.commafeed.frontend.CommaFeedSession; - -public class DemoLoginPage extends WebPage { - - private static final long serialVersionUID = 1L; - - @Inject - UserService userService; - - public DemoLoginPage() { - CommaFeedSession.get().authenticate(StartupBean.USERNAME_DEMO, StartupBean.USERNAME_DEMO); - setResponsePage(getApplication().getHomePage()); - } -} diff --git a/src/main/java/com/commafeed/frontend/pages/HomePage.html b/src/main/java/com/commafeed/frontend/pages/HomePage.html deleted file mode 100644 index f273775b..00000000 --- a/src/main/java/com/commafeed/frontend/pages/HomePage.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - -
-
- -
-
-
- - diff --git a/src/main/java/com/commafeed/frontend/pages/HomePage.java b/src/main/java/com/commafeed/frontend/pages/HomePage.java deleted file mode 100644 index 165cc612..00000000 --- a/src/main/java/com/commafeed/frontend/pages/HomePage.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.commafeed.frontend.pages; - -import org.apache.wicket.markup.head.CssHeaderItem; -import org.apache.wicket.markup.head.IHeaderResponse; -import org.apache.wicket.request.mapper.parameter.PageParameters; - -import com.commafeed.backend.model.User; -import com.commafeed.backend.model.UserRole.Role; -import com.commafeed.backend.model.UserSettings; -import com.commafeed.frontend.CommaFeedSession; -import com.commafeed.frontend.SecurityCheck; -import com.commafeed.frontend.resources.UserCustomCssReference; - -@SuppressWarnings("serial") -@SecurityCheck(Role.USER) -public class HomePage extends BasePage { - - @Override - public void renderHead(IHeaderResponse response) { - super.renderHead(response); - - response.render(CssHeaderItem.forReference(new UserCustomCssReference() { - @Override - protected String getCss() { - User user = CommaFeedSession.get().getUser(); - if (user == null) { - return null; - } - UserSettings settings = userSettingsDAO.findByUser(user); - return settings == null ? null : settings.getCustomCss(); - } - }, new PageParameters().add("_t", System.currentTimeMillis()), null)); - } -} diff --git a/src/main/java/com/commafeed/frontend/pages/LogoutPage.java b/src/main/java/com/commafeed/frontend/pages/LogoutPage.java deleted file mode 100644 index a7b98336..00000000 --- a/src/main/java/com/commafeed/frontend/pages/LogoutPage.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.commafeed.frontend.pages; - -import org.apache.wicket.markup.html.WebPage; - -@SuppressWarnings("serial") -public class LogoutPage extends WebPage { - public LogoutPage() { - getSession().invalidate(); - setResponsePage(getApplication().getHomePage()); - } -} diff --git a/src/main/java/com/commafeed/frontend/pages/NextUnreadRedirectPage.java b/src/main/java/com/commafeed/frontend/pages/NextUnreadRedirectPage.java deleted file mode 100755 index 571413ba..00000000 --- a/src/main/java/com/commafeed/frontend/pages/NextUnreadRedirectPage.java +++ /dev/null @@ -1,78 +0,0 @@ -package com.commafeed.frontend.pages; - -import java.util.List; - -import javax.inject.Inject; - -import org.apache.commons.collections.CollectionUtils; -import org.apache.commons.lang3.StringUtils; -import org.apache.wicket.markup.html.WebPage; -import org.apache.wicket.request.flow.RedirectToUrlException; -import org.apache.wicket.request.mapper.parameter.PageParameters; - -import com.commafeed.backend.dao.FeedCategoryDAO; -import com.commafeed.backend.dao.FeedEntryStatusDAO; -import com.commafeed.backend.dao.FeedSubscriptionDAO; -import com.commafeed.backend.model.FeedCategory; -import com.commafeed.backend.model.FeedEntryStatus; -import com.commafeed.backend.model.FeedSubscription; -import com.commafeed.backend.model.User; -import com.commafeed.backend.model.UserRole.Role; -import com.commafeed.backend.model.UserSettings.ReadingOrder; -import com.commafeed.frontend.CommaFeedSession; -import com.commafeed.frontend.SecurityCheck; -import com.commafeed.frontend.rest.resources.CategoryREST; -import com.google.common.collect.Iterables; - -@SuppressWarnings("serial") -@SecurityCheck(Role.USER) -public class NextUnreadRedirectPage extends WebPage { - - public static final String PARAM_CATEGORYID = "category"; - public static final String PARAM_READINGORDER = "order"; - - @Inject - FeedCategoryDAO feedCategoryDAO; - - @Inject - FeedEntryStatusDAO feedEntryStatusDAO; - - @Inject - FeedSubscriptionDAO feedSubscriptionDAO; - - public NextUnreadRedirectPage(PageParameters params) { - String categoryId = params.get(PARAM_CATEGORYID).toString(); - String orderParam = params.get(PARAM_READINGORDER).toString(); - - User user = CommaFeedSession.get().getUser(); - ReadingOrder order = ReadingOrder.desc; - - if (StringUtils.equals(orderParam, "asc")) { - order = ReadingOrder.asc; - } - - List statuses = null; - if (StringUtils.isBlank(categoryId) || CategoryREST.ALL.equals(categoryId)) { - List subs = feedSubscriptionDAO.findAll(user); - statuses = feedEntryStatusDAO.findBySubscriptions(user, subs, true, null, null, 0, 1, order, true, false, null); - } else { - FeedCategory category = feedCategoryDAO.findById(user, Long.valueOf(categoryId)); - if (category != null) { - List children = feedCategoryDAO.findAllChildrenCategories(user, category); - List subscriptions = feedSubscriptionDAO.findByCategories(user, children); - statuses = feedEntryStatusDAO.findBySubscriptions(user, subscriptions, true, null, null, 0, 1, order, true, false, null); - } - } - - if (CollectionUtils.isEmpty(statuses)) { - setResponsePage(HomePage.class); - } else { - FeedEntryStatus status = Iterables.getFirst(statuses, null); - String url = status.getEntry().getUrl(); - status.setRead(true); - feedEntryStatusDAO.saveOrUpdate(status); - throw new RedirectToUrlException(url); - } - } - -} diff --git a/src/main/java/com/commafeed/frontend/pages/PasswordRecoveryCallbackPage.html b/src/main/java/com/commafeed/frontend/pages/PasswordRecoveryCallbackPage.html deleted file mode 100644 index 2ef21f7e..00000000 --- a/src/main/java/com/commafeed/frontend/pages/PasswordRecoveryCallbackPage.html +++ /dev/null @@ -1,26 +0,0 @@ - - - -
-
- -
-
-
- - -
-
- - -
-
- - -
-
-
-
-
- - \ No newline at end of file diff --git a/src/main/java/com/commafeed/frontend/pages/PasswordRecoveryCallbackPage.java b/src/main/java/com/commafeed/frontend/pages/PasswordRecoveryCallbackPage.java deleted file mode 100644 index a889b29f..00000000 --- a/src/main/java/com/commafeed/frontend/pages/PasswordRecoveryCallbackPage.java +++ /dev/null @@ -1,77 +0,0 @@ -package com.commafeed.frontend.pages; - -import java.util.Date; - -import javax.inject.Inject; - -import org.apache.commons.lang.StringUtils; -import org.apache.commons.lang3.time.DateUtils; -import org.apache.wicket.markup.html.form.Form; -import org.apache.wicket.markup.html.form.PasswordTextField; -import org.apache.wicket.markup.html.link.BookmarkablePageLink; -import org.apache.wicket.model.IModel; -import org.apache.wicket.model.Model; -import org.apache.wicket.request.mapper.parameter.PageParameters; -import org.apache.wicket.validation.validator.StringValidator; - -import com.commafeed.backend.model.User; -import com.commafeed.backend.services.PasswordEncryptionService; -import com.commafeed.backend.services.UserService; -import com.commafeed.frontend.pages.components.BootstrapFeedbackPanel; -import com.commafeed.frontend.utils.exception.DisplayException; - -@SuppressWarnings("serial") -public class PasswordRecoveryCallbackPage extends BasePage { - - public static final String PARAM_EMAIL = "email"; - public static final String PARAM_TOKEN = "token"; - - @Inject - PasswordEncryptionService encryptionService; - - @Inject - UserService userService; - - public PasswordRecoveryCallbackPage(PageParameters params) { - String email = params.get(PARAM_EMAIL).toString(); - String token = params.get(PARAM_TOKEN).toString(); - - final User user = userDAO.findByEmail(email); - if (user == null) { - throw new DisplayException("email not found"); - } - if (user.getRecoverPasswordToken() == null || !user.getRecoverPasswordToken().equals(token)) { - throw new DisplayException("invalid token"); - } - if (user.getRecoverPasswordTokenDate().before(DateUtils.addDays(new Date(), -2))) { - throw new DisplayException("token expired"); - } - - final IModel password = new Model(); - final IModel confirm = new Model(); - add(new BootstrapFeedbackPanel("feedback")); - Form form = new Form("form") { - @Override - protected void onSubmit() { - String passwd = password.getObject(); - if (StringUtils.equals(passwd, confirm.getObject())) { - byte[] password = encryptionService.getEncryptedPassword(passwd, user.getSalt()); - user.setPassword(password); - user.setApiKey(userService.generateApiKey(user)); - user.setRecoverPasswordToken(null); - user.setRecoverPasswordTokenDate(null); - userDAO.saveOrUpdate(user); - info("Password saved."); - } else { - error("Passwords do not match."); - } - } - }; - add(form); - form.add(new PasswordTextField("password", password).setResetPassword(true).add(StringValidator.minimumLength(6))); - form.add(new PasswordTextField("confirm", confirm).setResetPassword(true).add(StringValidator.minimumLength(6))); - - form.add(new BookmarkablePageLink("cancel", HomePage.class)); - - } -} diff --git a/src/main/java/com/commafeed/frontend/pages/PasswordRecoveryPage.html b/src/main/java/com/commafeed/frontend/pages/PasswordRecoveryPage.html deleted file mode 100644 index 03c85239..00000000 --- a/src/main/java/com/commafeed/frontend/pages/PasswordRecoveryPage.html +++ /dev/null @@ -1,22 +0,0 @@ - - - -
-
- -
-
-
- - -
-
- - -
-
-
-
-
- - \ No newline at end of file diff --git a/src/main/java/com/commafeed/frontend/pages/PasswordRecoveryPage.java b/src/main/java/com/commafeed/frontend/pages/PasswordRecoveryPage.java deleted file mode 100644 index 1eb01229..00000000 --- a/src/main/java/com/commafeed/frontend/pages/PasswordRecoveryPage.java +++ /dev/null @@ -1,78 +0,0 @@ -package com.commafeed.frontend.pages; - -import java.util.Date; -import java.util.UUID; - -import lombok.extern.slf4j.Slf4j; - -import org.apache.commons.codec.digest.DigestUtils; -import org.apache.http.client.utils.URIBuilder; -import org.apache.wicket.extensions.validation.validator.RfcCompliantEmailAddressValidator; -import org.apache.wicket.markup.html.form.Form; -import org.apache.wicket.markup.html.form.RequiredTextField; -import org.apache.wicket.markup.html.link.BookmarkablePageLink; -import org.apache.wicket.model.IModel; -import org.apache.wicket.model.Model; - -import com.commafeed.backend.feeds.FeedUtils; -import com.commafeed.backend.model.User; -import com.commafeed.frontend.pages.components.BootstrapFeedbackPanel; - -@SuppressWarnings("serial") -@Slf4j -public class PasswordRecoveryPage extends BasePage { - - public PasswordRecoveryPage() { - - IModel email = new Model(); - add(new BootstrapFeedbackPanel("feedback")); - Form form = new Form("form", email) { - @Override - protected void onSubmit() { - super.onSubmit(); - User user = userDAO.findByEmail(getModelObject()); - if (user == null) { - error("Email not found."); - } else { - try { - user.setRecoverPasswordToken(DigestUtils.sha1Hex(UUID.randomUUID().toString())); - user.setRecoverPasswordTokenDate(new Date()); - userDAO.saveOrUpdate(user); - mailService.sendMail(user, "Password recovery", buildEmailContent(user)); - info("Email sent."); - } catch (Exception e) { - log.error(e.getMessage(), e); - error("Cannot send email, please contact the staff."); - } - - } - } - - }; - add(form); - - form.add(new RequiredTextField("email", email) { - @Override - protected String getInputType() { - return "email"; - } - }.add(RfcCompliantEmailAddressValidator.getInstance())); - - form.add(new BookmarkablePageLink("cancel", HomePage.class)); - } - - private String buildEmailContent(User user) throws Exception { - - String publicUrl = FeedUtils.removeTrailingSlash(applicationSettingsService.get().getPublicUrl()); - publicUrl += "/recover2"; - - return String - .format("You asked for password recovery for account '%s', follow this link to change your password. Ignore this if you didn't request a password recovery.", - user.getName(), callbackUrl(user, publicUrl)); - } - - private String callbackUrl(User user, String publicUrl) throws Exception { - return new URIBuilder(publicUrl).addParameter(PasswordRecoveryCallbackPage.PARAM_EMAIL, user.getEmail()) - .addParameter(PasswordRecoveryCallbackPage.PARAM_TOKEN, user.getRecoverPasswordToken()).build().toURL().toString(); - } -} diff --git a/src/main/java/com/commafeed/frontend/pages/TestRssPage.java b/src/main/java/com/commafeed/frontend/pages/TestRssPage.java deleted file mode 100644 index 65e4c038..00000000 --- a/src/main/java/com/commafeed/frontend/pages/TestRssPage.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.commafeed.frontend.pages; - -import java.io.StringWriter; -import java.util.Date; -import java.util.List; -import java.util.UUID; - -import org.apache.commons.lang.math.RandomUtils; -import org.apache.wicket.markup.html.WebPage; -import org.apache.wicket.request.handler.TextRequestHandler; - -import com.google.common.collect.Lists; -import com.sun.syndication.feed.synd.SyndEntry; -import com.sun.syndication.feed.synd.SyndEntryImpl; -import com.sun.syndication.feed.synd.SyndFeed; -import com.sun.syndication.feed.synd.SyndFeedImpl; -import com.sun.syndication.io.SyndFeedOutput; - -@SuppressWarnings("serial") -public class TestRssPage extends WebPage { - - public TestRssPage() { - SyndFeed feed = new SyndFeedImpl(); - feed.setFeedType("rss_2.0"); - feed.setTitle("Test RSS"); - - feed.setLink(""); - feed.setDescription("New entries everytime it is accessed"); - - List entries = Lists.newArrayList(); - for (int i = 0; i < 5; i++) { - SyndEntry entry = new SyndEntryImpl(); - String uuid = UUID.randomUUID().toString(); - entry.setUri(uuid); - entry.setTitle(uuid); - entry.setLink("http://www.example.com/" + uuid); - entry.setPublishedDate(new Date()); - entries.add(entry); - } - feed.setEntries(entries); - SyndFeedOutput output = new SyndFeedOutput(); - - StringWriter writer = new StringWriter(); - try { - output.output(feed, writer); - } catch (Exception e) { - writer.write("Could not get feed information"); - } - - try { - // simulate internet lag - Thread.sleep(Math.abs(RandomUtils.nextLong() % 5000)); - } catch (InterruptedException e) { - // do nothing - } - getRequestCycle().scheduleRequestHandlerAfterCurrent(new TextRequestHandler("text/xml", "UTF-8", writer.toString())); - } - -} diff --git a/src/main/java/com/commafeed/frontend/pages/WelcomePage.html b/src/main/java/com/commafeed/frontend/pages/WelcomePage.html deleted file mode 100644 index 3048b192..00000000 --- a/src/main/java/com/commafeed/frontend/pages/WelcomePage.html +++ /dev/null @@ -1,81 +0,0 @@ - - - - -
-
- -
-
-
-

Login

- -
-
-
-
-

Register

- -
-
-
- -
- -
-
-
- - diff --git a/src/main/java/com/commafeed/frontend/pages/WelcomePage.java b/src/main/java/com/commafeed/frontend/pages/WelcomePage.java deleted file mode 100644 index 5ca84a74..00000000 --- a/src/main/java/com/commafeed/frontend/pages/WelcomePage.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.commafeed.frontend.pages; - -import javax.inject.Inject; - -import org.apache.wicket.markup.html.link.BookmarkablePageLink; - -import com.commafeed.backend.services.ApplicationSettingsService; -import com.commafeed.frontend.pages.components.LoginPanel; -import com.commafeed.frontend.pages.components.RegisterPanel; - -@SuppressWarnings("serial") -public class WelcomePage extends BasePage { - - @Inject - ApplicationSettingsService applicationSettingsService; - - public WelcomePage() { - add(new BookmarkablePageLink("logo-link", getApplication().getHomePage())); - add(new BookmarkablePageLink("demo-login", DemoLoginPage.class)); - add(new LoginPanel("login")); - add(new RegisterPanel("register") { - @Override - protected void onConfigure() { - super.onConfigure(); - setVisibilityAllowed(applicationSettingsService.get().isAllowRegistrations()); - } - }); - } -} diff --git a/src/main/java/com/commafeed/frontend/pages/analytics.js b/src/main/java/com/commafeed/frontend/pages/analytics.js deleted file mode 100644 index fff4996f..00000000 --- a/src/main/java/com/commafeed/frontend/pages/analytics.js +++ /dev/null @@ -1,13 +0,0 @@ -(function(i, s, o, g, r, a, m) { - i['GoogleAnalyticsObject'] = r; - i[r] = i[r] || function() { - (i[r].q = i[r].q || []).push(arguments) - }, i[r].l = 1 * new Date(); - a = s.createElement(o), m = s.getElementsByTagName(o)[0]; - a.async = 1; - a.src = g; - m.parentNode.insertBefore(a, m) -})(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga'); - -ga('create', '${trackingCode}'); -ga('send', 'pageview'); diff --git a/src/main/java/com/commafeed/frontend/pages/components/BootstrapFeedbackPanel.java b/src/main/java/com/commafeed/frontend/pages/components/BootstrapFeedbackPanel.java deleted file mode 100644 index b965e694..00000000 --- a/src/main/java/com/commafeed/frontend/pages/components/BootstrapFeedbackPanel.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.commafeed.frontend.pages.components; - -import org.apache.wicket.behavior.AttributeAppender; -import org.apache.wicket.feedback.IFeedbackMessageFilter; -import org.apache.wicket.markup.ComponentTag; -import org.apache.wicket.markup.html.panel.FeedbackPanel; -import org.apache.wicket.model.AbstractReadOnlyModel; - -@SuppressWarnings("serial") -public class BootstrapFeedbackPanel extends FeedbackPanel { - - public BootstrapFeedbackPanel(String id) { - super(id); - init(); - } - - public BootstrapFeedbackPanel(String id, IFeedbackMessageFilter filter) { - super(id, filter); - init(); - } - - private void init() { - setOutputMarkupPlaceholderTag(true); - add(new AttributeAppender("class", new AbstractReadOnlyModel() { - - @Override - public String getObject() { - StringBuilder sb = new StringBuilder(); - if (anyMessage()) { - sb.append(" bs-fb alert"); - } - if (anyErrorMessage()) { - sb.append(" alert-error"); - } else { - sb.append(" alert-success"); - } - return sb.toString(); - } - })); - - get("feedbackul").add(new AttributeAppender("class", " unstyled")); - } - - @Override - protected void onComponentTag(ComponentTag tag) { - tag.setName("div"); - super.onComponentTag(tag); - } -} diff --git a/src/main/java/com/commafeed/frontend/pages/components/LoginPanel.html b/src/main/java/com/commafeed/frontend/pages/components/LoginPanel.html deleted file mode 100644 index 76550dab..00000000 --- a/src/main/java/com/commafeed/frontend/pages/components/LoginPanel.html +++ /dev/null @@ -1,28 +0,0 @@ - - - - - -
-
- - -
-
- - -
-
- -
- -
-
- - diff --git a/src/main/java/com/commafeed/frontend/pages/components/LoginPanel.java b/src/main/java/com/commafeed/frontend/pages/components/LoginPanel.java deleted file mode 100644 index d727262e..00000000 --- a/src/main/java/com/commafeed/frontend/pages/components/LoginPanel.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.commafeed.frontend.pages.components; - -import javax.inject.Inject; - -import org.apache.commons.lang3.StringUtils; -import org.apache.wicket.authroles.authentication.panel.SignInPanel; -import org.apache.wicket.feedback.ContainerFeedbackMessageFilter; -import org.apache.wicket.markup.html.form.Form; -import org.apache.wicket.markup.html.link.BookmarkablePageLink; - -import com.commafeed.backend.services.ApplicationSettingsService; -import com.commafeed.frontend.pages.PasswordRecoveryPage; - -@SuppressWarnings("serial") -public class LoginPanel extends SignInPanel { - - @Inject - ApplicationSettingsService applicationSettingsService; - - public LoginPanel(String id) { - super(id); - replace(new BootstrapFeedbackPanel("feedback", new ContainerFeedbackMessageFilter(this))); - Form form = (Form) get("signInForm"); - form.add(new BookmarkablePageLink("recover", PasswordRecoveryPage.class) { - @Override - protected void onConfigure() { - super.onConfigure(); - String smtpHost = applicationSettingsService.get().getSmtpHost(); - setVisibilityAllowed(StringUtils.isNotBlank(smtpHost)); - } - }); - } - -} diff --git a/src/main/java/com/commafeed/frontend/pages/components/RegisterPanel.html b/src/main/java/com/commafeed/frontend/pages/components/RegisterPanel.html deleted file mode 100644 index 8ef739e0..00000000 --- a/src/main/java/com/commafeed/frontend/pages/components/RegisterPanel.html +++ /dev/null @@ -1,25 +0,0 @@ - - - - -
-
-
- - -
-
- - -
-
- - -
-
- -
-
-
- - diff --git a/src/main/java/com/commafeed/frontend/pages/components/RegisterPanel.java b/src/main/java/com/commafeed/frontend/pages/components/RegisterPanel.java deleted file mode 100644 index 616c7055..00000000 --- a/src/main/java/com/commafeed/frontend/pages/components/RegisterPanel.java +++ /dev/null @@ -1,94 +0,0 @@ -package com.commafeed.frontend.pages.components; - -import java.util.Arrays; - -import javax.inject.Inject; - -import org.apache.wicket.authentication.IAuthenticationStrategy; -import org.apache.wicket.extensions.validation.validator.RfcCompliantEmailAddressValidator; -import org.apache.wicket.feedback.ContainerFeedbackMessageFilter; -import org.apache.wicket.markup.html.form.Form; -import org.apache.wicket.markup.html.form.PasswordTextField; -import org.apache.wicket.markup.html.form.RequiredTextField; -import org.apache.wicket.markup.html.form.StatelessForm; -import org.apache.wicket.markup.html.panel.Panel; -import org.apache.wicket.model.IModel; -import org.apache.wicket.model.Model; -import org.apache.wicket.model.PropertyModel; -import org.apache.wicket.validation.IValidatable; -import org.apache.wicket.validation.IValidator; -import org.apache.wicket.validation.ValidationError; -import org.apache.wicket.validation.validator.StringValidator; - -import com.commafeed.backend.dao.UserDAO; -import com.commafeed.backend.model.User; -import com.commafeed.backend.model.UserRole.Role; -import com.commafeed.backend.services.ApplicationSettingsService; -import com.commafeed.backend.services.UserService; -import com.commafeed.frontend.CommaFeedSession; -import com.commafeed.frontend.model.request.RegistrationRequest; - -@SuppressWarnings("serial") -public class RegisterPanel extends Panel { - - @Inject - UserDAO userDAO; - - @Inject - UserService userService; - - @Inject - ApplicationSettingsService applicationSettingsService; - - public RegisterPanel(String markupId) { - super(markupId); - - IModel model = Model.of(new RegistrationRequest()); - - Form form = new StatelessForm("form", model) { - @Override - protected void onSubmit() { - if (applicationSettingsService.get().isAllowRegistrations()) { - RegistrationRequest req = getModelObject(); - userService.register(req.getName(), req.getPassword(), req.getEmail(), Arrays.asList(Role.USER)); - - IAuthenticationStrategy strategy = getApplication().getSecuritySettings().getAuthenticationStrategy(); - strategy.save(req.getName(), req.getPassword()); - CommaFeedSession.get().signIn(req.getName(), req.getPassword()); - } - setResponsePage(getApplication().getHomePage()); - } - }; - add(form); - add(new BootstrapFeedbackPanel("feedback", new ContainerFeedbackMessageFilter(form))); - - form.add(new RequiredTextField("name", new PropertyModel(model, "name")).add(StringValidator.lengthBetween(3, 32)) - .add(new IValidator() { - @Override - public void validate(IValidatable validatable) { - String name = validatable.getValue(); - User user = userDAO.findByName(name); - if (user != null) { - validatable.error(new ValidationError("Name is already taken.")); - } - } - })); - form.add(new PasswordTextField("password", new PropertyModel(model, "password")).setResetPassword(false).add( - StringValidator.minimumLength(6))); - form.add(new RequiredTextField("email", new PropertyModel(model, "email")) { - @Override - protected String getInputType() { - return "email"; - } - }.add(RfcCompliantEmailAddressValidator.getInstance()).add(new IValidator() { - @Override - public void validate(IValidatable validatable) { - String email = validatable.getValue(); - User user = userDAO.findByEmail(email); - if (user != null) { - validatable.error(new ValidationError("Email is already taken.")); - } - } - })); - } -} diff --git a/src/main/java/com/commafeed/frontend/rest/resources/AdminREST.java b/src/main/java/com/commafeed/frontend/resource/AdminREST.java similarity index 52% rename from src/main/java/com/commafeed/frontend/rest/resources/AdminREST.java rename to src/main/java/com/commafeed/frontend/resource/AdminREST.java index 361fdc6f..aaec677d 100644 --- a/src/main/java/com/commafeed/frontend/rest/resources/AdminREST.java +++ b/src/main/java/com/commafeed/frontend/resource/AdminREST.java @@ -1,39 +1,39 @@ -package com.commafeed.frontend.rest.resources; +package com.commafeed.frontend.resource; + +import io.dropwizard.auth.Auth; +import io.dropwizard.hibernate.UnitOfWork; import java.util.Map; import java.util.Set; -import javax.inject.Inject; +import javax.ws.rs.Consumes; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; +import lombok.AllArgsConstructor; + import org.apache.commons.lang.StringUtils; import com.codahale.metrics.MetricRegistry; -import com.commafeed.backend.dao.FeedDAO; +import com.commafeed.CommaFeedApplication; +import com.commafeed.CommaFeedConfiguration; +import com.commafeed.CommaFeedConfiguration.ApplicationSettings; import com.commafeed.backend.dao.UserDAO; import com.commafeed.backend.dao.UserRoleDAO; -import com.commafeed.backend.feeds.FeedRefreshTaskGiver; -import com.commafeed.backend.feeds.FeedRefreshUpdater; -import com.commafeed.backend.feeds.FeedRefreshWorker; -import com.commafeed.backend.model.ApplicationSettings; import com.commafeed.backend.model.User; import com.commafeed.backend.model.UserRole; import com.commafeed.backend.model.UserRole.Role; -import com.commafeed.backend.services.ApplicationSettingsService; -import com.commafeed.backend.services.DatabaseCleaningService; -import com.commafeed.backend.services.FeedService; -import com.commafeed.backend.services.PasswordEncryptionService; -import com.commafeed.backend.services.UserService; -import com.commafeed.backend.startup.StartupBean; -import com.commafeed.frontend.SecurityCheck; +import com.commafeed.backend.service.DatabaseCleaningService; +import com.commafeed.backend.service.PasswordEncryptionService; +import com.commafeed.backend.service.UserService; import com.commafeed.frontend.model.UserModel; import com.commafeed.frontend.model.request.IDRequest; -import com.commafeed.frontend.rest.PrettyPrint; import com.google.common.base.Preconditions; import com.google.common.collect.Maps; import com.google.common.collect.Sets; @@ -41,51 +41,28 @@ import com.wordnik.swagger.annotations.Api; import com.wordnik.swagger.annotations.ApiOperation; import com.wordnik.swagger.annotations.ApiParam; -@SecurityCheck(Role.ADMIN) @Path("/admin") @Api(value = "/admin", description = "Operations about application administration") -public class AdminREST extends AbstractREST { +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +@AllArgsConstructor +public class AdminREST { - @Inject - FeedService feedService; + // TODO check roles - @Inject - UserService userService; - - @Inject - UserDAO userDAO; - - @Inject - UserRoleDAO userRoleDAO; - - @Inject - FeedDAO feedDAO; - - @Inject - MetricRegistry metrics; - - @Inject - DatabaseCleaningService cleaner; - - @Inject - FeedRefreshWorker feedRefreshWorker; - - @Inject - FeedRefreshUpdater feedRefreshUpdater; - - @Inject - FeedRefreshTaskGiver taskGiver; - - @Inject - PasswordEncryptionService encryptionService; - - @Inject - ApplicationSettingsService applicationSettingsService; + private final UserDAO userDAO; + private final UserRoleDAO userRoleDAO; + private final UserService userService; + private final PasswordEncryptionService encryptionService; + private final DatabaseCleaningService cleaner; + private final CommaFeedConfiguration config; + private final MetricRegistry metrics; @Path("/user/save") @POST + @UnitOfWork @ApiOperation(value = "Save or update a user", notes = "Save or update a user. If the id is not specified, a new user will be created") - public Response save(@ApiParam(required = true) UserModel userModel) { + public Response save(@Auth User user, @ApiParam(required = true) UserModel userModel) { Preconditions.checkNotNull(userModel); Preconditions.checkNotNull(userModel.getName()); @@ -103,26 +80,26 @@ public class AdminREST extends AbstractREST { return Response.status(Status.CONFLICT).entity(e.getMessage()).build(); } } else { - User user = userDAO.findById(id); - if (StartupBean.USERNAME_ADMIN.equals(user.getName()) && !userModel.isEnabled()) { + User u = userDAO.findById(id); + if (CommaFeedApplication.USERNAME_ADMIN.equals(u.getName()) && !userModel.isEnabled()) { return Response.status(Status.FORBIDDEN).entity("You cannot disable the admin user.").build(); } - user.setName(userModel.getName()); + u.setName(userModel.getName()); if (StringUtils.isNotBlank(userModel.getPassword())) { - user.setPassword(encryptionService.getEncryptedPassword(userModel.getPassword(), user.getSalt())); + u.setPassword(encryptionService.getEncryptedPassword(userModel.getPassword(), u.getSalt())); } - user.setEmail(userModel.getEmail()); - user.setDisabled(!userModel.isEnabled()); - userDAO.saveOrUpdate(user); + u.setEmail(userModel.getEmail()); + u.setDisabled(!userModel.isEnabled()); + userDAO.saveOrUpdate(u); - Set roles = userRoleDAO.findRoles(user); + Set roles = userRoleDAO.findRoles(u); if (userModel.isAdmin() && !roles.contains(Role.ADMIN)) { - userRoleDAO.saveOrUpdate(new UserRole(user, Role.ADMIN)); + userRoleDAO.saveOrUpdate(new UserRole(u, Role.ADMIN)); } else if (!userModel.isAdmin() && roles.contains(Role.ADMIN)) { - if (StartupBean.USERNAME_ADMIN.equals(user.getName())) { + if (CommaFeedApplication.USERNAME_ADMIN.equals(u.getName())) { return Response.status(Status.FORBIDDEN).entity("You cannot remove the admin role from the admin user.").build(); } - for (UserRole userRole : userRoleDAO.findAll(user)) { + for (UserRole userRole : userRoleDAO.findAll(u)) { if (userRole.getRole() == Role.ADMIN) { userRoleDAO.delete(userRole); } @@ -136,16 +113,17 @@ public class AdminREST extends AbstractREST { @Path("/user/get/{id}") @GET - @ApiOperation(value = "Get user information", notes = "Get user information", responseClass = "com.commafeed.frontend.model.UserModel") - public Response getUser(@ApiParam(value = "user id", required = true) @PathParam("id") Long id) { + @UnitOfWork + @ApiOperation(value = "Get user information", notes = "Get user information", response = UserModel.class) + public Response getUser(@Auth User user, @ApiParam(value = "user id", required = true) @PathParam("id") Long id) { Preconditions.checkNotNull(id); - User user = userDAO.findById(id); + User u = userDAO.findById(id); UserModel userModel = new UserModel(); - userModel.setId(user.getId()); - userModel.setName(user.getName()); - userModel.setEmail(user.getEmail()); - userModel.setEnabled(!user.isDisabled()); - for (UserRole role : userRoleDAO.findAll(user)) { + userModel.setId(u.getId()); + userModel.setName(u.getName()); + userModel.setEmail(u.getEmail()); + userModel.setEnabled(!u.isDisabled()); + for (UserRole role : userRoleDAO.findAll(u)) { if (role.getRole() == Role.ADMIN) { userModel.setAdmin(true); } @@ -155,21 +133,22 @@ public class AdminREST extends AbstractREST { @Path("/user/getAll") @GET - @ApiOperation(value = "Get all users", notes = "Get all users", responseClass = "List[com.commafeed.frontend.model.UserModel]") - public Response getUsers() { + @UnitOfWork + @ApiOperation(value = "Get all users", notes = "Get all users", response = UserModel.class, responseContainer = "List") + public Response getUsers(@Auth User user) { Map users = Maps.newHashMap(); for (UserRole role : userRoleDAO.findAll()) { - User user = role.getUser(); + User u = role.getUser(); Long key = user.getId(); UserModel userModel = users.get(key); if (userModel == null) { userModel = new UserModel(); - userModel.setId(user.getId()); - userModel.setName(user.getName()); - userModel.setEmail(user.getEmail()); - userModel.setEnabled(!user.isDisabled()); - userModel.setCreated(user.getCreated()); - userModel.setLastLogin(user.getLastLogin()); + userModel.setId(u.getId()); + userModel.setName(u.getName()); + userModel.setEmail(u.getEmail()); + userModel.setEnabled(!u.isDisabled()); + userModel.setCreated(u.getCreated()); + userModel.setLastLogin(u.getLastLogin()); users.put(key, userModel); } if (role.getRole() == Role.ADMIN) { @@ -181,53 +160,44 @@ public class AdminREST extends AbstractREST { @Path("/user/delete") @POST + @UnitOfWork @ApiOperation(value = "Delete a user", notes = "Delete a user, and all his subscriptions") - public Response delete(@ApiParam(required = true) IDRequest req) { + public Response delete(@Auth User user, @ApiParam(required = true) IDRequest req) { Preconditions.checkNotNull(req); Preconditions.checkNotNull(req.getId()); - User user = userDAO.findById(req.getId()); - if (user == null) { + User u = userDAO.findById(req.getId()); + if (u == null) { return Response.status(Status.NOT_FOUND).build(); } - if (StartupBean.USERNAME_ADMIN.equals(user.getName())) { + if (CommaFeedApplication.USERNAME_ADMIN.equals(u.getName())) { return Response.status(Status.FORBIDDEN).entity("You cannot delete the admin user.").build(); } - userService.unregister(user); + userService.unregister(u); return Response.ok().build(); } @Path("/settings") @GET - @ApiOperation( - value = "Retrieve application settings", - notes = "Retrieve application settings", - responseClass = "com.commafeed.backend.model.ApplicationSettings") - public Response getSettings() { - return Response.ok(applicationSettingsService.get()).build(); - } - - @Path("/settings") - @POST - @ApiOperation(value = "Save application settings", notes = "Save application settings") - public Response saveSettings(@ApiParam(required = true) ApplicationSettings settings) { - Preconditions.checkNotNull(settings); - applicationSettingsService.save(settings); - return Response.ok().build(); + @UnitOfWork + @ApiOperation(value = "Retrieve application settings", notes = "Retrieve application settings", response = ApplicationSettings.class) + public Response getSettings(@Auth User user) { + return Response.ok(config.getApplicationSettings()).build(); } @Path("/metrics") @GET - @PrettyPrint + @UnitOfWork @ApiOperation(value = "Retrieve server metrics") - public Response getMetrics() { + public Response getMetrics(@Auth User user) { return Response.ok(metrics).build(); } @Path("/cleanup/entries") @GET + @UnitOfWork @ApiOperation(value = "Entries cleanup", notes = "Delete entries without subscriptions") - public Response cleanupEntries() { + public Response cleanupEntries(@Auth User user) { Map map = Maps.newHashMap(); map.put("entries_without_subscriptions", cleaner.cleanEntriesWithoutSubscriptions()); return Response.ok(map).build(); @@ -235,8 +205,9 @@ public class AdminREST extends AbstractREST { @Path("/cleanup/feeds") @GET + @UnitOfWork @ApiOperation(value = "Feeds cleanup", notes = "Delete feeds without subscriptions") - public Response cleanupFeeds() { + public Response cleanupFeeds(@Auth User user) { Map map = Maps.newHashMap(); map.put("feeds_without_subscriptions", cleaner.cleanFeedsWithoutSubscriptions()); return Response.ok(map).build(); @@ -244,8 +215,9 @@ public class AdminREST extends AbstractREST { @Path("/cleanup/content") @GET + @UnitOfWork @ApiOperation(value = "Content cleanup", notes = "Delete contents without entries") - public Response cleanupContents() { + public Response cleanupContents(@Auth User user) { Map map = Maps.newHashMap(); map.put("contents_without_entries", cleaner.cleanContentsWithoutEntries()); return Response.ok(map).build(); diff --git a/src/main/java/com/commafeed/frontend/rest/resources/CategoryREST.java b/src/main/java/com/commafeed/frontend/resource/CategoryREST.java similarity index 76% rename from src/main/java/com/commafeed/frontend/rest/resources/CategoryREST.java rename to src/main/java/com/commafeed/frontend/resource/CategoryREST.java index 60907801..ad1f218f 100644 --- a/src/main/java/com/commafeed/frontend/rest/resources/CategoryREST.java +++ b/src/main/java/com/commafeed/frontend/resource/CategoryREST.java @@ -1,4 +1,7 @@ -package com.commafeed.frontend.rest.resources; +package com.commafeed.frontend.resource; + +import io.dropwizard.auth.Auth; +import io.dropwizard.hibernate.UnitOfWork; import java.io.StringWriter; import java.util.Collections; @@ -8,7 +11,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map; -import javax.inject.Inject; +import javax.ws.rs.Consumes; import javax.ws.rs.DefaultValue; import javax.ws.rs.GET; import javax.ws.rs.POST; @@ -19,28 +22,27 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; +import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang.ObjectUtils; import org.apache.commons.lang.StringUtils; -import org.apache.commons.lang3.ObjectUtils; +import com.commafeed.CommaFeedConfiguration; import com.commafeed.backend.cache.CacheService; import com.commafeed.backend.dao.FeedCategoryDAO; import com.commafeed.backend.dao.FeedEntryStatusDAO; import com.commafeed.backend.dao.FeedSubscriptionDAO; -import com.commafeed.backend.feeds.FeedUtils; +import com.commafeed.backend.feed.FeedUtils; import com.commafeed.backend.model.FeedCategory; import com.commafeed.backend.model.FeedEntryStatus; import com.commafeed.backend.model.FeedSubscription; import com.commafeed.backend.model.User; -import com.commafeed.backend.model.UserRole.Role; import com.commafeed.backend.model.UserSettings.ReadingMode; import com.commafeed.backend.model.UserSettings.ReadingOrder; -import com.commafeed.backend.services.ApplicationSettingsService; -import com.commafeed.backend.services.FeedEntryService; -import com.commafeed.backend.services.FeedSubscriptionService; -import com.commafeed.frontend.SecurityCheck; +import com.commafeed.backend.service.FeedEntryService; +import com.commafeed.backend.service.FeedSubscriptionService; import com.commafeed.frontend.model.Category; import com.commafeed.frontend.model.Entries; import com.commafeed.frontend.model.Entry; @@ -51,6 +53,7 @@ import com.commafeed.frontend.model.request.CategoryModificationRequest; import com.commafeed.frontend.model.request.CollapseRequest; import com.commafeed.frontend.model.request.IDRequest; import com.commafeed.frontend.model.request.MarkRequest; +import com.google.common.base.Optional; import com.google.common.base.Preconditions; import com.google.common.collect.Lists; import com.sun.syndication.feed.synd.SyndEntry; @@ -64,39 +67,28 @@ import com.wordnik.swagger.annotations.ApiParam; @Path("/category") @Api(value = "/category", description = "Operations about user categories") @Slf4j -public class CategoryREST extends AbstractREST { +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +@AllArgsConstructor +public class CategoryREST { public static final String ALL = "all"; public static final String STARRED = "starred"; - @Inject - FeedEntryStatusDAO feedEntryStatusDAO; - - @Inject - FeedEntryService feedEntryService; - - @Inject - FeedCategoryDAO feedCategoryDAO; - - @Inject - FeedSubscriptionDAO feedSubscriptionDAO; - - @Inject - FeedSubscriptionService feedSubscriptionService; - - @Inject - CacheService cache; - - @Inject - ApplicationSettingsService applicationSettingsService; + private final FeedCategoryDAO feedCategoryDAO; + private final FeedEntryStatusDAO feedEntryStatusDAO; + private final FeedSubscriptionDAO feedSubscriptionDAO; + private final FeedEntryService feedEntryService; + private final FeedSubscriptionService feedSubscriptionService; + private final CacheService cache; + private final CommaFeedConfiguration config; @Path("/entries") @GET - @ApiOperation( - value = "Get category entries", - notes = "Get a list of category entries", - responseClass = "com.commafeed.frontend.model.Entries") + @UnitOfWork + @ApiOperation(value = "Get category entries", notes = "Get a list of category entries", response = Entries.class) public Response getCategoryEntries( + @Auth User user, @ApiParam(value = "id of the category, 'all' or 'starred'", required = true) @QueryParam("id") String id, @ApiParam(value = "all entries or only unread ones", allowableValues = "all,unread", required = true) @DefaultValue("unread") @QueryParam("readType") ReadingMode readType, @ApiParam(value = "only entries newer than this") @QueryParam("newerThan") Long newerThan, @@ -136,38 +128,38 @@ public class CategoryREST extends AbstractREST { } if (ALL.equals(id)) { - entries.setName(ObjectUtils.defaultIfNull(tag, "All")); - List subs = feedSubscriptionDAO.findAll(getUser()); + entries.setName(Optional.fromNullable(tag).or("All")); + List subs = feedSubscriptionDAO.findAll(user); removeExcludedSubscriptions(subs, excludedIds); - List list = feedEntryStatusDAO.findBySubscriptions(getUser(), subs, unreadOnly, keywords, newerThanDate, - offset, limit + 1, order, true, onlyIds, tag); + List list = feedEntryStatusDAO.findBySubscriptions(user, subs, unreadOnly, keywords, newerThanDate, offset, + limit + 1, order, true, onlyIds, tag); for (FeedEntryStatus status : list) { entries.getEntries().add( - Entry.build(status, applicationSettingsService.get().getPublicUrl(), applicationSettingsService.get() + Entry.build(status, config.getApplicationSettings().getPublicUrl(), config.getApplicationSettings() .isImageProxyEnabled())); } } else if (STARRED.equals(id)) { entries.setName("Starred"); - List starred = feedEntryStatusDAO.findStarred(getUser(), newerThanDate, offset, limit + 1, order, !onlyIds); + List starred = feedEntryStatusDAO.findStarred(user, newerThanDate, offset, limit + 1, order, !onlyIds); for (FeedEntryStatus status : starred) { entries.getEntries().add( - Entry.build(status, applicationSettingsService.get().getPublicUrl(), applicationSettingsService.get() + Entry.build(status, config.getApplicationSettings().getPublicUrl(), config.getApplicationSettings() .isImageProxyEnabled())); } } else { - FeedCategory parent = feedCategoryDAO.findById(getUser(), Long.valueOf(id)); + FeedCategory parent = feedCategoryDAO.findById(user, Long.valueOf(id)); if (parent != null) { - List categories = feedCategoryDAO.findAllChildrenCategories(getUser(), parent); - List subs = feedSubscriptionDAO.findByCategories(getUser(), categories); + List categories = feedCategoryDAO.findAllChildrenCategories(user, parent); + List subs = feedSubscriptionDAO.findByCategories(user, categories); removeExcludedSubscriptions(subs, excludedIds); - List list = feedEntryStatusDAO.findBySubscriptions(getUser(), subs, unreadOnly, keywords, newerThanDate, + List list = feedEntryStatusDAO.findBySubscriptions(user, subs, unreadOnly, keywords, newerThanDate, offset, limit + 1, order, true, onlyIds, tag); for (FeedEntryStatus status : list) { entries.getEntries().add( - Entry.build(status, applicationSettingsService.get().getPublicUrl(), applicationSettingsService.get() + Entry.build(status, config.getApplicationSettings().getPublicUrl(), config.getApplicationSettings() .isImageProxyEnabled())); } entries.setName(parent.getName()); @@ -190,10 +182,11 @@ public class CategoryREST extends AbstractREST { @Path("/entriesAsFeed") @GET + @UnitOfWork @ApiOperation(value = "Get category entries as feed", notes = "Get a feed of category entries") @Produces(MediaType.APPLICATION_XML) - @SecurityCheck(value = Role.USER, apiKeyAllowed = true) public Response getCategoryEntriesAsFeed( + @Auth User user, @ApiParam(value = "id of the category, 'all' or 'starred'", required = true) @QueryParam("id") String id, @ApiParam(value = "all entries or only unread ones", allowableValues = "all,unread", required = true) @DefaultValue("all") @QueryParam("readType") ReadingMode readType, @ApiParam(value = "only entries newer than this") @QueryParam("newerThan") Long newerThan, @@ -206,8 +199,8 @@ public class CategoryREST extends AbstractREST { @ApiParam(value = "comma-separated list of excluded subscription ids") @QueryParam("excludedSubscriptionIds") String excludedSubscriptionIds, @ApiParam(value = "keep only entries tagged with this tag") @QueryParam("tag") String tag) { - Response response = getCategoryEntries(id, readType, newerThan, offset, limit, order, keywords, onlyIds, excludedSubscriptionIds, - tag); + Response response = getCategoryEntries(user, id, readType, newerThan, offset, limit, order, keywords, onlyIds, + excludedSubscriptionIds, tag); if (response.getStatus() != Status.OK.getStatusCode()) { return response; } @@ -217,7 +210,7 @@ public class CategoryREST extends AbstractREST { feed.setFeedType("rss_2.0"); feed.setTitle("CommaFeed - " + entries.getName()); feed.setDescription("CommaFeed - " + entries.getName()); - String publicUrl = applicationSettingsService.get().getPublicUrl(); + String publicUrl = config.getApplicationSettings().getPublicUrl(); feed.setLink(publicUrl); List children = Lists.newArrayList(); @@ -239,25 +232,26 @@ public class CategoryREST extends AbstractREST { @Path("/mark") @POST + @UnitOfWork @ApiOperation(value = "Mark category entries", notes = "Mark feed entries of this category as read") - public Response markCategoryEntries(@ApiParam(value = "category id, or 'all'", required = true) MarkRequest req) { + public Response markCategoryEntries(@Auth User user, @ApiParam(value = "category id, or 'all'", required = true) MarkRequest req) { Preconditions.checkNotNull(req); Preconditions.checkNotNull(req.getId()); Date olderThan = req.getOlderThan() == null ? null : new Date(req.getOlderThan()); if (ALL.equals(req.getId())) { - List subs = feedSubscriptionDAO.findAll(getUser()); + List subs = feedSubscriptionDAO.findAll(user); removeExcludedSubscriptions(subs, req.getExcludedSubscriptions()); - feedEntryService.markSubscriptionEntries(getUser(), subs, olderThan); + feedEntryService.markSubscriptionEntries(user, subs, olderThan); } else if (STARRED.equals(req.getId())) { - feedEntryService.markStarredEntries(getUser(), olderThan); + feedEntryService.markStarredEntries(user, olderThan); } else { - FeedCategory parent = feedCategoryDAO.findById(getUser(), Long.valueOf(req.getId())); - List categories = feedCategoryDAO.findAllChildrenCategories(getUser(), parent); - List subs = feedSubscriptionDAO.findByCategories(getUser(), categories); + FeedCategory parent = feedCategoryDAO.findById(user, Long.valueOf(req.getId())); + List categories = feedCategoryDAO.findAllChildrenCategories(user, parent); + List subs = feedSubscriptionDAO.findByCategories(user, categories); removeExcludedSubscriptions(subs, req.getExcludedSubscriptions()); - feedEntryService.markSubscriptionEntries(getUser(), subs, olderThan); + feedEntryService.markSubscriptionEntries(user, subs, olderThan); } return Response.ok().build(); } @@ -276,14 +270,15 @@ public class CategoryREST extends AbstractREST { @Path("/add") @POST - @ApiOperation(value = "Add a category", notes = "Add a new feed category", responseClass = "java.lang.Long") - public Response addCategory(@ApiParam(required = true) AddCategoryRequest req) { + @UnitOfWork + @ApiOperation(value = "Add a category", notes = "Add a new feed category", response = Long.class) + public Response addCategory(@Auth User user, @ApiParam(required = true) AddCategoryRequest req) { Preconditions.checkNotNull(req); Preconditions.checkNotNull(req.getName()); FeedCategory cat = new FeedCategory(); cat.setName(req.getName()); - cat.setUser(getUser()); + cat.setUser(user); cat.setPosition(0); String parentId = req.getParentId(); if (parentId != null && !ALL.equals(parentId)) { @@ -292,26 +287,27 @@ public class CategoryREST extends AbstractREST { cat.setParent(parent); } feedCategoryDAO.saveOrUpdate(cat); - cache.invalidateUserRootCategory(getUser()); + cache.invalidateUserRootCategory(user); return Response.ok(cat.getId()).build(); } @POST @Path("/delete") + @UnitOfWork @ApiOperation(value = "Delete a category", notes = "Delete an existing feed category") - public Response deleteCategory(@ApiParam(required = true) IDRequest req) { + public Response deleteCategory(@Auth User user, @ApiParam(required = true) IDRequest req) { Preconditions.checkNotNull(req); Preconditions.checkNotNull(req.getId()); - FeedCategory cat = feedCategoryDAO.findById(getUser(), req.getId()); + FeedCategory cat = feedCategoryDAO.findById(user, req.getId()); if (cat != null) { - List subs = feedSubscriptionDAO.findByCategory(getUser(), cat); + List subs = feedSubscriptionDAO.findByCategory(user, cat); for (FeedSubscription sub : subs) { sub.setCategory(null); } feedSubscriptionDAO.saveOrUpdate(subs); - List categories = feedCategoryDAO.findAllChildrenCategories(getUser(), cat); + List categories = feedCategoryDAO.findAllChildrenCategories(user, cat); for (FeedCategory child : categories) { if (!child.getId().equals(cat.getId()) && child.getParent().getId().equals(cat.getId())) { child.setParent(null); @@ -320,7 +316,7 @@ public class CategoryREST extends AbstractREST { feedCategoryDAO.saveOrUpdate(categories); feedCategoryDAO.delete(cat); - cache.invalidateUserRootCategory(getUser()); + cache.invalidateUserRootCategory(user); return Response.ok().build(); } else { return Response.status(Status.NOT_FOUND).build(); @@ -329,12 +325,13 @@ public class CategoryREST extends AbstractREST { @POST @Path("/modify") + @UnitOfWork @ApiOperation(value = "Rename a category", notes = "Rename an existing feed category") - public Response modifyCategory(@ApiParam(required = true) CategoryModificationRequest req) { + public Response modifyCategory(@Auth User user, @ApiParam(required = true) CategoryModificationRequest req) { Preconditions.checkNotNull(req); Preconditions.checkNotNull(req.getId()); - FeedCategory category = feedCategoryDAO.findById(getUser(), req.getId()); + FeedCategory category = feedCategoryDAO.findById(user, req.getId()); if (StringUtils.isNotBlank(req.getName())) { category.setName(req.getName()); @@ -343,12 +340,12 @@ public class CategoryREST extends AbstractREST { FeedCategory parent = null; if (req.getParentId() != null && !CategoryREST.ALL.equals(req.getParentId()) && !StringUtils.equals(req.getParentId(), String.valueOf(req.getId()))) { - parent = feedCategoryDAO.findById(getUser(), Long.valueOf(req.getParentId())); + parent = feedCategoryDAO.findById(user, Long.valueOf(req.getParentId())); } category.setParent(parent); if (req.getPosition() != null) { - List categories = feedCategoryDAO.findByParent(getUser(), parent); + List categories = feedCategoryDAO.findByParent(user, parent); Collections.sort(categories, new Comparator() { @Override public int compare(FeedCategory o1, FeedCategory o2) { @@ -376,44 +373,42 @@ public class CategoryREST extends AbstractREST { } feedCategoryDAO.saveOrUpdate(category); - cache.invalidateUserRootCategory(getUser()); + cache.invalidateUserRootCategory(user); return Response.ok().build(); } @POST @Path("/collapse") + @UnitOfWork @ApiOperation(value = "Collapse a category", notes = "Save collapsed or expanded status for a category") - public Response collapse(@ApiParam(required = true) CollapseRequest req) { + public Response collapse(@Auth User user, @ApiParam(required = true) CollapseRequest req) { Preconditions.checkNotNull(req); Preconditions.checkNotNull(req.getId()); - FeedCategory category = feedCategoryDAO.findById(getUser(), Long.valueOf(req.getId())); + FeedCategory category = feedCategoryDAO.findById(user, Long.valueOf(req.getId())); if (category == null) { return Response.status(Status.NOT_FOUND).build(); } category.setCollapsed(req.isCollapse()); feedCategoryDAO.saveOrUpdate(category); - cache.invalidateUserRootCategory(getUser()); + cache.invalidateUserRootCategory(user); return Response.ok().build(); } @GET @Path("/unreadCount") - @ApiOperation(value = "Get unread count for feed subscriptions", responseClass = "List[com.commafeed.frontend.model.UnreadCount]") - public Response getUnreadCount() { - Map unreadCount = feedSubscriptionService.getUnreadCount(getUser()); + @UnitOfWork + @ApiOperation(value = "Get unread count for feed subscriptions", response = UnreadCount.class, responseContainer = "List") + public Response getUnreadCount(@Auth User user) { + Map unreadCount = feedSubscriptionService.getUnreadCount(user); return Response.ok(Lists.newArrayList(unreadCount.values())).build(); } @GET @Path("/get") - @ApiOperation( - value = "Get feed categories", - notes = "Get all categories and subscriptions of the user", - responseClass = "com.commafeed.frontend.model.Category") - public Response getSubscriptions() { - User user = getUser(); - + @UnitOfWork + @ApiOperation(value = "Get feed categories", notes = "Get all categories and subscriptions of the user", response = Category.class) + public Response getSubscriptions(@Auth User user) { Category root = cache.getUserRootCategory(user); if (root == null) { log.debug("tree cache miss for {}", user.getId()); @@ -460,7 +455,7 @@ public class CategoryREST extends AbstractREST { if ((id == null && subscription.getCategory() == null) || (subscription.getCategory() != null && ObjectUtils.equals(subscription.getCategory().getId(), id))) { UnreadCount uc = unreadCount.get(subscription.getId()); - Subscription sub = Subscription.build(subscription, applicationSettingsService.get().getPublicUrl(), uc); + Subscription sub = Subscription.build(subscription, config.getApplicationSettings().getPublicUrl(), uc); category.getFeeds().add(sub); } } diff --git a/src/main/java/com/commafeed/frontend/rest/resources/EntryREST.java b/src/main/java/com/commafeed/frontend/resource/EntryREST.java similarity index 52% rename from src/main/java/com/commafeed/frontend/rest/resources/EntryREST.java rename to src/main/java/com/commafeed/frontend/resource/EntryREST.java index 0669e6f0..bef9b51a 100644 --- a/src/main/java/com/commafeed/frontend/rest/resources/EntryREST.java +++ b/src/main/java/com/commafeed/frontend/resource/EntryREST.java @@ -1,19 +1,24 @@ -package com.commafeed.frontend.rest.resources; +package com.commafeed.frontend.resource; + +import io.dropwizard.auth.Auth; +import io.dropwizard.hibernate.UnitOfWork; import java.util.List; -import javax.inject.Inject; +import javax.ws.rs.Consumes; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; -import com.commafeed.backend.dao.FeedEntryStatusDAO; +import lombok.AllArgsConstructor; + import com.commafeed.backend.dao.FeedEntryTagDAO; -import com.commafeed.backend.dao.FeedSubscriptionDAO; -import com.commafeed.backend.services.ApplicationSettingsService; -import com.commafeed.backend.services.FeedEntryService; -import com.commafeed.backend.services.FeedEntryTagService; +import com.commafeed.backend.model.User; +import com.commafeed.backend.service.FeedEntryService; +import com.commafeed.backend.service.FeedEntryTagService; import com.commafeed.frontend.model.request.MarkRequest; import com.commafeed.frontend.model.request.MultipleMarkRequest; import com.commafeed.frontend.model.request.StarRequest; @@ -25,46 +30,37 @@ import com.wordnik.swagger.annotations.ApiParam; @Path("/entry") @Api(value = "/entry", description = "Operations about feed entries") -public class EntryREST extends AbstractREST { +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +@AllArgsConstructor +public class EntryREST { - @Inject - FeedEntryService feedEntryService; - - @Inject - FeedEntryStatusDAO feedEntryStatusDAO; - - @Inject - FeedSubscriptionDAO feedSubscriptionDAO; - - @Inject - FeedEntryTagDAO feedEntryTagDAO; - - @Inject - FeedEntryTagService feedEntryTagService; - - @Inject - ApplicationSettingsService applicationSettingsService; + private final FeedEntryTagDAO feedEntryTagDAO; + private final FeedEntryService feedEntryService; + private final FeedEntryTagService feedEntryTagService; @Path("/mark") @POST + @UnitOfWork @ApiOperation(value = "Mark a feed entry", notes = "Mark a feed entry as read/unread") - public Response markFeedEntry(@ApiParam(value = "Mark Request", required = true) MarkRequest req) { + public Response markFeedEntry(@Auth User user, @ApiParam(value = "Mark Request", required = true) MarkRequest req) { Preconditions.checkNotNull(req); Preconditions.checkNotNull(req.getId()); - feedEntryService.markEntry(getUser(), Long.valueOf(req.getId()), req.isRead()); + feedEntryService.markEntry(user, Long.valueOf(req.getId()), req.isRead()); return Response.ok().build(); } @Path("/markMultiple") @POST + @UnitOfWork @ApiOperation(value = "Mark multiple feed entries", notes = "Mark feed entries as read/unread") - public Response markFeedEntries(@ApiParam(value = "Multiple Mark Request", required = true) MultipleMarkRequest req) { + public Response markFeedEntries(@Auth User user, @ApiParam(value = "Multiple Mark Request", required = true) MultipleMarkRequest req) { Preconditions.checkNotNull(req); Preconditions.checkNotNull(req.getRequests()); for (MarkRequest r : req.getRequests()) { - markFeedEntry(r); + markFeedEntry(user, r); } return Response.ok().build(); @@ -72,33 +68,36 @@ public class EntryREST extends AbstractREST { @Path("/star") @POST + @UnitOfWork @ApiOperation(value = "Mark a feed entry", notes = "Mark a feed entry as read/unread") - public Response starFeedEntry(@ApiParam(value = "Star Request", required = true) StarRequest req) { + public Response starFeedEntry(@Auth User user, @ApiParam(value = "Star Request", required = true) StarRequest req) { Preconditions.checkNotNull(req); Preconditions.checkNotNull(req.getId()); Preconditions.checkNotNull(req.getFeedId()); - feedEntryService.starEntry(getUser(), Long.valueOf(req.getId()), req.getFeedId(), req.isStarred()); + feedEntryService.starEntry(user, Long.valueOf(req.getId()), req.getFeedId(), req.isStarred()); return Response.ok().build(); } @Path("/tags") @GET + @UnitOfWork @ApiOperation(value = "Get list of tags for the user", notes = "Get list of tags for the user") - public Response getTags() { - List tags = feedEntryTagDAO.findByUser(getUser()); + public Response getTags(@Auth User user) { + List tags = feedEntryTagDAO.findByUser(user); return Response.ok(tags).build(); } @Path("/tag") @POST + @UnitOfWork @ApiOperation(value = "Mark a feed entry", notes = "Mark a feed entry as read/unread") - public Response tagFeedEntry(@ApiParam(value = "Tag Request", required = true) TagRequest req) { + public Response tagFeedEntry(@Auth User user, @ApiParam(value = "Tag Request", required = true) TagRequest req) { Preconditions.checkNotNull(req); Preconditions.checkNotNull(req.getEntryId()); - feedEntryTagService.updateTags(getUser(), req.getEntryId(), req.getTags()); + feedEntryTagService.updateTags(user, req.getEntryId(), req.getTags()); return Response.ok().build(); } diff --git a/src/main/java/com/commafeed/frontend/rest/resources/FeedREST.java b/src/main/java/com/commafeed/frontend/resource/FeedREST.java similarity index 70% rename from src/main/java/com/commafeed/frontend/rest/resources/FeedREST.java rename to src/main/java/com/commafeed/frontend/resource/FeedREST.java index 189aee1f..b36f5f71 100644 --- a/src/main/java/com/commafeed/frontend/rest/resources/FeedREST.java +++ b/src/main/java/com/commafeed/frontend/resource/FeedREST.java @@ -1,5 +1,9 @@ -package com.commafeed.frontend.rest.resources; +package com.commafeed.frontend.resource; +import io.dropwizard.auth.Auth; +import io.dropwizard.hibernate.UnitOfWork; + +import java.io.InputStream; import java.io.StringWriter; import java.net.URI; import java.util.Arrays; @@ -9,8 +13,6 @@ import java.util.Comparator; import java.util.Date; import java.util.List; -import javax.inject.Inject; -import javax.servlet.http.HttpServletRequest; import javax.ws.rs.Consumes; import javax.ws.rs.DefaultValue; import javax.ws.rs.GET; @@ -21,45 +23,40 @@ import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.CacheControl; -import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.ResponseBuilder; import javax.ws.rs.core.Response.Status; +import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.fileupload.FileItem; -import org.apache.commons.fileupload.FileItemFactory; -import org.apache.commons.fileupload.disk.DiskFileItemFactory; -import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.apache.commons.io.IOUtils; import org.apache.commons.lang.ObjectUtils; import org.apache.commons.lang.StringUtils; +import com.commafeed.CommaFeedApplication; +import com.commafeed.CommaFeedConfiguration; import com.commafeed.backend.cache.CacheService; import com.commafeed.backend.dao.FeedCategoryDAO; import com.commafeed.backend.dao.FeedEntryStatusDAO; import com.commafeed.backend.dao.FeedSubscriptionDAO; -import com.commafeed.backend.feeds.FaviconFetcher; -import com.commafeed.backend.feeds.FeedFetcher; -import com.commafeed.backend.feeds.FeedRefreshTaskGiver; -import com.commafeed.backend.feeds.FeedUtils; -import com.commafeed.backend.feeds.FetchedFeed; +import com.commafeed.backend.feed.FaviconFetcher; +import com.commafeed.backend.feed.FeedFetcher; +import com.commafeed.backend.feed.FeedQueues; +import com.commafeed.backend.feed.FeedUtils; +import com.commafeed.backend.feed.FetchedFeed; import com.commafeed.backend.model.Feed; import com.commafeed.backend.model.FeedCategory; import com.commafeed.backend.model.FeedEntryStatus; import com.commafeed.backend.model.FeedSubscription; -import com.commafeed.backend.model.UserRole.Role; +import com.commafeed.backend.model.User; import com.commafeed.backend.model.UserSettings.ReadingMode; import com.commafeed.backend.model.UserSettings.ReadingOrder; import com.commafeed.backend.opml.OPMLExporter; import com.commafeed.backend.opml.OPMLImporter; -import com.commafeed.backend.services.ApplicationSettingsService; -import com.commafeed.backend.services.FeedEntryService; -import com.commafeed.backend.services.FeedSubscriptionService; -import com.commafeed.backend.startup.StartupBean; -import com.commafeed.frontend.SecurityCheck; +import com.commafeed.backend.service.FeedEntryService; +import com.commafeed.backend.service.FeedSubscriptionService; import com.commafeed.frontend.model.Entries; import com.commafeed.frontend.model.Entry; import com.commafeed.frontend.model.FeedInfo; @@ -73,6 +70,7 @@ import com.commafeed.frontend.model.request.SubscribeRequest; import com.google.common.base.Preconditions; import com.google.common.base.Throwables; import com.google.common.collect.Lists; +import com.sun.jersey.multipart.FormDataParam; import com.sun.syndication.feed.opml.Opml; import com.sun.syndication.feed.synd.SyndEntry; import com.sun.syndication.feed.synd.SyndFeed; @@ -86,54 +84,30 @@ import com.wordnik.swagger.annotations.ApiParam; @Path("/feed") @Api(value = "/feed", description = "Operations about feeds") @Slf4j -public class FeedREST extends AbstractREST { +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +@AllArgsConstructor +public class FeedREST { - @Inject - StartupBean startupBean; - - @Inject - FeedCategoryDAO feedCategoryDAO; - - @Inject - FaviconFetcher faviconFetcher; - - @Inject - FeedSubscriptionDAO feedSubscriptionDAO; - - @Inject - FeedEntryService feedEntryService; - - @Inject - FeedSubscriptionService feedSubscriptionService; - - @Inject - FeedFetcher feedFetcher; - - @Inject - FeedEntryStatusDAO feedEntryStatusDAO; - - @Inject - FeedRefreshTaskGiver taskGiver; - - @Inject - OPMLImporter opmlImporter; - - @Inject - OPMLExporter opmlExporter; - - @Inject - CacheService cache; - - @Context - private HttpServletRequest request; - - @Inject - ApplicationSettingsService applicationSettingsService; + private final FeedSubscriptionDAO feedSubscriptionDAO; + private final FeedCategoryDAO feedCategoryDAO; + private final FeedEntryStatusDAO feedEntryStatusDAO; + private final FaviconFetcher faviconFetcher; + private final FeedFetcher feedFetcher; + private final FeedEntryService feedEntryService; + private final FeedSubscriptionService feedSubscriptionService; + private final FeedQueues queues; + private final OPMLImporter opmlImporter; + private final OPMLExporter opmlExporter; + private final CacheService cache; + private final CommaFeedConfiguration config; @Path("/entries") @GET - @ApiOperation(value = "Get feed entries", notes = "Get a list of feed entries", responseClass = "com.commafeed.frontend.model.Entries") + @UnitOfWork + @ApiOperation(value = "Get feed entries", notes = "Get a list of feed entries", response = Entries.class) public Response getFeedEntries( + @Auth User user, @ApiParam(value = "id of the feed", required = true) @QueryParam("id") String id, @ApiParam(value = "all entries or only unread ones", allowableValues = "all,unread", required = true) @DefaultValue("unread") @QueryParam("readType") ReadingMode readType, @ApiParam(value = "only entries newer than this") @QueryParam("newerThan") Long newerThan, @@ -161,19 +135,19 @@ public class FeedREST extends AbstractREST { Date newerThanDate = newerThan == null ? null : new Date(Long.valueOf(newerThan)); - FeedSubscription subscription = feedSubscriptionDAO.findById(getUser(), Long.valueOf(id)); + FeedSubscription subscription = feedSubscriptionDAO.findById(user, Long.valueOf(id)); if (subscription != null) { entries.setName(subscription.getTitle()); entries.setMessage(subscription.getFeed().getMessage()); entries.setErrorCount(subscription.getFeed().getErrorCount()); entries.setFeedLink(subscription.getFeed().getLink()); - List list = feedEntryStatusDAO.findBySubscriptions(getUser(), Arrays.asList(subscription), unreadOnly, - keywords, newerThanDate, offset, limit + 1, order, true, onlyIds, null); + List list = feedEntryStatusDAO.findBySubscriptions(user, Arrays.asList(subscription), unreadOnly, keywords, + newerThanDate, offset, limit + 1, order, true, onlyIds, null); for (FeedEntryStatus status : list) { entries.getEntries().add( - Entry.build(status, applicationSettingsService.get().getPublicUrl(), applicationSettingsService.get() + Entry.build(status, config.getApplicationSettings().getPublicUrl(), config.getApplicationSettings() .isImageProxyEnabled())); } @@ -194,10 +168,11 @@ public class FeedREST extends AbstractREST { @Path("/entriesAsFeed") @GET + @UnitOfWork @ApiOperation(value = "Get feed entries as a feed", notes = "Get a feed of feed entries") @Produces(MediaType.APPLICATION_XML) - @SecurityCheck(value = Role.USER, apiKeyAllowed = true) public Response getFeedEntriesAsFeed( + @Auth User user, @ApiParam(value = "id of the feed", required = true) @QueryParam("id") String id, @ApiParam(value = "all entries or only unread ones", allowableValues = "all,unread", required = true) @DefaultValue("all") @QueryParam("readType") ReadingMode readType, @ApiParam(value = "only entries newer than this") @QueryParam("newerThan") Long newerThan, @@ -208,7 +183,7 @@ public class FeedREST extends AbstractREST { value = "search for keywords in either the title or the content of the entries, separated by spaces, 3 characters minimum") @QueryParam("keywords") String keywords, @ApiParam(value = "return only entry ids") @DefaultValue("false") @QueryParam("onlyIds") boolean onlyIds) { - Response response = getFeedEntries(id, readType, newerThan, offset, limit, order, keywords, onlyIds); + Response response = getFeedEntries(user, id, readType, newerThan, offset, limit, order, keywords, onlyIds); if (response.getStatus() != Status.OK.getStatusCode()) { return response; } @@ -218,7 +193,7 @@ public class FeedREST extends AbstractREST { feed.setFeedType("rss_2.0"); feed.setTitle("CommaFeed - " + entries.getName()); feed.setDescription("CommaFeed - " + entries.getName()); - String publicUrl = applicationSettingsService.get().getPublicUrl(); + String publicUrl = config.getApplicationSettings().getPublicUrl(); feed.setLink(publicUrl); List children = Lists.newArrayList(); @@ -257,8 +232,9 @@ public class FeedREST extends AbstractREST { @POST @Path("/fetch") - @ApiOperation(value = "Fetch a feed", notes = "Fetch a feed by its url", responseClass = "com.commafeed.frontend.model.FeedInfo") - public Response fetchFeed(@ApiParam(value = "feed url", required = true) FeedInfoRequest req) { + @UnitOfWork + @ApiOperation(value = "Fetch a feed", notes = "Fetch a feed by its url", response = FeedInfo.class) + public Response fetchFeed(@Auth User user, @ApiParam(value = "feed url", required = true) FeedInfoRequest req) { Preconditions.checkNotNull(req); Preconditions.checkNotNull(req.getUrl()); @@ -274,24 +250,26 @@ public class FeedREST extends AbstractREST { @Path("/refreshAll") @GET + @UnitOfWork @ApiOperation(value = "Queue all feeds of the user for refresh", notes = "Manually add all feeds of the user to the refresh queue") - public Response queueAllForRefresh() { - feedSubscriptionService.refreshAll(getUser()); + public Response queueAllForRefresh(@Auth User user) { + feedSubscriptionService.refreshAll(user); return Response.ok().build(); } @Path("/refresh") @POST + @UnitOfWork @ApiOperation(value = "Queue a feed for refresh", notes = "Manually add a feed to the refresh queue") - public Response queueForRefresh(@ApiParam(value = "Feed id") IDRequest req) { + public Response queueForRefresh(@Auth User user, @ApiParam(value = "Feed id") IDRequest req) { Preconditions.checkNotNull(req); Preconditions.checkNotNull(req.getId()); - FeedSubscription sub = feedSubscriptionDAO.findById(getUser(), req.getId()); + FeedSubscription sub = feedSubscriptionDAO.findById(user, req.getId()); if (sub != null) { Feed feed = sub.getFeed(); - taskGiver.add(feed, true); + queues.add(feed, true); return Response.ok().build(); } return Response.ok(Status.NOT_FOUND).build(); @@ -299,41 +277,44 @@ public class FeedREST extends AbstractREST { @Path("/mark") @POST + @UnitOfWork @ApiOperation(value = "Mark feed entries", notes = "Mark feed entries as read (unread is not supported)") - public Response markFeedEntries(@ApiParam(value = "Mark request") MarkRequest req) { + public Response markFeedEntries(@Auth User user, @ApiParam(value = "Mark request") MarkRequest req) { Preconditions.checkNotNull(req); Preconditions.checkNotNull(req.getId()); Date olderThan = req.getOlderThan() == null ? null : new Date(req.getOlderThan()); - FeedSubscription subscription = feedSubscriptionDAO.findById(getUser(), Long.valueOf(req.getId())); + FeedSubscription subscription = feedSubscriptionDAO.findById(user, Long.valueOf(req.getId())); if (subscription != null) { - feedEntryService.markSubscriptionEntries(getUser(), Arrays.asList(subscription), olderThan); + feedEntryService.markSubscriptionEntries(user, Arrays.asList(subscription), olderThan); } return Response.ok().build(); } @GET @Path("/get/{id}") + @UnitOfWork @ApiOperation(value = "", notes = "") - public Response get(@ApiParam(value = "user id", required = true) @PathParam("id") Long id) { + public Response get(@Auth User user, @ApiParam(value = "user id", required = true) @PathParam("id") Long id) { Preconditions.checkNotNull(id); - FeedSubscription sub = feedSubscriptionDAO.findById(getUser(), id); + FeedSubscription sub = feedSubscriptionDAO.findById(user, id); if (sub == null) { return Response.status(Status.NOT_FOUND).build(); } - UnreadCount unreadCount = feedSubscriptionService.getUnreadCount(getUser()).get(id); - return Response.ok(Subscription.build(sub, applicationSettingsService.get().getPublicUrl(), unreadCount)).build(); + UnreadCount unreadCount = feedSubscriptionService.getUnreadCount(user).get(id); + return Response.ok(Subscription.build(sub, config.getApplicationSettings().getPublicUrl(), unreadCount)).build(); } @GET @Path("/favicon/{id}") + @UnitOfWork @ApiOperation(value = "Fetch a feed's icon", notes = "Fetch a feed's icon") - public Response getFavicon(@ApiParam(value = "subscription id") @PathParam("id") Long id) { + public Response getFavicon(@Auth User user, @ApiParam(value = "subscription id") @PathParam("id") Long id) { Preconditions.checkNotNull(id); - FeedSubscription subscription = feedSubscriptionDAO.findById(getUser(), id); + FeedSubscription subscription = feedSubscriptionDAO.findById(user, id); if (subscription == null) { return Response.status(Status.NOT_FOUND).build(); } @@ -343,7 +324,7 @@ public class FeedREST extends AbstractREST { ResponseBuilder builder = null; if (icon == null) { - String baseUrl = FeedUtils.removeTrailingSlash(applicationSettingsService.get().getPublicUrl()); + String baseUrl = FeedUtils.removeTrailingSlash(config.getApplicationSettings().getPublicUrl()); builder = Response.status(Status.MOVED_PERMANENTLY).location(URI.create(baseUrl + "/images/default_favicon.gif")); } else { builder = Response.ok(icon, "image/x-icon"); @@ -358,15 +339,16 @@ public class FeedREST extends AbstractREST { Calendar calendar = Calendar.getInstance(); calendar.add(Calendar.MONTH, 1); builder.expires(calendar.getTime()); - builder.lastModified(new Date(startupBean.getStartupTime())); + builder.lastModified(CommaFeedApplication.STARTUP_TIME); return builder.build(); } @POST @Path("/subscribe") + @UnitOfWork @ApiOperation(value = "Subscribe to a feed", notes = "Subscribe to a feed") - public Response subscribe(@ApiParam(value = "subscription request", required = true) SubscribeRequest req) { + public Response subscribe(@Auth User user, @ApiParam(value = "subscription request", required = true) SubscribeRequest req) { Preconditions.checkNotNull(req); Preconditions.checkNotNull(req.getTitle()); Preconditions.checkNotNull(req.getUrl()); @@ -380,9 +362,9 @@ public class FeedREST extends AbstractREST { category = feedCategoryDAO.findById(Long.valueOf(req.getCategoryId())); } FeedInfo info = fetchFeedInternal(url); - feedSubscriptionService.subscribe(getUser(), info.getUrl(), req.getTitle(), category); + feedSubscriptionService.subscribe(user, info.getUrl(), req.getTitle(), category); } catch (Exception e) { - log.info("Failed to subscribe to URL {}: {}", url, e.getMessage()); + log.error("Failed to subscribe to URL {}: {}", url, e.getMessage(), e); return Response.status(Status.SERVICE_UNAVAILABLE).entity("Failed to subscribe to URL " + url + ": " + e.getMessage()).build(); } return Response.ok().build(); @@ -390,8 +372,9 @@ public class FeedREST extends AbstractREST { @GET @Path("/subscribe") + @UnitOfWork @ApiOperation(value = "Subscribe to a feed", notes = "Subscribe to a feed") - public Response subscribe(@ApiParam(value = "feed url", required = true) @QueryParam("url") String url) { + public Response subscribe(@Auth User user, @ApiParam(value = "feed url", required = true) @QueryParam("url") String url) { try { Preconditions.checkNotNull(url); @@ -400,11 +383,11 @@ public class FeedREST extends AbstractREST { url = fetchFeedInternal(url).getUrl(); FeedInfo info = fetchFeedInternal(url); - feedSubscriptionService.subscribe(getUser(), info.getUrl(), info.getTitle(), null); + feedSubscriptionService.subscribe(user, info.getUrl(), info.getTitle(), null); } catch (Exception e) { log.info("Could not subscribe to url {} : {}", url, e.getMessage()); } - return Response.temporaryRedirect(URI.create(applicationSettingsService.get().getPublicUrl())).build(); + return Response.temporaryRedirect(URI.create(config.getApplicationSettings().getPublicUrl())).build(); } private String prependHttp(String url) { @@ -416,12 +399,13 @@ public class FeedREST extends AbstractREST { @POST @Path("/unsubscribe") + @UnitOfWork @ApiOperation(value = "Unsubscribe from a feed", notes = "Unsubscribe from a feed") - public Response unsubscribe(@ApiParam(required = true) IDRequest req) { + public Response unsubscribe(@Auth User user, @ApiParam(required = true) IDRequest req) { Preconditions.checkNotNull(req); Preconditions.checkNotNull(req.getId()); - boolean deleted = feedSubscriptionService.unsubscribe(getUser(), req.getId()); + boolean deleted = feedSubscriptionService.unsubscribe(user, req.getId()); if (deleted) { return Response.ok().build(); } else { @@ -431,12 +415,13 @@ public class FeedREST extends AbstractREST { @POST @Path("/modify") + @UnitOfWork @ApiOperation(value = "Modify a subscription", notes = "Modify a feed subscription") - public Response modify(@ApiParam(value = "subscription id", required = true) FeedModificationRequest req) { + public Response modify(@Auth User user, @ApiParam(value = "subscription id", required = true) FeedModificationRequest req) { Preconditions.checkNotNull(req); Preconditions.checkNotNull(req.getId()); - FeedSubscription subscription = feedSubscriptionDAO.findById(getUser(), req.getId()); + FeedSubscription subscription = feedSubscriptionDAO.findById(user, req.getId()); if (StringUtils.isNotBlank(req.getName())) { subscription.setTitle(req.getName()); @@ -444,12 +429,12 @@ public class FeedREST extends AbstractREST { FeedCategory parent = null; if (req.getCategoryId() != null && !CategoryREST.ALL.equals(req.getCategoryId())) { - parent = feedCategoryDAO.findById(getUser(), Long.valueOf(req.getCategoryId())); + parent = feedCategoryDAO.findById(user, Long.valueOf(req.getCategoryId())); } subscription.setCategory(parent); if (req.getPosition() != null) { - List subs = feedSubscriptionDAO.findByCategory(getUser(), parent); + List subs = feedSubscriptionDAO.findByCategory(user, parent); Collections.sort(subs, new Comparator() { @Override public int compare(FeedSubscription o1, FeedSubscription o2) { @@ -475,49 +460,43 @@ public class FeedREST extends AbstractREST { } else { feedSubscriptionDAO.saveOrUpdate(subscription); } - cache.invalidateUserRootCategory(getUser()); + cache.invalidateUserRootCategory(user); return Response.ok().build(); } @POST @Path("/import") + @UnitOfWork @Consumes(MediaType.MULTIPART_FORM_DATA) @ApiOperation(value = "OPML import", notes = "Import an OPML file, posted as a FORM with the 'file' name") - public Response importOpml() { + public Response importOpml(@Auth User user, @FormDataParam("file") InputStream input) { - String publicUrl = applicationSettingsService.get().getPublicUrl(); + String publicUrl = config.getApplicationSettings().getPublicUrl(); if (StringUtils.isBlank(publicUrl)) { throw new WebApplicationException(Response.status(Status.INTERNAL_SERVER_ERROR) .entity("Set the public URL in the admin section.").build()); } - if (StartupBean.USERNAME_DEMO.equals(getUser().getName())) { + if (CommaFeedApplication.USERNAME_DEMO.equals(user.getName())) { return Response.status(Status.FORBIDDEN).entity("Import is disabled for the demo account").build(); } try { - FileItemFactory factory = new DiskFileItemFactory(1000000, null); - ServletFileUpload upload = new ServletFileUpload(factory); - for (FileItem item : upload.parseRequest(request)) { - if ("file".equals(item.getFieldName())) { - String opml = IOUtils.toString(item.getInputStream(), "UTF-8"); - if (StringUtils.isNotBlank(opml)) { - opmlImporter.importOpml(getUser(), opml); - } - break; - } - } + String opml = IOUtils.toString(input, "UTF-8"); + opmlImporter.importOpml(user, opml); } catch (Exception e) { + log.error(e.getMessage(), e); throw new WebApplicationException(Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build()); } - return Response.temporaryRedirect(URI.create(applicationSettingsService.get().getPublicUrl())).build(); + return Response.seeOther(URI.create(config.getApplicationSettings().getPublicUrl())).build(); } @GET @Path("/export") + @UnitOfWork @Produces(MediaType.APPLICATION_XML) @ApiOperation(value = "OPML export", notes = "Export an OPML file of the user's subscriptions") - public Response exportOpml() { - Opml opml = opmlExporter.export(getUser()); + public Response exportOpml(@Auth User user) { + Opml opml = opmlExporter.export(user); WireFeedOutput output = new WireFeedOutput(); String opmlString = null; try { diff --git a/src/main/java/com/commafeed/frontend/rest/resources/PubSubHubbubCallbackREST.java b/src/main/java/com/commafeed/frontend/resource/PubSubHubbubCallbackREST.java similarity index 68% rename from src/main/java/com/commafeed/frontend/rest/resources/PubSubHubbubCallbackREST.java rename to src/main/java/com/commafeed/frontend/resource/PubSubHubbubCallbackREST.java index 96ab38c5..0a207139 100644 --- a/src/main/java/com/commafeed/frontend/rest/resources/PubSubHubbubCallbackREST.java +++ b/src/main/java/com/commafeed/frontend/resource/PubSubHubbubCallbackREST.java @@ -1,10 +1,10 @@ -package com.commafeed.frontend.rest.resources; +package com.commafeed.frontend.resource; + +import io.dropwizard.hibernate.UnitOfWork; import java.util.Date; import java.util.List; -import javax.annotation.PostConstruct; -import javax.inject.Inject; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.Consumes; import javax.ws.rs.GET; @@ -17,59 +17,44 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.io.IOUtils; -import org.apache.commons.lang3.ArrayUtils; -import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang.ArrayUtils; +import org.apache.commons.lang.StringUtils; -import com.codahale.metrics.Meter; import com.codahale.metrics.MetricRegistry; +import com.commafeed.CommaFeedConfiguration; import com.commafeed.backend.dao.FeedDAO; -import com.commafeed.backend.feeds.FeedParser; -import com.commafeed.backend.feeds.FeedRefreshTaskGiver; -import com.commafeed.backend.feeds.FetchedFeed; +import com.commafeed.backend.feed.FeedParser; +import com.commafeed.backend.feed.FeedQueues; +import com.commafeed.backend.feed.FetchedFeed; import com.commafeed.backend.model.Feed; -import com.commafeed.backend.model.UserRole.Role; -import com.commafeed.backend.services.ApplicationSettingsService; -import com.commafeed.frontend.SecurityCheck; import com.google.common.base.Preconditions; @Path("/push") @Slf4j -public class PubSubHubbubCallbackREST extends AbstractREST { +@RequiredArgsConstructor +public class PubSubHubbubCallbackREST { @Context private HttpServletRequest request; - @Inject - FeedDAO feedDAO; - - @Inject - FeedParser parser; - - @Inject - FeedRefreshTaskGiver taskGiver; - - @Inject - ApplicationSettingsService applicationSettingsService; - - private Meter pushReceived; - - @PostConstruct - public void initMetrics() { - pushReceived = metrics.meter(MetricRegistry.name(getClass(), "pushReceived")); - - } + private final FeedDAO feedDAO; + private final FeedParser parser; + private final FeedQueues queues; + private final CommaFeedConfiguration config; + private final MetricRegistry metricRegistry; @Path("/callback") @GET + @UnitOfWork @Produces(MediaType.TEXT_PLAIN) - @SecurityCheck(Role.NONE) public Response verify(@QueryParam("hub.mode") String mode, @QueryParam("hub.topic") String topic, @QueryParam("hub.challenge") String challenge, @QueryParam("hub.lease_seconds") String leaseSeconds, @QueryParam("hub.verify_token") String verifyToken) { - if (!applicationSettingsService.get().isPubsubhubbub()) { + if (!config.getApplicationSettings().isPubsubhubbub()) { return Response.status(Status.FORBIDDEN).entity("pubsubhubbub is disabled").build(); } @@ -95,11 +80,11 @@ public class PubSubHubbubCallbackREST extends AbstractREST { @Path("/callback") @POST + @UnitOfWork @Consumes({ MediaType.APPLICATION_ATOM_XML, "application/rss+xml" }) - @SecurityCheck(Role.NONE) public Response callback() { - if (!applicationSettingsService.get().isPubsubhubbub()) { + if (!config.getApplicationSettings().isPubsubhubbub()) { return Response.status(Status.FORBIDDEN).entity("pubsubhubbub is disabled").build(); } @@ -124,9 +109,9 @@ public class PubSubHubbubCallbackREST extends AbstractREST { for (Feed feed : feeds) { log.debug("pushing content to queue for {}", feed.getUrl()); - taskGiver.add(feed, false); + queues.add(feed, false); } - pushReceived.mark(); + metricRegistry.meter(MetricRegistry.name(getClass(), "pushReceived")).mark(); } catch (Exception e) { log.error("Could not parse pubsub callback: " + e.getMessage()); diff --git a/src/main/java/com/commafeed/frontend/resource/ServerREST.java b/src/main/java/com/commafeed/frontend/resource/ServerREST.java new file mode 100644 index 00000000..d16d2dc4 --- /dev/null +++ b/src/main/java/com/commafeed/frontend/resource/ServerREST.java @@ -0,0 +1,68 @@ +package com.commafeed.frontend.resource; + +import io.dropwizard.auth.Auth; +import io.dropwizard.hibernate.UnitOfWork; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; + +import lombok.AllArgsConstructor; + +import com.commafeed.CommaFeedConfiguration; +import com.commafeed.backend.HttpGetter; +import com.commafeed.backend.HttpGetter.HttpResult; +import com.commafeed.backend.feed.FeedUtils; +import com.commafeed.backend.model.User; +import com.commafeed.backend.service.ApplicationPropertiesService; +import com.commafeed.frontend.model.ServerInfo; +import com.wordnik.swagger.annotations.Api; +import com.wordnik.swagger.annotations.ApiOperation; + +@Path("/server") +@Api(value = "/server", description = "Operations about server infos") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +@AllArgsConstructor +public class ServerREST { + + private final HttpGetter httpGetter; + private final CommaFeedConfiguration config; + private final ApplicationPropertiesService applicationPropertiesService; + + @Path("/get") + @GET + @UnitOfWork + @ApiOperation(value = "Get server infos", notes = "Get server infos", response = ServerInfo.class) + public Response get(@Auth User user) { + ServerInfo infos = new ServerInfo(); + infos.setAnnouncement(config.getApplicationSettings().getAnnouncement()); + infos.setVersion(applicationPropertiesService.getVersion()); + infos.setGitCommit(applicationPropertiesService.getGitCommit()); + return Response.ok(infos).build(); + } + + @Path("/proxy") + @GET + @UnitOfWork + @ApiOperation(value = "proxy image") + @Produces("image/png") + public Response get(@Auth User user, @QueryParam("u") String url) { + if (!config.getApplicationSettings().isImageProxyEnabled()) { + return Response.status(Status.FORBIDDEN).build(); + } + + url = FeedUtils.imageProxyDecoder(url); + try { + HttpResult result = httpGetter.getBinary(url, 20000); + return Response.ok(result.getContent()).build(); + } catch (Exception e) { + return Response.status(Status.SERVICE_UNAVAILABLE).entity(e.getMessage()).build(); + } + } +} diff --git a/src/main/java/com/commafeed/frontend/rest/resources/UserREST.java b/src/main/java/com/commafeed/frontend/resource/UserREST.java similarity index 73% rename from src/main/java/com/commafeed/frontend/rest/resources/UserREST.java rename to src/main/java/com/commafeed/frontend/resource/UserREST.java index d790be9e..b8ff3bcf 100644 --- a/src/main/java/com/commafeed/frontend/rest/resources/UserREST.java +++ b/src/main/java/com/commafeed/frontend/resource/UserREST.java @@ -1,16 +1,24 @@ -package com.commafeed.frontend.rest.resources; +package com.commafeed.frontend.resource; + +import io.dropwizard.auth.Auth; +import io.dropwizard.hibernate.UnitOfWork; import java.util.Arrays; -import javax.inject.Inject; +import javax.ws.rs.Consumes; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; +import lombok.AllArgsConstructor; + import org.apache.commons.lang.StringUtils; +import com.commafeed.CommaFeedApplication; import com.commafeed.backend.dao.UserDAO; import com.commafeed.backend.dao.UserRoleDAO; import com.commafeed.backend.dao.UserSettingsDAO; @@ -21,11 +29,8 @@ import com.commafeed.backend.model.UserSettings; import com.commafeed.backend.model.UserSettings.ReadingMode; import com.commafeed.backend.model.UserSettings.ReadingOrder; import com.commafeed.backend.model.UserSettings.ViewMode; -import com.commafeed.backend.services.ApplicationSettingsService; -import com.commafeed.backend.services.PasswordEncryptionService; -import com.commafeed.backend.services.UserService; -import com.commafeed.backend.startup.StartupBean; -import com.commafeed.frontend.SecurityCheck; +import com.commafeed.backend.service.PasswordEncryptionService; +import com.commafeed.backend.service.UserService; import com.commafeed.frontend.model.Settings; import com.commafeed.frontend.model.UserModel; import com.commafeed.frontend.model.request.ProfileModificationRequest; @@ -37,44 +42,30 @@ import com.wordnik.swagger.annotations.ApiParam; @Path("/user") @Api(value = "/user", description = "Operations about the user") -public class UserREST extends AbstractREST { +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +@AllArgsConstructor +public class UserREST { - @Inject - UserDAO userDAO; - - @Inject - UserSettingsDAO userSettingsDAO; - - @Inject - UserRoleDAO userRoleDAO; - - @Inject - StartupBean startupBean; - - @Inject - UserService userService; - - @Inject - PasswordEncryptionService encryptionService; - - @Inject - ApplicationSettingsService applicationSettingsService; + private final UserDAO userDAO; + private final UserRoleDAO userRoleDAO; + private final UserSettingsDAO userSettingsDAO; + private final UserService userService; + private final PasswordEncryptionService encryptionService; @Path("/settings") @GET - @ApiOperation( - value = "Retrieve user settings", - notes = "Retrieve user settings", - responseClass = "com.commafeed.frontend.model.Settings") - public Response getSettings() { + @UnitOfWork + @ApiOperation(value = "Retrieve user settings", notes = "Retrieve user settings", response = Settings.class) + public Response getSettings(@Auth User user) { Settings s = new Settings(); - UserSettings settings = userSettingsDAO.findByUser(getUser()); + UserSettings settings = userSettingsDAO.findByUser(user); if (settings != null) { s.setReadingMode(settings.getReadingMode().name()); s.setReadingOrder(settings.getReadingOrder().name()); s.setViewMode(settings.getViewMode().name()); s.setShowRead(settings.isShowRead()); - + s.setEmail(settings.isEmail()); s.setGmail(settings.isGmail()); s.setFacebook(settings.isFacebook()); @@ -85,7 +76,7 @@ public class UserREST extends AbstractREST { s.setInstapaper(settings.isInstapaper()); s.setBuffer(settings.isBuffer()); s.setReadability(settings.isReadability()); - + s.setScrollMarks(settings.isScrollMarks()); s.setTheme(settings.getTheme()); s.setCustomCss(settings.getCustomCss()); @@ -97,7 +88,7 @@ public class UserREST extends AbstractREST { s.setViewMode(ViewMode.title.name()); s.setShowRead(true); s.setTheme("default"); - + s.setEmail(true); s.setGmail(true); s.setFacebook(true); @@ -108,7 +99,7 @@ public class UserREST extends AbstractREST { s.setInstapaper(true); s.setBuffer(true); s.setReadability(true); - + s.setScrollMarks(true); s.setLanguage("en"); s.setScrollSpeed(400); @@ -118,18 +109,15 @@ public class UserREST extends AbstractREST { @Path("/settings") @POST + @UnitOfWork @ApiOperation(value = "Save user settings", notes = "Save user settings") - public Response saveSettings(@ApiParam Settings settings) { + public Response saveSettings(@Auth User user, @ApiParam(required = true) Settings settings) { Preconditions.checkNotNull(settings); - if (startupBean.getSupportedLanguages().get(settings.getLanguage()) == null) { - settings.setLanguage("en"); - } - - UserSettings s = userSettingsDAO.findByUser(getUser()); + UserSettings s = userSettingsDAO.findByUser(user); if (s == null) { s = new UserSettings(); - s.setUser(getUser()); + s.setUser(user); } s.setReadingMode(ReadingMode.valueOf(settings.getReadingMode())); s.setReadingOrder(ReadingOrder.valueOf(settings.getReadingOrder())); @@ -140,7 +128,7 @@ public class UserREST extends AbstractREST { s.setCustomCss(settings.getCustomCss()); s.setLanguage(settings.getLanguage()); s.setScrollSpeed(settings.getScrollSpeed()); - + s.setEmail(settings.isEmail()); s.setGmail(settings.isGmail()); s.setFacebook(settings.isFacebook()); @@ -151,7 +139,7 @@ public class UserREST extends AbstractREST { s.setInstapaper(settings.isInstapaper()); s.setBuffer(settings.isBuffer()); s.setReadability(settings.isReadability()); - + userSettingsDAO.saveOrUpdate(s); return Response.ok().build(); @@ -159,9 +147,9 @@ public class UserREST extends AbstractREST { @Path("/profile") @GET - @ApiOperation(value = "Retrieve user's profile", responseClass = "com.commafeed.frontend.model.UserModel") - public Response get() { - User user = getUser(); + @UnitOfWork + @ApiOperation(value = "Retrieve user's profile", response = UserModel.class) + public Response get(@Auth User user) { UserModel userModel = new UserModel(); userModel.setId(user.getId()); userModel.setName(user.getName()); @@ -178,17 +166,16 @@ public class UserREST extends AbstractREST { @Path("/profile") @POST + @UnitOfWork @ApiOperation(value = "Save user's profile") - public Response save(@ApiParam(required = true) ProfileModificationRequest request) { - User user = getUser(); - + public Response save(@Auth User user, @ApiParam(required = true) ProfileModificationRequest request) { Preconditions.checkArgument(StringUtils.isBlank(request.getPassword()) || request.getPassword().length() >= 6); if (StringUtils.isNotBlank(request.getEmail())) { User u = userDAO.findByEmail(request.getEmail()); Preconditions.checkArgument(u == null || user.getId().equals(u.getId())); } - if (StartupBean.USERNAME_DEMO.equals(user.getName())) { + if (CommaFeedApplication.USERNAME_DEMO.equals(user.getName())) { return Response.status(Status.FORBIDDEN).build(); } @@ -201,14 +188,14 @@ public class UserREST extends AbstractREST { if (request.isNewApiKey()) { user.setApiKey(userService.generateApiKey(user)); } - userDAO.saveOrUpdate(user); + userDAO.merge(user); return Response.ok().build(); } @Path("/register") @POST + @UnitOfWork @ApiOperation(value = "Register a new account") - @SecurityCheck(Role.NONE) public Response register(@ApiParam(required = true) RegistrationRequest req) { try { userService.register(req.getName(), req.getPassword(), req.getEmail(), Arrays.asList(Role.USER)); @@ -221,12 +208,13 @@ public class UserREST extends AbstractREST { @Path("/profile/deleteAccount") @POST + @UnitOfWork @ApiOperation(value = "Delete the user account") - public Response delete() { - if (StartupBean.USERNAME_ADMIN.equals(getUser().getName()) || StartupBean.USERNAME_DEMO.equals(getUser().getName())) { + public Response delete(@Auth User user) { + if (CommaFeedApplication.USERNAME_ADMIN.equals(user.getName()) || CommaFeedApplication.USERNAME_DEMO.equals(user.getName())) { return Response.status(Status.FORBIDDEN).build(); } - userService.unregister(getUser()); + userService.unregister(user); return Response.ok().build(); } } diff --git a/src/main/java/com/commafeed/frontend/resources/CustomCssUrlRewritingProcessor.java b/src/main/java/com/commafeed/frontend/resources/CustomCssUrlRewritingProcessor.java deleted file mode 100644 index 83585a24..00000000 --- a/src/main/java/com/commafeed/frontend/resources/CustomCssUrlRewritingProcessor.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.commafeed.frontend.resources; - -import ro.isdc.wro.model.resource.processor.impl.css.CssUrlRewritingProcessor; - -public class CustomCssUrlRewritingProcessor extends CssUrlRewritingProcessor { - - /** - * ignore webjar image replacements since they won't be available at runtime anyway - */ - @Override - protected String replaceImageUrl(String cssUri, String imageUrl) { - if (cssUri.startsWith("webjar:")) { - return imageUrl; - } - return super.replaceImageUrl(cssUri, imageUrl); - } - -} diff --git a/src/main/java/com/commafeed/frontend/resources/SassImportProcessor.java b/src/main/java/com/commafeed/frontend/resources/SassImportProcessor.java deleted file mode 100644 index 18862691..00000000 --- a/src/main/java/com/commafeed/frontend/resources/SassImportProcessor.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.commafeed.frontend.resources; - -import java.io.IOException; -import java.util.List; - -import ro.isdc.wro.model.resource.Resource; -import ro.isdc.wro.model.resource.ResourceType; -import ro.isdc.wro.model.resource.SupportedResourceType; -import ro.isdc.wro.model.resource.processor.impl.css.CssImportPreProcessor; - -@SupportedResourceType(ResourceType.CSS) -public class SassImportProcessor extends CssImportPreProcessor { - - @Override - protected String doTransform(String cssContent, List foundImports) throws IOException { - for (Resource resource : foundImports) { - String uri = resource.getUri(); - int lastSlash = uri.lastIndexOf('/'); - String prefix = uri.substring(0, lastSlash); - String suffix = uri.substring(lastSlash + 1); - uri = prefix + "/_" + suffix + ".scss"; - resource.setUri(uri); - } - return super.doTransform(cssContent, foundImports); - } -} diff --git a/src/main/java/com/commafeed/frontend/resources/SassOnlyProcessor.java b/src/main/java/com/commafeed/frontend/resources/SassOnlyProcessor.java deleted file mode 100644 index 3b22d41e..00000000 --- a/src/main/java/com/commafeed/frontend/resources/SassOnlyProcessor.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.commafeed.frontend.resources; - -import java.io.IOException; -import java.io.Reader; -import java.io.Writer; - -import org.apache.commons.io.IOUtils; - -import ro.isdc.wro.extensions.processor.css.RubySassCssProcessor; -import ro.isdc.wro.model.resource.Resource; -import ro.isdc.wro.model.resource.ResourceType; -import ro.isdc.wro.model.resource.SupportedResourceType; - -@SupportedResourceType(ResourceType.CSS) -public class SassOnlyProcessor extends RubySassCssProcessor { - - @Override - public void process(Resource resource, Reader reader, Writer writer) throws IOException { - if (resource.getUri().endsWith(".sass") || resource.getUri().endsWith(".scss")) { - super.process(resource, reader, writer); - } else { - writer.write(IOUtils.toString(reader)); - } - } - -} diff --git a/src/main/java/com/commafeed/frontend/resources/TimestampProcessor.java b/src/main/java/com/commafeed/frontend/resources/TimestampProcessor.java deleted file mode 100644 index d844ff7a..00000000 --- a/src/main/java/com/commafeed/frontend/resources/TimestampProcessor.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.commafeed.frontend.resources; - -import java.io.IOException; -import java.io.Reader; -import java.io.Writer; - -import org.apache.commons.io.IOUtils; - -import ro.isdc.wro.model.resource.Resource; -import ro.isdc.wro.model.resource.ResourceType; -import ro.isdc.wro.model.resource.SupportedResourceType; -import ro.isdc.wro.model.resource.processor.ResourcePreProcessor; - -@SupportedResourceType(ResourceType.JS) -public class TimestampProcessor implements ResourcePreProcessor { - - private static final String NOW = "" + System.currentTimeMillis(); - - @Override - public void process(Resource resource, Reader reader, Writer writer) throws IOException { - String content = IOUtils.toString(reader); - content = content.replace("${timestamp}", NOW); - writer.write(content); - } - -} diff --git a/src/main/java/com/commafeed/frontend/resources/UserCustomCssReference.java b/src/main/java/com/commafeed/frontend/resources/UserCustomCssReference.java deleted file mode 100644 index f13131ce..00000000 --- a/src/main/java/com/commafeed/frontend/resources/UserCustomCssReference.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.commafeed.frontend.resources; - -import java.io.IOException; - -import org.apache.commons.lang.StringUtils; -import org.apache.wicket.request.resource.AbstractResource; -import org.apache.wicket.request.resource.IResource; -import org.apache.wicket.request.resource.ResourceReference; - -@SuppressWarnings("serial") -public abstract class UserCustomCssReference extends ResourceReference { - - public UserCustomCssReference() { - super(UserCustomCssReference.class, "custom.css"); - } - - @Override - public IResource getResource() { - return new AbstractResource() { - @Override - protected ResourceResponse newResourceResponse(Attributes attributes) { - ResourceResponse resourceResponse = new ResourceResponse(); - resourceResponse.setContentType("text/css"); - resourceResponse.setTextEncoding("UTF-8"); - resourceResponse.setWriteCallback(new WriteCallback() { - @Override - public void writeData(Attributes attributes) throws IOException { - attributes.getResponse().write(StringUtils.trimToEmpty(getCss())); - } - }); - return resourceResponse; - } - }; - } - - protected abstract String getCss(); -} diff --git a/src/main/java/com/commafeed/frontend/resources/WroAdditionalProvider.java b/src/main/java/com/commafeed/frontend/resources/WroAdditionalProvider.java deleted file mode 100644 index 27bae84f..00000000 --- a/src/main/java/com/commafeed/frontend/resources/WroAdditionalProvider.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.commafeed.frontend.resources; - -import java.util.Map; - -import ro.isdc.wro.model.resource.processor.ResourcePostProcessor; -import ro.isdc.wro.model.resource.processor.ResourcePreProcessor; -import ro.isdc.wro.model.resource.processor.support.ProcessorProvider; - -import com.google.common.collect.Maps; - -/** - * Build-time solution - * - */ -public class WroAdditionalProvider implements ProcessorProvider { - - @Override - public Map providePreProcessors() { - Map map = Maps.newHashMap(); - map.put("sassOnlyProcessor", new SassOnlyProcessor()); - map.put("sassImport", new SassImportProcessor()); - map.put("timestamp", new TimestampProcessor()); - map.put("cssUrlRewriting", new CustomCssUrlRewritingProcessor()); - return map; - } - - @Override - public Map providePostProcessors() { - return Maps.newHashMap(); - } - -} diff --git a/src/main/java/com/commafeed/frontend/resources/WroListener.java b/src/main/java/com/commafeed/frontend/resources/WroListener.java deleted file mode 100644 index 36ea5a7c..00000000 --- a/src/main/java/com/commafeed/frontend/resources/WroListener.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.commafeed.frontend.resources; - -import ro.isdc.wro.config.jmx.WroConfiguration; -import ro.isdc.wro.http.WroServletContextListener; - -import com.commafeed.backend.services.ApplicationPropertiesService; - -public class WroListener extends WroServletContextListener { - - @Override - protected WroConfiguration newConfiguration() { - WroConfiguration conf = super.newConfiguration(); - ApplicationPropertiesService properties = ApplicationPropertiesService.get(); - boolean prod = properties.isProduction(); - - conf.setResourceWatcherUpdatePeriod(prod ? 0 : 1); - conf.setDisableCache(!prod); - conf.setDebug(!prod); - return conf; - } - -} diff --git a/src/main/java/com/commafeed/frontend/resources/WroManagerFactory.java b/src/main/java/com/commafeed/frontend/resources/WroManagerFactory.java deleted file mode 100644 index ba34eff0..00000000 --- a/src/main/java/com/commafeed/frontend/resources/WroManagerFactory.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.commafeed.frontend.resources; - -import java.util.Map; - -import ro.isdc.wro.manager.factory.ConfigurableWroManagerFactory; -import ro.isdc.wro.model.resource.processor.ResourcePreProcessor; - -/** - * Runtime solution - * - */ -public class WroManagerFactory extends ConfigurableWroManagerFactory { - - @Override - protected void contributePreProcessors(Map map) { - map.put("sassOnlyProcessor", new SassOnlyProcessor()); - map.put("sassImport", new SassImportProcessor()); - map.put("timestamp", new TimestampProcessor()); - map.put("cssUrlRewriting", new CustomCssUrlRewritingProcessor()); - } - -} diff --git a/src/main/java/com/commafeed/frontend/rest/JsonProvider.java b/src/main/java/com/commafeed/frontend/rest/JsonProvider.java deleted file mode 100644 index 29cf2b6e..00000000 --- a/src/main/java/com/commafeed/frontend/rest/JsonProvider.java +++ /dev/null @@ -1,95 +0,0 @@ -package com.commafeed.frontend.rest; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.lang.annotation.Annotation; -import java.lang.reflect.Type; - -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.Consumes; -import javax.ws.rs.Produces; -import javax.ws.rs.WebApplicationException; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.MultivaluedMap; -import javax.ws.rs.ext.MessageBodyReader; -import javax.ws.rs.ext.MessageBodyWriter; -import javax.ws.rs.ext.Provider; - -import org.apache.http.HttpHeaders; - -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.ObjectWriter; - -@Provider -@Consumes(MediaType.APPLICATION_JSON) -@Produces(MediaType.APPLICATION_JSON) -public class JsonProvider implements MessageBodyReader, MessageBodyWriter { - - private static final String CONTENT_TYPE_VALUE_SUFFIX = ";charset=UTF-8"; - private static final String CACHE_CONTROL_VALUE = "no-cache"; - - private static final ObjectMapper MAPPER = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - - @Context - private HttpServletRequest request; - - @Override - public void writeTo(Object value, Class type, Type genericType, Annotation[] annotations, MediaType mediaType, - MultivaluedMap httpHeaders, OutputStream entityStream) throws IOException { - - httpHeaders.putSingle(HttpHeaders.CONTENT_TYPE, mediaType.toString() + CONTENT_TYPE_VALUE_SUFFIX); - httpHeaders.putSingle(HttpHeaders.CACHE_CONTROL, CACHE_CONTROL_VALUE); - httpHeaders.putSingle(HttpHeaders.PRAGMA, CACHE_CONTROL_VALUE); - - ObjectWriter writer = getMapper().writer(); - if (hasPrettyPrint(annotations)) { - writer = writer.withDefaultPrettyPrinter(); - } - writer.writeValue(entityStream, value); - - } - - private boolean hasPrettyPrint(Annotation[] annotations) { - boolean prettyPrint = false; - - for (Annotation annotation : annotations) { - if (PrettyPrint.class.equals(annotation.annotationType())) { - prettyPrint = true; - break; - } - } - if (!prettyPrint && request != null) { - prettyPrint = Boolean.parseBoolean(request.getParameter("pretty")); - } - return prettyPrint; - } - - @Override - public Object readFrom(Class type, Type genericType, Annotation[] annotations, MediaType mediaType, - MultivaluedMap httpHeaders, InputStream entityStream) throws IOException, WebApplicationException { - return getMapper().readValue(entityStream, type); - } - - @Override - public boolean isWriteable(Class type, Type genericType, Annotation[] annotations, MediaType mediaType) { - return true; - } - - @Override - public long getSize(Object t, Class type, Type genericType, Annotation[] annotations, MediaType mediaType) { - return -1; - } - - @Override - public boolean isReadable(Class type, Type genericType, Annotation[] annotations, MediaType mediaType) { - return true; - } - - public static ObjectMapper getMapper() { - return MAPPER; - } - -} diff --git a/src/main/java/com/commafeed/frontend/rest/PrettyPrint.java b/src/main/java/com/commafeed/frontend/rest/PrettyPrint.java deleted file mode 100644 index 5498d48a..00000000 --- a/src/main/java/com/commafeed/frontend/rest/PrettyPrint.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.commafeed.frontend.rest; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Target({ ElementType.METHOD }) -@Retention(RetentionPolicy.RUNTIME) -public @interface PrettyPrint { - -} diff --git a/src/main/java/com/commafeed/frontend/rest/RESTApplication.java b/src/main/java/com/commafeed/frontend/rest/RESTApplication.java deleted file mode 100644 index eeb42c52..00000000 --- a/src/main/java/com/commafeed/frontend/rest/RESTApplication.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.commafeed.frontend.rest; - -import java.util.Set; - -import javax.ws.rs.ApplicationPath; -import javax.ws.rs.core.Application; - -import com.commafeed.frontend.rest.resources.AdminREST; -import com.commafeed.frontend.rest.resources.CategoryREST; -import com.commafeed.frontend.rest.resources.EntryREST; -import com.commafeed.frontend.rest.resources.FeedREST; -import com.commafeed.frontend.rest.resources.PubSubHubbubCallbackREST; -import com.commafeed.frontend.rest.resources.ServerREST; -import com.commafeed.frontend.rest.resources.UserREST; -import com.google.common.collect.Sets; - -@ApplicationPath("/rest") -public class RESTApplication extends Application { - - @Override - public Set> getClasses() { - Set> set = Sets.newHashSet(); - set.add(JsonProvider.class); - - set.add(EntryREST.class); - set.add(FeedREST.class); - set.add(CategoryREST.class); - set.add(UserREST.class); - set.add(ServerREST.class); - set.add(AdminREST.class); - - set.add(PubSubHubbubCallbackREST.class); - - return set; - } -} diff --git a/src/main/java/com/commafeed/frontend/rest/resources/AbstractREST.java b/src/main/java/com/commafeed/frontend/rest/resources/AbstractREST.java deleted file mode 100644 index 2b0b2cfe..00000000 --- a/src/main/java/com/commafeed/frontend/rest/resources/AbstractREST.java +++ /dev/null @@ -1,150 +0,0 @@ -package com.commafeed.frontend.rest.resources; - -import java.lang.reflect.Method; - -import javax.annotation.PostConstruct; -import javax.inject.Inject; -import javax.interceptor.AroundInvoke; -import javax.interceptor.InvocationContext; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.ws.rs.Consumes; -import javax.ws.rs.Produces; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.HttpHeaders; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import javax.ws.rs.core.Response.Status; - -import org.apache.wicket.ThreadContext; -import org.apache.wicket.authentication.IAuthenticationStrategy; -import org.apache.wicket.authroles.authorization.strategies.role.Roles; -import org.apache.wicket.protocol.http.servlet.ServletWebRequest; -import org.apache.wicket.protocol.http.servlet.ServletWebResponse; -import org.apache.wicket.request.cycle.RequestCycle; -import org.apache.wicket.util.crypt.Base64; - -import com.codahale.metrics.MetricRegistry; -import com.commafeed.backend.dao.UserDAO; -import com.commafeed.backend.model.User; -import com.commafeed.backend.model.UserRole.Role; -import com.commafeed.frontend.CommaFeedApplication; -import com.commafeed.frontend.CommaFeedSession; -import com.commafeed.frontend.SecurityCheck; - -@Produces(MediaType.APPLICATION_JSON) -@Consumes(MediaType.APPLICATION_JSON) -@SecurityCheck(Role.USER) -public abstract class AbstractREST { - - @Context - private HttpServletRequest request; - - @Context - private HttpServletResponse response; - - @Inject - MetricRegistry metrics; - - @Inject - private UserDAO userDAO; - - @PostConstruct - public void init() { - CommaFeedApplication app = CommaFeedApplication.get(); - ServletWebRequest swreq = new ServletWebRequest(request, ""); - ServletWebResponse swresp = new ServletWebResponse(swreq, response); - RequestCycle cycle = app.createRequestCycle(swreq, swresp); - ThreadContext.setRequestCycle(cycle); - CommaFeedSession session = (CommaFeedSession) app.fetchCreateAndSetSession(cycle); - - if (session.getUser() == null) { - cookieLogin(app, session); - } - if (session.getUser() == null) { - basicHttpLogin(swreq, session); - } - } - - private void cookieLogin(CommaFeedApplication app, CommaFeedSession session) { - IAuthenticationStrategy authenticationStrategy = app.getSecuritySettings().getAuthenticationStrategy(); - String[] data = authenticationStrategy.load(); - if (data != null && data.length > 1) { - session.signIn(data[0], data[1]); - } - } - - private void basicHttpLogin(ServletWebRequest req, CommaFeedSession session) { - String value = req.getHeader(HttpHeaders.AUTHORIZATION); - if (value != null && value.startsWith("Basic ")) { - value = value.substring(6); - String decoded = new String(Base64.decodeBase64(value)); - String[] data = decoded.split(":"); - if (data != null && data.length > 1) { - session.signIn(data[0], data[1]); - } - } - } - - private void apiKeyLogin() { - String apiKey = request.getParameter("apiKey"); - User user = userDAO.findByApiKey(apiKey); - CommaFeedSession.get().setUser(user); - } - - protected User getUser() { - return CommaFeedSession.get().getUser(); - } - - @AroundInvoke - public Object intercept(InvocationContext context) throws Exception { - Method method = context.getMethod(); - - // check security - boolean allowed = true; - User user = null; - - SecurityCheck check = method.isAnnotationPresent(SecurityCheck.class) ? method.getAnnotation(SecurityCheck.class) : method - .getDeclaringClass().getAnnotation(SecurityCheck.class); - - if (check != null) { - user = getUser(); - if (user == null && check.apiKeyAllowed()) { - apiKeyLogin(); - user = getUser(); - } - - allowed = checkRole(check.value()); - } - if (!allowed) { - if (user == null) { - return Response.status(Status.UNAUTHORIZED).entity("You are not authorized to do this.").build(); - } else { - return Response.status(Status.FORBIDDEN).entity("You are not authorized to do this.").build(); - } - - } - - Object result = null; - com.codahale.metrics.Timer.Context timer = metrics.timer( - MetricRegistry.name(method.getDeclaringClass(), method.getName(), "responseTime")).time(); - try { - result = context.proceed(); - } finally { - timer.stop(); - } - - return result; - } - - private boolean checkRole(Role requiredRole) { - if (requiredRole == Role.NONE) { - return true; - } - - Roles roles = CommaFeedSession.get().getRoles(); - boolean authorized = roles.hasAnyRole(new Roles(requiredRole.name())); - return authorized; - } - -} diff --git a/src/main/java/com/commafeed/frontend/rest/resources/ServerREST.java b/src/main/java/com/commafeed/frontend/rest/resources/ServerREST.java deleted file mode 100644 index e99ebb09..00000000 --- a/src/main/java/com/commafeed/frontend/rest/resources/ServerREST.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.commafeed.frontend.rest.resources; - -import javax.inject.Inject; -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; -import javax.ws.rs.core.Response; -import javax.ws.rs.core.Response.Status; - -import com.commafeed.backend.HttpGetter; -import com.commafeed.backend.HttpGetter.HttpResult; -import com.commafeed.backend.feeds.FeedUtils; -import com.commafeed.backend.services.ApplicationPropertiesService; -import com.commafeed.backend.services.ApplicationSettingsService; -import com.commafeed.backend.startup.StartupBean; -import com.commafeed.frontend.model.ServerInfo; -import com.wordnik.swagger.annotations.Api; -import com.wordnik.swagger.annotations.ApiOperation; - -@Path("/server") -@Api(value = "/server", description = "Operations about server infos") -public class ServerREST extends AbstractREST { - - @Inject - StartupBean startupBean; - - @Inject - HttpGetter httpGetter; - - @Inject - ApplicationSettingsService applicationSettingsService; - - @Path("/get") - @GET - @ApiOperation(value = "Get server infos", notes = "Get server infos", responseClass = "com.commafeed.frontend.model.ServerInfo") - public Response get() { - ApplicationPropertiesService properties = ApplicationPropertiesService.get(); - - ServerInfo infos = new ServerInfo(); - infos.setAnnouncement(applicationSettingsService.get().getAnnouncement()); - infos.getSupportedLanguages().putAll(startupBean.getSupportedLanguages()); - infos.setVersion(properties.getVersion()); - infos.setGitCommit(properties.getGitCommit()); - return Response.ok(infos).build(); - } - - @Path("/proxy") - @GET - @ApiOperation(value = "proxy image") - @Produces("image/png") - public Response get(@QueryParam("u") String url) { - if (!applicationSettingsService.get().isImageProxyEnabled()) { - return Response.status(Status.FORBIDDEN).build(); - } - - url = FeedUtils.imageProxyDecoder(url); - try { - HttpResult result = httpGetter.getBinary(url, 20000); - return Response.ok(result.getContent()).build(); - } catch (Exception e) { - return Response.status(Status.SERVICE_UNAVAILABLE).entity(e.getMessage()).build(); - } - } -} diff --git a/src/main/java/com/commafeed/frontend/utils/InternationalizationDevelopmentFilter.java b/src/main/java/com/commafeed/frontend/utils/InternationalizationDevelopmentFilter.java deleted file mode 100644 index 96747f5a..00000000 --- a/src/main/java/com/commafeed/frontend/utils/InternationalizationDevelopmentFilter.java +++ /dev/null @@ -1,128 +0,0 @@ -package com.commafeed.frontend.utils; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.util.Properties; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import javax.inject.Inject; -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletOutputStream; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpServletResponseWrapper; - -import lombok.extern.slf4j.Slf4j; - -import org.apache.commons.io.IOUtils; - -import com.commafeed.backend.dao.UserSettingsDAO; -import com.commafeed.backend.model.UserSettings; -import com.commafeed.backend.services.ApplicationPropertiesService; -import com.commafeed.frontend.CommaFeedSession; - -/** - * Replace variables from templates on the fly in dev mode only. In production the substitution is done at build-time. - * - */ -@Slf4j -public class InternationalizationDevelopmentFilter implements Filter { - - @Inject - UserSettingsDAO userSettingsDAO; - - private boolean production = true; - - @Override - public void init(FilterConfig filterConfig) throws ServletException { - ApplicationPropertiesService properties = ApplicationPropertiesService.get(); - production = properties.isProduction(); - } - - @Override - public void destroy() { - // do nothing - } - - @Override - public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { - - if (production) { - chain.doFilter(request, response); - return; - } - - final ServletOutputStream wrapper = new ServletOutputStreamWrapper(); - ServletResponse interceptor = new HttpServletResponseWrapper((HttpServletResponse) response) { - - @Override - public ServletOutputStream getOutputStream() throws IOException { - return wrapper; - } - }; - chain.doFilter(request, interceptor); - - UserSettings settings = userSettingsDAO.findByUser(CommaFeedSession.get().getUser()); - String lang = (settings == null || settings.getLanguage() == null) ? "en" : settings.getLanguage(); - - byte[] bytes = translate(wrapper.toString(), lang).getBytes("UTF-8"); - response.setContentLength(bytes.length); - response.setCharacterEncoding("UTF-8"); - response.getOutputStream().write(bytes); - response.getOutputStream().close(); - - } - - private String translate(String content, String lang) { - Properties props = new Properties(); - InputStream is = null; - try { - is = getClass().getResourceAsStream("/i18n/" + lang + ".properties"); - props.load(new InputStreamReader(is, "UTF-8")); - } catch (Exception e) { - log.error(e.getMessage(), e); - } finally { - IOUtils.closeQuietly(is); - } - - return replace(content, props); - } - - private static final Pattern PATTERN = Pattern.compile("\\$\\{(.+?)\\}"); - - public String replace(String content, Properties props) { - Matcher m = PATTERN.matcher(content); - StringBuffer sb = new StringBuffer(); - while (m.find()) { - String var = m.group(1); - Object replacement = props.get(var); - String replacementValue = replacement == null ? var : replacement.toString().split("#")[0]; - m.appendReplacement(sb, replacementValue); - } - m.appendTail(sb); - return sb.toString(); - } - - private static class ServletOutputStreamWrapper extends ServletOutputStream { - - private ByteArrayOutputStream baos = new ByteArrayOutputStream(); - - @Override - public void write(int b) throws IOException { - baos.write(b); - } - - @Override - public String toString() { - return baos.toString(); - } - } - -} diff --git a/src/main/java/com/commafeed/frontend/utils/WicketUtils.java b/src/main/java/com/commafeed/frontend/utils/WicketUtils.java deleted file mode 100644 index 21fa782a..00000000 --- a/src/main/java/com/commafeed/frontend/utils/WicketUtils.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.commafeed.frontend.utils; - -import java.util.Map; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.wicket.markup.head.HeaderItem; -import org.apache.wicket.markup.head.IHeaderResponse; -import org.apache.wicket.markup.head.JavaScriptHeaderItem; -import org.apache.wicket.protocol.http.servlet.ServletWebRequest; -import org.apache.wicket.request.cycle.RequestCycle; -import org.apache.wicket.request.http.WebResponse; -import org.apache.wicket.request.resource.JavaScriptResourceReference; -import org.apache.wicket.util.io.IOUtils; -import org.apache.wicket.util.template.PackageTextTemplate; - -public class WicketUtils { - - public static void loadJS(IHeaderResponse response, Class klass, String fileName) { - HeaderItem result = JavaScriptHeaderItem.forReference(new JavaScriptResourceReference(klass, fileName + ".js")); - response.render(result); - } - - public static void loadJS(IHeaderResponse response, Class klass, String fileName, Map variables) { - HeaderItem result = null; - PackageTextTemplate template = null; - try { - template = new PackageTextTemplate(klass, fileName + ".js"); - String script = template.asString(variables); - result = JavaScriptHeaderItem.forScript(script, null); - } finally { - IOUtils.closeQuietly(template); - } - response.render(result); - } - - public static HttpServletRequest getHttpServletRequest() { - ServletWebRequest servletWebRequest = (ServletWebRequest) RequestCycle.get().getRequest(); - return servletWebRequest.getContainerRequest(); - } - - public static HttpServletResponse getHttpServletResponse() { - WebResponse webResponse = (WebResponse) RequestCycle.get().getResponse(); - return (HttpServletResponse) webResponse.getContainerResponse(); - } - - /** - * like wicket's Request.getClientUrl() but returns an absolute url instead of a relative one - */ - public static String getClientFullUrl() { - HttpServletRequest request = getHttpServletRequest(); - StringBuffer requestURL = request.getRequestURL(); - String queryString = request.getQueryString(); - - if (queryString == null) { - return requestURL.toString(); - } else { - return requestURL.append('?').append(queryString).toString(); - } - } -} diff --git a/src/main/java/com/commafeed/frontend/utils/exception/DisplayException.java b/src/main/java/com/commafeed/frontend/utils/exception/DisplayException.java deleted file mode 100644 index 1c3aa481..00000000 --- a/src/main/java/com/commafeed/frontend/utils/exception/DisplayException.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.commafeed.frontend.utils.exception; - -public class DisplayException extends RuntimeException { - - private static final long serialVersionUID = 1L; - - private DisplayException() { - - } - - public DisplayException(String message) { - super(message, new DisplayException()); - } - - public DisplayException(Throwable t) { - super(t.getMessage(), t); - } - - public DisplayException(String message, Throwable t) { - super(message, t); - } - -} diff --git a/src/main/java/com/commafeed/frontend/utils/exception/DisplayExceptionPage.html b/src/main/java/com/commafeed/frontend/utils/exception/DisplayExceptionPage.html deleted file mode 100644 index 2aaa6583..00000000 --- a/src/main/java/com/commafeed/frontend/utils/exception/DisplayExceptionPage.html +++ /dev/null @@ -1,27 +0,0 @@ - - - - -
- - -
-
    -
  • - -
  • -
-
- - Go back to the previous page or to the home page. - -
-

-			
-
-
- - diff --git a/src/main/java/com/commafeed/frontend/utils/exception/DisplayExceptionPage.java b/src/main/java/com/commafeed/frontend/utils/exception/DisplayExceptionPage.java deleted file mode 100644 index d94d1946..00000000 --- a/src/main/java/com/commafeed/frontend/utils/exception/DisplayExceptionPage.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.commafeed.frontend.utils.exception; - -import java.io.PrintWriter; -import java.io.StringWriter; - -import org.apache.wicket.markup.html.basic.Label; -import org.apache.wicket.markup.html.link.BookmarkablePageLink; - -import com.commafeed.frontend.pages.BasePage; - -public class DisplayExceptionPage extends BasePage { - - private static final long serialVersionUID = 1L; - - public DisplayExceptionPage(Throwable t) { - Throwable de = findDisplayException(t); - if (de != null) { - t = de; - } - - add(new Label("message", t.getMessage())); - - add(new BookmarkablePageLink("homepage", getApplication().getHomePage())); - - StringWriter stringWriter = new StringWriter(); - t.printStackTrace(new PrintWriter(stringWriter)); - t.printStackTrace(); - add(new Label("stacktrace", stringWriter.toString())); - - } - - private Throwable findDisplayException(Throwable t) { - while (t != null && !(t instanceof DisplayException)) { - t = t.getCause(); - } - return t; - } -} diff --git a/src/main/resources/META-INF/persistence.xml b/src/main/resources/META-INF/persistence.xml deleted file mode 100644 index 1cd8862a..00000000 --- a/src/main/resources/META-INF/persistence.xml +++ /dev/null @@ -1,39 +0,0 @@ - - - - org.hibernate.ejb.HibernatePersistence - ${jpa.datasource.name} - ENABLE_SELECTIVE - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/main/resources/META-INF/services/ro.isdc.wro.model.resource.processor.support.ProcessorProvider b/src/main/resources/META-INF/services/ro.isdc.wro.model.resource.processor.support.ProcessorProvider deleted file mode 100644 index 92fe1ed8..00000000 --- a/src/main/resources/META-INF/services/ro.isdc.wro.model.resource.processor.support.ProcessorProvider +++ /dev/null @@ -1 +0,0 @@ -com.commafeed.frontend.resources.WroAdditionalProvider \ No newline at end of file diff --git a/src/main/resources/changelogs/db.changelog-1.0.xml b/src/main/resources/changelogs/db.changelog-1.0.xml index 547f0f25..4d7041f3 100644 --- a/src/main/resources/changelogs/db.changelog-1.0.xml +++ b/src/main/resources/changelogs/db.changelog-1.0.xml @@ -1,7 +1,7 @@ + xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd"> 7:6d3ad493d25dd9c50067e804efc9ffcc diff --git a/src/main/resources/changelogs/db.changelog-1.1.xml b/src/main/resources/changelogs/db.changelog-1.1.xml index fa2094e0..68747189 100644 --- a/src/main/resources/changelogs/db.changelog-1.1.xml +++ b/src/main/resources/changelogs/db.changelog-1.1.xml @@ -1,7 +1,7 @@ + xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd"> diff --git a/src/main/resources/changelogs/db.changelog-1.2.xml b/src/main/resources/changelogs/db.changelog-1.2.xml index d64f564d..2139d0ce 100644 --- a/src/main/resources/changelogs/db.changelog-1.2.xml +++ b/src/main/resources/changelogs/db.changelog-1.2.xml @@ -1,6 +1,6 @@ + xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd"> diff --git a/src/main/resources/changelogs/db.changelog-1.3.xml b/src/main/resources/changelogs/db.changelog-1.3.xml index 65e576fd..691dbde5 100644 --- a/src/main/resources/changelogs/db.changelog-1.3.xml +++ b/src/main/resources/changelogs/db.changelog-1.3.xml @@ -1,6 +1,6 @@ + xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd"> diff --git a/src/main/resources/changelogs/db.changelog-1.4.xml b/src/main/resources/changelogs/db.changelog-1.4.xml index ded25898..4920edcf 100644 --- a/src/main/resources/changelogs/db.changelog-1.4.xml +++ b/src/main/resources/changelogs/db.changelog-1.4.xml @@ -1,6 +1,6 @@ + xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd"> diff --git a/src/main/resources/changelogs/db.changelog-1.5.xml b/src/main/resources/changelogs/db.changelog-1.5.xml index acd23ce5..6a188b7f 100644 --- a/src/main/resources/changelogs/db.changelog-1.5.xml +++ b/src/main/resources/changelogs/db.changelog-1.5.xml @@ -49,5 +49,9 @@ + + + + diff --git a/src/main/resources/i18n/ar.properties b/src/main/resources/i18n/ar.properties deleted file mode 100644 index b42c64ff..00000000 --- a/src/main/resources/i18n/ar.properties +++ /dev/null @@ -1,157 +0,0 @@ -global.save=حفظ -global.cancel=إلغاء -global.delete=حذف -global.required=مطلوب -global.download=تحميل -global.link=رابط -global.bookmark=مرجعية -global.close=أغلق -global.tags=Tags ####### Needs translation - -tree.subscribe=اشترك -tree.import=استورد -tree.new_category=فئة جديدة -tree.all=الكل -tree.starred=المفضل - -subscribe.feed_url=رابط المغذي -subscribe.feed_name=اسم المغذي -subscribe.category=فئة - -import.google_reader_prefix=اسمح لي استيرا المغذيات الخاص بك -import.google_reader_suffix=حساب. -import.google_download=بدلا من ذلك، يمكنك تحميل ملف subscriptions.xml الخاص بك. -import.google_download_link=تحميل من هنا. -import.xml_file=ملف OPML - -new_category.name=الإ سم -new_category.parent=الأصل - -toolbar.unread=غير مقروء -toolbar.all=الكل -toolbar.previous_entry=الإدخال السابقة -toolbar.next_entry=الإدخال التالي -toolbar.refresh=إعادة انعاش -toolbar.refresh_all=Force refresh all my feeds ####### Needs translation -toolbar.sort_by_asc_desc=الترتيب حسب التاريخ تصاعدي / تنازلي -toolbar.titles_only=العناوين فقط -toolbar.expanded_view=عرض موسع -toolbar.mark_all_as_read=اعتبر الكل مقروء -toolbar.mark_all_older_12_hours=Items older than 12 hours ####### Needs translation -toolbar.mark_all_older_day=العناصر الأقدم من يوم -toolbar.mark_all_older_week=العناصر الأقدم من أسبوع -toolbar.mark_all_older_two_weeks=العناصر الأقدم من أسبوعين -toolbar.settings=إعدادات -toolbar.profile=الملف الشخصي -toolbar.admin=المشرف -toolbar.about=معلومات حول -toolbar.logout=تسجيل الخروج -toolbar.donate=تبرع - -view.entry_source=from ####### Needs translation -view.entry_author=by ####### Needs translation -view.error_while_loading_feed=خطأ أثناء تحميل هذه التغذية -view.keep_unread=إبقائه غير مقروء -view.no_unread_items=لا يحتوي عناصر غير مقروءة. -view.mark_up_to_here=Mark as read up to here ####### Needs translation -view.search_for=searching for: ####### Needs translation -view.no_search_results=No match found for the requested keywords ####### Needs translation - -feedsearch.hint=أدخل اشتراك ... -feedsearch.help=استخدام مفتاح العودة للاختيار ومفاتيح الأسهم للتنقل. -feedsearch.result_prefix=الاشتراكات الخاصة بك: - -settings.general=General -settings.general.language=Language -settings.general.language.contribute=Contribute with translations -settings.general.show_unread=Show feeds and categories with no unread entries -settings.general.social_buttons=Show social sharing buttons -settings.general.scroll_marks=In expanded view, scrolling through entries mark them as read -settings.appearance=Appearance -settings.scroll_speed=Scrolling speed when navigating between entries (in milliseconds) ####### Needs translation -settings.scroll_speed.help=set to 0 to disable ####### Needs translation -settings.theme=Theme -settings.submit_your_theme=Submit your theme -settings.custom_css=Custom CSS - -details.feed_details=Feed details -details.url=URL -details.website=Website ####### Needs translation -details.name=Name -details.category=Category -details.position=Position -details.last_refresh=Last refresh -details.message=Last refresh message ####### Needs translation -details.next_refresh=Next refresh -details.queued_for_refresh=Queued for refresh -details.feed_url=Feed URL -details.generate_api_key_first=Generate an API key in your profile first. -details.unsubscribe=Unsubscribe -details.unsubscribe_confirmation=Are you sure you want to unsubscribe from this feed? ####### Needs translation -details.delete_category_confirmation=Are you sure you want to delete this category? ####### Needs translation -details.category_details=Category details -details.tag_details=Tag details ####### Needs translation -details.parent_category=Parent category - -profile.user_name=User name -profile.email=E-mail -profile.change_password=Change password -profile.confirm_password=Confirm password -profile.minimum_6_chars=Minimum 6 characters -profile.passwords_do_not_match=Passwords do not match -profile.api_key=API key -profile.api_key_not_generated=Not generated yet -profile.generate_new_api_key=Generate new API key -profile.generate_new_api_key_info=Changing password will generate a new API key -profile.opml_export=OPML export -profile.delete_account=Delete account -profile.delete_account_confirmation=Delete your acount? There's no turning back! ####### Needs translation - -about.rest_api=REST API -about.keyboard_shortcuts=Keyboard shortcuts -about.version=CommaFeed version ####### Needs translation -about.line1_prefix=CommaFeed is an open-source project. Sources are hosted on -about.line1_suffix=. -about.line2_prefix=If you encounter an issue, please report it on the issues page of the -about.line2_suffix=\ project. -about.line3=If you like this project, please consider a donation to support the developer and help cover the costs of keeping this website online. -about.line4=For those of you who prefer bitcoin, here is the address -about.goodies=Goodies -about.goodies.android_app=Android app ####### Needs translation -about.goodies.subscribe_url=Subscribe URL -about.goodies.chrome_extension=Chrome extension -about.goodies.firefox_extension=Firefox extension -about.goodies.opera_extension=Opera extension -about.goodies.subscribe_bookmarklet=Add subscription bookmarklet (click) -about.goodies.subscribe_bookmarklet_asc=Oldest first ####### Needs translation -about.goodies.subscribe_bookmarklet_desc=Newest first ####### Needs translation -about.goodies.next_unread_bookmarklet=Next unread item bookmarklet (drag to bookmark bar) -about.translation=Translation -about.translation.message=We need your help to translate CommaFeed. -about.translation.link=See how to contribute with translations. -about.announcements=Announcements -about.rest_api.line1=CommaFeed is built on top of JAX-RS and AngularJS. As such, a REST API is available. -about.rest_api.link_to_documentation=Link to the documentation. - -about.shortcuts.mouse_middleclick=mouse middleclick -about.shortcuts.open_next_entry=open next entry -about.shortcuts.open_previous_entry=open previous entry -about.shortcuts.spacebar=space/shift+space ####### Needs translation -about.shortcuts.move_page_down_up=moves the page down/up ####### Needs translation -about.shortcuts.focus_next_entry=set focus on next entry without opening it -about.shortcuts.focus_previous_entry=set focus on previous entry without opening it -about.shortcuts.open_next_feed=open next feed or category -about.shortcuts.open_previous_feed=open previous feed or category -about.shortcuts.open_close_current_entry=open/close current entry -about.shortcuts.open_current_entry_in_new_window=open current entry in a new window -about.shortcuts.open_current_entry_in_new_window_background=open current entry in a new window in the background -about.shortcuts.star_unstar=star/unstar current entry -about.shortcuts.mark_current_entry=mark as read/unread current entry -about.shortcuts.mark_all_as_read=mark all entries as read -about.shortcuts.open_in_new_tab_mark_as_read=open entry in new tab and mark as read -about.shortcuts.fullscreen=toggle full screen mode ####### Needs translation -about.shortcuts.font_size=increase/decrease font size of the current entry ####### Needs translation -about.shortcuts.go_to_all=go to the All view ####### Needs translation -about.shortcuts.go_to_starred=go to the Starred view ####### Needs translation -about.shortcuts.feed_search=navigate to a subscription by entering the subscription name - diff --git a/src/main/resources/i18n/ca.properties b/src/main/resources/i18n/ca.properties deleted file mode 100644 index 4f22b8b0..00000000 --- a/src/main/resources/i18n/ca.properties +++ /dev/null @@ -1,156 +0,0 @@ -global.save=Desa -global.cancel=Cancel·la -global.delete=Esborra -global.required=Requerit -global.download=Descarrega -global.link=Enllaç -global.bookmark=Adreça d'interès -global.close=Tancar -global.tags=Etiquetes - -tree.subscribe=Subscriure -tree.import=Importa -tree.new_category=Nova categoria -tree.all=Tot -tree.starred=Destacats - -subscribe.feed_url=URL del canal -subscribe.feed_name=Nom del canal -subscribe.category=Categoria - -import.google_reader_prefix=Importaré els canals del teu -import.google_reader_suffix= compte. -import.google_download=O be, carrega el teu fitxer subscriptions.xml. -import.google_download_link=Descarrega'l d'aquí. -import.xml_file=Fitxer OPML - -new_category.name=Nom -new_category.parent=Arrel - -toolbar.unread=Per llegir -toolbar.all=Tots -toolbar.previous_entry=Entrada prèvia -toolbar.next_entry=Entrada següent -toolbar.refresh=Actualitzar -toolbar.refresh_all=Força l'actualització de tots els canals -toolbar.sort_by_asc_desc=Ordenar per data asc/desc -toolbar.titles_only=Només títols -toolbar.expanded_view=Vista ampliada -toolbar.mark_all_as_read=Marcar tots llegits -toolbar.mark_all_older_12_hours=Ítems més vells de 12 hores -toolbar.mark_all_older_day=Ítems més vells d'un dia -toolbar.mark_all_older_week=Ítems més vells d'una setmana -toolbar.mark_all_older_two_weeks=Ítems més vells de dues setmanes -toolbar.settings=Configuració -toolbar.profile=Perfil -toolbar.admin=Admin -toolbar.about=Quant a -toolbar.logout=Desconnecta't -toolbar.donate=Donació - -view.entry_source=de -view.entry_author=per -view.error_while_loading_feed=Error carregant el canal -view.keep_unread=Conserva com a no llegit -view.no_unread_items=no té ítems sense llegir. -view.mark_up_to_here=Marcar com a llegit fins aquí -view.search_for=cercant: -view.no_search_results=No hi ha coincidències per les paraules clau sol·licitades - -feedsearch.hint=Introdueix una subscripció... -feedsearch.help=Utilitza la tecla de retorn per seleccionar i les tecles de cursor per navegar. -feedsearch.result_prefix=Les teves subscripcions: - -settings.general=General -settings.general.language=Idioma -settings.general.language.contribute=Contribueix amb traduccions -settings.general.show_unread=Mostrar canals i categories amb entrades sense llegir -settings.general.social_buttons=Mostrar botons per compartir en xarxes socials -settings.general.scroll_marks=A la vista ampliada si et desplaces per les entrades les marques com a llegides -settings.appearance=Aparença -settings.scroll_speed=Velocitat de desplaçament quan navegues entre entrades (en mil·lisegons) -settings.scroll_speed.help=Fixa a 0 per desactivar -settings.theme=Tema -settings.submit_your_theme=Envia un tema -settings.custom_css=CSS personalitzat - -details.feed_details=Detalls del canal -details.url=URL -details.website=Lloc web -details.name=Nom -details.category=Categoria -details.position=Posició -details.last_refresh=Darrera actualització -details.message=Darrer missatge d'actualització -details.next_refresh=Propera actualització -details.queued_for_refresh=A la cua d'actualització -details.feed_url=URL del canal -details.generate_api_key_first=Abans cal que generis una clau API en el teu perfil. -details.unsubscribe=Cancel·la la subscripció -details.unsubscribe_confirmation=Segur que vols cancel·lar la subscripció del canal? -details.delete_category_confirmation=Segur que vols esborrar la categoria? -details.category_details=Detalls de la categoria -details.tag_details=Detalls de l'etiqueta -details.parent_category=Categoria arrel - -profile.user_name=Nom d'usuari -profile.email=Adreça electrònica -profile.change_password=Canvia la contrasenya -profile.confirm_password=Confirma la contrasenya -profile.minimum_6_chars=Mínim de 6 caracters -profile.passwords_do_not_match=Les contrasenyes no coincideixen -profile.api_key=Clau API -profile.api_key_not_generated=Encara no s'ha generat -profile.generate_new_api_key=Genera una nova clau API -profile.generate_new_api_key_info=El canvi de contrasenya generarà una nova clau API -profile.opml_export=Exporta OPML -profile.delete_account=Esborra el compte -profile.delete_account_confirmation=Vols esborrar el teu compte? No ho podràs desfer! - -about.rest_api=REST API -about.keyboard_shortcuts=Dreceres de teclat -about.version=Versió de CommaFeed -about.line1_prefix=CommaFeed és un projecte de codi font obert. El codi font és hostatjat a -about.line1_suffix=. -about.line2_prefix=Si trobes un problema, si us plau informa'n a la pàgina de problemes del -about.line2_suffix=\ projecte. -about.line3=Si t'agrada el projecte, pensa en fer un donatiu per recolzar el desenvolupador i per ajudar amb les despeses de l'hostatge del lloc web. -about.line4=I pels que preferiu bitcoin, aquí teniu l'adreça -about.goodies=Afegitons -about.goodies.android_app=App Android -about.goodies.subscribe_url=URL de subscripció -about.goodies.chrome_extension=Extensió del Chrome -about.goodies.firefox_extension=Extensió del Firefox -about.goodies.opera_extension=Extensió de l'Opera -about.goodies.subscribe_bookmarklet=Afegeix bookmarklet de subscripció (clica) -about.goodies.subscribe_bookmarklet_asc=Primer els vells -about.goodies.subscribe_bookmarklet_desc=Primer els nous -about.goodies.next_unread_bookmarklet=Bookmarklet del proper ítem sense llegir (arrosega a la barra d'adreces d'interès) -about.translation=Traducció -about.translation.message=Necessitem la teva ajuda per traduir CommaFeed. -about.translation.link=Informació per contribuir amb traduccions. -about.announcements=Anuncis -about.rest_api.line1=CommaFeed funciona amb JAX-RS i AngularJS. Per tant, té disponible una API REST. -about.rest_api.link_to_documentation=Enllaç a la documentació. - -about.shortcuts.mouse_middleclick=Clic amb el botó del mig -about.shortcuts.open_next_entry=obrir entrada següent -about.shortcuts.open_previous_entry=obrir entrada prèvia -about.shortcuts.spacebar=espai/majúscula+espai -about.shortcuts.move_page_down_up=mou la pàgina avall/amunt -about.shortcuts.focus_next_entry=fixa el focus en l'entrada següent entrada sense obrir-la -about.shortcuts.focus_previous_entry=fixa el focus en l'entrada prèvia sense obrir-la -about.shortcuts.open_next_feed=obrir canal o categoria següent -about.shortcuts.open_previous_feed=obrir canal o categoria prèvia -about.shortcuts.open_close_current_entry=obre/tanca entrada actual -about.shortcuts.open_current_entry_in_new_window=obrir entrada actual en una finestra nova -about.shortcuts.open_current_entry_in_new_window_background=obrir entrada actual en una finestra nova en segon pla -about.shortcuts.star_unstar=destacar/treure destacat a l'entrada actual -about.shortcuts.mark_current_entry=marcar com a llegida/no llegida l'entrada actual -about.shortcuts.mark_all_as_read=marcar totes les entrades com a llegides -about.shortcuts.open_in_new_tab_mark_as_read=obrir entrada en una pestanya nova i marcar com a llegida -about.shortcuts.fullscreen=commutar el mode de pantalla completa -about.shortcuts.font_size=incrementar/reduir la mida de la font de l'entrada actual -about.shortcuts.go_to_all=anar a la vista de Tot -about.shortcuts.go_to_starred=anar a la vista de Destacats -about.shortcuts.feed_search=navegar a una subscripció introduint-ne el nom diff --git a/src/main/resources/i18n/cs.properties b/src/main/resources/i18n/cs.properties deleted file mode 100644 index 3398ad00..00000000 --- a/src/main/resources/i18n/cs.properties +++ /dev/null @@ -1,157 +0,0 @@ -global.save = Uložit -global.cancel = Zrušit -global.delete = Odstranit -global.required = Povinné -global.download = Stáhnout -global.link = Odkaz -global.bookmark = Záložky -global.close = Zavřít -global.tags=Tags ####### Needs translation - -tree.subscribe = Nový odběr -tree.import = Importovat -tree.new_category = Nová kategorie -tree.all = Vše -tree.starred = Oblíbené - -subscribe.feed_url = URL RSS zdroje -subscribe.feed_name = Název -subscribe.category = Kategorie - -import.google_reader_prefix = Importujte si RSS zdroje s vašeho -import.google_reader_suffix = účtu. -import.google_download = Anebo můžete nahrát váš subscriptions.xml soubor -import.google_download_link = Stáhnout jej múžete odtud -import.xml_file=Soubor OPML - -new_category.name = Název -new_category.parent = Hlavní - -toolbar.unread = Nepřečtené -toolbar.all = Vše -toolbar.previous_entry = Předchozí položka -toolbar.next_entry = Následující položka -toolbar.refresh = Obnovit -toolbar.refresh_all=Force refresh all my feeds ####### Needs translation -toolbar.sort_by_asc_desc = Seřadit podle nejnovějšího/nejstaršího -toolbar.titles_only = Zobrazit jenom titulky -toolbar.expanded_view = Rozšířený náhled -toolbar.mark_all_as_read = Označit vše jako přečtené -toolbar.mark_all_older_12_hours=Items older than 12 hours ####### Needs translation -toolbar.mark_all_older_day = Položky starší než den -toolbar.mark_all_older_week = Položky starší než týden -toolbar.mark_all_older_two_weeks = Položky starší než dva týdny -toolbar.settings = Nastavení -toolbar.profile = Profil -toolbar.admin = Admin -toolbar.about = O CommaFeed -toolbar.logout = Odhlásit -toolbar.donate = Donate - -view.entry_source = s -view.entry_author = od -view.error_while_loading_feed = Během načítání se vyskytla chyba -view.keep_unread = Označit jako nepřečtené -view.no_unread_items = nemá žádné nepřečtené položky. -view.mark_up_to_here = Až potud označit položky jako přečtené -view.search_for=searching for: ####### Needs translation -view.no_search_results=No match found for the requested keywords ####### Needs translation - -feedsearch.hint = Zadejte název pro nový odběr ... -feedsearch.help = Použijte klávesu enter pro výběr a směrové klávesy pro navigaci. -feedsearch.result_prefix = Vaše odebírání: - -settings.general = Všeobecné -settings.general.language = Jazyk -settings.general.language.contribute = Zapojte se a pomozte z překladem -settings.general.show_unread = Zobrazit položky a kategorie z přečtenými položkami -settings.general.social_buttons = Zobrazit možnosti sdílení -settings.general.scroll_marks = Skrolování v rozšířeném náhledu označí položky jako přečtené -settings.appearance = Vzhled -settings.scroll_speed=Scrolling speed when navigating between entries (in milliseconds) ####### Needs translation -settings.scroll_speed.help=set to 0 to disable ####### Needs translation -settings.theme = Motiv -settings.submit_your_theme = Nahrát vlastní motiv -settings.custom_css = Vlastní motiv (CSS) - -details.feed_details = Detail odběru -details.url = URL odkaz -details.website = Web stránka -details.name = Název -details.category = Kategorie -details.position = Pozice -details.last_refresh = Poslední obnovení -details.message=Last refresh message ####### Needs translation -details.next_refresh = Nadcházející obnovení -details.queued_for_refresh = Ve frontě na obnovu -details.feed_url = URL RSS zdroje -details.generate_api_key_first = Vygenerujte si API klíč na stránce vašeho profilu. -details.unsubscribe = Odhlásit odběr. -details.unsubscribe_confirmation=Are you sure you want to unsubscribe from this feed? ####### Needs translation -details.delete_category_confirmation=Are you sure you want to delete this category? ####### Needs translation -details.category_details = Detail kategorie -details.tag_details=Tag details ####### Needs translation -details.parent_category = Hlavní kategorie - -profile.user_name = Uživatelské jméno -profile.email = E-mail -profile.change_password = Změnit heslo -profile.confirm_password = Potvrdit heslo -profile.minimum_6_chars = Minimum je 6 znaků -profile.passwords_do_not_match = Hesla se neshodují -profile.api_key = API klíč -profile.api_key_not_generated = Není vygenerován -profile.generate_new_api_key = Vygenerovat nový API klíč -profile.generate_new_api_key_info = Změnou hesla vygenerujete nový API klíč -profile.opml_export = exportovat do formátu OPML -profile.delete_account = Odstranit účet -profile.delete_account_confirmation=Delete your acount? There's no turning back! ####### Needs translation - -about.rest_api = REST API -about.keyboard_shortcuts = Klávesové zkratky -about.version=CommaFeed version ####### Needs translation -about.line1_prefix = CommaFeed je open source projekt. Zdrojový kód je dostupný na -about.line1_suffix =. -about.line2_prefix = V případě, že narazíte na problém, ohlaste ho prosím na stránkách -about.line2_suffix = \ projektu. -about.line3 = V případě, že se vám líbí CommaFeed, zvažte prosím finanční příspěvek. Podpoříte tak budoucí vývoj a také pomůžete udržet web stránky online. -about.line4 = Bitcoin -about.goodies = Rozšíření -about.goodies.android_app = Aplikace pro zařízení Android -about.goodies.subscribe_url = URL -about.goodies.chrome_extension = Rozšíření pro prohlížeč Chrome -about.goodies.firefox_extension = Rozšíření pro prohlížeč Firefox -about.goodies.opera_extension = Rozšíření pro prohlížeč Opera -about.goodies.subscribe_bookmarklet = Bookmarklet (klikněte) -about.goodies.subscribe_bookmarklet_asc = Seřadit od nejstaršího k nejnovějšímu -about.goodies.subscribe_bookmarklet_desc = Seřadit od nejnovějšího k nejstaršímu -about.goodies.next_unread_bookmarklet = Záložka následující nepřečtené položky (protáhnout k záložkám) -about.translation = Překlad -about.translation.message = Pomozte z překladem CommaFeed. -about.translation.link = Zjistěte jak můžete pomoct s překladem. -about.announcements = Oznámení -about.rest_api.line1 = CommaFeed je postaven na JAX-RS a AngularJS. Dostupná je REST API. -about.rest_api.link_to_documentation = Dokumentace. - -about.shortcuts.mouse_middleclick = klik prostředním tlačítkem -about.shortcuts.open_next_entry = zobrazit následující položku -about.shortcuts.open_previous_entry = zobrazit předchozí položku -about.shortcuts.spacebar = space / shift + mezerník -about.shortcuts.move_page_down_up = pohyb směrem dolů/nahoru -about.shortcuts.focus_next_entry = přesun na následující položku bez jejího zobrazení -about.shortcuts.focus_previous_entry = přesun na předchozí položku bez jejího zobrazení -about.shortcuts.open_next_feed = přesun na následující odběr/kategorii -about.shortcuts.open_previous_feed = přesun na předchozí odběr/kategorii -about.shortcuts.open_close_current_entry = zobrazit/zavřít vybranou položku -about.shortcuts.open_current_entry_in_new_window = otevřít vybranou položku v novém okně -about.shortcuts.open_current_entry_in_new_window_background = otevřít vybranou položku na pozadí -about.shortcuts.star_unstar = označit vybranou položku jako oblíbenou/neoblíbenou -about.shortcuts.mark_current_entry = označit vybrané položky jako přečtené/nepřečtené -about.shortcuts.mark_all_as_read = označit všechny položky jako přečtené! -about.shortcuts.open_in_new_tab_mark_as_read = otevřít položku na nové kartě a označit ji jako přečtenou -about.shortcuts.fullscreen = přepnout zobrazení na celou obrazovku -about.shortcuts.font_size = zvětšit/zmenšit velikost písma pro vybranou položku -about.shortcuts.go_to_all=go to the All view ####### Needs translation -about.shortcuts.go_to_starred=go to the Starred view ####### Needs translation -about.shortcuts.feed_search = přejít na odběr vložením jeho názvu - diff --git a/src/main/resources/i18n/cy.properties b/src/main/resources/i18n/cy.properties deleted file mode 100644 index 84cedb6f..00000000 --- a/src/main/resources/i18n/cy.properties +++ /dev/null @@ -1,157 +0,0 @@ -global.save=Cadw -global.cancel=Diddymu -global.delete=Dileu -global.required=Gofynnol -global.download=Lawrlwytho -global.link=Dolen -global.bookmark=Nod tudalen -global.close=Cau -global.tags=Tags ####### Needs translation - -tree.subscribe=Tanysgrifio -tree.import=Mewnforio -tree.new_category=Categori newydd -tree.all=Popeth -tree.starred=Serennwyd - -subscribe.feed_url=URL Ffrwd -subscribe.feed_name=Enw Ffrwd -subscribe.category=Categori - -import.google_reader_prefix=Gad i mi fewnforio dy ffrydiau o dy -import.google_reader_suffix= gyfrif. -import.google_download=Fel arall, lanlwytha dy ffeil tanysgrifiadau.xml -import.google_download_link=Lawrlwytha fe yma. -import.xml_file=Ffeil OPML - -new_category.name=Enw -new_category.parent=Rhiant - -toolbar.unread=Heb ddarllen -toolbar.all=Popeth -toolbar.previous_entry=Eitem blaenorol -toolbar.next_entry=Eitem nesaf -toolbar.refresh=Adnewyddu -toolbar.refresh_all=Gorfodi ail-lwytho pob ffrwd -toolbar.sort_by_asc_desc=Trefnu yn ôl dyddiad -toolbar.titles_only=Teitlau yn unig -toolbar.expanded_view=Golwg estynedig -toolbar.mark_all_as_read=Nodi'r cyfan fel wedi ei ddarllen -toolbar.mark_all_older_12_hours=Items older than 12 hours ####### Needs translation -toolbar.mark_all_older_day=Eitemau hyn na diwrnod -toolbar.mark_all_older_week=Eitemau hyn nag wythnos -toolbar.mark_all_older_two_weeks=Eitemau hyn na phythefnos -toolbar.settings=Gosodiadau -toolbar.profile=Proffil -toolbar.admin=Gweinyddwr -toolbar.about=Ynghylch -toolbar.logout=Allgofnodi -toolbar.donate=Rhoddi - -view.entry_source=o -view.entry_author=gan -view.error_while_loading_feed=Gwall wrth lwytho'r ffrwd -view.keep_unread=Parhau i'w nodi fel heb ei ddarllen -view.no_unread_items=: Dim eitemau heb eu darllen ###### Cynnwys y colon oherwydd gystrawen y cyd-destyn -view.mark_up_to_here=Nodi'r rhai hyd yma fel wedi eu darllen -view.search_for=yn chwilio am: -view.no_search_results=Ni chanfuwyd unrhyw beth gyda'r geiriau hynny - -feedsearch.hint=Rho'r tanysgrifiad... -feedsearch.help=Defnyddia'r dychwelwr i ddethol a saethau i lywio -feedsearch.result_prefix=Dy danysgrifiadau: - -settings.general=Cyffredinol -settings.general.language=Iaith -settings.general.language.contribute=Cyfrannu drwy gyfieithu -settings.general.show_unread=Dangos ffrydiau a chategoriau gyda dim eitemau heb eu darllen -settings.general.social_buttons=Dangos botymau rhannu -settings.general.scroll_marks=Marcio eitemau fel wedi eu darllen wrth sgrolio drwyddynt yn y golwg estynedig ###### Defnyddio gystrawen debyg i'r ddau uwch. -settings.appearance=Golwg -settings.scroll_speed=Scrolling speed when navigating between entries (in milliseconds) ####### Needs translation -settings.scroll_speed.help=set to 0 to disable ####### Needs translation -settings.theme=Thema -settings.submit_your_theme=Cyflwyna dy thema -settings.custom_css=CSS wedi'i addasu - -details.feed_details=Manylion ffrwd -details.url=URL -details.website=Gwefan -details.name=Enw -details.category=Categori -details.position=Safle -details.last_refresh=Adnewyddiad diwethaf -details.message=Neges adnewyddiad diwethaf -details.next_refresh=Adnewyddiad nesaf -details.queued_for_refresh=Ciwiwyd i'w adnewyddu -details.feed_url=URL Ffrwd -details.generate_api_key_first=Rhaid creu allwedd API yn dy broffil yn gyntaf. -details.unsubscribe=Dad-danysgrifio -details.unsubscribe_confirmation=Are you sure you want to unsubscribe from this feed? ####### Needs translation -details.delete_category_confirmation=Are you sure you want to delete this category? ####### Needs translation -details.category_details=Manylion categori -details.tag_details=Tag details ####### Needs translation -details.parent_category=Categori rhiant - -profile.user_name=Enw defnyddiwr -profile.email=E-bost -profile.change_password=Newid cyfrinair -profile.confirm_password=Cadarnhau cyfrinair -profile.minimum_6_chars=Isafswm 6 nod -profile.passwords_do_not_match=Mae'r cyfrineiriau yn wahanol -profile.api_key=Allwedd API -profile.api_key_not_generated=Heb ei gynhyrchu eto -profile.generate_new_api_key=Creu allwedd API newydd -profile.generate_new_api_key_info=Mae newid cyfrinair yn creu allwedd API newydd -profile.opml_export=Allforio OPML -profile.delete_account=Dileu cyfrif -profile.delete_account_confirmation=Delete your acount? There's no turning back! ####### Needs translation - -about.rest_api=REST API -about.keyboard_shortcuts=Llwybr byr bysellfwrdd -about.version=Fersiwn CommaFeed: ###### Cynnwys y colon oherwydd gystrawen y cyd-destun -about.line1_prefix=Mae CommaFeed yn prosiect cod agored. Mae'r cod ar -about.line1_suffix=. -about.line2_prefix=Os wyt ti'n ffeindio problem, plîs gad wybod amdano ar dudalen problemau o'r -about.line2_suffix=\ prosiect. -about.line3=Os wyt ti'n hoffi'r prosiect, plîs ystyria cyfrannu i gefnogi'r datblygwr a helpu gyda chynnal a chadw'r wefan hon. -about.line4=I'r rhai sy'n hoff o Bitcoin, dyma'r cyfeiriad -about.goodies=Goodies -about.goodies.android_app=Ap Android -about.goodies.subscribe_url=URL Tanysgrifio -about.goodies.chrome_extension=estyniad Chrome -about.goodies.firefox_extension=estyniad Firefox -about.goodies.opera_extension=estyniad Opera -about.goodies.subscribe_bookmarklet=Ychwanegu botwm tanysgrifio ###### Dim angen 'Click' - digon amlwg o'r cyd-destyn -about.goodies.subscribe_bookmarklet_asc=Hynaf yn gyntaf -about.goodies.subscribe_bookmarklet_desc=Diweddaraf yn gyntaf -about.goodies.next_unread_bookmarklet=Botwm eitem nesaf heb ei ddarllen (llusgo i far nodau) -about.translation=Cyfieithiad -about.translation.message=Rydym angen dy help i gyfieithu CommaFeed. -about.translation.link=Gweler sut i gyfrannu i gyfieithiadau. -about.announcements=Datganiadau -about.rest_api.line1=Adeiladir CommaFeed ar JAX-RS ac AngularJS. Mae REST API ar gael. -about.rest_api.link_to_documentation=Dolen i'r ddogfennaeth. - -about.shortcuts.mouse_middleclick=clic botwm canol llygoden -about.shortcuts.open_next_entry=agor yr eitem nesaf -about.shortcuts.open_previous_entry=agor yr eitem flaenorol -about.shortcuts.spacebar=space/shift+space -about.shortcuts.move_page_down_up=symud y tudalen i lawr/fyny -about.shortcuts.focus_next_entry=newid ffocws i'r eitem nesaf heb ei hagor -about.shortcuts.focus_previous_entry=newid ffocws i'r eitem flaenorol heb ei hagor -about.shortcuts.open_next_feed=agor y ffrwd neu gategori nesaf -about.shortcuts.open_previous_feed=agor y ffrwd neu gategori blaenorol -about.shortcuts.open_close_current_entry=agor/cau yr eitem gyfredol -about.shortcuts.open_current_entry_in_new_window=agor yr eitem gyfredol mewn ffenestr newydd -about.shortcuts.open_current_entry_in_new_window_background=agor yr eitem gyfredol mewn ffenestr newydd yn y cefndir -about.shortcuts.star_unstar=serennu/dadserennu'r eitem gyfredol -about.shortcuts.mark_current_entry=marcio'r eitem gyfredol fel wedi/heb ei ddarllen -about.shortcuts.mark_all_as_read=marcio popeth fel wedi ei ddarllen -about.shortcuts.open_in_new_tab_mark_as_read=agor yr eitem mewn tab newydd a'i farcio fel wedi ei ddarllen -about.shortcuts.fullscreen=toglo'r golwg sgrin lawn -about.shortcuts.font_size=cynyddu/lleihau maint ffont yr eitem gyfredol -about.shortcuts.go_to_all=newid i olwg 'Popeth' -about.shortcuts.go_to_starred=newid i olwg 'Serennwyd' -about.shortcuts.feed_search=llywio i danysgrifiad gan roi ei enw mewn - diff --git a/src/main/resources/i18n/da.properties b/src/main/resources/i18n/da.properties deleted file mode 100644 index 5b89ed22..00000000 --- a/src/main/resources/i18n/da.properties +++ /dev/null @@ -1,157 +0,0 @@ -global.save=Gem -global.cancel=Annuller -global.delete=Slet -global.required=Påkrævet -global.download=Hent -global.link=Link -global.bookmark=Bogmærke -global.close=Luk -global.tags=Tags ####### Needs translation - -tree.subscribe=Abonner -tree.import=Importer -tree.new_category=Ny kategori -tree.all=Alle -tree.starred=Favoritter - -subscribe.feed_url=URL for abonnement -subscribe.feed_name=Abonnementsnavn -subscribe.category=Kategori - -import.google_reader_prefix=Lad mig importere dine abonnementer fra -import.google_reader_suffix= konto. -import.google_download=Alternativt, upload din subscriptions.xml fil. -import.google_download_link=Hent den herfra. -import.xml_file=OPML fil - -new_category.name=Navn -new_category.parent=Overordnet - -toolbar.unread=Ulæst -toolbar.all=Alle -toolbar.previous_entry=Forrige artikkel -toolbar.next_entry=Næste artikkel -toolbar.refresh=Opdater -toolbar.refresh_all=Force refresh all my feeds ####### Needs translation -toolbar.sort_by_asc_desc=Sorter efter dato ny/gammel -toolbar.titles_only=Kun titler -toolbar.expanded_view=Udvidet visning -toolbar.mark_all_as_read=Marker alle som læst -toolbar.mark_all_older_12_hours=Items older than 12 hours ####### Needs translation -toolbar.mark_all_older_day=Artikler ældere end én dag -toolbar.mark_all_older_week=Artikler ældere end én uge -toolbar.mark_all_older_two_weeks=Artikler ældere end to uger -toolbar.settings=Indstillinger -toolbar.profile=Profil -toolbar.admin=Admin -toolbar.about=Om -toolbar.logout=Log ud -toolbar.donate=Donér - -view.entry_source=from ####### Needs translation -view.entry_author=af -view.error_while_loading_feed=Fejl under indlæsning af artikel -view.keep_unread=Behold som ulæst -view.no_unread_items=har ingen ulæste artikler. -view.mark_up_to_here=Mark as read up to here ####### Needs translation -view.search_for=searching for: ####### Needs translation -view.no_search_results=No match found for the requested keywords ####### Needs translation - -feedsearch.hint=Angiv et abonnement... -feedsearch.help=Brug enter tasten til at vælge og piltasterne til at navigere. -feedsearch.result_prefix=Dine abonnementer: - -settings.general=Generelt -settings.general.language=Sprog -settings.general.language.contribute=Kontribuer med en oversættelse -settings.general.show_unread=Vis abonnomenter og kategorier med læste artikler -settings.general.social_buttons=Vis delingsknapper -settings.general.scroll_marks=I udvidet visning, marker artikler som læste når der rulles forbi dem -settings.appearance=Udseende -settings.scroll_speed=Scrolling speed when navigating between entries (in milliseconds) ####### Needs translation -settings.scroll_speed.help=set to 0 to disable ####### Needs translation -settings.theme=Tema -settings.submit_your_theme=Indsend dit tema -settings.custom_css=Brugerdefineret CSS - -details.feed_details=Abonnementsdetaljer -details.url=URL -details.website=Website ####### Needs translation -details.name=Navn -details.category=Kategori -details.position=Position -details.last_refresh=Sidste opdatering -details.message=Last refresh message ####### Needs translation -details.next_refresh=Næste opdatering -details.queued_for_refresh=I kø til opdatering -details.feed_url=URL for abonnement -details.generate_api_key_first=Generer en API nøgle i din profil først. -details.unsubscribe=Afmeld abonnement -details.unsubscribe_confirmation=Are you sure you want to unsubscribe from this feed? ####### Needs translation -details.delete_category_confirmation=Are you sure you want to delete this category? ####### Needs translation -details.category_details=Kategori detaljer -details.tag_details=Tag details ####### Needs translation -details.parent_category=Overordnet kategori - -profile.user_name=Brugernavn -profile.email=E-mail -profile.change_password=Skift adgangskode -profile.confirm_password=Bekræft adgangskode -profile.minimum_6_chars=Minimum 6 karakter -profile.passwords_do_not_match=Adgangskoderne er ikke ens -profile.api_key=API nøgle -profile.api_key_not_generated=Ikke genereret endnu -profile.generate_new_api_key=Generer ny API nøgle -profile.generate_new_api_key_info=Ændring af adgangskode vil generere en ny API nøgle -profile.opml_export=OPML eksport -profile.delete_account=Slet konto -profile.delete_account_confirmation=Delete your acount? There's no turning back! ####### Needs translation - -about.rest_api=REST API -about.keyboard_shortcuts=Tastaturgenveje -about.version=CommaFeed version ####### Needs translation -about.line1_prefix=CommaFeed er et open-source project. Kildekoden kan findes på -about.line1_suffix=. -about.line2_prefix=Hvis du opdager et problem, så rapporter det venligst på -about.line2_suffix=\ projekt. -about.line3=Hvis du syntes om projektet, overvej venligst at donere for at hjælpe udviklerne og dække omkostningerne til drift af hjemmesiden. -about.line4=Til dig der foretrækker bitcoin, her er adressen -about.goodies=Godter -about.goodies.android_app=Android app ####### Needs translation -about.goodies.subscribe_url=Abonner URL -about.goodies.chrome_extension=Chrome udvidelse -about.goodies.firefox_extension=Firefox udvidelse -about.goodies.opera_extension=Opera udvidelse -about.goodies.subscribe_bookmarklet=Tilføj abonnoment bogmærkeprogram (click) -about.goodies.subscribe_bookmarklet_asc=Oldest first ####### Needs translation -about.goodies.subscribe_bookmarklet_desc=Newest first ####### Needs translation -about.goodies.next_unread_bookmarklet=Næste ulæste artikel bogmærkeprogram (træk til bogmærkebaren) -about.translation=Oversættelse -about.translation.message=Vi har brug for din hjælp til at oversætte CommaFeed. -about.translation.link=Se hvordan du kan kontribuere med oversættelser. -about.announcements=Meddelelser -about.rest_api.line1=CommaFeed er bygget oven på JAX-RS og AngularJS. Hvilket gør et REST API tilgængeligt. -about.rest_api.link_to_documentation=Link til dokumentationen. - -about.shortcuts.mouse_middleclick=mellemmuseklik -about.shortcuts.open_next_entry=åben næste artikel -about.shortcuts.open_previous_entry=åben forrige artikel -about.shortcuts.spacebar=space/shift+space ####### Needs translation -about.shortcuts.move_page_down_up=moves the page down/up ####### Needs translation -about.shortcuts.focus_next_entry=sæt fokus på næste arktiel uden at åbne den -about.shortcuts.focus_previous_entry=sæt fokus på forrige artikel uden at åbne den -about.shortcuts.open_next_feed=åben næste artikel eller kategori -about.shortcuts.open_previous_feed=åben forrige artikel eller kategori -about.shortcuts.open_close_current_entry=åben/luk nuværende artikel -about.shortcuts.open_current_entry_in_new_window=åben nuværende artikel i et nyt vindue -about.shortcuts.open_current_entry_in_new_window_background=åben nuværende artikel i et nyt vindue i baggrunden -about.shortcuts.star_unstar=marker/fjern favorit -about.shortcuts.mark_current_entry=marker som læst/ulæst -about.shortcuts.mark_all_as_read=marker alle artikler som læste -about.shortcuts.open_in_new_tab_mark_as_read=åben artikel i ny fane og marker som læst -about.shortcuts.fullscreen=toggle full screen mode ####### Needs translation -about.shortcuts.font_size=increase/decrease font size of the current entry ####### Needs translation -about.shortcuts.go_to_all=go to the All view ####### Needs translation -about.shortcuts.go_to_starred=go to the Starred view ####### Needs translation -about.shortcuts.feed_search=naviger til et abonnoment ved at skrive dets navn - diff --git a/src/main/resources/i18n/de.properties b/src/main/resources/i18n/de.properties deleted file mode 100644 index 3182be6e..00000000 --- a/src/main/resources/i18n/de.properties +++ /dev/null @@ -1,157 +0,0 @@ -global.save=Speichern -global.cancel=Abbrechen -global.delete=Löschen -global.required=Erforderlich -global.download=Herunterladen -global.link=Link -global.bookmark=Lesezeichen -global.close=Schließen -global.tags=Tags - -tree.subscribe=Abonnieren -tree.import=Importieren -tree.new_category=Neue Kategorie -tree.all=Alles -tree.starred=Favoriten - -subscribe.feed_url=Feed Adresse -subscribe.feed_name=Feed Name -subscribe.category=Kategorie - -import.google_reader_prefix=Importiere die Feeds von deinem -import.google_reader_suffix= Account. -import.google_download=Alternativ kannst du eine XML-Datei hochladen. -import.google_download_link=Lade sie hier herunter. -import.xml_file=OPML Datei - -new_category.name=Name -new_category.parent=Übergeordnet - -toolbar.unread=Ungelesen -toolbar.all=Alles -toolbar.previous_entry=Vorheriger Artikel -toolbar.next_entry=Nächster Artikel -toolbar.refresh=Aktualisieren -toolbar.refresh_all=Erzwinge Aktualisierung aller Feeds -toolbar.sort_by_asc_desc=Nach Datum sortieren (auf-/absteigend) -toolbar.titles_only=Nur Überschriften -toolbar.expanded_view=Ausgedehnte Ansicht -toolbar.mark_all_as_read=Alle Artikel als gelesen markieren -toolbar.mark_all_older_12_hours=Artikel älter als 12 Stunden -toolbar.mark_all_older_day=Artikel älter als ein Tag -toolbar.mark_all_older_week=Artikel älter als eine Woche -toolbar.mark_all_older_two_weeks=Artikel älter als zwei Wochen -toolbar.settings=Einstellungen -toolbar.profile=Profil -toolbar.admin=Admin -toolbar.about=Über -toolbar.logout=Abmelden -toolbar.donate=Spenden - -view.entry_source=von -view.entry_author=von -view.error_while_loading_feed=Fehler beim Laden des Feeds -view.keep_unread=Als ungelesen behalten -view.no_unread_items=hat keine ungelesenen Einträge. -view.mark_up_to_here=Bis hier alle als gelesen markieren -view.search_for=Suche nach: -view.no_search_results=Kein Treffer bei der Suche nach den angegebenen Stichworten - -feedsearch.hint=Gib einen Feednamen ein... -feedsearch.help=Drück Enter zum Auswählen und die Pfeiltasten zum Navigieren. -feedsearch.result_prefix=Deine Feeds: - -settings.general=Allgemein -settings.general.language=Sprache -settings.general.language.contribute=Beteilige dich mit Übersetzungen -settings.general.show_unread=Zeige Feeds und Kategorien mit ungelesenen Einträgen -settings.general.social_buttons=Zeige Buttons zum Teilen von Inhalten über soziale Netzwerke -settings.general.scroll_marks=In der ausgedehnten Ansicht werden Artikel beim Scrollen als gelesen markiert -settings.appearance=Aussehen -settings.scroll_speed=Geschwindigkeit beim scrollen zwischen Einträgen (in Millisekunden) -settings.scroll_speed.help=setze auf 0 zum deaktivieren -settings.theme=Theme -settings.submit_your_theme=Füg dein Theme hinzu -settings.custom_css=Eigenes CSS - -details.feed_details=Feed details -details.url=URL -details.website=Webseite -details.name=Name -details.category=Kategorie -details.position=Position -details.last_refresh=Letzte Aktualisierung -details.message=Nachricht der letzten Aktualisierung -details.next_refresh=Nächste Aktualisierung -details.queued_for_refresh=Wartet auf Aktualisierung -details.feed_url=Feed Adresse -details.generate_api_key_first=Generiere zuerst einen API Schlüssel in deinem Profil. -details.unsubscribe=Kündigen -details.unsubscribe_confirmation=Bist du sicher das du diesen Feed kündigen möchtest? -details.delete_category_confirmation=Bist du sicher das du diese Kategorie löschen möchtest? -details.category_details=Kategoriedetails -details.tag_details=Tag Details -details.parent_category=Übergeordnete Kategorie - -profile.user_name=Benutzername -profile.email=E-mail -profile.change_password=Passwort ändern -profile.confirm_password=Passwort bestätigen -profile.minimum_6_chars=Mindestens 6 Zeichen -profile.passwords_do_not_match=Passwörter stimmen nicht überein -profile.api_key=API Schlüssel -profile.api_key_not_generated=Noch nicht generiert -profile.generate_new_api_key=Generiere einen neuen API key -profile.generate_new_api_key_info=Das Ändern des Passwortes erzeugt einen neuen API Schlüssel -profile.opml_export=OPML exportieren -profile.delete_account=Account löschen -profile.delete_account_confirmation=Deinen Account löschen? Es gibt kein Zurück! - -about.rest_api=REST API -about.keyboard_shortcuts=Tastatur Kurzbefehle -about.version=CommaFeed Version -about.line1_prefix=CommaFeed ist ein quell-offenes Projekt. Quellen werden auf -about.line1_suffix=\ gehosted. -about.line2_prefix=Wenn Probleme auftauchen, melde diese bitte auf dem -about.line2_suffix=\ Projekt. -about.line3=Wenn dir dieses Projekt gefällt, würde ich mich über eine kleine Spende zur Deckung der Serverkosten freuen. -about.line4=Für diejenigen, die Bitcoin bevorzugen ist hier meine Adresse -about.goodies=Goodies -about.goodies.android_app=Android app -about.goodies.subscribe_url=Abonnement-URL -about.goodies.chrome_extension=Chrome Erweiterung -about.goodies.firefox_extension=Firefox Add-on -about.goodies.opera_extension=Opera Add-on -about.goodies.subscribe_bookmarklet=Abonnieren-bookmarklet (klicken) -about.goodies.subscribe_bookmarklet_asc=Älteste zuerst -about.goodies.subscribe_bookmarklet_desc=Neuste zuerst -about.goodies.next_unread_bookmarklet=Nächster ungelesener Artikel-bookmarklet (in Lesezeichenleiste ziehen) -about.translation=Übersetzung -about.translation.message=Wir brauchen deine Hilfe zur Übersetzung von CommaFeed. -about.translation.link=Wie du uns dabei helfen kannst -about.announcements=Bekanntmachungen -about.rest_api.line1=CommaFeed basiert auf JAX-RS und AngularJS. Daher ist eine REST API verfügbar. -about.rest_api.link_to_documentation=Link zur Dokumentation. - -about.shortcuts.mouse_middleclick=Mittlere Maustaste -about.shortcuts.open_next_entry=nächsten Artikel öffnen -about.shortcuts.open_previous_entry=vorherigen Artikels öffnen -about.shortcuts.spacebar=Leertaste/Shift+Leertaste -about.shortcuts.move_page_down_up=Bewegt die Seite hoch/runter -about.shortcuts.focus_next_entry=nächsten Artikel fokussieren ohne ihn zu öffnen -about.shortcuts.focus_previous_entry=vorherigen Artikel fokussieren ohne ihn zu öffnen -about.shortcuts.open_next_feed=nächsten Feed oder Kategorie öffnen -about.shortcuts.open_previous_feed=vorherigen Feed oder Kategorie öffnen -about.shortcuts.open_close_current_entry=aktuellen Artikels öffnen/schließen -about.shortcuts.open_current_entry_in_new_window=aktuellen Artikel in neuem Fenster öffnen -about.shortcuts.open_current_entry_in_new_window_background=aktuellen Artikel in neuem Fenster im Hintergrund öffnen -about.shortcuts.star_unstar=de-/favorisieren des aktuellen Artikels -about.shortcuts.mark_current_entry=aktuellen Artikel als gelesen/ungelesen markieren -about.shortcuts.mark_all_as_read=alle Artikel als gelesen markieren -about.shortcuts.open_in_new_tab_mark_as_read=öffnen des Artikels in einem neuen Tab und als gelesen markieren -about.shortcuts.fullscreen=Vollbildmodus an-/ausschalten -about.shortcuts.font_size=Schriftgröße des aktuellen Artikels vergrößern/verkleinern -about.shortcuts.go_to_all=Gehe zur Ansicht "Alle" -about.shortcuts.go_to_starred=Gehe zur Ansicht "Favoriten" -about.shortcuts.feed_search=zu einem Feed springen durch durch eingeben seines Namens - diff --git a/src/main/resources/i18n/en.properties b/src/main/resources/i18n/en.properties deleted file mode 100644 index fd7a19fe..00000000 --- a/src/main/resources/i18n/en.properties +++ /dev/null @@ -1,156 +0,0 @@ -global.save=Save -global.cancel=Cancel -global.delete=Delete -global.required=Required -global.download=Download -global.link=Link -global.bookmark=Bookmark -global.close=Close -global.tags=Tags - -tree.subscribe=Subscribe -tree.import=Import -tree.new_category=New category -tree.all=All -tree.starred=Starred - -subscribe.feed_url=Feed URL -subscribe.feed_name=Feed Name -subscribe.category=Category - -import.google_reader_prefix=Let me import your feeds from your -import.google_reader_suffix= account. -import.google_download=Alternatively, upload your subscriptions.xml file. -import.google_download_link=Download it from here. -import.xml_file=OPML File - -new_category.name=Name -new_category.parent=Parent - -toolbar.unread=Unread -toolbar.all=All -toolbar.previous_entry=Previous entry -toolbar.next_entry=Next entry -toolbar.refresh=Refresh -toolbar.refresh_all=Force refresh all my feeds -toolbar.sort_by_asc_desc=Sort by date asc/desc -toolbar.titles_only=Titles only -toolbar.expanded_view=Expanded view -toolbar.mark_all_as_read=Mark all as read -toolbar.mark_all_older_12_hours=Items older than 12 hours -toolbar.mark_all_older_day=Items older than a day -toolbar.mark_all_older_week=Items older than a week -toolbar.mark_all_older_two_weeks=Items older than two weeks -toolbar.settings=Settings -toolbar.profile=Profile -toolbar.admin=Admin -toolbar.about=About -toolbar.logout=Logout -toolbar.donate=Donate - -view.entry_source=from -view.entry_author=by -view.error_while_loading_feed=Error while loading this feed -view.keep_unread=Keep unread -view.no_unread_items=has no unread items. -view.mark_up_to_here=Mark as read up to here -view.search_for=searching for: -view.no_search_results=No match found for the requested keywords - -feedsearch.hint=Type in a subscription... -feedsearch.help=Use the return key to select and arrow keys to navigate. -feedsearch.result_prefix=Your subscriptions: - -settings.general=General -settings.general.language=Language -settings.general.language.contribute=Contribute with translations -settings.general.show_unread=Show feeds and categories with no unread entries -settings.general.social_buttons=Show social sharing buttons -settings.general.scroll_marks=In expanded view, scrolling through entries mark them as read -settings.appearance=Appearance -settings.scroll_speed=Scrolling speed when navigating between entries (in milliseconds) -settings.scroll_speed.help=set to 0 to disable -settings.theme=Theme -settings.submit_your_theme=Submit your theme -settings.custom_css=Custom CSS - -details.feed_details=Feed details -details.url=URL -details.website=Website -details.name=Name -details.category=Category -details.position=Position -details.last_refresh=Last refresh -details.message=Last refresh message -details.next_refresh=Next refresh -details.queued_for_refresh=Queued for refresh -details.feed_url=Feed URL -details.generate_api_key_first=Generate an API key in your profile first. -details.unsubscribe=Unsubscribe -details.unsubscribe_confirmation=Are you sure you want to unsubscribe from this feed? -details.delete_category_confirmation=Are you sure you want to delete this category? -details.category_details=Category details -details.tag_details=Tag details -details.parent_category=Parent category - -profile.user_name=User name -profile.email=E-mail -profile.change_password=Change password -profile.confirm_password=Confirm password -profile.minimum_6_chars=Minimum 6 characters -profile.passwords_do_not_match=Passwords do not match -profile.api_key=API key -profile.api_key_not_generated=Not generated yet -profile.generate_new_api_key=Generate new API key -profile.generate_new_api_key_info=Changing password will generate a new API key -profile.opml_export=OPML export -profile.delete_account=Delete account -profile.delete_account_confirmation=Delete your account? There's no turning back! - -about.rest_api=REST API -about.keyboard_shortcuts=Keyboard shortcuts -about.version=CommaFeed version -about.line1_prefix=CommaFeed is an open-source project. Sources are hosted on -about.line1_suffix=. -about.line2_prefix=If you encounter an issue, please report it on the issues page of the -about.line2_suffix=\ project. -about.line3=If you like this project, please consider a donation to support the developer and help cover the costs of keeping this website online. -about.line4=For those of you who prefer bitcoin, here is the address -about.goodies=Goodies -about.goodies.android_app=Android app -about.goodies.subscribe_url=Subscribe URL -about.goodies.chrome_extension=Chrome extension -about.goodies.firefox_extension=Firefox extension -about.goodies.opera_extension=Opera extension -about.goodies.subscribe_bookmarklet=Add subscription bookmarklet (click) -about.goodies.subscribe_bookmarklet_asc=Oldest first -about.goodies.subscribe_bookmarklet_desc=Newest first -about.goodies.next_unread_bookmarklet=Next unread item bookmarklet (drag to bookmark bar) -about.translation=Translation -about.translation.message=We need your help to translate CommaFeed. -about.translation.link=See how to contribute with translations. -about.announcements=Announcements -about.rest_api.line1=CommaFeed is built on top of JAX-RS and AngularJS. As such, a REST API is available. -about.rest_api.link_to_documentation=Link to the documentation. - -about.shortcuts.mouse_middleclick=mouse middleclick -about.shortcuts.open_next_entry=open next entry -about.shortcuts.open_previous_entry=open previous entry -about.shortcuts.spacebar=space/shift+space -about.shortcuts.move_page_down_up=moves the page down/up -about.shortcuts.focus_next_entry=set focus on next entry without opening it -about.shortcuts.focus_previous_entry=set focus on previous entry without opening it -about.shortcuts.open_next_feed=open next feed or category -about.shortcuts.open_previous_feed=open previous feed or category -about.shortcuts.open_close_current_entry=open/close current entry -about.shortcuts.open_current_entry_in_new_window=open current entry in a new window -about.shortcuts.open_current_entry_in_new_window_background=open current entry in a new window in the background -about.shortcuts.star_unstar=star/unstar current entry -about.shortcuts.mark_current_entry=mark as read/unread current entry -about.shortcuts.mark_all_as_read=mark all entries as read -about.shortcuts.open_in_new_tab_mark_as_read=open entry in new tab and mark as read -about.shortcuts.fullscreen=toggle full screen mode -about.shortcuts.font_size=increase/decrease font size of the current entry -about.shortcuts.go_to_all=go to the All view -about.shortcuts.go_to_starred=go to the Starred view -about.shortcuts.feed_search=navigate to a subscription by entering the subscription name diff --git a/src/main/resources/i18n/es.properties b/src/main/resources/i18n/es.properties deleted file mode 100644 index df51df76..00000000 --- a/src/main/resources/i18n/es.properties +++ /dev/null @@ -1,157 +0,0 @@ -global.save=Guardar -global.cancel=Cancelar -global.delete=Eliminar -global.required=Requerido -global.download=Descargar -global.link=Enlace -global.bookmark=Marcador -global.close=Close ####### Needs translation -global.tags=Tags ####### Needs translation - -tree.subscribe=Subscribir -tree.import=Importar -tree.new_category=Nueva categoría -tree.all=Todos -tree.starred=Destacado - -subscribe.feed_url=URL del Canal -subscribe.feed_name=Nombre del Canal -subscribe.category=Categoría - -import.google_reader_prefix=Déjame importar tus canales de tu -import.google_reader_suffix= cuenta. -import.google_download=También puedes subir tu archivo subscriptions.xml. -import.google_download_link=Descárgalo de aquí. -import.xml_file=Archivo OPML - -new_category.name=Nombre -new_category.parent=Padre - -toolbar.unread=Sin Leer -toolbar.all=Todos -toolbar.previous_entry=Entrada Anterior -toolbar.next_entry=Próxima Entrada -toolbar.refresh=Atualizar -toolbar.refresh_all=Force refresh all my feeds ####### Needs translation -toolbar.sort_by_asc_desc=Ordenar por fecha asc/desc -toolbar.titles_only=Sólo Títulos -toolbar.expanded_view=Vista Expandida -toolbar.mark_all_as_read=Marcar todos como leído -toolbar.mark_all_older_12_hours=Items older than 12 hours ####### Needs translation -toolbar.mark_all_older_day=Artículos anteriores a un día -toolbar.mark_all_older_week=Artículos más de una semana -toolbar.mark_all_older_two_weeks=Artículos más de does semanas -toolbar.settings=Ajustes -toolbar.profile=Perfil -toolbar.admin=Admin -toolbar.about=Acerca de -toolbar.logout=Cerrar sesión -toolbar.donate=Donar - -view.entry_source=from ####### Needs translation -view.entry_author=by ####### Needs translation -view.error_while_loading_feed=Error mientras se cargaba este canal -view.keep_unread=Guardar no leídos -view.no_unread_items=no tiene items sin leer. -view.mark_up_to_here=Mark as read up to here ####### Needs translation -view.search_for=searching for: ####### Needs translation -view.no_search_results=No match found for the requested keywords ####### Needs translation - -feedsearch.hint=Type in a subscription... ####### Needs translation -feedsearch.help=Use the return key to select and arrow keys to navigate. ####### Needs translation -feedsearch.result_prefix=Your subscriptions: ####### Needs translation - -settings.general=General -settings.general.language=Lenguaje -settings.general.language.contribute=Contribuye con traducciones -settings.general.show_unread=Mostrar canales y categorías sin entradas no leídas. -settings.general.social_buttons=Mostrar botones de compartir de redes sociales. -settings.general.scroll_marks=En vista expandida, el desplazamiento por las entradas las marca como leídas -settings.appearance=Appearance ####### Needs translation -settings.scroll_speed=Scrolling speed when navigating between entries (in milliseconds) ####### Needs translation -settings.scroll_speed.help=set to 0 to disable ####### Needs translation -settings.theme=Theme ####### Needs translation -settings.submit_your_theme=Submit your theme ####### Needs translation -settings.custom_css=CSS Personalizado - -details.feed_details=Detalles de Canales -details.url=URL -details.website=Website ####### Needs translation -details.name=Nombre -details.category=Categoría -details.position=Position ####### Needs translation -details.last_refresh=Última actualización -details.message=Last refresh message ####### Needs translation -details.next_refresh=Next refresh ####### Needs translation -details.queued_for_refresh=Queued for refresh ####### Needs translation -details.feed_url=URL del Canal -details.generate_api_key_first=Genera una llave API en tu perfil primero. -details.unsubscribe=Terminar subscripción -details.unsubscribe_confirmation=Are you sure you want to unsubscribe from this feed? ####### Needs translation -details.delete_category_confirmation=Are you sure you want to delete this category? ####### Needs translation -details.category_details=Detalles de la categoría -details.tag_details=Tag details ####### Needs translation -details.parent_category=Categoría principal - -profile.user_name=Nombre de usuario -profile.email=Correo -profile.change_password=Cambiar contraseña -profile.confirm_password=Confirmar contraseña -profile.minimum_6_chars=Mínimo 6 caracteres -profile.passwords_do_not_match=Las contraseñas no coinciden -profile.api_key=Llave API -profile.api_key_not_generated=No generado todavía -profile.generate_new_api_key=Generar nueva llave API -profile.generate_new_api_key_info=Al cambiar la contraseña se generará una nueva llave API -profile.opml_export=Exportación de OPML -profile.delete_account=Eliminar cuenta -profile.delete_account_confirmation=Delete your acount? There's no turning back! ####### Needs translation - -about.rest_api=REST API -about.keyboard_shortcuts=Atajos de teclado -about.version=CommaFeed version ####### Needs translation -about.line1_prefix=CommaFeed es un proyecto open-source. El código se encuentra en -about.line1_suffix=. -about.line2_prefix=Si encuentras un problema, por favor reportalo en la página de problemas de -about.line2_suffix=\ del proyecto. -about.line3=Si te gusta este proyecto, por favor considera realizar una donacion para apoyar al desarrollador y ayudar a cubrir los costos de mantenimiento. -about.line4=For those of you who prefer bitcoin, here is the address ####### Needs translation -about.goodies=Goodies -about.goodies.android_app=Android app ####### Needs translation -about.goodies.subscribe_url=Subscribe URL ####### Needs translation -about.goodies.chrome_extension=Extensión de Chrome -about.goodies.firefox_extension=Extensión de Firefox -about.goodies.opera_extension=Opera extension ####### Needs translation -about.goodies.subscribe_bookmarklet=Add subscription bookmarklet (click) ####### Needs translation -about.goodies.subscribe_bookmarklet_asc=Oldest first ####### Needs translation -about.goodies.subscribe_bookmarklet_desc=Newest first ####### Needs translation -about.goodies.next_unread_bookmarklet=Next unread item bookmarklet (drag to bookmark bar) ####### Needs translation -about.translation=Traducción -about.translation.message=Necesitamos tu ayuda para ayudar a traducir CommaFeed. -about.translation.link=Ver como contribuir con traducciones. -about.announcements=Anuncios -about.rest_api.line1=CommaFeed está construido con el uso de JAX-RS y AngularJS. Por eso, un REST API esta disponible. -about.rest_api.link_to_documentation=Vínculo de la documentación. - -about.shortcuts.mouse_middleclick=ratón botón medio -about.shortcuts.open_next_entry=abrir próxima entrada -about.shortcuts.open_previous_entry=abrir entrada previa -about.shortcuts.spacebar=space/shift+space ####### Needs translation -about.shortcuts.move_page_down_up=moves the page down/up ####### Needs translation -about.shortcuts.focus_next_entry=Establecer el foco en la próxima entrada sin abrirlo -about.shortcuts.focus_previous_entry=Establecer el foco en la entrada anterior sin abrirlo -about.shortcuts.open_next_feed=open next feed or category ####### Needs translation -about.shortcuts.open_previous_feed=open previous feed or category ####### Needs translation -about.shortcuts.open_close_current_entry=abrir/cerrar entrada actual -about.shortcuts.open_current_entry_in_new_window=abrir entrada actual en una nueva ventana -about.shortcuts.open_current_entry_in_new_window_background=open current entry in a new window in the background ####### Needs translation -about.shortcuts.star_unstar=marcar/no marcar la entrada actual -about.shortcuts.mark_current_entry=marcar como leída/no la leída entrada actual -about.shortcuts.mark_all_as_read=marcar todas las entradas como leídas -about.shortcuts.open_in_new_tab_mark_as_read=abrir entrada en una nueva pestaña y marcar como leída -about.shortcuts.fullscreen=toggle full screen mode ####### Needs translation -about.shortcuts.font_size=increase/decrease font size of the current entry ####### Needs translation -about.shortcuts.go_to_all=go to the All view ####### Needs translation -about.shortcuts.go_to_starred=go to the Starred view ####### Needs translation -about.shortcuts.feed_search=navigate to a subscription by entering the subscription name ####### Needs translation - diff --git a/src/main/resources/i18n/fa.properties b/src/main/resources/i18n/fa.properties deleted file mode 100644 index 616dcc5e..00000000 --- a/src/main/resources/i18n/fa.properties +++ /dev/null @@ -1,157 +0,0 @@ -global.save=ذخیره -global.cancel=لغو -global.delete=حذف -global.required=لازم -global.download=بارگیری -global.link=پیوند -global.bookmark=بوکمارک -global.close=بستن -global.tags=برجسپ‌ها - -tree.subscribe=مشترک شوید -tree.import=درون‌ریزی -tree.new_category=ردهٔ جدید -tree.all=کل مطالب -tree.starred=ستاره‌دار - -subscribe.feed_url=نشانی خوراک -subscribe.feed_name=نام خوراک -subscribe.category=دسته - -import.google_reader_prefix=اجازه بده خوراک‌هایتان را از حساب -import.google_reader_suffix=وارد سازم. -import.google_download=یا به جای آن، پروندهٔ subscriptions.xml خود را بارگذاری کنید. -import.google_download_link=آن را اینجا بارگیری کنید. -import.xml_file=پروندهٔ OPML - -new_category.name=نام -new_category.parent=پدر - -toolbar.unread=خوانده‌نشده -toolbar.all=همه -toolbar.previous_entry=مطلب قبلی -toolbar.next_entry=مطلب بعدی -toolbar.refresh=تازه‌سازی -toolbar.refresh_all=مجبورکردن تازه‌سازی همهٔ خوراک‌ها -toolbar.sort_by_asc_desc=مرتب‌کردن بر اساس تاریخ به‌صورت صعودی/نزولی -toolbar.titles_only=فقط عنوان‌ها -toolbar.expanded_view=نمای گسترش‌یافته -toolbar.mark_all_as_read=علامت‌گذاری تمامی مطالب به‌عنوان خوانده‌شده -toolbar.mark_all_older_12_hours=مطالب قدیمی‌تر از ۱۲ ساعت -toolbar.mark_all_older_day=مطالب قدیمی‌تر از یک روز -toolbar.mark_all_older_week=مطالب قدیمی‌تر از یک هفته -toolbar.mark_all_older_two_weeks=مطالب قدیمی تر از چند هفته قیل -toolbar.settings=تنظیمات -toolbar.profile=نمایه -toolbar.admin=مدیریت -toolbar.about=درباره -toolbar.logout=خروج -toolbar.donate=کمک مالی - -view.entry_source=از -view.entry_author=توسط -view.error_while_loading_feed=متأسفانه، هنگام بارگیری این خوراک خطایی رخ‌داده‌است. -view.keep_unread=خوانده‌نشده نگه‌دار -view.no_unread_items=هیچ مطلب خوانده‌نشده‌ای ندارد. -view.mark_up_to_here=تا اینجا را خوانده‌شده در نظر بگیر -view.search_for=جستجو برای: -view.no_search_results=هیج نتیجه‌ای برای کلیدواژه‌های درخواستی یافت نشد - -feedsearch.hint=نوشتن بر روی یک اشتراک... -feedsearch.help=دکمهٔ بازگشت برای انتخاب و دکمه‌های جهت‌دار را برای ناوبری استفاده کن. -feedsearch.result_prefix=اشتراک‌های شما: - -settings.general=همگانی -settings.general.language=زبان -settings.general.language.contribute=مشارکت در ترجمه -settings.general.show_unread=تنها خوراک‌ها و دسته‌های را که دارای مطالب نخوانده هستند نمایش بده. -settings.general.social_buttons=نشان‌دادن دکمه‌های اشتراک‌گذاری در شبکه‌های اجتماعی -settings.general.scroll_marks=در نمای گسترش‌یافته، لغزیدن بر روی مطالب به‌عنوان نشانه‌گذاری به‌عنوان خوانده‌شده در نظر گرفته‌شوند. -settings.appearance=ظاهر -settings.scroll_speed=سرعت لغزش هنگام گشتن بین مدخل‌ها (به میلی‌ثانیه) -settings.scroll_speed.help=قراردادن به ۰ برای غیرفعال‌کردن -settings.theme=پوسته -settings.submit_your_theme=پوستهٔ خود را ارسال‌کنید -settings.custom_css=سی‌اس‌اس شخصی‌سازی‌شده - -details.feed_details=جزئیات خوراک -details.url=نشانی -details.website=وب‌گاه -details.name=نام -details.category=دسته -details.position=موقعیت -details.last_refresh=آخرین بروزرسانی -details.message=پیام آخرین تازه‌سازی -details.next_refresh=بروزرسانی بعدی -details.queued_for_refresh=منتظر برای بروزرسانی -details.feed_url=نشانی خوراک -details.generate_api_key_first=ابتدا یک کلید API در نمایهٔ خود ایجاد کنید. -details.unsubscribe=لغو اشتراک -details.unsubscribe_confirmation=مطمئنید می‌خواهید از این این لغو اشتراک کنید؟ -details.delete_category_confirmation=مطمئنید می‌خواهید این رده را حذف کنید؟ -details.category_details=جزئیات دسته -details.tag_details=جزئیات برچسپ -details.parent_category=ردهٔ پدر - -profile.user_name=نام کاربری -profile.email=رایانامه -profile.change_password=تغییر گذرواژه -profile.confirm_password=تأیید گذرواژه -profile.minimum_6_chars=حداقل ۶ نویسه -profile.passwords_do_not_match=گذرواژه‌ها انطباق ندارند -profile.api_key=کلید API -profile.api_key_not_generated=هنوز ایجاد نشده‌است -profile.generate_new_api_key=ایجاد کلید جدید API -profile.generate_new_api_key_info=تغییر گذرواژه کلید API به‌وجود خواهد آورد. -profile.opml_export=خارج‌سازی OPML -profile.delete_account=حذف حساب کاربری -profile.delete_account_confirmation=حذف حسابتان؟ بازگشتی وجود ندارد! - -about.rest_api=REST API -about.keyboard_shortcuts=کلیدهای میانبر -about.version=نسخهٔ کامافید -about.line1_prefix=کامافید یک پروژه متن‌باز است. مخازن آن در -about.line1_suffix=میزبانی می‌شود. -about.line2_prefix=اگر شما به مسئله‌ای برخورده اید، لطفاً آن را در صفحه مسائل گزارش دهید -about.line2_suffix=\ پروژه. -about.line3=در صورتی که شما به این پروژه علاقمندید، لطفاً مبلغی را هرچند ناچیزه برای حمایت از توسعه‌دهنده و کمک به تأمین هزینه‌های نگه‌داری این وب‌گاه کمک کنید. -about.line4=برای کسانی که بیت‌کوین را ترجیح می‌دهند، نشانی آن اینجاست -about.goodies=افزونه‌ها -about.goodies.android_app=برنامهٔ اندرویدی -about.goodies.subscribe_url=اشتراک در نشانی -about.goodies.chrome_extension=افزونهٔ کروم -about.goodies.firefox_extension=افزونهٔ فایرفاکس -about.goodies.opera_extension=افزونهٔ اپرا -about.goodies.subscribe_bookmarklet=افزودن بوک‌مارک‌لت اشتراک (با کلیک) -about.goodies.subscribe_bookmarklet_asc=اول قدیمی‌ترین‌ها -about.goodies.subscribe_bookmarklet_desc=اول جدیدترین‌ها -about.goodies.next_unread_bookmarklet=بوک‌مارک‌لت مطلب خوانده نشدهٔ بعدی(با کشیدن و رهاکردن در نوار بوک‌مارک‌لت) -about.translation=ترجمه -about.translation.message=ما به کمک شما برای ترجمهٔ کامافید نیازمدیم. -about.translation.link=ببینید چگونه می‌توان در ترجمه‌های مشارکت نمود. -about.announcements=اطلاعیه‌ها -about.rest_api.line1=کامافید بر روی JAX-RS و AngularJS ساخته‌شده‌است. به همین دلیل API REST موجود است. -about.rest_api.link_to_documentation=پیوند به مستندات. - -about.shortcuts.mouse_middleclick=کلیک وسطی موشواره -about.shortcuts.open_next_entry=بازکردن مطلب بعدی -about.shortcuts.open_previous_entry=بازکردن مطلب قبلی -about.shortcuts.spacebar=space/shift+space -about.shortcuts.move_page_down_up=صفحه را بالا/پایین انتقال می‌دهد -about.shortcuts.focus_next_entry=رفتن بر روی مطلب بعدی بدون بازکردن کامل آن -about.shortcuts.focus_previous_entry=رفتن بر روی مطلب بعدی قبلی بازکردن کامل آن -about.shortcuts.open_next_feed=بازکردن خوراک یا دستهٔ بعدی -about.shortcuts.open_previous_feed=بازکردن خوراک یا دستهٔ بعدی -about.shortcuts.open_close_current_entry=باز/بستن مطلب جاری -about.shortcuts.open_current_entry_in_new_window=بازکردن مطلب جاری در پنجره‌ای جدید -about.shortcuts.open_current_entry_in_new_window_background=بازکردن مطلب جاری در پنجره‌ای جدید در پس‌زمینه -about.shortcuts.star_unstar=نشانه‌دارکردن/نکردن مطلب جاری -about.shortcuts.mark_current_entry=علامت‌گذاری مطلب جاری به‌عنوان خوانده‌شده/نشده -about.shortcuts.mark_all_as_read=علامت‌گذاری تمامی مطالب به‌عنوان خوانده‌شده -about.shortcuts.open_in_new_tab_mark_as_read=باز‌کردن مطلب در سربرگ جدید و علامت‌گذاری آن به‌عنوان خوانده‌شده -about.shortcuts.fullscreen=فعال/غیرفعال‌کردن حالت تمام صفحه -about.shortcuts.font_size=افزایش/کاهش اندازهٔ قلم مدخل فعلی -about.shortcuts.go_to_all=رفتن به نمای همه -about.shortcuts.go_to_starred=رفتن به نمای ستاره داده‌شده‌ها -about.shortcuts.feed_search=ناوبری به یک اشتراک با نوشتن نام اشتراک - diff --git a/src/main/resources/i18n/fi.properties b/src/main/resources/i18n/fi.properties deleted file mode 100644 index a647b467..00000000 --- a/src/main/resources/i18n/fi.properties +++ /dev/null @@ -1,157 +0,0 @@ -global.save=Tallenna -global.cancel=Peruuta -global.delete=Poista -global.required=Pakollinen -global.download=Lataa -global.link=Linkki -global.bookmark=Kirjanmerkki -global.close=Sulje -global.tags=Tagit - -tree.subscribe=Tilaa syöte -tree.import=Tuo -tree.new_category=Uusi kansio -tree.all=Kaikki -tree.starred=Tähdelliset - -subscribe.feed_url=Syötteen osoite -subscribe.feed_name=Syötteen nimi -subscribe.category=Kansio - -import.google_reader_prefix=Tuo tilaukset -import.google_reader_suffix=-tunnukseltasi. -import.google_download=Vaihtoehtoisesti voit tuoda tilaukset subscriptions.xml -tiedostolla. -import.google_download_link=Lataa se täältä. -import.xml_file=OPML-tiedosto - -new_category.name=Nimi -new_category.parent=Yläkansio - -toolbar.unread=Lukemattomat -toolbar.all=Kaikki -toolbar.previous_entry=Edellinen otsikko -toolbar.next_entry=Seuraava otsikko -toolbar.refresh=Päivitä -toolbar.refresh_all=Pakota kaikkien syötteiden päivitys -toolbar.sort_by_asc_desc=Järjestä päivämäärän mukaan nousevasti/laskevasti -toolbar.titles_only=Näytä vain otsikot -toolbar.expanded_view=Laajennettu näkymä -toolbar.mark_all_as_read=Merkitse kaikki luetuiksi -toolbar.mark_all_older_12_hours=12 tuntia vanhemmat otsikot -toolbar.mark_all_older_day=Päivää vanhemmat otsikot -toolbar.mark_all_older_week=Viikkoa vanhemmat otsikot -toolbar.mark_all_older_two_weeks=Kahta viikkoa vanhemmat otsikot -toolbar.settings=Asetukset -toolbar.profile=Profiili -toolbar.admin=Ylläpito -toolbar.about=Tietoja -toolbar.logout=Kirjaudu ulos -toolbar.donate=Lahjoita - -view.entry_source=syötteestä -view.entry_author=kirjoittanut -view.error_while_loading_feed=Virhe tilausta ladattaessa -view.keep_unread=Pidä lukemattomana -view.no_unread_items=ei sisällä lukemattomia otsikoita. -view.mark_up_to_here=Merkitse luetuksi tähän asti -view.search_for=Etsi sanoilla: -view.no_search_results=Ei tuloksia annetuilla hakusanoilla. - -feedsearch.hint=Kirjoita syötteen nimi... -feedsearch.help=Siirry syötteiden välillä nuolinäppäimillä ja valitse syöte enterillä. -feedsearch.result_prefix=Tilatut syötteesi: - -settings.general=Yleiset -settings.general.language=Kieli -settings.general.language.contribute=Avusta käännösten tekemisessä. -settings.general.show_unread=Näytä syötteet ja kansiot, joissa ei ole lukemattomia otsikoita -settings.general.social_buttons=Näytä jakonapit -settings.general.scroll_marks=Laajennetussa näkymässä otsikoiden selaaminen merkitsee ne luetuiksi -settings.appearance=Ulkonäkö -settings.scroll_speed=Vieritysnopeus otsikoiden välillä navigoidessa (millisekunneissa) -settings.scroll_speed.help=Aseta 0 poistaaksesi vieritys käytöstä. -settings.theme=Teema -settings.submit_your_theme=Lähetä oma teemasi -settings.custom_css=Oma CSS - -details.feed_details=Tilauksen tiedot -details.url=Osoite -details.website=Sivusto -details.name=Nimi -details.category=Kansio -details.position=Paikka -details.last_refresh=Viimeisin päivitys -details.message=Viimeisimmän päivityksen viesti -details.next_refresh=Seuraava päivitys -details.queued_for_refresh=Jonossa päivitettäväksi -details.feed_url=Syötteen osoite -details.generate_api_key_first=Luo API-avain profiilissasi. -details.unsubscribe=Peruuta tilaus -details.unsubscribe_confirmation=Haluatko varmasti lopettaa tämän syötteen tilauksen? -details.delete_category_confirmation=Haluatko varmasti poistaa tämän kansion? -details.category_details=Kansion tiedot -details.tag_details=Tagin tiedot -details.parent_category=Yläkansio - -profile.user_name=Käyttäjänimi -profile.email=Sähköposti -profile.change_password=Vaihda salasana -profile.confirm_password=Vahvista uusi salasana -profile.minimum_6_chars=Vähintään 6 merkkiä -profile.passwords_do_not_match=Salasanat eivät täsmää -profile.api_key=API-avain -profile.api_key_not_generated=API-avainta ei ole vielä luotu -profile.generate_new_api_key=Luo uusi API-avain -profile.generate_new_api_key_info=Salasanan vaihtaminen luo uuden API-avaimen -profile.opml_export=OPML vienti -profile.delete_account=Poista tunnus -profile.delete_account_confirmation=Haluatko varmasti poistaa tunnuksesi? Tätä ei voi perua! - -about.rest_api=REST-API -about.keyboard_shortcuts=Näppäinoikotiet -about.version=CommaFeedin versio -about.line1_prefix=CommaFeed on avoimen lähdekoodin projekti. Lähdekoodi on saatavilla -about.line1_suffix=:ssa. -about.line2_prefix=Jos huomaat ongelmia, ilmoita niistä -about.line2_suffix=-projektin ongelmasivulla. -about.line3=Jos pidät CommaFeedistä, harkitse lahjoitusta kehittäjää tukeaksesi ja auttaaksesi sivuston kulujen kattamisessa. -about.line4=Tässä myös osoite bitcoin-lahjoituksia varten: -about.goodies=Ekstrat -about.goodies.android_app=Android-sovellus -about.goodies.subscribe_url=Tilausosoite -about.goodies.chrome_extension=Chrome-laajennus -about.goodies.firefox_extension=Firefox-laajennus -about.goodies.opera_extension=Opera-laajennus -about.goodies.subscribe_bookmarklet=Lisää tilaus -kirjanmerkki (klikkaa) -about.goodies.subscribe_bookmarklet_asc=Vanhin ensiksi -about.goodies.subscribe_bookmarklet_desc=Uusin ensiksi -about.goodies.next_unread_bookmarklet=Seuraava lukematon otsikko -kirjanmerkki (raahaa kirjanmerkkipalkkiin) -about.translation=Kääntäminen -about.translation.message=Tarvitsemme apuasi CommaFeedin kääntämiseksi. -about.translation.link=Katso kuinka voit auttaa kännösten tekemisessä. -about.announcements=Ilmoitukset -about.rest_api.line1=CommaFeed on rakennettu JAX-RS:n ja AngularJS:n avulla. REST API on myös saatavilla. -about.rest_api.link_to_documentation=Linkki dokumentaatioon. - -about.shortcuts.mouse_middleclick=hiiren keskinappi -about.shortcuts.open_next_entry=avaa seuraava otsikko -about.shortcuts.open_previous_entry=avaa edellinen otsikko -about.shortcuts.spacebar=välilyönti/shift+välilyönti -about.shortcuts.move_page_down_up=liikuta sivua ylös tai alas -about.shortcuts.focus_next_entry=valitse seuraava otsikko sitä avaamatta -about.shortcuts.focus_previous_entry=valitse edellinen otsikko sitä avaamatta -about.shortcuts.open_next_feed=avaa seuraava kansio tai syöte -about.shortcuts.open_previous_feed=avaa edellinen kansio tai syöte -about.shortcuts.open_close_current_entry=avaa tai sulje valittu otsikko -about.shortcuts.open_current_entry_in_new_window=avaa valittu otsikko uudessa ikkunassa -about.shortcuts.open_current_entry_in_new_window_background=avaa valittu otsikko uudessa ikkunassa taustalla -about.shortcuts.star_unstar=merkitse valittu otsikko tähdelliseksi -about.shortcuts.mark_current_entry=merkitse valittu otsikko luetuksi tai lukemattomaksi -about.shortcuts.mark_all_as_read=merkitse kaikki otsikot luetuiksi -about.shortcuts.open_in_new_tab_mark_as_read=avaa otsikko uudessa ikkunassa ja merkitse se luetuksi -about.shortcuts.fullscreen=siirry kokoruututilaan -about.shortcuts.font_size=suurenna/pienennä valitun artikkelin kirjasinkokoa -about.shortcuts.go_to_all=Siirry Kaikki-näkymään -about.shortcuts.go_to_starred=Siirry Tähdelliset-näkymään -about.shortcuts.feed_search=etsi tilaus sen nimen perusteella - diff --git a/src/main/resources/i18n/fr.properties b/src/main/resources/i18n/fr.properties deleted file mode 100644 index 28884c7c..00000000 --- a/src/main/resources/i18n/fr.properties +++ /dev/null @@ -1,157 +0,0 @@ -global.save=Enregistrer -global.cancel=Annuler -global.delete=Effacer -global.required=Obligatoire -global.download=Télécharger -global.link=Lien -global.bookmark=Favoris -global.close=Fermer -global.tags=Tags ####### Needs translation - -tree.subscribe=S'abonner -tree.import=Importer -tree.new_category=Nouvelle catégorie -tree.all=Tous -tree.starred=Favoris - -subscribe.feed_url=URL du flux -subscribe.feed_name=Nom du flux -subscribe.category=Catégorie - -import.google_reader_prefix=Laissez-moi importer vos flux depuis votre compte -import.google_reader_suffix=. -import.google_download=Ou alors, téléchargez votre fichier subscriptions.xml. -import.google_download_link=Récupérez-le ici. -import.xml_file=Fichier OPML - -new_category.name=Nom -new_category.parent=Parent - -toolbar.unread=Non-lus -toolbar.all=Tous -toolbar.previous_entry=Article précédent -toolbar.next_entry=Article suivant -toolbar.refresh=Rafraîchir -toolbar.refresh_all=Force refresh all my feeds ####### Needs translation -toolbar.sort_by_asc_desc=Trier par date croissante/décroissante -toolbar.titles_only=Titres uniquement -toolbar.expanded_view=Vue étendue -toolbar.mark_all_as_read=Tout marquer comme lu -toolbar.mark_all_older_12_hours=Items older than 12 hours ####### Needs translation -toolbar.mark_all_older_day=Articles de plus d'un jour -toolbar.mark_all_older_week=Articles de plus d'une semaine -toolbar.mark_all_older_two_weeks=Articles de plus d'un mois -toolbar.settings=Préférences -toolbar.profile=Profil -toolbar.admin=Administration -toolbar.about=A propos -toolbar.logout=Déconnexion -toolbar.donate=Faire un don - -view.entry_source=sur -view.entry_author=par -view.error_while_loading_feed=Erreur durant le chargement de ce flux -view.keep_unread=Garder non-lu -view.no_unread_items=n'a pas d'articles non-lus. -view.mark_up_to_here=Marquer comme lu jusqu'ici -view.search_for=searching for: ####### Needs translation -view.no_search_results=No match found for the requested keywords ####### Needs translation - -feedsearch.hint=Tapez un nom de flux -feedsearch.help=Utilisez la touche entrée pour sélectionner et les flèches pour naviguer -feedsearch.result_prefix=Vos flux: - -settings.general=Général -settings.general.language=Langue -settings.general.language.contribute=Contribuer aux traductions -settings.general.show_unread=Afficher les flux et les catégories pour lesquels tout est déjà lu -settings.general.social_buttons=Afficher les boutons de partage sur réseaux sociaux -settings.general.scroll_marks=En mode de lecture étendu, marquer comme lu les éléments lorsque la fenêtre descend. -settings.appearance=Apparence -settings.scroll_speed=Scrolling speed when navigating between entries (in milliseconds) ####### Needs translation -settings.scroll_speed.help=set to 0 to disable ####### Needs translation -settings.theme=Thème -settings.submit_your_theme=Soumettez votre thème. -settings.custom_css=CSS personnelle - -details.feed_details=Détails du flux -details.url=URL -details.website=Site web -details.name=Nom -details.category=Catégorie -details.position=Position -details.last_refresh=Dernière mise à jour -details.message=Last refresh message ####### Needs translation -details.next_refresh=Prochaine mise à jour -details.queued_for_refresh=En file d'attente -details.feed_url=URL du flux -details.generate_api_key_first=Générez une clé API dans votre profil d'abord. -details.unsubscribe=Se désabonner -details.unsubscribe_confirmation=Are you sure you want to unsubscribe from this feed? ####### Needs translation -details.delete_category_confirmation=Are you sure you want to delete this category? ####### Needs translation -details.category_details=Détails de la catégorie -details.tag_details=Tag details ####### Needs translation -details.parent_category=Catégorie parente - -profile.user_name=Nom -profile.email=E-mail -profile.change_password=Changer de mot de passe -profile.confirm_password=Confirmer le mot de passe -profile.minimum_6_chars=Minimum 6 caractères -profile.passwords_do_not_match=Les mots de passe ne correspondent pas -profile.api_key=Clé API -profile.api_key_not_generated=Pas encore générée -profile.generate_new_api_key=Générer une nouvelle clé API -profile.generate_new_api_key_info=Changer de mot de passe va générer une nouvelle clé API -profile.opml_export=Export du fichier OPML -profile.delete_account=Effacer le compte -profile.delete_account_confirmation=Delete your acount? There's no turning back! ####### Needs translation - -about.rest_api=API REST -about.keyboard_shortcuts=Raccourcis clavier -about.version=CommaFeed version -about.line1_prefix=CommaFeed est un projet open-source. Les sources sont disponibles sur -about.line1_suffix=. -about.line2_prefix=Si vous rencontrez un problème, rapportez-le sur la page du projet sur -about.line2_suffix=. -about.line3=Si vous aimez ce projet, n'hésitez pas à faire un don pour encourager le développeur et aider à couvrir les coûts d'hébergement de la plate-forme. -about.line4=Pour ceux qui préfèrent Bitcoin, voici l'adresse -about.goodies=Extensions -about.goodies.android_app=App Android -about.goodies.subscribe_url=URL pour s'abonner -about.goodies.chrome_extension=Extension Chrome -about.goodies.firefox_extension=Extension Firefox -about.goodies.opera_extension=Extension Opera -about.goodies.subscribe_bookmarklet=Bookmarklet d'ajout d'abonnement -about.goodies.subscribe_bookmarklet_asc=Du plus ancien au plus récent -about.goodies.subscribe_bookmarklet_desc=Du plus récent au plus ancien -about.goodies.next_unread_bookmarklet=Bookmarklet vers le prochain article non-lu -about.translation=Traduction -about.translation.message=Nous avons besoin d'aide pour traduire CommaFeed. -about.translation.link=Cliquez ici pour voir comment vous pouvez nous aider. -about.announcements=Annonces -about.rest_api.line1=CommaFeed utilise JAX-RS et AngularJS, donc une API REST est disponible. -about.rest_api.link_to_documentation=Lien vers la documentation. - -about.shortcuts.mouse_middleclick=clic du milieu de la souris -about.shortcuts.open_next_entry=Ouvrir l'article suivant -about.shortcuts.open_previous_entry=Ouvrir l'article précédent -about.shortcuts.spacebar=espace/shift+espace -about.shortcuts.move_page_down_up=Faire descendre/monter la page -about.shortcuts.focus_next_entry=Sélectionner l'article suivant sans l'ouvrir -about.shortcuts.focus_previous_entry=Sélectionner l'article précédent sans l'ouvrir -about.shortcuts.open_next_feed=Sélectionner le flux ou la catégorie suivante -about.shortcuts.open_previous_feed=Sélectionner le flux ou la catégorie précédente -about.shortcuts.open_close_current_entry=Ouvrir/fermer l'article courant -about.shortcuts.open_current_entry_in_new_window=Ouvrir l'article courant dans une nouvelle fenêtre -about.shortcuts.open_current_entry_in_new_window_background=Ouvrir l'article courant dans une nouvelle fenêtre en arrière plan -about.shortcuts.star_unstar=Ajouter/enlever l'article courant des favoris -about.shortcuts.mark_current_entry=Marquer comme lue/non-lue l'article courant -about.shortcuts.mark_all_as_read=Marquer tous les articles comme lus -about.shortcuts.open_in_new_tab_mark_as_read=Ouvrir l'article courant dans une nouvelle fenêtre et marquer comme lu -about.shortcuts.fullscreen=Activer/désactiver le mode plein-écran -about.shortcuts.font_size=Augmenter/diminuer la taille de la police de l'article courant -about.shortcuts.go_to_all=Afficher tous les articles -about.shortcuts.go_to_starred=Afficher les articles favoris -about.shortcuts.feed_search=Naviguer vers un flux en entrant son nom - diff --git a/src/main/resources/i18n/gl.properties b/src/main/resources/i18n/gl.properties deleted file mode 100644 index 31a2522e..00000000 --- a/src/main/resources/i18n/gl.properties +++ /dev/null @@ -1,157 +0,0 @@ -global.save=Gardar -global.cancel=Cancelar -global.delete=Eliminar -global.required=Requerido -global.download=Descargar -global.link=Ligazón -global.bookmark=Marcador -global.close=Pechar -global.tags=Tags ####### Needs translation - -tree.subscribe=Subscribir -tree.import=Importar -tree.new_category=Nova categoría -tree.all=Todos -tree.starred=Destacado - -subscribe.feed_url=URL da fonte -subscribe.feed_name=Nome da fonte -subscribe.category=Categoría - -import.google_reader_prefix=Deixame importar as fontes da túa -import.google_reader_suffix= conta. -import.google_download=Tamén podes subir un ficheiro subscriptions.xml. -import.google_download_link=Descárgao de aquí. -import.xml_file=Ficheiro OPML - -new_category.name=Nome -new_category.parent=Pai - -toolbar.unread=Sen Ler -toolbar.all=Todos -toolbar.previous_entry=Entrada Anterior -toolbar.next_entry=Próxima Entrada -toolbar.refresh=Actualizar -toolbar.refresh_all=Force refresh all my feeds ####### Needs translation -toolbar.sort_by_asc_desc=Ordenar por data asc/desc -toolbar.titles_only=Só títulos -toolbar.expanded_view=Vista expandida -toolbar.mark_all_as_read=Marcar todos como lidos -toolbar.mark_all_older_12_hours=Items older than 12 hours ####### Needs translation -toolbar.mark_all_older_day=Artigos anteriores a un día -toolbar.mark_all_older_week=Artigos de máis de unha semana -toolbar.mark_all_older_two_weeks=Artigos de máis de dúas semanas -toolbar.settings=Configuración -toolbar.profile=Perfil -toolbar.admin=Admin -toolbar.about=Sobre -toolbar.logout=Pechar sesión -toolbar.donate=Doar - -view.entry_source=from ####### Needs translation -view.entry_author=by ####### Needs translation -view.error_while_loading_feed=Erro mentras se cargaba esta fonte -view.keep_unread=Gardar non lidos -view.no_unread_items=non ten elementos sen ler. -view.mark_up_to_here=Mark as read up to here ####### Needs translation -view.search_for=searching for: ####### Needs translation -view.no_search_results=No match found for the requested keywords ####### Needs translation - -feedsearch.hint=Escriba unha suscrición... -feedsearch.help=Use a teclar retorno para seleccionar e as flechas para navegar. -feedsearch.result_prefix=As súas suscricións: - -settings.general=Xeral -settings.general.language=Idioma -settings.general.language.contribute=Contribúe traducindo -settings.general.show_unread=Mostrar fontes e categorías sen entradas non lidas. -settings.general.social_buttons=Mostrar botóns de compartir en redes sociais. -settings.general.scroll_marks=En vista expandida, o desplazamento polas entradas márcaas como lidas. -settings.appearance=Aspecto -settings.scroll_speed=Scrolling speed when navigating between entries (in milliseconds) ####### Needs translation -settings.scroll_speed.help=set to 0 to disable ####### Needs translation -settings.theme=Decorado -settings.submit_your_theme=Envíe o seu decorado -settings.custom_css=CSS Personalizado - -details.feed_details=Detalles de fontes -details.url=URL -details.website=Website ####### Needs translation -details.name=Nome -details.category=Categoría -details.position=Position ####### Needs translation -details.last_refresh=Última actualización -details.message=Last refresh message ####### Needs translation -details.next_refresh=Próxima actualización -details.queued_for_refresh=En cola para actualizar -details.feed_url=URL da fonte -details.generate_api_key_first=Antes debes xerar unha chave API no teu perfil. -details.unsubscribe=Rematar suscripción -details.unsubscribe_confirmation=Are you sure you want to unsubscribe from this feed? ####### Needs translation -details.delete_category_confirmation=Are you sure you want to delete this category? ####### Needs translation -details.category_details=Detalles da categoría -details.tag_details=Tag details ####### Needs translation -details.parent_category=Categoría principal - -profile.user_name=Nome de usuario -profile.email=Correo -profile.change_password=Cambiar contrasinal -profile.confirm_password=Confirmar contrasinal -profile.minimum_6_chars=Mínimo 6 caracteres -profile.passwords_do_not_match=Os contrasinais non coinciden no coinciden -profile.api_key=Chave API -profile.api_key_not_generated=Non xerado todavía -profile.generate_new_api_key=Xerar nova chave da API -profile.generate_new_api_key_info=Ao cambiar o contrasinal xerarase unha nova chave API -profile.opml_export=Exportación de OPML -profile.delete_account=Eliminar conta -profile.delete_account_confirmation=Delete your acount? There's no turning back! ####### Needs translation - -about.rest_api=REST API -about.keyboard_shortcuts=Atallos de teclado -about.version=CommaFeed version ####### Needs translation -about.line1_prefix=CommaFeed é un proxecto de código aberto. O código está en -about.line1_suffix=. -about.line2_prefix=Se atopas un problema, por favor informa na páxina de problemas do -about.line2_suffix=\ do proxecto. -about.line3=Se che gusta este proxecto, por favor considera realizar unha doación para apoiar ao desenvolvedor e axudar a cubrir os gastos de mantemento. -about.line4=Para aqueles de vostedes que prefiran bitcoin, aquí está o enderezo -about.goodies=Extras -about.goodies.android_app=Android app ####### Needs translation -about.goodies.subscribe_url=Suscribirse a URL -about.goodies.chrome_extension=Engadido para Chrome -about.goodies.firefox_extension=Engadido para Firefox -about.goodies.opera_extension=Engadido para Opera -about.goodies.subscribe_bookmarklet=Engadir bookmarklet para suscrición(click) -about.goodies.subscribe_bookmarklet_asc=Oldest first ####### Needs translation -about.goodies.subscribe_bookmarklet_desc=Newest first ####### Needs translation -about.goodies.next_unread_bookmarklet=Bookmarklet de seguinte elemento non lido (arrastre a barra de marcadores) -about.translation=Tradución -about.translation.message=Precisamos a túa axuda para traducir CommaFeed. -about.translation.link=Ver como contribuir con traducións. -about.announcements=Anuncios -about.rest_api.line1=CommaFeed está feito co uso de JAX-RS e AngularJS. Polo que está dispoñible un REST API. -about.rest_api.link_to_documentation=Ligazón a documentación. - -about.shortcuts.mouse_middleclick=botón central do rato -about.shortcuts.open_next_entry=abrir próxima entrada -about.shortcuts.open_previous_entry=abrir entrada anterior -about.shortcuts.spacebar=space/shift+space ####### Needs translation -about.shortcuts.move_page_down_up=moves the page down/up ####### Needs translation -about.shortcuts.focus_next_entry=Establecer o foco na próxima entrada sen abrila -about.shortcuts.focus_previous_entry=Establecer o foco na entrada anterior sen abrila -about.shortcuts.open_next_feed=abrir a seguinte fonte ou categoría -about.shortcuts.open_previous_feed=abrir a fonte ou categoría anterior -about.shortcuts.open_close_current_entry=abrir/pechar entrada actual -about.shortcuts.open_current_entry_in_new_window=abrir entrada actual nunha nova ventana -about.shortcuts.open_current_entry_in_new_window_background=abrir entrada actual nunha nova ventá en segundo plano -about.shortcuts.star_unstar=marcar/desmarcar a entrada actual -about.shortcuts.mark_current_entry=marcar como lida/non lida a entrada actual -about.shortcuts.mark_all_as_read=marcar todas as entradas como lidas -about.shortcuts.open_in_new_tab_mark_as_read=abrir entrada nunha nova lapela e marcar como lida -about.shortcuts.fullscreen=toggle full screen mode ####### Needs translation -about.shortcuts.font_size=increase/decrease font size of the current entry ####### Needs translation -about.shortcuts.go_to_all=go to the All view ####### Needs translation -about.shortcuts.go_to_starred=go to the Starred view ####### Needs translation -about.shortcuts.feed_search=navegue ate unha suscrición introducindo o nome da suscrición - diff --git a/src/main/resources/i18n/glk.properties b/src/main/resources/i18n/glk.properties deleted file mode 100644 index f3d69379..00000000 --- a/src/main/resources/i18n/glk.properties +++ /dev/null @@ -1,157 +0,0 @@ -global.save=قزنج -global.cancel=باطیل -global.delete=پاک -global.required=لازم -global.download=جیرأکش -global.link=خال -global.bookmark=بوکمارک -global.close=دَوَستن -global.tags=Tags ####### Needs translation - -tree.subscribe=مشترک ببید -tree.import=درینأدأن -tree.new_category=تازه جرگه -tree.all=همه ته مطالب -tree.starred=ستاره‌دار - -subscribe.feed_url=خوراکˇ نشانی -subscribe.feed_name=خوراکˇ نام -subscribe.category=جرگه - -import.google_reader_prefix=بدأر تی خوراکانه حسابˇ جی -import.google_reader_suffix=درینأدم. -import.google_download=یا اونˇ جا تی subscriptions.xml پروندهٰ جیرأکش. -import.google_download_link=اونه ائره جیرأکش. -import.xml_file=اکس.ام.الˇ پرونده - -new_category.name=نام -new_category.parent=پئر - -toolbar.unread=نخانده -toolbar.all=همه -toolbar.previous_entry=قبلی -toolbar.next_entry=بعدی -toolbar.refresh=واج‌أری -toolbar.refresh_all=Force refresh all my feeds ####### Needs translation -toolbar.sort_by_asc_desc=تاریخˇ سر دچئن -toolbar.titles_only=خالی تیتران -toolbar.expanded_view=واشاده نما -toolbar.mark_all_as_read=همه‌ته مطالبه چاکون بخانده -toolbar.mark_all_older_12_hours=Items older than 12 hours ####### Needs translation -toolbar.mark_all_older_day=یک روز پیشترˇ مطالب -toolbar.mark_all_older_week=یک هفته پیشترˇ مطالب -toolbar.mark_all_older_two_weeks=چن هفته پیشترˇ مطالب -toolbar.settings=تنظیم -toolbar.profile=نمایه -toolbar.admin=مدیریت -toolbar.about=راجه‌به -toolbar.logout=برین -toolbar.donate=مالی ایلجار - -view.entry_source=from ####### Needs translation -view.entry_author=by ####### Needs translation -view.error_while_loading_feed=حئف ببؤ! ای خوراکˇ جؤر أمأنˇ سر خطا ببؤ. -view.keep_unread=نخانده بدأر. -view.no_unread_items=نخانده مطلب دنه. -view.mark_up_to_here=Mark as read up to here ####### Needs translation -view.search_for=searching for: ####### Needs translation -view.no_search_results=No match found for the requested keywords ####### Needs translation - -feedsearch.hint=یکته اشتراکˇ سر نویشتن... -feedsearch.help=دکمهٔ بازگشت برای انتخاب و دکمه‌های جهت‌دار را برای ناوبری استفاده کن. -feedsearch.result_prefix=تی اشتراکان: - -settings.general=همگانی -settings.general.language=زوان -settings.general.language.contribute=واگردانˇ مئنˇ ایلجار -settings.general.show_unread=تنها خوراک‌ها و دسته‌های را که دارای مطالب نخوانده هستند نمایش بده. -settings.general.social_buttons=نشان‌دادن دکمه‌های اشتراک‌گذاری در شبکه‌های اجتماعی -settings.general.scroll_marks=در نمای گسترش‌یافته، لغزیدن بر روی مطالب به‌عنوان نشانه‌گذاری به‌عنوان خوانده‌شده در نظر گرفته‌شوند. -settings.appearance=ظاهر -settings.scroll_speed=Scrolling speed when navigating between entries (in milliseconds) ####### Needs translation -settings.scroll_speed.help=set to 0 to disable ####### Needs translation -settings.theme=پوسته -settings.submit_your_theme=شیمه پوستهٰ اوسه کونید -settings.custom_css=سی‌اس‌اس شخصی‌سازی‌شده - -details.feed_details=جزئیات خوراک -details.url=نشانی -details.website=Website ####### Needs translation -details.name=نام -details.category=جرگه -details.position=Position ####### Needs translation -details.last_refresh=آخرین بروزرسانی -details.message=Last refresh message ####### Needs translation -details.next_refresh=بروزرسانی بعدی -details.queued_for_refresh=منتظر برای بروزرسانی -details.feed_url=نشانی خوراک -details.generate_api_key_first=ابتدا یک کلید API در نمایهٔ خود ایجاد کنید. -details.unsubscribe=لغو اشتراک -details.unsubscribe_confirmation=Are you sure you want to unsubscribe from this feed? ####### Needs translation -details.delete_category_confirmation=Are you sure you want to delete this category? ####### Needs translation -details.category_details=جرگه جزئیات -details.tag_details=Tag details ####### Needs translation -details.parent_category=پئرˇ جرگه - -profile.user_name=کاربری نام -profile.email=ایمئل -profile.change_password=رمزه عوضأگودن -profile.confirm_password=رمزه تأیید گودن -profile.minimum_6_chars=ناقلن 6 کارکتر -profile.passwords_do_not_match=رمزان کس‌به‌کسه نخانید -profile.api_key=کلید API -profile.api_key_not_generated=هلئه چاگوده نبؤ -profile.generate_new_api_key=تازه کلید چاگودن API -profile.generate_new_api_key_info=رمزه عوضأگودن API کلیده چاکونه. -profile.opml_export=برینأدأن OPML -profile.delete_account=کاربری حسابه پاکودن -profile.delete_account_confirmation=Delete your acount? There's no turning back! ####### Needs translation - -about.rest_api=REST API -about.keyboard_shortcuts=وئر زئنˇ کلیدان -about.version=CommaFeed version ####### Needs translation -about.line1_prefix=کامافید یکته «رهاوؤت» پروژه ایسه. اینˇ تلمبارؤن -about.line1_suffix=ˇمئن میزبانی به. -about.line2_prefix=أگه مشکلی پیش بمأ پیشأکشئنˇ صفحه مئن مطرح بکونین. -about.line2_suffix=\ پروژه. -about.line3=أگه ای پرؤژهٰ خوش دأنین، یک مبلغی هرچی‌م کی کم ببون ای سایتˇ هزینه‌ٰن و اینˇ توسعه‌دأن‌کسˇ وأسی هدین. -about.line4=اوشانی کی بیت‌کؤینه ترجیح دئنن، نشانی ائره نأ. -about.goodies=علاوه‌ٰن -about.goodies.android_app=Android app ####### Needs translation -about.goodies.subscribe_url=نشانی مئنˇ اشتراک -about.goodies.chrome_extension=کرؤمˇ علاوه -about.goodies.firefox_extension=فایرفاکسˇ علاوه -about.goodies.opera_extension=اؤپرا علاوه -about.goodies.subscribe_bookmarklet=افزودن بوک‌مارک‌لت اشتراک (با کلیک) -about.goodies.subscribe_bookmarklet_asc=Oldest first ####### Needs translation -about.goodies.subscribe_bookmarklet_desc=Newest first ####### Needs translation -about.goodies.next_unread_bookmarklet=بوک‌مارک‌لت مطلب خوانده نشدهٔ بعدی(با کشیدن و رهاکردن در نوار بوک‌مارک‌لت) -about.translation=واگردان -about.translation.message=أمه شیمه ایلجاره کامافیدˇ واگردانˇ مئن خأییم. -about.translation.link=ببدینید چوتؤ تانید واگردانˇ مئن ایلجار بکونید. -about.announcements=اطلاعیه‌ٰن -about.rest_api.line1=کامافید بر روی JAX-RS و AngularJS ساخته‌شده‌است. به همین دلیل API REST موجود است. -about.rest_api.link_to_documentation=خال به مستندات. - -about.shortcuts.mouse_middleclick=مؤسˇ مئنی کلیک -about.shortcuts.open_next_entry=بعدی مطلبه واگدن -about.shortcuts.open_previous_entry=قبلی مطلبه واگودن -about.shortcuts.spacebar=space/shift+space ####### Needs translation -about.shortcuts.move_page_down_up=moves the page down/up ####### Needs translation -about.shortcuts.focus_next_entry=بعدی مطلبˇ سر شؤن بی اینکه وابکونه -about.shortcuts.focus_previous_entry=قبلی مطلبˇ سر شؤن بی اینکه وابکونه -about.shortcuts.open_next_feed=بعدی خوراک یا جرگهٰ واگودن -about.shortcuts.open_previous_feed=قبلی خوراک یا جرگهٰ واگودن -about.shortcuts.open_close_current_entry=مطلبه واگودن/دوستن -about.shortcuts.open_current_entry_in_new_window=مطلبه تازه درجیکˇ مئن واگودن -about.shortcuts.open_current_entry_in_new_window_background=مطلبه تازه درجیکˇ مئن پس‌زمینه واگودن -about.shortcuts.star_unstar=مطلبه نشانه‌دار گودن/نگودن -about.shortcuts.mark_current_entry=مطلبه نشانه‌دار گودن کی بخانه/نخانده ایسه -about.shortcuts.mark_all_as_read=همه‌ته مطالبه نشانه بنه کی بخانده ببؤن -about.shortcuts.open_in_new_tab_mark_as_read=مطلبه تازه سرولگˇ میان واگودن و نشانه‌دار کودن به عنوانˇ بخانده -about.shortcuts.fullscreen=toggle full screen mode ####### Needs translation -about.shortcuts.font_size=increase/decrease font size of the current entry ####### Needs translation -about.shortcuts.go_to_all=go to the All view ####### Needs translation -about.shortcuts.go_to_starred=go to the Starred view ####### Needs translation -about.shortcuts.feed_search=اشتراکˇ نامه بنویس و اونه وئر بزن - diff --git a/src/main/resources/i18n/hu.properties b/src/main/resources/i18n/hu.properties deleted file mode 100644 index 11437107..00000000 --- a/src/main/resources/i18n/hu.properties +++ /dev/null @@ -1,157 +0,0 @@ -global.save=Mentés -global.cancel=Mégsem -global.delete=Törlés -global.required=Szükséges -global.download=Letöltés -global.link=Link -global.bookmark=Könyvjelző -global.close=Bezár -global.tags=Címkék - -tree.subscribe=Feliratkozás -tree.import=Importálás -tree.new_category=Új kategória -tree.all=Összes -tree.starred=Csillagozott - -subscribe.feed_url=Hírcsatorna URL -subscribe.feed_name=Hírcsatorna neve -subscribe.category=Kategória - -import.google_reader_prefix=Engedd meg, hogy importáljuk a hírcsatornáidat a -import.google_reader_suffix= fiókjából. -import.google_download=Alternatívaként, feltöltheti a subscriptions.xml fájlt. -import.google_download_link=Letöltheti innen. -import.xml_file=OPML Fájl - -new_category.name=Név -new_category.parent=Szülő - -toolbar.unread=Olvasatlan -toolbar.all=Összes -toolbar.previous_entry=Előző elem -toolbar.next_entry=Következő elem -toolbar.refresh=Frissítés -toolbar.refresh_all=Force refresh all my feeds ####### Needs translation -toolbar.sort_by_asc_desc=Rendezés időrend szerint -toolbar.titles_only=Csak cím -toolbar.expanded_view=Részletes nézet -toolbar.mark_all_as_read=Az összes megjelölése olvasottként -toolbar.mark_all_older_12_hours=Régebbiek 12 óránál -toolbar.mark_all_older_day=Régebbiek, mint egy nap -toolbar.mark_all_older_week=Régebbiek, mint egy hét -toolbar.mark_all_older_two_weeks=Régebbiek, mint két hét -toolbar.settings=Beállítások -toolbar.profile=Profil -toolbar.admin=Admin -toolbar.about=Névjegy -toolbar.logout=Kilépés -toolbar.donate=Anyagi támogatás - -view.entry_source=forrás -view.entry_author=szerző -view.error_while_loading_feed=Hiba történt ennek a hírcsatornának a betöltésekor -view.keep_unread=Megtartása olvasatlanként -view.no_unread_items=nincsen olvasatlan eleme. -view.mark_up_to_here=Megjelölés olvasottnak eddig -view.search_for=keresés erre: -view.no_search_results=Nem található semmi erre a keresett szóra - -feedsearch.hint=Keressen a hírcsatornák között... -feedsearch.help=Használja a nyíl billentyűket a navigáláshoz, az enter-t a kiválasztáshoz. -feedsearch.result_prefix=Az ön feliratkozásai: - -settings.general=Általános -settings.general.language=Nyelv -settings.general.language.contribute=Segítsen a fordításban -settings.general.show_unread=Mutassa azokat a hírcsatornákat és kategóriákat amelyekben nincsen olvasatlan bejegyzés -settings.general.social_buttons=Mutassa a közösségi oldalak megosztás gombjait -settings.general.scroll_marks=Kiterjesztett nézetben, görgetéssel olvasottként jelöli meg a bejegyzést -settings.appearance=Megjelenés -settings.scroll_speed=A görgetés sebessége, amikor a cikkek között navigál (miliszekundumban) -settings.scroll_speed.help=Írjon be 0-át a letiltáshoz -settings.theme=Téma -settings.submit_your_theme=Küldje el a témáját -settings.custom_css=Saját CSS - -details.feed_details=Hírcsatorna részletei -details.url=URL -details.website=Weboldal -details.name=Név -details.category=Kategória -details.position=Pozició -details.last_refresh=Utolsó frissítés -details.message=Utolsó frissítési üzenet -details.next_refresh=Következő frissítés -details.queued_for_refresh=Frissítésre vár -details.feed_url=Hírcsatorna URL -details.generate_api_key_first=A profiljában először egy API kulcsot kell generálnia. -details.unsubscribe=Leiratkozás -details.unsubscribe_confirmation=Biztos, hogy le akar iratkozni errről a csatornáról? -details.delete_category_confirmation=Biztos, hog törölni akarja ezt a kategóriát? -details.category_details=Kategória részletei -details.tag_details=Címke részletei -details.parent_category=Szülő kategória - -profile.user_name=Felhasználói név -profile.email=E-mail -profile.change_password=Jelszó megváltoztatás -profile.confirm_password=Jelszó megerősítése -profile.minimum_6_chars=Legalább 8 karakter -profile.passwords_do_not_match=A jelszavak nem egyeznek -profile.api_key=API kulcs -profile.api_key_not_generated=Még nincsen generálva -profile.generate_new_api_key=Új API kulcs generálása -profile.generate_new_api_key_info=A jelszó megváltoztatása új API kulcsot generál -profile.opml_export=OPML exportálása -profile.delete_account=Fiók törlése -profile.delete_account_confirmation=Törli a fiókját? Innen már nincs visszatérés! - -about.rest_api=REST API -about.keyboard_shortcuts=Gyorsbillentyűk -about.version=CommaFeed verzió -about.line1_prefix=A CommaFeed egy nyílt forrású projekt. A forrás megtalálható a -about.line1_suffix=oldalán. -about.line2_prefix=Ha hibába ütközik, kérjük jelentse azt a -about.line2_suffix=projekt oldalán. -about.line3=Ha tetszik önnek ez a szolgáltatás, akkor kérjük támogassa a fejlesztőket és, hogy fentarthassák a weboldalt. -about.line4=Akik jobban szeretnék az oldalt bitcon-nal támogatni, itt a cím -about.goodies=Hasznos dolgok -about.goodies.android_app=Android alkalmazás -about.goodies.subscribe_url=Feliratkozás az URL-re -about.goodies.chrome_extension=Chrome bővítmény -about.goodies.firefox_extension=Firefox kiterjesztés -about.goodies.opera_extension=Opera kiterjesztés -about.goodies.subscribe_bookmarklet=Feliratkozás bookmarklet hozzáadása (klikkeléssel) -about.goodies.subscribe_bookmarklet_asc=Régebbiek először -about.goodies.subscribe_bookmarklet_desc=Újak először -about.goodies.next_unread_bookmarklet=Következő olvasatlan elem bookmarklet (húzza fel a könyvjelzősávba) -about.translation=Fordítás -about.translation.message=Segítségét kérjük a CommaFeed fordításához. -about.translation.link=Nézze meg, hogyan tud segíteni ebben. -about.announcements=Bejelentések -about.rest_api.line1=A CommaFeed a JAX-RS-re és az AngularJS-re épül. Ezért a RESTA API elérhető. -about.rest_api.link_to_documentation=Link a dokumentációhoz. - -about.shortcuts.mouse_middleclick=középső egérgomb -about.shortcuts.open_next_entry=következő hír megnyitása -about.shortcuts.open_previous_entry=előző hír megnyitása -about.shortcuts.spacebar=szóköz/shift+szóköz -about.shortcuts.move_page_down_up=fel/le lépkedhet az oldalon -about.shortcuts.focus_next_entry=megnyitás nélkül fókuszál a övetkező elemre -about.shortcuts.focus_previous_entry=megnyitás nélkül fókuszál az előző elemre -about.shortcuts.open_next_feed=a következő hírcsatorna vagy kategória megnyitása -about.shortcuts.open_previous_feed=az előző hírcsatorna vagy kategória megnyitása -about.shortcuts.open_close_current_entry=a jelenlegi elem megnyitása/bezárása -about.shortcuts.open_current_entry_in_new_window=a jelenlegi elem megnyitása új ablakban -about.shortcuts.open_current_entry_in_new_window_background=a jelenlegi elem megnyitása a háttérben, új ablakban -about.shortcuts.star_unstar=hírelem csillagozása -about.shortcuts.mark_current_entry=elem megjelölése olvasottként -about.shortcuts.mark_all_as_read=az összes elem megjelölése olvasottként -about.shortcuts.open_in_new_tab_mark_as_read=elem megnyitása új fülön és megjelölése olvasottként -about.shortcuts.fullscreen=teljes képernyős mód bekapcsolása -about.shortcuts.font_size=a jelenlegi elemnél növeli/csökkenti a betűméretet -about.shortcuts.go_to_all=átkapcsol az Összes nézetre -about.shortcuts.go_to_starred=átkapcsol a Csillagozott nézetre -about.shortcuts.feed_search=név szerinti keresés a hírcsatornák között - diff --git a/src/main/resources/i18n/it.properties b/src/main/resources/i18n/it.properties deleted file mode 100644 index 3ab3b2f1..00000000 --- a/src/main/resources/i18n/it.properties +++ /dev/null @@ -1,157 +0,0 @@ -global.save=Salva -global.cancel=Cancella -global.delete=Elimina -global.required=Required -global.download=Download -global.link=Link -global.bookmark=Segnalibro -global.close=Chiudi -global.tags=Tags ####### Needs translation - -tree.subscribe=Iscriviti -tree.import=Importa -tree.new_category=Nuova categoria -tree.all=Tutto -tree.starred=Preferiti - -subscribe.feed_url=Feed URL -subscribe.feed_name=Nome Feed -subscribe.category=Categoria - -import.google_reader_prefix=Importa i tuoi feed dal tuo -import.google_reader_suffix= account. -import.google_download=Oppure, carica il tuo subscriptions.xml -import.google_download_link=Scaricalo da qui -import.xml_file=OPML File - -new_category.name=Nome -new_category.parent=Parent - -toolbar.unread=Non letti -toolbar.all=Tutti -toolbar.previous_entry=Precedente -toolbar.next_entry=Successivo -toolbar.refresh=Ricarica -toolbar.refresh_all=Force refresh all my feeds ####### Needs translation -toolbar.sort_by_asc_desc=Sort by date asc/desc -toolbar.titles_only=Solo titoli -toolbar.expanded_view=Espandi -toolbar.mark_all_as_read=Contrassegna tutto come già letto -toolbar.mark_all_older_12_hours=Items older than 12 hours ####### Needs translation -toolbar.mark_all_older_day=Elementi più vecchi di un giorno -toolbar.mark_all_older_week=Elementi più vecchi di una settimana -toolbar.mark_all_older_two_weeks=Elementi più vecchi di due settimane -toolbar.settings=Impostazioni -toolbar.profile=Profilo -toolbar.admin=Admin -toolbar.about=Informazioni -toolbar.logout=Logout -toolbar.donate=Dona - -view.entry_source=from ####### Needs translation -view.entry_author=by ####### Needs translation -view.error_while_loading_feed=Si è verificato un errore, mentre caricavo il feed -view.keep_unread=Mantiene come da leggere -view.no_unread_items=Non ci sono elementi da leggere. -view.mark_up_to_here=Mark as read up to here ####### Needs translation -view.search_for=searching for: ####### Needs translation -view.no_search_results=No match found for the requested keywords ####### Needs translation - -feedsearch.hint=Type in a subscription... ####### Needs translation -feedsearch.help=Use the return key to select and arrow keys to navigate. ####### Needs translation -feedsearch.result_prefix=Le tue sottoscrizioni - -settings.general=Generali -settings.general.language=Lingua -settings.general.language.contribute=Contribuisci con le traduzioni -settings.general.show_unread=Show feeds and categories with no unread entries -settings.general.social_buttons=Visualizza i social button -settings.general.scroll_marks=Marca come letto quando scorri -settings.appearance=Appearance ####### Needs translation -settings.scroll_speed=Scrolling speed when navigating between entries (in milliseconds) ####### Needs translation -settings.scroll_speed.help=set to 0 to disable ####### Needs translation -settings.theme=Tema -settings.submit_your_theme=Sottoponi il tuo tema -settings.custom_css=Css modificato - -details.feed_details=Dettagli feed -details.url=URL -details.website=Website ####### Needs translation -details.name=Nome -details.category=Categoria -details.position=Posizione -details.last_refresh=Ultimo aggiornamento -details.message=Last refresh message ####### Needs translation -details.next_refresh=Next refresh ####### Needs translation -details.queued_for_refresh=In attesa per l'aggiornamento -details.feed_url=Feed URL -details.generate_api_key_first=Generate an API key in your profile first. -details.unsubscribe=Annulla l"'"iscrizione -details.unsubscribe_confirmation=Are you sure you want to unsubscribe from this feed? ####### Needs translation -details.delete_category_confirmation=Are you sure you want to delete this category? ####### Needs translation -details.category_details=Dettagli categoria -details.tag_details=Tag details ####### Needs translation -details.parent_category=Parent category - -profile.user_name=User name -profile.email=E-mail -profile.change_password=Cambia password -profile.confirm_password=Conferma password -profile.minimum_6_chars=Minimo 6 caratteri -profile.passwords_do_not_match=Le password non corrispondono -profile.api_key=API key -profile.api_key_not_generated=Non generata ancora -profile.generate_new_api_key=Genera una nuova chiave API -profile.generate_new_api_key_info=Cambiando la password sarà generata una nuova chiave API -profile.opml_export=Esporta OPML -profile.delete_account=Elimina account -profile.delete_account_confirmation=Delete your acount? There's no turning back! ####### Needs translation - -about.rest_api=REST API -about.keyboard_shortcuts=Scorciatoie da tastiera -about.version=CommaFeed version ####### Needs translation -about.line1_prefix=Commefeed è un progetto open-source. I codici sono hostati su -about.line1_suffix=. -about.line2_prefix=Se hai qualche problema, segnalalo sulla pagina del -about.line2_suffix=\ progetto. -about.line3=Se ti piace il progetto, prendi in considerazione una donazione per supportare lo sviluppatore e contribuire a coprire i costi di mantenenimento di questo sito on-line. -about.line4=Per chi preferisce Bitcoin, questo è l"'"indirizzo -about.goodies=Goodies -about.goodies.android_app=Android app ####### Needs translation -about.goodies.subscribe_url=Subscribe URL -about.goodies.chrome_extension=Estenzione per Chrome -about.goodies.firefox_extension=Estensione per Firefox -about.goodies.opera_extension=Estensione per Opera -about.goodies.subscribe_bookmarklet=Add subscription bookmarklet (click) ####### Needs translation -about.goodies.subscribe_bookmarklet_asc=Oldest first ####### Needs translation -about.goodies.subscribe_bookmarklet_desc=Newest first ####### Needs translation -about.goodies.next_unread_bookmarklet=Next unread item bookmarklet (drag to bookmark bar) ####### Needs translation -about.translation=Traduzioni -about.translation.message=Abbiamo bisogno del tuo aiuto per tradurre CommaFeed. -about.translation.link=Vedi come aiutare con le traduzioni. -about.announcements=Annunci -about.rest_api.line1=CommaFeed is built on top of JAX-RS and AngularJS. As such, a REST API is available. -about.rest_api.link_to_documentation=Link alla documentazione. - -about.shortcuts.mouse_middleclick=mouse middleclick -about.shortcuts.open_next_entry=open next entry -about.shortcuts.open_previous_entry=open previous entry -about.shortcuts.spacebar=space/shift+space ####### Needs translation -about.shortcuts.move_page_down_up=moves the page down/up ####### Needs translation -about.shortcuts.focus_next_entry=set focus on next entry without opening it ####### Needs translation -about.shortcuts.focus_previous_entry=set focus on previous entry without opening it ####### Needs translation -about.shortcuts.open_next_feed=open next feed or category ####### Needs translation -about.shortcuts.open_previous_feed=open previous feed or category ####### Needs translation -about.shortcuts.open_close_current_entry=open/close current entry -about.shortcuts.open_current_entry_in_new_window=open current entry in a new window -about.shortcuts.open_current_entry_in_new_window_background=open current entry in a new window in the background ####### Needs translation -about.shortcuts.star_unstar=star/unstar current entry -about.shortcuts.mark_current_entry=mark as read/unread current entry -about.shortcuts.mark_all_as_read=mark all entries as read -about.shortcuts.open_in_new_tab_mark_as_read=open entry in new tab and mark as read -about.shortcuts.fullscreen=toggle full screen mode ####### Needs translation -about.shortcuts.font_size=increase/decrease font size of the current entry ####### Needs translation -about.shortcuts.go_to_all=go to the All view ####### Needs translation -about.shortcuts.go_to_starred=go to the Starred view ####### Needs translation -about.shortcuts.feed_search=navigate to a subscription by entering the subscription name ####### Needs translation - diff --git a/src/main/resources/i18n/ja.properties b/src/main/resources/i18n/ja.properties deleted file mode 100644 index 84f051c5..00000000 --- a/src/main/resources/i18n/ja.properties +++ /dev/null @@ -1,157 +0,0 @@ -global.save=保存 -global.cancel=取り消し -global.delete=削除 -global.required=Required -global.download=ダウンロード -global.link=リンク -global.bookmark=ブックマーク -global.close=閉じる -global.tags=タグ - -tree.subscribe=購読 -tree.import=インポート -tree.new_category=新しいカテゴリー -tree.all=全て -tree.starred=スター付 - -subscribe.feed_url=フィードURL -subscribe.feed_name=フィード名 -subscribe.category=カテゴリー - -import.google_reader_prefix=Googleアカウントからフィードを -import.google_reader_suffix=インポートします。 -import.google_download=または、お持ちのsubscriptions.xmlファイルをアップロードします。 -import.google_download_link=このリンクからダウンロードして下さい。 -import.xml_file=OPMLファイル - -new_category.name=名前 -new_category.parent=親カテゴリー - -toolbar.unread=未読 -toolbar.all=全て -toolbar.previous_entry=前のエントリー -toolbar.next_entry=次のエントリー -toolbar.refresh=更新 -toolbar.refresh_all=全てのフィードを更新 -toolbar.sort_by_asc_desc=昇順/降順にソート -toolbar.titles_only=タイトルのみ -toolbar.expanded_view=拡張ビュー -toolbar.mark_all_as_read=全て既読にする -toolbar.mark_all_older_12_hours=12時間以上前のアイテム -toolbar.mark_all_older_day=前日より前のアイテム -toolbar.mark_all_older_week=1週間以上前のアイテム -toolbar.mark_all_older_two_weeks=2週間以上前のアイテム -toolbar.settings=設定 -toolbar.profile=Profile -toolbar.admin=管理者 -toolbar.about=About -toolbar.logout=ログアウト -toolbar.donate=寄付 - -view.entry_source= より -view.entry_author= 著者 -view.error_while_loading_feed=フィード読み込み中にエラーが発生しました。 -view.keep_unread=未読として保持 -view.no_unread_items=未読アイテムはありません。 -view.mark_up_to_here=ここまで既読 -view.search_for=検索: -view.no_search_results=検索結果はありません。 - -feedsearch.hint=購読フィードを入力... -feedsearch.help=Enterキーで選択、矢印キーで移動します。 -feedsearch.result_prefix=見つかった購読フィード: - -settings.general=一般 -settings.general.language=言語 -settings.general.language.contribute=翻訳に貢献する -settings.general.show_unread=未読エントリーのないフィードとカテゴリーを表示 -settings.general.social_buttons=共有ボタンを表示 -settings.general.scroll_marks=拡張ビューではエントリーのスクロールで既読にする -settings.appearance=外観 -settings.scroll_speed=エントリー間のスクロールスピード(ミリ秒) -settings.scroll_speed.help=0に設定すると無効になります -settings.theme=テーマ -settings.submit_your_theme=テーマを登録する -settings.custom_css=カスタムCSS - -details.feed_details=フィードの詳細 -details.url=URL -details.website=Webサイト -details.name=名前 -details.category=カテゴリー -details.position=位置 -details.last_refresh=最終更新 -details.message=最終更新メッセージ -details.next_refresh=次回更新 -details.queued_for_refresh=更新キュー -details.feed_url=フィードURL -details.generate_api_key_first=最初にあなたのAPIキーを生成して下さい。 -details.unsubscribe=購読解除 -details.unsubscribe_confirmation=Are you sure you want to unsubscribe from this feed? ####### Needs translation -details.delete_category_confirmation=Are you sure you want to delete this category? ####### Needs translation -details.category_details=カテゴリー詳細 -details.tag_details=タグ詳細 -details.parent_category=親カテゴリー - -profile.user_name=ユーザ名 -profile.email=E-mail -profile.change_password=パスワードの変更 -profile.confirm_password=変更パスワードの確認 -profile.minimum_6_chars=6文字以上 -profile.passwords_do_not_match=パスワードが一致しません -profile.api_key=APIキー -profile.api_key_not_generated=APIキーが生成されていません -profile.generate_new_api_key=新しいAPIキーを生成 -profile.generate_new_api_key_info=パスワードの変更は新しいAPIキーが生成されます -profile.opml_export=OPMLエクスポート -profile.delete_account=アカウント削除 -profile.delete_account_confirmation=Delete your acount? There's no turning back! ####### Needs translation - -about.rest_api=REST API -about.keyboard_shortcuts=キーボードショートカット -about.version=CommaFeedバージョン -about.line1_prefix=CommaFeedはオープンソースプロジェクトです。ソースは -about.line1_suffix=にホスティングされています。 -about.line2_prefix=もし問題を登録したい場合、 -about.line2_suffix=プロジェクトのissuesページに報告して下さい。 -about.line3=このプロジェクトを気に入った場合、開発者やWebサイトの運営コストをサポートするための寄付を検討して下さいね。 -about.line4=Bitcoinなら寄付できる方、アドレスはこちらです。 -about.goodies=Goodies -about.goodies.android_app=Androidアプリ -about.goodies.subscribe_url=購読URL -about.goodies.chrome_extension=Chrome拡張 -about.goodies.firefox_extension=Firefox拡張 -about.goodies.opera_extension=Opera拡張 -about.goodies.subscribe_bookmarklet=購読ブックマークレットを追加(クリック) -about.goodies.subscribe_bookmarklet_asc=古い順 -about.goodies.subscribe_bookmarklet_desc=新しい順 -about.goodies.next_unread_bookmarklet=次の未読アイテムブックマークレット(ブックマークバーへドラッグ) -about.translation=翻訳 -about.translation.message=CommaFeedの翻訳に助けが必要です! -about.translation.link=どうやって翻訳に貢献できるか見て下さい。 -about.announcements=Announcements -about.rest_api.line1=CommaFeedはJAX-RSとAngularJSを使用しているので、REST APIも利用可能です。 -about.rest_api.link_to_documentation=ドキュメントへのリンク - -about.shortcuts.mouse_middleclick=中クリック -about.shortcuts.open_next_entry=次のエントリーを開く -about.shortcuts.open_previous_entry=前のエントリーを開く -about.shortcuts.spacebar=space/shift+space -about.shortcuts.move_page_down_up=ページ移動 -about.shortcuts.focus_next_entry=次のエントリーを開かずにフォーカス移動 -about.shortcuts.focus_previous_entry=前のエントリーを開かずにフォーカス移動 -about.shortcuts.open_next_feed=次のフィード/カテゴリーを開く -about.shortcuts.open_previous_feed=前のフィード/カテゴリーを開く -about.shortcuts.open_close_current_entry=現在のエントリーを開く/閉じる -about.shortcuts.open_current_entry_in_new_window=現在のエントリーを新しいウィンドウで開く -about.shortcuts.open_current_entry_in_new_window_background=現在のエントリーを新しいバックグラウンドウィンドウで開く -about.shortcuts.star_unstar=現在のエントリーにスターを付ける/解除する -about.shortcuts.mark_current_entry=現在のエントリーを既読/未読にする -about.shortcuts.mark_all_as_read=全エントリーを既読にする -about.shortcuts.open_in_new_tab_mark_as_read=エントリーを既読にして新しいタブで開く -about.shortcuts.fullscreen=フルスクリーントグル -about.shortcuts.font_size=現在のエントリーのフォントサイズを大きく/小さくする -about.shortcuts.go_to_all=All viewに変更する -about.shortcuts.go_to_starred=スター付きviewに変更する -about.shortcuts.feed_search=購読画面(subscription nameの入力)に移動する - diff --git a/src/main/resources/i18n/ko.properties b/src/main/resources/i18n/ko.properties deleted file mode 100644 index bb5ba910..00000000 --- a/src/main/resources/i18n/ko.properties +++ /dev/null @@ -1,157 +0,0 @@ -global.save=저장 -global.cancel=취소 -global.delete=삭제 -global.required=필수 -global.download=Download ####### Needs translation -global.link=Link ####### Needs translation -global.bookmark=Bookmark ####### Needs translation -global.close=Close ####### Needs translation -global.tags=Tags ####### Needs translation - -tree.subscribe=구독 -tree.import=임포트 -tree.new_category=새로운 카테고리 -tree.all=전체 -tree.starred=스타 - -subscribe.feed_url=피드 URL -subscribe.feed_name=피드 이름 -subscribe.category=카테로기 - -import.google_reader_prefix=당신의 Google Reader -import.google_reader_suffix= 에서 피드들을 가져오겠습니다. -import.google_download=아니면, subscription.xml 파일을 업로드 해주세요. -import.google_download_link=다운로드 링크 -import.xml_file=OPML File - -new_category.name=이름 -new_category.parent=카테고리 주소로 가기 - -toolbar.unread=안읽음 -toolbar.all=전체 -toolbar.previous_entry=Previous entry ####### Needs translation -toolbar.next_entry=Next entry ####### Needs translation -toolbar.refresh=리프래쉬 -toolbar.refresh_all=Force refresh all my feeds ####### Needs translation -toolbar.sort_by_asc_desc=Sort by date asc/desc ####### Needs translation -toolbar.titles_only=Titles only ####### Needs translation -toolbar.expanded_view=Expanded view ####### Needs translation -toolbar.mark_all_as_read=읽음표시 -toolbar.mark_all_older_12_hours=Items older than 12 hours ####### Needs translation -toolbar.mark_all_older_day=Items older than a day ####### Needs translation -toolbar.mark_all_older_week=Items older than a week ####### Needs translation -toolbar.mark_all_older_two_weeks=Items older than two weeks ####### Needs translation -toolbar.settings=설정 -toolbar.profile=프로필 -toolbar.admin=괸리자 -toolbar.about=더보기 -toolbar.logout=로그아웃 -toolbar.donate=기부하기 - -view.entry_source=from ####### Needs translation -view.entry_author=by ####### Needs translation -view.error_while_loading_feed=피드로딩중 에러 -view.keep_unread=안읽은것 저장 -view.no_unread_items= 읽지않은 항목이 없읍니다. -view.mark_up_to_here=Mark as read up to here ####### Needs translation -view.search_for=searching for: ####### Needs translation -view.no_search_results=No match found for the requested keywords ####### Needs translation - -feedsearch.hint=Type in a subscription... ####### Needs translation -feedsearch.help=Use the return key to select and arrow keys to navigate. ####### Needs translation -feedsearch.result_prefix=Your subscriptions: ####### Needs translation - -settings.general=일반 -settings.general.language=일반 언어 -settings.general.language.contribute=번역 도움하기 -settings.general.show_unread=안읽은 항목들이 있는 피드와 카테고리 보여주기 -settings.general.social_buttons=소셜미디아 버튼들 보여주기 -settings.general.scroll_marks=Expanded View에서 스크롤하면 항목들을 읽음으로 저장하기 -settings.appearance=Appearance ####### Needs translation -settings.scroll_speed=Scrolling speed when navigating between entries (in milliseconds) ####### Needs translation -settings.scroll_speed.help=set to 0 to disable ####### Needs translation -settings.theme=Theme ####### Needs translation -settings.submit_your_theme=Submit your theme ####### Needs translation -settings.custom_css=커스톰 CSS - -details.feed_details=피드 세부 -details.url=유알엘 -details.website=Website ####### Needs translation -details.name=이름 -details.category=카테고리 -details.position=Position ####### Needs translation -details.last_refresh=마지막 리프래쉬 -details.message=Last refresh message ####### Needs translation -details.next_refresh=Next refresh ####### Needs translation -details.queued_for_refresh=Queued for refresh ####### Needs translation -details.feed_url=피드 유알엘 -details.generate_api_key_first=당신의 프로필을 위해 API Key를 먼저 생성하세요. -details.unsubscribe=주소 삭제 -details.unsubscribe_confirmation=Are you sure you want to unsubscribe from this feed? ####### Needs translation -details.delete_category_confirmation=Are you sure you want to delete this category? ####### Needs translation -details.category_details=카테고리 세부 -details.tag_details=Tag details ####### Needs translation -details.parent_category=부모 카테고리 - -profile.user_name=사용자 이름 -profile.email=이메일 -profile.change_password=비밀번호변경 -profile.confirm_password=비밀번호확인 -profile.minimum_6_chars=최소로 6자문자가 필요합니다. -profile.passwords_do_not_match=비밀번호가 일치하지 않습니다. -profile.api_key=API key -profile.api_key_not_generated=아직 API Key가 생성되지 않았습니다. -profile.generate_new_api_key=API Key 생성하기 -profile.generate_new_api_key_info=비밀번호를 변경하면 새로운 API Key가 생성됩니다. -profile.opml_export=OPML export ####### Needs translation -profile.delete_account=프로필삭제 -profile.delete_account_confirmation=Delete your acount? There's no turning back! ####### Needs translation - -about.rest_api=REST API -about.keyboard_shortcuts=단축기 -about.version=CommaFeed version ####### Needs translation -about.line1_prefix=CommaFeed는 오픈 소스프로젝트입니다. 소스는 -about.line1_suffix=에 있습니다. -about.line2_prefix=문제가 발생하는 경우 -about.line2_suffix= 프로젝트 문제페이지에 보고하십시요. -about.line3=이 프로젝트를 좋아하시면 개발자를 지원하고 웹사이트 유지용비를 충당하는 데 도움이되는 기부금을 고려하시기 바랍니다. -about.line4=For those of you who prefer bitcoin, here is the address ####### Needs translation -about.goodies=Goodies -about.goodies.android_app=Android app ####### Needs translation -about.goodies.subscribe_url=Subscribe URL ####### Needs translation -about.goodies.chrome_extension=Chrome extension ####### Needs translation -about.goodies.firefox_extension=Firefox extension ####### Needs translation -about.goodies.opera_extension=Opera extension ####### Needs translation -about.goodies.subscribe_bookmarklet=Add subscription bookmarklet (click) ####### Needs translation -about.goodies.subscribe_bookmarklet_asc=Oldest first ####### Needs translation -about.goodies.subscribe_bookmarklet_desc=Newest first ####### Needs translation -about.goodies.next_unread_bookmarklet=Next unread item bookmarklet (drag to bookmark bar) ####### Needs translation -about.translation=번역 -about.translation.message=CommaFeed를 번역할려면 당신의 도움이 필요합니다. -about.translation.link=번역에 기여하기 -about.announcements=공지 -about.rest_api.line1=CommaFeed는 JAX-RS하고 AngularJS를 이용해서 만들었습니다. 그렇기 때문에 REST API를 사용할수있습니다. -about.rest_api.link_to_documentation=문서 링크. - -about.shortcuts.mouse_middleclick=마우시 미들클릭 -about.shortcuts.open_next_entry=다음 항목 열기 -about.shortcuts.open_previous_entry=이전 항목 열기 -about.shortcuts.spacebar=space/shift+space ####### Needs translation -about.shortcuts.move_page_down_up=moves the page down/up ####### Needs translation -about.shortcuts.focus_next_entry=set focus on next entry without opening it ####### Needs translation -about.shortcuts.focus_previous_entry=set focus on previous entry without opening it ####### Needs translation -about.shortcuts.open_next_feed=open next feed or category ####### Needs translation -about.shortcuts.open_previous_feed=open previous feed or category ####### Needs translation -about.shortcuts.open_close_current_entry=현재 항목 열기/닫기 -about.shortcuts.open_current_entry_in_new_window=새 창에서 현재 항목열기 -about.shortcuts.open_current_entry_in_new_window_background=open current entry in a new window in the background ####### Needs translation -about.shortcuts.star_unstar=현재 항목 스타/스타제거 -about.shortcuts.mark_current_entry=현재 항목 읽음/안읽음 표시 -about.shortcuts.mark_all_as_read=모든 항목 읽음으로 표시 -about.shortcuts.open_in_new_tab_mark_as_read=읽음으로 표시하고 새로운 탭에서 열기 -about.shortcuts.fullscreen=toggle full screen mode ####### Needs translation -about.shortcuts.font_size=increase/decrease font size of the current entry ####### Needs translation -about.shortcuts.go_to_all=go to the All view ####### Needs translation -about.shortcuts.go_to_starred=go to the Starred view ####### Needs translation -about.shortcuts.feed_search=navigate to a subscription by entering the subscription name ####### Needs translation - diff --git a/src/main/resources/i18n/languages.properties b/src/main/resources/i18n/languages.properties deleted file mode 100644 index 5d245129..00000000 --- a/src/main/resources/i18n/languages.properties +++ /dev/null @@ -1,28 +0,0 @@ -ar=العربية -ca=Català -en=English -es=Español -de=Deutsch -fa=فارسی -fr=Français -gl=Galician -glk=گیلکی -hu=Magyar -ja=日本語 -ko=한국어 -nl=Nederlands -nb=Norsk (bokmål) -nn=Norsk (nynorsk) -pt=Português -pl=Polski -ru=русский -fi=Suomi -sv=Svenska -zh=简体中文 -it=Italiano -tr=Türkçe -cy=Cymraeg -sk=Slovenčina -da=Danish -cs=Čeština -ms=Bahasa Malaysian \ No newline at end of file diff --git a/src/main/resources/i18n/ms.properties b/src/main/resources/i18n/ms.properties deleted file mode 100644 index f5687ff2..00000000 --- a/src/main/resources/i18n/ms.properties +++ /dev/null @@ -1,157 +0,0 @@ -global.save=Save -global.cancel=Batal -global.delete=Padam -global.required=Wajib -global.download=Muat turun -global.link=Pautan -global.bookmark=Bookmark -global.close=Tutup -global.tags=Tags ####### Needs translation - -tree.subscribe=Langgan -tree.import=Import -tree.new_category=Kategori Baru -tree.all=Semua -tree.starred=Dibintang - -subscribe.feed_url=URL Feed -subscribe.feed_name=Nama Feed -subscribe.category=Kategori - -import.google_reader_prefix=Import feed dari -import.google_reader_suffix= akaun. -import.google_download=Sebagai alternatif, muat naik fail subscriptions.xml anda. -import.google_download_link=Muat turun dari sini -import.xml_file=Fail OPML - -new_category.name=Nama -new_category.parent=Induk - -toolbar.unread=Belum Dibaca -toolbar.all=Semua -toolbar.previous_entry=Sebelumnya -toolbar.next_entry=Selepasnya -toolbar.refresh=Refresh -toolbar.refresh_all=Force refresh all my feeds ####### Needs translation -toolbar.sort_by_asc_desc=Aturkan mengikut tarikh (baru/lama) -toolbar.titles_only=Tajuk sahaja -toolbar.expanded_view=Wide view -toolbar.mark_all_as_read=Tanda kesemuanya telah dibaca -toolbar.mark_all_older_12_hours=Items older than 12 hours ####### Needs translation -toolbar.mark_all_older_day=Lebih lama daripada sehari -toolbar.mark_all_older_week=Lebih lama daripada seminggu -toolbar.mark_all_older_two_weeks=Lebih lama daripada dua minggu -toolbar.settings=Setting -toolbar.profile=Profil -toolbar.admin=Admin -toolbar.about=About -toolbar.logout=Logout -toolbar.donate=Derma - -view.entry_source=from ####### Needs translation -view.entry_author=oleh -view.error_while_loading_feed=Kesilapan semasa memuat turun feed ini -view.keep_unread=Simpan tidak dibaca -view.no_unread_items=tiada item yang belum dibaca. -view.mark_up_to_here=Mark as read up to here ####### Needs translation -view.search_for=searching for: ####### Needs translation -view.no_search_results=No match found for the requested keywords ####### Needs translation - -feedsearch.hint=Taipkan langganan... -feedsearch.help=Guna kekunci Return untuk membuat pilihan dan kekunci arah untuk menavigasi. -feedsearch.result_prefix=Langganan anda: - -settings.general=Setting am -settings.general.language=Bahasa -settings.general.language.contribute=Sumbang penterjemahan -settings.general.show_unread=Tunjuk semua feed dan kategori yang telah dibaca -settings.general.social_buttons=Tunjuk social sharing -settings.general.scroll_marks=Dalam wide view, tanda item dibaca ketika scrolling -settings.appearance=Rupa -settings.scroll_speed=Scrolling speed when navigating between entries (in milliseconds) ####### Needs translation -settings.scroll_speed.help=set to 0 to disable ####### Needs translation -settings.theme=Tema -settings.submit_your_theme=Muat naik tema anda -settings.custom_css=Custom CSS - -details.feed_details=Butir-butir Feed -details.url=URL -details.website=Website ####### Needs translation -details.name=Nama -details.category=Kategori -details.position=Posisi -details.last_refresh=Refresh terakhir -details.message=Last refresh message ####### Needs translation -details.next_refresh=Refresh seterusnya -details.queued_for_refresh=Diaturkan untuk refresh -details.feed_url=URL Feed -details.generate_api_key_first=Janakan API key dalam profil anda dahulu. -details.unsubscribe=Hentikan langganan -details.unsubscribe_confirmation=Are you sure you want to unsubscribe from this feed? ####### Needs translation -details.delete_category_confirmation=Are you sure you want to delete this category? ####### Needs translation -details.category_details=Butir-butir kategori -details.tag_details=Tag details ####### Needs translation -details.parent_category=Kategori induk - -profile.user_name=User name -profile.email=E-mel -profile.change_password=Tukar kata laluan -profile.confirm_password=Sahkan kata laluan -profile.minimum_6_chars=Minimum 6 huruf -profile.passwords_do_not_match=Kata laluan tidak sama -profile.api_key=API key -profile.api_key_not_generated=Belum dijana -profile.generate_new_api_key=Jana API key baru -profile.generate_new_api_key_info=Pertukaran kata laluan akan menjanakan API key yang baru -profile.opml_export=Export OPML -profile.delete_account=Padam akaun -profile.delete_account_confirmation=Delete your acount? There's no turning back! ####### Needs translation - -about.rest_api=REST API -about.keyboard_shortcuts=Pintasan papan kekunci -about.version=CommaFeed version ####### Needs translation -about.line1_prefix=CommaFeed adalah projek open-source. Sources are berada di -about.line1_suffix=. -about.line2_prefix=Jika anda menghadapi masalah, sila laporkan di halaman isu-isu di -about.line2_suffix=\ projek. -about.line3=Jika anda suka projek ini, anda boleh menbuat dermaan kepada pengaturcara untuk membantu menampung kos laman web ini. -about.line4=Jika anda guna bitcoin, halamannya adalah -about.goodies=Goodies -about.goodies.android_app=Android app -about.goodies.subscribe_url=URL melanggan -about.goodies.chrome_extension=Chrome extension -about.goodies.firefox_extension=Firefox extension -about.goodies.opera_extension=Opera extension -about.goodies.subscribe_bookmarklet=Jana bookmarklet langganan (klik) -about.goodies.subscribe_bookmarklet_asc=Oldest first ####### Needs translation -about.goodies.subscribe_bookmarklet_desc=Newest first ####### Needs translation -about.goodies.next_unread_bookmarklet=Item bookmarklet yang belum dibaca seterusnya (seret ke bookmark bar) -about.translation=Terjemahan -about.translation.message=Kami perlukan bantuan anda untuk menterjemahkan CommaFeed. -about.translation.link=Bagaimana mengyumbang penterjemahan. -about.announcements=Pengumuman -about.rest_api.line1=CommaFeed diaturcarakan dengan JAX-RS dan AngularJS. Oleh itu, REST API boleh didapati. -about.rest_api.link_to_documentation=Pautan ke dokumentasi. - -about.shortcuts.mouse_middleclick=Klik tengah -about.shortcuts.open_next_entry=buka item seterusya -about.shortcuts.open_previous_entry=buka item sebelumnya -about.shortcuts.spacebar=space/shift+space -about.shortcuts.move_page_down_up=Gerak halaman ke bawah/atas -about.shortcuts.focus_next_entry=fokus kepada item seterusnya tanpa membuka -about.shortcuts.focus_previous_entry=fokus kepada item sebelumnya tanpa membuka -about.shortcuts.open_next_feed=buka feed atau kategori seterusnya -about.shortcuts.open_previous_feed=buka feed atau kategori sebelumnya -about.shortcuts.open_close_current_entry=buka/tutup entry kini -about.shortcuts.open_current_entry_in_new_window=buka entry kini di window yang baru -about.shortcuts.open_current_entry_in_new_window_background=buka entry kini di window baru di latar belakang -about.shortcuts.star_unstar=bintang/nyah-bintang entry kini -about.shortcuts.mark_current_entry=tanda entry kini telah dibaca/belum dibaca -about.shortcuts.mark_all_as_read=tanda semua entry telah dibaca -about.shortcuts.open_in_new_tab_mark_as_read=buka entry di tab baru dan tanda telah dibaca -about.shortcuts.fullscreen=toggle mod skrin penuh -about.shortcuts.font_size=kecil/besar fon entry kini -about.shortcuts.go_to_all=go to the All view ####### Needs translation -about.shortcuts.go_to_starred=go to the Starred view ####### Needs translation -about.shortcuts.feed_search=pergi ke langganan dengan nama langganan - diff --git a/src/main/resources/i18n/nb.properties b/src/main/resources/i18n/nb.properties deleted file mode 100644 index b2ffa150..00000000 --- a/src/main/resources/i18n/nb.properties +++ /dev/null @@ -1,157 +0,0 @@ -global.save=Lagre -global.cancel=Avbryt -global.delete=Slett -global.required=Påkrevd -global.download=Last ned -global.link=Lenke -global.bookmark=Bokmerke -global.close=Lukk -global.tags=Tags ####### Needs translation - -tree.subscribe=Abonner -tree.import=Importer -tree.new_category=Ny kategori -tree.all=Alle -tree.starred=Merkede artikler - -subscribe.feed_url=URL for abonnement -subscribe.feed_name=Abonnementsnavn -subscribe.category=Kategori - -import.google_reader_prefix=La meg importere dine abonnementer fra din -import.google_reader_suffix= bruker. -import.google_download=Alternativt, last opp din egen subscriptions.xml-fil. -import.google_download_link=Last ned herfra. -import.xml_file=OPML-fil - -new_category.name=Navn -new_category.parent=Overordnet - -toolbar.unread=Uleste -toolbar.all=Alle -toolbar.previous_entry=Forrige artikkel -toolbar.next_entry=Neste artikkel -toolbar.refresh=Oppdater -toolbar.refresh_all=Force refresh all my feeds ####### Needs translation -toolbar.sort_by_asc_desc=Sorter etter dato ny/gammel -toolbar.titles_only=Kun titler -toolbar.expanded_view=Utvidet visning -toolbar.mark_all_as_read=Merk alle som lest -toolbar.mark_all_older_12_hours=Items older than 12 hours ####### Needs translation -toolbar.mark_all_older_day=Artikler eldre enn én dag -toolbar.mark_all_older_week=Artikler eldre enn én uke -toolbar.mark_all_older_two_weeks=Artikler eldre enn to uker -toolbar.settings=Innstillinger -toolbar.profile=Profil -toolbar.admin=Admin -toolbar.about=Om -toolbar.logout=Logg ut -toolbar.donate=Doner - -view.entry_source=from ####### Needs translation -view.entry_author=by ####### Needs translation -view.error_while_loading_feed=Feil under lasting av artikkel -view.keep_unread=Behold som ulest -view.no_unread_items=har ingen uleste artikler. -view.mark_up_to_here=Mark as read up to here ####### Needs translation -view.search_for=searching for: ####### Needs translation -view.no_search_results=No match found for the requested keywords ####### Needs translation - -feedsearch.hint=Skriv inn et abonnement... -feedsearch.help=Bruk entertasten for å velge og piltastene for å navigere. -feedsearch.result_prefix=Dine abonnementer: - -settings.general=Generelt -settings.general.language=Språk -settings.general.language.contribute=Bidra med oversettelser -settings.general.show_unread=Vis abonnementer og kategorier uten nye artikler -settings.general.social_buttons=Vis delingsknapper -settings.general.scroll_marks=I utvidet visning, merk artikler som leste når du blar deg forbi dem. -settings.appearance=Utseende -settings.scroll_speed=Scrolling speed when navigating between entries (in milliseconds) ####### Needs translation -settings.scroll_speed.help=set to 0 to disable ####### Needs translation -settings.theme=Drakt -settings.submit_your_theme=Legg til egen drakt -settings.custom_css=Egendefinert CSS - -details.feed_details=Abonnementsdetaljer -details.url=URL -details.website=Website ####### Needs translation -details.name=Navn -details.category=Kategori -details.position=Posisjon -details.last_refresh=Siste oppdatering -details.message=Last refresh message ####### Needs translation -details.next_refresh=Neste oppdatering -details.queued_for_refresh=I kø for oppdatering -details.feed_url=URL for abonnement -details.generate_api_key_first=Generer en API-nøkkel under profilinnstillinger først. -details.unsubscribe=Avslutt abonnement -details.unsubscribe_confirmation=Are you sure you want to unsubscribe from this feed? ####### Needs translation -details.delete_category_confirmation=Are you sure you want to delete this category? ####### Needs translation -details.category_details=Kategoridetaljer -details.tag_details=Tag details ####### Needs translation -details.parent_category=Overordnet kategori - -profile.user_name=Brukernavn -profile.email=E-post -profile.change_password=Endre passord -profile.confirm_password=Bekreft passord -profile.minimum_6_chars=Minimum 6 tegn -profile.passwords_do_not_match=Passordene er ikke like -profile.api_key=API-nøkkel -profile.api_key_not_generated=Har ikke blitt generert -profile.generate_new_api_key=Generer ny API-nøkkel -profile.generate_new_api_key_info=Endring av passord vil generere en ny API-nøkkel -profile.opml_export=OPML-eksport -profile.delete_account=Slett bruker -profile.delete_account_confirmation=Delete your acount? There's no turning back! ####### Needs translation - -about.rest_api=REST API -about.keyboard_shortcuts=Hurtigtaster -about.version=CommaFeed version ####### Needs translation -about.line1_prefix=CommaFeed er et prosjekt med åpen kildekode. Kildekoden er tilgjengelig på -about.line1_suffix=. -about.line2_prefix=Vis du oppdager en feil eller et problem, rapporter det på -about.line2_suffix=\ siden til prosjekt. -about.line3=Dersom du liker dette prosjektet, kan du vurdere en donasjon for støtte utvikleren, og bidra med å dekke kostnadene til å drifte nettsiden. -about.line4=For de som foretrekker bitcoin, her er adressa -about.goodies=Godsaker -about.goodies.android_app=Android app ####### Needs translation -about.goodies.subscribe_url=Abonner URL -about.goodies.chrome_extension=Chrome-utvidelse -about.goodies.firefox_extension=Firefox-utvidelse -about.goodies.opera_extension=Opera-utvidelse -about.goodies.subscribe_bookmarklet=Nytt abonnement-bokmerkeprogram (klikk) -about.goodies.subscribe_bookmarklet_asc=Oldest first ####### Needs translation -about.goodies.subscribe_bookmarklet_desc=Newest first ####### Needs translation -about.goodies.next_unread_bookmarklet=Neste uleste artikkel-bokmerkeprogram (dra til bokmerkemenyen) -about.translation=Oversettelse -about.translation.message=Vi trenger din hjelp til å oversette CommaFeed. -about.translation.link=Se hvordan du kan hjelpe til med oversettelser. -about.announcements=Kunngjøringer -about.rest_api.line1=CommaFeed er bygget på toppen av JAX-RS og AngularJS. På grunn av dette er REST API tilgjengelig. -about.rest_api.link_to_documentation=Lenke til dokumentasjon. - -about.shortcuts.mouse_middleclick=midtre museknapp/musehjulet -about.shortcuts.open_next_entry=åpne neste artikkel -about.shortcuts.open_previous_entry=åpne forrige artikkel -about.shortcuts.spacebar=space/shift+space ####### Needs translation -about.shortcuts.move_page_down_up=moves the page down/up ####### Needs translation -about.shortcuts.focus_next_entry=sett fokus på neste artikkel uten å åpne den -about.shortcuts.focus_previous_entry=sett fokus på forrige artikkel uten å åpne den -about.shortcuts.open_next_feed=åpne neste abonnement eller kategori -about.shortcuts.open_previous_feed=åpne forrige abonnement eller kategori -about.shortcuts.open_close_current_entry=åpne/lukke gjeldende artikkel -about.shortcuts.open_current_entry_in_new_window=åpne gjeldende artikkel i et nytt vindu -about.shortcuts.open_current_entry_in_new_window_background=åpne gjeldende artikkel i et nytt bakgrunnsvindu -about.shortcuts.star_unstar=legg til stjerne/fjern stjerne fra gjeldende artikkel -about.shortcuts.mark_current_entry=merk gjeldende artikkel som lest/ulest -about.shortcuts.mark_all_as_read=merk alle artikler som lest -about.shortcuts.open_in_new_tab_mark_as_read=åpne artikkel i ny fane og merk som lest -about.shortcuts.fullscreen=toggle full screen mode ####### Needs translation -about.shortcuts.font_size=increase/decrease font size of the current entry ####### Needs translation -about.shortcuts.go_to_all=go to the All view ####### Needs translation -about.shortcuts.go_to_starred=go to the Starred view ####### Needs translation -about.shortcuts.feed_search=naviger til et abonnement ved å skrive inn abonnementsnavnet - diff --git a/src/main/resources/i18n/nl.properties b/src/main/resources/i18n/nl.properties deleted file mode 100644 index cdff552a..00000000 --- a/src/main/resources/i18n/nl.properties +++ /dev/null @@ -1,157 +0,0 @@ -global.save=Opslaan -global.cancel=Annuleren -global.delete=Verwijderen -global.required=Verplicht -global.download=Download -global.link=Link -global.bookmark=Bookmark -global.close=Sluiten -global.tags=Tags ####### Needs translation - -tree.subscribe=Abonneer -tree.import=Importeer -tree.new_category=Nieuwe categorie -tree.all=Alles -tree.starred=Favorieten - -subscribe.feed_url=Feed URL -subscribe.feed_name=Feed naam -subscribe.category=Categorie - -import.google_reader_prefix=Laat je feeds importeren vanuit jouw -import.google_reader_suffix= account. -import.google_download=Als alternatief kun je je subscriptions.xml bestand uploaden. -import.google_download_link=Download het hier. -import.xml_file=OPML Bestand - -new_category.name=Naam -new_category.parent=Parent - -toolbar.unread=Ongelezen -toolbar.all=Alles -toolbar.previous_entry=Vorig artikel -toolbar.next_entry=Volgend artikel -toolbar.refresh=Vernieuwen -toolbar.refresh_all=Force refresh all my feeds ####### Needs translation -toolbar.sort_by_asc_desc=Sorteer op datum opl/afl -toolbar.titles_only=Alleen titels -toolbar.expanded_view=Uitgebreide weergave -toolbar.mark_all_as_read=Markeer alles als gelezen -toolbar.mark_all_older_12_hours=Items older than 12 hours ####### Needs translation -toolbar.mark_all_older_day=Artikelen ouder dan een dag -toolbar.mark_all_older_week=Artikelen ouder dan een week -toolbar.mark_all_older_two_weeks=Artikelen ouder dan twee weken -toolbar.settings=Instellingen -toolbar.profile=Profiel -toolbar.admin=Administratie -toolbar.about=Over ons -toolbar.logout=Log uit -toolbar.donate=Doneer - -view.entry_source=van -view.entry_author=door -view.error_while_loading_feed=Fout tijdens het laden van de feed -view.keep_unread=Behoud ongelezen -view.no_unread_items=Heeft geen ongelezen artikelen -view.mark_up_to_here=Markeer tot hier als gelezen -view.search_for=searching for: ####### Needs translation -view.no_search_results=No match found for the requested keywords ####### Needs translation - -feedsearch.hint=Type een abonnement in... ####### Type in a subscription... -feedsearch.help=Gebruik Enter om te selecteren en de pijltjestoetsen om te navigeren. -feedsearch.result_prefix=Jouw abonnementen: - -settings.general=Algemeen -settings.general.language=Taal -settings.general.language.contribute=Draag bij met vertalingen -settings.general.show_unread=Laat feeds en categorieën zonder ongelezen artikelen zien -settings.general.social_buttons=Laat Social Media knoppen zien -settings.general.scroll_marks=Markeer artikelen als gelezen, wanneer je er doorheen scrollt -settings.appearance=Uiterlijk -settings.scroll_speed=Scrolling speed when navigating between entries (in milliseconds) ####### Needs translation -settings.scroll_speed.help=set to 0 to disable ####### Needs translation -settings.theme=Thema -settings.submit_your_theme=Stuur thema in -settings.custom_css=Custom CSS - -details.feed_details=Feed details -details.url=URL -details.website=Website -details.name=Naam -details.category=Categorie -details.position=Positie -details.last_refresh=Laatste vernieuwing -details.message=Last refresh message ####### Needs translation -details.next_refresh=Volgende vernieuwing -details.queued_for_refresh=In wachtrij voor vernieuwing -details.feed_url=Feed URL -details.generate_api_key_first=Genereer eerst een API sleutel in je profiel. -details.unsubscribe=Abonnement opzeggen -details.unsubscribe_confirmation=Are you sure you want to unsubscribe from this feed? ####### Needs translation -details.delete_category_confirmation=Are you sure you want to delete this category? ####### Needs translation -details.category_details=Categorie details -details.tag_details=Tag details ####### Needs translation -details.parent_category=Bovenliggende categorie - -profile.user_name=Gebruikersnaam -profile.email=E-mail -profile.change_password=Verander wachtwoord -profile.confirm_password=Bevestig wachtwoord -profile.minimum_6_chars=Minimaal 6 tekens -profile.passwords_do_not_match=Wachtwoorden komen niet overeen -profile.api_key=API sleutel -profile.api_key_not_generated=Nog niet gegenereerd -profile.generate_new_api_key=Genereer nieuwe API sleutel -profile.generate_new_api_key_info=Het veranderen van het wachtwoord genereert een nieuwe API sleutel -profile.opml_export=OPML export -profile.delete_account=Verwijder account -profile.delete_account_confirmation=Delete your acount? There's no turning back! ####### Needs translation - -about.rest_api=REST API -about.keyboard_shortcuts=Sneltoetsen -about.version=CommaFeed version ####### Needs translation -about.line1_prefix=CommaFeed is een open-source project. Bronnen worden gehost op -about.line1_suffix=. -about.line2_prefix=Als je een probleem tegenkomt, rapporteer dit dan a.u.b. op de Issues pagina van het -about.line2_suffix=\ project. -about.line3=Als je dit project leuk vindt, overweeg dan te doneren om de ontwikkelaars te ondersteunen en hosting kosten te drukken. -about.line4=Voor degenen die liever bitcoin gebruiken, hier is het adres -about.goodies=Goodies -about.goodies.android_app=Android app -about.goodies.subscribe_url=Abonneer URL -about.goodies.chrome_extension=Chrome extensie -about.goodies.firefox_extension=Firefox extensie -about.goodies.opera_extension=Opera extensie -about.goodies.subscribe_bookmarklet=Voeg abonnement toe bookmarklet (klik) -about.goodies.subscribe_bookmarklet_asc=Oudste eerst -about.goodies.subscribe_bookmarklet_desc=Nieuwste eerst -about.goodies.next_unread_bookmarklet=Volgend ongelezen item bookmarklet (sleep naar bladwijzerbalk) -about.translation=Vertalingen -about.translation.message=We hebben jouw hulp nodig om CommaFeed te vertalen. -about.translation.link=Bekijk hier hoe je kunt bijdragen met vertalingen. -about.announcements=Aankondigingen -about.rest_api.line1=CommaFeed is gebouwd op basis van JAX-RS en AngularJS. Als zodanig is er een REST API beschikbaar. -about.rest_api.link_to_documentation=Link naar de documentatie - -about.shortcuts.mouse_middleclick=middelste muisknop -about.shortcuts.open_next_entry=open het volgende artikel -about.shortcuts.open_previous_entry=open het vorige artikel -about.shortcuts.spacebar=spatie/shift+spatie -about.shortcuts.move_page_down_up=beweegt de pagina naar onder/boven -about.shortcuts.focus_next_entry=plaats focus op volgend artikel zonder het te openen -about.shortcuts.focus_previous_entry=plaats focus op vorig artikel zonder het te openen -about.shortcuts.open_next_feed=open volgende feed of categorie -about.shortcuts.open_previous_feed=open vorige feed of categorie -about.shortcuts.open_close_current_entry=open/sluit het huidige artikel -about.shortcuts.open_current_entry_in_new_window=open het huidige artikel in een nieuw venster -about.shortcuts.open_current_entry_in_new_window_background=open huidig artikel in een nieuw venster op de achtergrond -about.shortcuts.star_unstar=voeg artikel toe aan/verwijder uit favorieten -about.shortcuts.mark_current_entry=markeer huidig artikel als gelezen/ongelezen -about.shortcuts.mark_all_as_read=markeer alle artikelen als gelezen -about.shortcuts.open_in_new_tab_mark_as_read=open artikel in een nieuw tabblad en markeer als gelezen -about.shortcuts.fullscreen=schakel tussen fullscreen weergave -about.shortcuts.font_size=vergroot/verklein tekst in huidig artikel -about.shortcuts.go_to_all=ga naar de ALLES-weergave -about.shortcuts.go_to_starred=ga naar de Favorieten-weergave -about.shortcuts.feed_search=navigeer naar een abonnement door diens naam in te typen - diff --git a/src/main/resources/i18n/nn.properties b/src/main/resources/i18n/nn.properties deleted file mode 100644 index 88f76472..00000000 --- a/src/main/resources/i18n/nn.properties +++ /dev/null @@ -1,157 +0,0 @@ -global.save=Lagre -global.cancel=Avbryt -global.delete=Slett -global.required=Påkravd -global.download=Last ned -global.link=Lenkje -global.bookmark=Bokmerke -global.close=Lukk -global.tags=Tags ####### Needs translation - -tree.subscribe=Abonner -tree.import=Importer -tree.new_category=Ny kategori -tree.all=Alle -tree.starred=Merka artiklar - -subscribe.feed_url=URL for abonnement -subscribe.feed_name=Abonnementsnamn -subscribe.category=Kategori - -import.google_reader_prefix=La meg importere abonnementa dine frå -import.google_reader_suffix=-brukaren din. -import.google_download=Alternativt, last opp di eiga subscriptions.xml-fil. -import.google_download_link=Last ned herifrå. -import.xml_file=OPML-fil - -new_category.name=Namn -new_category.parent=Overordna - -toolbar.unread=Ulesne -toolbar.all=Alle -toolbar.previous_entry=Førre artikkel -toolbar.next_entry=Neste artikkel -toolbar.refresh=Oppdater -toolbar.refresh_all=Force refresh all my feeds ####### Needs translation -toolbar.sort_by_asc_desc=Sorter etter dato ny/gamal -toolbar.titles_only=Berre titlar -toolbar.expanded_view=Utvida visning -toolbar.mark_all_as_read=Merk alle som lesne -toolbar.mark_all_older_12_hours=Items older than 12 hours ####### Needs translation -toolbar.mark_all_older_day=Artiklar eldre enn éin dag -toolbar.mark_all_older_week=Artiklar eldre enn éi veke -toolbar.mark_all_older_two_weeks=Artiklar eldre enn to veker -toolbar.settings=Innstillingar -toolbar.profile=Profil -toolbar.admin=Admin -toolbar.about=Om -toolbar.logout=Logg ut -toolbar.donate=Doner - -view.entry_source=from ####### Needs translation -view.entry_author=av -view.error_while_loading_feed=Feil under lasting av artikkel -view.keep_unread=Behold som ulesen -view.no_unread_items=har ingen ulesne artiklar. -view.mark_up_to_here=Mark as read up to here ####### Needs translation -view.search_for=searching for: ####### Needs translation -view.no_search_results=No match found for the requested keywords ####### Needs translation - -feedsearch.hint=Skriv inn eit abonnement... -feedsearch.help=Bruk entertasten for å velje og piltastane for å navigere. -feedsearch.result_prefix=Dine abonnement: - -settings.general=Generelt -settings.general.language=Språk -settings.general.language.contribute=Bidra med omsetjingar -settings.general.show_unread=Vis abonnement og kategoriar utan nye artiklar -settings.general.social_buttons=Vis delingsknappar -settings.general.scroll_marks=I utvida visning, merk artiklar som lesne når du blar deg forbi dei. -settings.appearance=Utsjånad -settings.scroll_speed=Scrolling speed when navigating between entries (in milliseconds) ####### Needs translation -settings.scroll_speed.help=set to 0 to disable ####### Needs translation -settings.theme=Drakt -settings.submit_your_theme=Legg til eiga drakt -settings.custom_css=Skreddarsydd CSS - -details.feed_details=Abonnementsdetaljar -details.url=URL -details.website=Website ####### Needs translation -details.name=Namn -details.category=Kategori -details.position=Posisjon -details.last_refresh=Siste oppdatering -details.message=Last refresh message ####### Needs translation -details.next_refresh=Neste oppdatering -details.queued_for_refresh=I kø for oppdatering -details.feed_url=URL for abonnement -details.generate_api_key_first=Generer ein API-nykel under profilinnstillingar fyrst. -details.unsubscribe=Avslutt abonnement -details.unsubscribe_confirmation=Are you sure you want to unsubscribe from this feed? ####### Needs translation -details.delete_category_confirmation=Are you sure you want to delete this category? ####### Needs translation -details.category_details=Kategoridetaljar -details.tag_details=Tag details ####### Needs translation -details.parent_category=Overordna kategori - -profile.user_name=Brukarnamn -profile.email=E-post -profile.change_password=Endre passord -profile.confirm_password=Stadfest passord -profile.minimum_6_chars=Minimum 6 teikn -profile.passwords_do_not_match=Passorda er usamde -profile.api_key=API-nykel -profile.api_key_not_generated=Har ikkje vorte generert -profile.generate_new_api_key=Generer ny API-nykel -profile.generate_new_api_key_info=Endring av passord vil generere ein ny API-nykel -profile.opml_export=OPML-eksport -profile.delete_account=Slett brukar -profile.delete_account_confirmation=Delete your acount? There's no turning back! ####### Needs translation - -about.rest_api=REST API -about.keyboard_shortcuts=Hurtigtastar -about.version=CommaFeed version ####### Needs translation -about.line1_prefix=CommaFeed er eit prosjekt med open kjeldekode. Kjeldekoden er tilgjengeleg på -about.line1_suffix=. -about.line2_prefix=Viss du finn ein feil eller eit problem, rapporter det på -about.line2_suffix=\ prosjektsida. -about.line3=Viss du likar dette prosjektet, kan du vurdere ein donasjon for å støtte utviklaren, og bidra med å dekkje kostnadane til å drifte nettstaden. -about.line4=For dei som føretrekkjer bitcoin, her er adressa -about.goodies=Godsakar -about.goodies.android_app=Android app ####### Needs translation -about.goodies.subscribe_url=Abonner URL -about.goodies.chrome_extension=Chrome-utviding -about.goodies.firefox_extension=Firefox-utviding -about.goodies.opera_extension=Opera-utviding -about.goodies.subscribe_bookmarklet=Nytt abonnement-bokmerkjeprogram (klikk) -about.goodies.subscribe_bookmarklet_asc=Oldest first ####### Needs translation -about.goodies.subscribe_bookmarklet_desc=Newest first ####### Needs translation -about.goodies.next_unread_bookmarklet=Neste ulesne artikkel-bokmerkeprogram (dra til bokmerkemenyen) -about.translation=Omsetjing -about.translation.message=Vi behøver di hjelp til å omsetje CommaFeed. -about.translation.link=Sjå korleis du kan hjelpe til med omsetjingar. -about.announcements=Kunngjøringer -about.rest_api.line1=CommaFeed er bygd på toppen av JAX-RS og AngularJS. Difor er REST API tilgjengeleg. -about.rest_api.link_to_documentation=Lenkje til dokumentasjon. - -about.shortcuts.mouse_middleclick=midtre museknapp/musehjulet -about.shortcuts.open_next_entry=opne neste artikkel -about.shortcuts.open_previous_entry=opne førre artikkel -about.shortcuts.spacebar=space/shift+space ####### Needs translation -about.shortcuts.move_page_down_up=moves the page down/up ####### Needs translation -about.shortcuts.focus_next_entry=sett fokus på neste artikkel utan å opne han -about.shortcuts.focus_previous_entry=sett fokus på forrige artikkel utan å opne han -about.shortcuts.open_next_feed=opne neste abonnement eller kategori -about.shortcuts.open_previous_feed=opne førre abonnement eller kategori -about.shortcuts.open_close_current_entry=opne/lukke gjeldande artikkel -about.shortcuts.open_current_entry_in_new_window=opne gjeldande artikkel i eit nytt vindauge -about.shortcuts.open_current_entry_in_new_window_background=opne gjeldande artikkel i eit nytt bakgrunnsvindauge -about.shortcuts.star_unstar=legg til stjerne/fjern stjerne frå gjeldande artikkel -about.shortcuts.mark_current_entry=merk gjeldande artikkel som lesen/ulesen -about.shortcuts.mark_all_as_read=merk alle artiklar som lesne -about.shortcuts.open_in_new_tab_mark_as_read=opne artikkel i ny fane og merk som lesen -about.shortcuts.fullscreen=toggle full screen mode ####### Needs translation -about.shortcuts.font_size=increase/decrease font size of the current entry ####### Needs translation -about.shortcuts.go_to_all=go to the All view ####### Needs translation -about.shortcuts.go_to_starred=go to the Starred view ####### Needs translation -about.shortcuts.feed_search=naviger til eit abonnement ved å skrive inn abonnementsnamnet - diff --git a/src/main/resources/i18n/pl.properties b/src/main/resources/i18n/pl.properties deleted file mode 100644 index 1e497776..00000000 --- a/src/main/resources/i18n/pl.properties +++ /dev/null @@ -1,157 +0,0 @@ -global.save=Zachowaj -global.cancel=Anuluj -global.delete=Usuń -global.required=Wymagane -global.download=Pobierz -global.link=Odnośnik -global.bookmark=Zakładka -global.close=Zamknij -global.tags=Tags ####### Needs translation - -tree.subscribe=Subskrybuj -tree.import=Importuj -tree.new_category=Nowa kategoria -tree.all=Wszystkie elementy -tree.starred=Elementy oznaczone gwiazdką - -subscribe.feed_url=URL kanału -subscribe.feed_name=Nazwa kanału -subscribe.category=Kategoria - -import.google_reader_prefix=Pozwól mi zaimportować kanały z twojego -import.google_reader_suffix= konta -import.google_download=albo, wrzuć pilk subskrypcje.xml -import.google_download_link=Ściągnij go stąd. -import.xml_file=Plik OPML - -new_category.name=Nazwa -new_category.parent=Kategoria nadrzędna - -toolbar.unread=Nieprzeczytane -toolbar.all=Wszystkie -toolbar.previous_entry=Poprzedni element -toolbar.next_entry=Następny element -toolbar.refresh=Odswież -toolbar.refresh_all=Force refresh all my feeds ####### Needs translation -toolbar.sort_by_asc_desc=Sortuj od najnowszego/najstarszego -toolbar.titles_only=Widok listy -toolbar.expanded_view=Widok rozwinięty -toolbar.mark_all_as_read=Oznacz wszystko jako przeczytane -toolbar.mark_all_older_12_hours=Items older than 12 hours ####### Needs translation -toolbar.mark_all_older_day=Elementy starsze niż dzień -toolbar.mark_all_older_week=Elementy starsze niż tydzień -toolbar.mark_all_older_two_weeks=Elementy starsze niż dwa tygodnie -toolbar.settings=Ustawienia -toolbar.profile=Profil -toolbar.admin=Admin -toolbar.about=O CommaFeed -toolbar.logout=Wyloguj -toolbar.donate=Wspomóż - -view.entry_source=from ####### Needs translation -view.entry_author=przez -view.error_while_loading_feed=Wystąpił błąd podczas ładowania tego kanału. -view.keep_unread=Pozostaw nieprzeczytane -view.no_unread_items= nie ma nieprzeczytanych elementów. -view.mark_up_to_here=Mark as read up to here ####### Needs translation -view.search_for=searching for: ####### Needs translation -view.no_search_results=No match found for the requested keywords ####### Needs translation - -feedsearch.hint=Wpisz subskrybcję... -feedsearch.help=Użyj klawisza Enter do zaznaczenia a strzałek do nawigacji. -feedsearch.result_prefix=Twoje subskrybcje: - -settings.general=Ogólne -settings.general.language=Język -settings.general.language.contribute=Pomóż w tłumaczeniu -settings.general.show_unread=Pokaż kanały i kategorie bez nieprzeczytanych elementów -settings.general.social_buttons=Pokaż przyciski udostępniania -settings.general.scroll_marks=W widoku rozwiniętym przewijanie oznacza elementy jako przeczytane -settings.appearance=Wygląd -settings.scroll_speed=Scrolling speed when navigating between entries (in milliseconds) ####### Needs translation -settings.scroll_speed.help=set to 0 to disable ####### Needs translation -settings.theme=Motyw -settings.submit_your_theme=Wyślij swój motyw -settings.custom_css=Własny styl CSS - -details.feed_details=Szczegóły kanału -details.url=URL -details.website=Website ####### Needs translation -details.name=Nazwa -details.category=Kategoria -details.position=Pozycja -details.last_refresh=Ostatnio odświeżony -details.message=Last refresh message ####### Needs translation -details.next_refresh=Następne odświeżenie -details.queued_for_refresh=W kolejce do odświeżenia -details.feed_url=URL kanału -details.generate_api_key_first=Najpierw wygeneruj klucz API w swoim profilu. -details.unsubscribe=Cofnij subskrypcje -details.unsubscribe_confirmation=Are you sure you want to unsubscribe from this feed? ####### Needs translation -details.delete_category_confirmation=Are you sure you want to delete this category? ####### Needs translation -details.category_details=Szczegóły kategorii -details.tag_details=Tag details ####### Needs translation -details.parent_category=Kategoria nadrzędna - -profile.user_name=Nazwa użytkownika -profile.email=E-mail -profile.change_password=Zmień hasło -profile.confirm_password=Potwierdź hasło -profile.minimum_6_chars=Minimum 6 znaków -profile.passwords_do_not_match=Hasła nie pasują do siebie -profile.api_key=Klucz API -profile.api_key_not_generated=Jeszcze niewygenerowany -profile.generate_new_api_key=Wygeneruj nowy klucz API -profile.generate_new_api_key_info=Zmiana hasła spowoduje wygenerowanie nowego klucza API -profile.opml_export=Eksportuj do pliku OPML -profile.delete_account=Usuń konto -profile.delete_account_confirmation=Delete your acount? There's no turning back! ####### Needs translation - -about.rest_api=REST API -about.keyboard_shortcuts=Skróty klawiszowe -about.version=CommaFeed version ####### Needs translation -about.line1_prefix=CommaFeed jest projektem Open-Source. Źródła są dostępne na -about.line1_suffix=. -about.line2_prefix=Jeśli napotkasz jakiś problem, proszę zgłoś go na stronie -about.line2_suffix=\ projektu. -about.line3=Jeśli podoba ci się ten projekt, rozważ wsparcie autora i pomóż w utrzymaniu tej strony. -about.line4=Jeśli wolisz bitcoin, użyj tego adresu -about.goodies=Dodatki -about.goodies.android_app=Aplikacja na Androida -about.goodies.subscribe_url=Subskrybuj URL -about.goodies.chrome_extension=Dodatek do Chrome -about.goodies.firefox_extension=Dodatek do Firefoxa -about.goodies.opera_extension=Dodatek do Opery -about.goodies.subscribe_bookmarklet=Dodaj subskrybcje jako skryptozakładkę (kliknij) -about.goodies.subscribe_bookmarklet_asc=Oldest first ####### Needs translation -about.goodies.subscribe_bookmarklet_desc=Newest first ####### Needs translation -about.goodies.next_unread_bookmarklet=Następny nieprzeczytany element jako skryptozakładka (przeciągnij na pasek zakładek) -about.translation=Tłumaczenia -about.translation.message=Potrzebujemy pomocy w tłumaczeniu CommaFeed. -about.translation.link=Zobacz jak możesz pomóc. -about.announcements=Ogłoszenia -about.rest_api.line1=CommaFeed jest oparty o JAX-RS i AngularJS. Dzięki temu REST API jest dostępne. -about.rest_api.link_to_documentation=Link do dokumentacji. - -about.shortcuts.mouse_middleclick=środkowy przycisk myszy -about.shortcuts.open_next_entry=otwórz następny element -about.shortcuts.open_previous_entry=otwórz poprzedni element -about.shortcuts.spacebar=spacja/shift+spacja -about.shortcuts.move_page_down_up=przesuwa stronę w górę/dół -about.shortcuts.focus_next_entry=wyróżnij następny element bez otwierania go -about.shortcuts.focus_previous_entry=wyróżnij poprzedni element bez otwierania go -about.shortcuts.open_next_feed=otwórz następny kanał lub kategorię -about.shortcuts.open_previous_feed=otwórz poprzedni kanał lub kategorię -about.shortcuts.open_close_current_entry=otwórz/zamknij bieżący element -about.shortcuts.open_current_entry_in_new_window=otwórz bieżący element w nowym oknie -about.shortcuts.open_current_entry_in_new_window_background=otwórz bieżący element w nowym oknie w tle -about.shortcuts.star_unstar=oznacz/odznacz gwiazdką bieżący element -about.shortcuts.mark_current_entry=oznacz jako przeczytany/nieprzeczytany obecny element -about.shortcuts.mark_all_as_read=oznacz wszystko jako przeczytane -about.shortcuts.open_in_new_tab_mark_as_read=otwórz w nowej zakładce i oznacz jako przeczytane -about.shortcuts.fullscreen=przełącz tryb pełnoekranowy -about.shortcuts.font_size=zmień wielkość czcionki -about.shortcuts.go_to_all=go to the All view ####### Needs translation -about.shortcuts.go_to_starred=go to the Starred view ####### Needs translation -about.shortcuts.feed_search=przejdź do subskrybcji wpisując jej nazwę - diff --git a/src/main/resources/i18n/pt.properties b/src/main/resources/i18n/pt.properties deleted file mode 100644 index bce3898a..00000000 --- a/src/main/resources/i18n/pt.properties +++ /dev/null @@ -1,157 +0,0 @@ -global.save=Salvar -global.cancel=Cancelar -global.delete=Excluir -global.required=Obrigatório -global.download=Download -global.link=Link -global.bookmark=Favorito -global.close=Fechar -global.tags=Tags ####### Needs translation - -tree.subscribe=Inscrever-se -tree.import=Importar -tree.new_category=Nova categoria -tree.all=Todos -tree.starred=Com estrela - -subscribe.feed_url=URL de feed -subscribe.feed_name=Nome do feed -subscribe.category=Categoria - -import.google_reader_prefix=Deixe-me importar seus feeds de sua conta -import.google_reader_suffix=. -import.google_download=Alternativamente, faça upload de seu arquivo subscriptions.xml. -import.google_download_link=Fazer download daqui. -import.xml_file=Arquivo OPML - -new_category.name=Nome -new_category.parent=Pai - -toolbar.unread=Não lidos -toolbar.all=Todos -toolbar.previous_entry=Item anterior -toolbar.next_entry=Próximo item -toolbar.refresh=Atualizar -toolbar.refresh_all=Forçar atualização de todos os meus feeds -toolbar.sort_by_asc_desc=Ordenar por data cresc/decres -toolbar.titles_only=Somente títulos -toolbar.expanded_view=Modo Expandido -toolbar.mark_all_as_read=Marcar tudo como lido -toolbar.mark_all_older_12_hours=Items older than 12 hours ####### Needs translation -toolbar.mark_all_older_day=Itens mais antigos que um dia -toolbar.mark_all_older_week=Itens mais antigos que uma semana -toolbar.mark_all_older_two_weeks=Itens mais antigos que duas semanas -toolbar.settings=Configurações -toolbar.profile=Perfil -toolbar.admin=Admin -toolbar.about=Sobre -toolbar.logout=Sair -toolbar.donate=Doar - -view.entry_source=de -view.entry_author=por -view.error_while_loading_feed=Erro lendo esse feed -view.keep_unread=Manter como não lido -view.no_unread_items=não tem itens não lidos. -view.mark_up_to_here=Marcar como lido até aqui -view.search_for=searching for: ####### Needs translation -view.no_search_results=No match found for the requested keywords ####### Needs translation - -feedsearch.hint=Digite o nome de uma Inscrição... -feedsearch.help=Use a tecla ENTER e setas direcionais para navegar. -feedsearch.result_prefix=Suas inscrições: - -settings.general=Geral -settings.general.language=Idioma -settings.general.language.contribute=Contribua com traduções -settings.general.show_unread=Mostrar feeds e categorias sem itens não lidos -settings.general.social_buttons=Mostrar botões de mídias sociais -settings.general.scroll_marks=No modo expandido, percorrer os itens marca-os como lidos -settings.appearance=Aparência -settings.scroll_speed=Scrolling speed when navigating between entries (in milliseconds) ####### Needs translation -settings.scroll_speed.help=set to 0 to disable ####### Needs translation -settings.theme=Tema -settings.submit_your_theme=Envie seu tema -settings.custom_css=CSS personalizado - -details.feed_details=Detalhes do feed -details.url=URL -details.website=Website -details.name=Nome -details.category=Categoria -details.position=Posição -details.last_refresh=Última atualização -details.message=Last refresh message ####### Needs translation -details.next_refresh=Próxima atualização -details.queued_for_refresh=Na fila para atualizar -details.feed_url=URL do feed -details.generate_api_key_first=Gerar uma chave de API em seu perfil primeiro. -details.unsubscribe=Cancelar inscrição -details.unsubscribe_confirmation=Are you sure you want to unsubscribe from this feed? ####### Needs translation -details.delete_category_confirmation=Are you sure you want to delete this category? ####### Needs translation -details.category_details=Detalhes da categoria -details.tag_details=Tag details ####### Needs translation -details.parent_category=Categoria pai - -profile.user_name=Nome de usuário -profile.email=E-mail -profile.change_password=Trocar senha -profile.confirm_password=Confirmar senha -profile.minimum_6_chars=Mínimo de 6 caracteres -profile.passwords_do_not_match=Senhas não conferem -profile.api_key=Chave de API -profile.api_key_not_generated=Ainda não gerada -profile.generate_new_api_key=Gerar nova chave de API -profile.generate_new_api_key_info=Mudar a senha irá gerar uma nova chave de API -profile.opml_export=Exportar OPML -profile.delete_account=Excluir conta -profile.delete_account_confirmation=Delete your acount? There's no turning back! ####### Needs translation - -about.rest_api=API REST -about.keyboard_shortcuts=Atalhos de teclado -about.version=CommaFeed versão -about.line1_prefix=CommaFeed é um projeto de código livre. Fontes estão hospedados em -about.line1_suffix=. -about.line2_prefix=Se você encontrar um problema, por favor relate-o na página de problemas do projeto -about.line2_suffix=. -about.line3=Se você gostar desse projeto, por favor considere uma doação para apoiar o desenvolvedor e ajudar a cobrir os custos de manter esse website no ar. -about.line4=Para quem preferir bitcoin, esse é o endereço -about.goodies=Extras -about.goodies.android_app=Aplicativo Android -about.goodies.subscribe_url=URL de inscrição -about.goodies.chrome_extension=Extensão para o Chrome -about.goodies.firefox_extension=Extensão para o Firefox -about.goodies.opera_extension=Extensão para o Opera -about.goodies.subscribe_bookmarklet=Bookmarklet para adicionar inscrição (clique) -about.goodies.subscribe_bookmarklet_asc=Mais velhas primeiro -about.goodies.subscribe_bookmarklet_desc=Mais novas primeiro -about.goodies.next_unread_bookmarklet=Bookmarklet para o próximo item não lido (arraste para a barra de favoritos) -about.translation=Tradução -about.translation.message=Precisamos de sua ajuda para traduzir CommaFeed. -about.translation.link=Veja como contribuir com traduções. -about.announcements=Anúncios -about.rest_api.line1=CommaFeed foi desenvolvido sobre JAX-RS e AngularJS. Como tal, uma API REST está disponível. -about.rest_api.link_to_documentation=Link para a documentação. - -about.shortcuts.mouse_middleclick=clique com o botão do meio do mouse -about.shortcuts.open_next_entry=abre próximo item -about.shortcuts.open_previous_entry=abre item anterior -about.shortcuts.spacebar=barra de espaço/shift+barra de espaço -about.shortcuts.move_page_down_up=move a página para baixo/cima -about.shortcuts.focus_next_entry=seleciona próximo item sem abri-lo -about.shortcuts.focus_previous_entry=seleciona item anterior sem abri-lo -about.shortcuts.open_next_feed=abre próximo feed ou categoria -about.shortcuts.open_previous_feed=abre feed ou categoria anterior -about.shortcuts.open_close_current_entry=abre/fecha item atual -about.shortcuts.open_current_entry_in_new_window=abre item atual em uma nova janela -about.shortcuts.open_current_entry_in_new_window_background=abre item atual em uma nova janela em plano de fundo -about.shortcuts.star_unstar=marca/desmarca estrela do item atual -about.shortcuts.mark_current_entry=marca item atual como lido/não lido -about.shortcuts.mark_all_as_read=marca todos os itens como lidos -about.shortcuts.open_in_new_tab_mark_as_read=abre item em uma nova aba e marca como lido -about.shortcuts.fullscreen=modo tela cheia -about.shortcuts.font_size=aumenta/diminui o tamanho da fonte na entrada atual -about.shortcuts.go_to_all=vá para Todos os itens -about.shortcuts.go_to_starred=vá para itens com estrela -about.shortcuts.feed_search=navega entre inscrições buscando pelo nome - diff --git a/src/main/resources/i18n/ru.properties b/src/main/resources/i18n/ru.properties deleted file mode 100644 index 28e8bde4..00000000 --- a/src/main/resources/i18n/ru.properties +++ /dev/null @@ -1,157 +0,0 @@ -global.save=Сохранить -global.cancel=Отмена -global.delete=Удалить -global.required=Обязательно -global.download=Скачать -global.link=Ссылка -global.bookmark=Закладка -global.close=Закрыть -global.tags=Теги - -tree.subscribe=Подписаться -tree.import=Импорт -tree.new_category=Новая категория -tree.all=Все -tree.starred=Избранное - -subscribe.feed_url=Адрес ленты -subscribe.feed_name=Название ленты -subscribe.category=Категория - -import.google_reader_prefix=Можно импотрировать подписки из -import.google_reader_suffix= аккаунта. -import.google_download=Или загрузить собсвенный XML-файл подпискок. -import.google_download_link=Скачайте его здесь. -import.xml_file=OPML-файл - -new_category.name=Название -new_category.parent=Родительская категория - -toolbar.unread=Непрочитанные -toolbar.all=Все -toolbar.previous_entry=Предыдущая запись -toolbar.next_entry=Следующая запись -toolbar.refresh=Обновить -toolbar.refresh_all=Обновить все подписки вручную -toolbar.sort_by_asc_desc=Сначала новые/старые -toolbar.titles_only=Только заголовки -toolbar.expanded_view=Развёрнутый вид -toolbar.mark_all_as_read=Отметить всё как прочитанное -toolbar.mark_all_older_12_hours=Записи старше 12-и часов -toolbar.mark_all_older_day=Записи старше суток -toolbar.mark_all_older_week=Записи старше недели -toolbar.mark_all_older_two_weeks=Записи старше двух недель -toolbar.settings=Настройки -toolbar.profile=Профиль -toolbar.admin=Администратор -toolbar.about=Справка -toolbar.logout=Выйти -toolbar.donate=Поддержать проект - -view.entry_source=от -view.entry_author=автор -view.error_while_loading_feed=Не удалось загрузить ленту -view.keep_unread=Оставить непрочитанным -view.no_unread_items=нет непрочитанных записей. -view.mark_up_to_here=Отметить прочитанным до сюда -view.search_for=искать: -view.no_search_results=По данному запросу ничего не найдено. - -feedsearch.hint=Введите подписку... -feedsearch.help=Используйте клавишу ввода для выбора и стрелки для перемещения. -feedsearch.result_prefix=Ваши подписки: - -settings.general=Основное -settings.general.language=Язык -settings.general.language.contribute=Принять участие в переводе -settings.general.show_unread=Показывать прочтённые ленты и категории -settings.general.social_buttons=Показывать социальные кнопки -settings.general.scroll_marks=В развёрнутом виде помечать записи как прочитанные по мере прокрутки -settings.appearance=Вид -settings.scroll_speed=Скорость прокрутки при навигации между записями (в миллисекундах) -settings.scroll_speed.help=смените на 0 чтобы выключить -settings.theme=Тема -settings.submit_your_theme=Добавьте свою тему -settings.custom_css=Собственная CSS - -details.feed_details=Информация о ленте -details.url=URL -details.website=Сайт -details.name=Название -details.category=Категория -details.position=Позиция -details.last_refresh=Последнее обновление -details.message=Сообщение последнего обновления -details.next_refresh=Следующее обновление -details.queued_for_refresh=В очереди на обновление -details.feed_url=Адрес ленты -details.generate_api_key_first=Сначала сгенерируйте API-ключ в вашем профиле. -details.unsubscribe=Отписаться -details.unsubscribe_confirmation=Подтвердить отписку от этой ленты? Are you sure you want to unsubscribe from this feed? ####### Needs translation -details.delete_category_confirmation=Подтвердить удаление этой категории? -details.category_details=Информация о категории -details.tag_details=Детали тега -details.parent_category=Родительская категория - -profile.user_name=Имя пользователя -profile.email=Эл. почта -profile.change_password=Изменить пароль -profile.confirm_password=Подтвердите пароль -profile.minimum_6_chars=Не меньше 6 символов -profile.passwords_do_not_match=Пароли не совпадают -profile.api_key=API-ключ -profile.api_key_not_generated=Не сгенерирован -profile.generate_new_api_key=Сгенерировать новый API-ключ -profile.generate_new_api_key_info=После изменения пароля, API-ключ изменится -profile.opml_export=Экспорт OPML -profile.delete_account=Удалить аккаунт -profile.delete_account_confirmation=Удалить ваш аккаунт? Назад пути не будет! - -about.rest_api=REST API -about.keyboard_shortcuts=Горячие клавиши -about.version=Версия CommaFeed -about.line1_prefix=CommaFeed — проект с открытым исходным кодом. Исходники находятся на -about.line1_suffix=. -about.line2_prefix=Если вы обнаружите ошибку, пожалуйста, сообщите о ней на -about.line2_suffix=. -about.line3=Если вам понравился этот проект, пожалуйста, поддержите разработчика суммой, которую вам не жалко, чтобы сайт продолжал работать. -about.line4=Адрес для тех, кто предпочитает bitcoin -about.goodies=Дополнения -about.goodies.android_app=Приложение для Андроид -about.goodies.subscribe_url=Адрес для подписки (заменить FEED_URL_HERE на адрес ленты) -about.goodies.chrome_extension=Расширение для Chrome -about.goodies.firefox_extension=Расширение для Firefox -about.goodies.opera_extension=Расширение для Opera -about.goodies.subscribe_bookmarklet=Закладка для быстрой подписки на ленты (нужно кликнуть) -about.goodies.subscribe_bookmarklet_asc=Сначала старые -about.goodies.subscribe_bookmarklet_desc=Сначала новые -about.goodies.next_unread_bookmarklet=Открыть следующую непрочитанную запись в новой вкладке (перетащить на панель закладок) -about.translation=Перевод -about.translation.message=Нам нужна ваша помощь в переводе CommaFeed на другие языки. -about.translation.link=Посмотрите как поучаствовать в переводе. -about.announcements=Объявления -about.rest_api.line1=CommaFeed основан на JAX-RS и AngularJS. Вам доступно REST API. -about.rest_api.link_to_documentation=Ссылка на документацию. - -about.shortcuts.mouse_middleclick=средняя кнопка мыши -about.shortcuts.open_next_entry=открыть следующую запись -about.shortcuts.open_previous_entry=открыть предыдущую запись -about.shortcuts.spacebar=пробел/shift+пробел -about.shortcuts.move_page_down_up=передвигает страницу вверх/вниз -about.shortcuts.focus_next_entry=выбрать следующую запись не открывая её -about.shortcuts.focus_previous_entry=выбрать предыдущую запись не открывая её -about.shortcuts.open_next_feed=открыть следующую ленту или категорию -about.shortcuts.open_previous_feed=открыть предыдущую ленту или категорию -about.shortcuts.open_close_current_entry=открыть/закрыть текущюю запись -about.shortcuts.open_current_entry_in_new_window=открыть текущюю запись в новом окне -about.shortcuts.open_current_entry_in_new_window_background= открыть текущую запись в новом окне на фоне -about.shortcuts.star_unstar=добавить/убрать из избранного текущюю запись -about.shortcuts.mark_current_entry=пометить текущюю запись как прочитанную -about.shortcuts.mark_all_as_read=пометить всё как прочитанное -about.shortcuts.open_in_new_tab_mark_as_read=открыть запись в новом окне и пометить как прочитанную -about.shortcuts.fullscreen=переключиться в полноэкранный режим -about.shortcuts.font_size=увеличить/уменьшить размер шрифта текущей записи -about.shortcuts.go_to_all=перейти ко всем -about.shortcuts.go_to_starred=перейти к избранным -about.shortcuts.feed_search=перейти к подписке по названию - diff --git a/src/main/resources/i18n/sk.properties b/src/main/resources/i18n/sk.properties deleted file mode 100644 index c79e00ae..00000000 --- a/src/main/resources/i18n/sk.properties +++ /dev/null @@ -1,157 +0,0 @@ -global.save=Uložiť -global.cancel=Zrušiť -global.delete=Odstrániť -global.required=Povinné -global.download=Stiahnuť -global.link=Link -global.bookmark=Záložky -global.close=Zavrieť -global.tags=Tagy - -tree.subscribe=Odoberať -tree.import=Importovať -tree.new_category=Nová kategória -tree.all=Všetko -tree.starred=Obľúbené - -subscribe.feed_url=URL RSS zdroja -subscribe.feed_name=Názov RSS zdroja -subscribe.category=Kategória - -import.google_reader_prefix=Importujte si RSS zdroje s vášho -import.google_reader_suffix= účtu. -import.google_download=Alternatívne, môžte nahrať váš subscriptions.xml súbor -import.google_download_link=Stiahnuť to môžete s lokácie. -import.xml_file=OPML súbor - -new_category.name=Názov -new_category.parent=Hlavná - -toolbar.unread=Neprečítané -toolbar.all=Všetky -toolbar.previous_entry=Predchádzajúca položka -toolbar.next_entry=Nasledujúca položka -toolbar.refresh=Obnoviť -toolbar.refresh_all=Vynútené obnovenie všetkých položiek -toolbar.sort_by_asc_desc=Zoradiť podľa najnovšieho/najstaršieho -toolbar.titles_only=Náhľad titulkov -toolbar.expanded_view=Rozšírený náhľad -toolbar.mark_all_as_read=Označiť všetky ako prečítané -toolbar.mark_all_older_12_hours=Položky staršie ako 12 hodín -toolbar.mark_all_older_day=Položky staršie ako deň -toolbar.mark_all_older_week=Položky staršie ako týždeň -toolbar.mark_all_older_two_weeks=Položky staršie ako dva týždne -toolbar.settings=Nastavenia -toolbar.profile=Profil -toolbar.admin=Admin -toolbar.about=O CommaFeed -toolbar.logout=Odhlásiť -toolbar.donate=Donate - -view.entry_source=z -view.entry_author=od -view.error_while_loading_feed=Počas načítavania sa vyskytla chyba -view.keep_unread=Ponechať ako neprečítané -view.no_unread_items=nemá žiadne neprečítané položky. -view.mark_up_to_here=Až potiaľto označiť položky ako prečítané -view.search_for=Hľadaný výraz: -view.no_search_results=Nenašla sa žiadna zhoda pre hľadaný výraz. - -feedsearch.hint=Zadajte názov odoberania... -feedsearch.help=Použite klávesu enter pre výber a smerové klávesy pre navigáciu. -feedsearch.result_prefix=Vaše odoberania: - -settings.general=Všeobecné -settings.general.language=Jazyk -settings.general.language.contribute=Zapojte sa do prekladu -settings.general.show_unread=Zobraziť príspevky a kategórie bez neprečítaných položiek -settings.general.social_buttons=Zobraziť možnosti zdieľania -settings.general.scroll_marks=Scrollovanie v rozšírenom náhľade označí položky ako prečítané -settings.appearance=Vzhľad -settings.scroll_speed=Rýchlosť skrolovania—pohybu medzi položkami (v milisekundách) -settings.scroll_speed.help=nastavte 0 pre deaktiváciu -settings.theme=Motív -settings.submit_your_theme=Nahrať vlastný motív vzhľadu -settings.custom_css=Vlastný motív vzhľadu (CSS) - -details.feed_details=Detaily odoberania -details.url=URL odkaz -details.website=Web stránka -details.name=Názov -details.category=Kategória -details.position=Pozícia -details.last_refresh=Predchádzajúce obnovenie -details.message=Predchádzajúca správa obnovenia -details.next_refresh=Nasledujúce obnovenie -details.queued_for_refresh=Vo fronte -details.feed_url=URL RSS zdroja -details.generate_api_key_first=Vygenerujte si API kľúč vo vašom profile. -details.unsubscribe=Zrušiť odoberanie. -details.unsubscribe_confirmation=Are you sure you want to unsubscribe from this feed? ####### Needs translation -details.delete_category_confirmation=Are you sure you want to delete this category? ####### Needs translation -details.category_details=Detaily kategórie -details.tag_details=Detaily tagu -details.parent_category=Hlavná kategória - -profile.user_name=Uživateľské meno -profile.email=E-mail -profile.change_password=Zmeniť heslo -profile.confirm_password=Potvrdiť heslo -profile.minimum_6_chars=Minimum je 6 znakov -profile.passwords_do_not_match=Heslá sa nezhodujú -profile.api_key=API kľúč -profile.api_key_not_generated=Nie je vygenerovaný -profile.generate_new_api_key=Vygenerovať nový API kľúč -profile.generate_new_api_key_info=Zmenou hesla vygenerujete nový API kľúč -profile.opml_export=exportovať do formátu OPML -profile.delete_account=Odstrániť účet -profile.delete_account_confirmation=Delete your acount? There's no turning back! ####### Needs translation - -about.rest_api=REST API -about.keyboard_shortcuts=Klávesové skratky -about.version=CommaFeed verzia -about.line1_prefix=CommaFeed je open source projekt. Zdrojový kód je dostupný na -about.line1_suffix=. -about.line2_prefix=V prípade, že narazíte na problém, ohláste ho prosím na stránkach -about.line2_suffix=\ projektu. -about.line3=V prípade, že sa vám páči CommaFeed, zvážte prosím finančný príspevok. Podporíte tým vývojárov a tiež pomôžete udržať web stránky online. -about.line4=Pre tých, ktorí preferujú bitcoin -about.goodies=Rozšírenia -about.goodies.android_app=Aplikácia pre zariadenia Android -about.goodies.subscribe_url=URL -about.goodies.chrome_extension=Rozšírenie pre prehliadač Chrome -about.goodies.firefox_extension=Rozšírenie pre prehliadač Firefox -about.goodies.opera_extension=Rozšírenie pre prehliadač Opera -about.goodies.subscribe_bookmarklet=Bookmarklet -about.goodies.subscribe_bookmarklet_asc=Zoradiť podľa najstaršieho -about.goodies.subscribe_bookmarklet_desc=Zoradiť podľa najnovšieho -about.goodies.next_unread_bookmarklet=Záložka nasledujúcej neprečítanej položky(pretiahuť k záložkám) -about.translation=Preklad -about.translation.message=Pomôžte s prekladom CommaFeed. -about.translation.link=Zistite, ako sa možete zapojiť do prekladu CommaFeed. -about.announcements=Oznámenia -about.rest_api.line1=CommaFeed je postavený na JAX-RS a AngularJS. Dostupná je REST API. -about.rest_api.link_to_documentation=Prejsť na dokumentáciu. - -about.shortcuts.mouse_middleclick=klik prostredným tlačítkom -about.shortcuts.open_next_entry=zobraziť nasledujúcu položku -about.shortcuts.open_previous_entry=zobraziť predchádzajúcu položku -about.shortcuts.spacebar=medzerník/shift+medzerník -about.shortcuts.move_page_down_up=pohyb smerom dole/hore -about.shortcuts.focus_next_entry=presun na nasledujúcu položku bez jej zobrazenia -about.shortcuts.focus_previous_entry=presun na predchádzajúcu položku bez jej zobrazenia -about.shortcuts.open_next_feed=presun na nasledujúci RSS zdroj alebo kategóriu -about.shortcuts.open_previous_feed=presun na predchádzajúci RSS zdroj alebo kategóriu -about.shortcuts.open_close_current_entry=zobraziť vybranú položku -about.shortcuts.open_current_entry_in_new_window=zobraziť vybranú položku v novom okne -about.shortcuts.open_current_entry_in_new_window_background=otvoriť vybranú položku na pozadí -about.shortcuts.star_unstar=označiť vybranú položku ako obľúbená -about.shortcuts.mark_current_entry=označiť vybranú položku ako prečítanú/neprečítanú -about.shortcuts.mark_all_as_read=označiť všetky položky ako prečítané! -about.shortcuts.open_in_new_tab_mark_as_read=zobraziť položku na novej karte a označí ju ako prečítanú -about.shortcuts.fullscreen=prepnutie zobrazenia na celú obrazovku -about.shortcuts.font_size=zmeniť veľkosť písma pre vybranú položku -about.shortcuts.go_to_all=zobraziť všetky položky -about.shortcuts.go_to_starred=zobraziť obľúbené položiek -about.shortcuts.feed_search=presun na odoberaný RSS zdroj vložením jeho názvu - diff --git a/src/main/resources/i18n/sv.properties b/src/main/resources/i18n/sv.properties deleted file mode 100644 index 9e486894..00000000 --- a/src/main/resources/i18n/sv.properties +++ /dev/null @@ -1,157 +0,0 @@ -global.save=Spara -global.cancel=Avbryt -global.delete=Radera -global.required=Obligatorisk -global.download=Ladda ned -global.link=Länka -global.bookmark=Bokmärk -global.close=Stäng -global.tags=Taggar - -tree.subscribe=Prenumerera -tree.import=Importera -tree.new_category=Ny kategori -tree.all=Alla -tree.starred=Stjärnmärkt - -subscribe.feed_url=Prenumerationens URL -subscribe.feed_name=Prenumerationens namn -subscribe.category=Kategori - -import.google_reader_prefix=Låt mig importera dina prenumerationer från ditt -import.google_reader_suffix=-konto. -import.google_download=Alternativt, ladda upp din subscriptions.xml-fil. -import.google_download_link=Ladda ned den här. -import.xml_file=OPML-fil - -new_category.name=Namn -new_category.parent=Överordnad - -toolbar.unread=Oläst -toolbar.all=Alla -toolbar.previous_entry=Föregående post -toolbar.next_entry=Nästa post -toolbar.refresh=Uppdatera -toolbar.refresh_all=Tvinga uppdatering av alla prenumerationer -toolbar.sort_by_asc_desc=Sortera efter datum stigande/fallande -toolbar.titles_only=Endast titlar -toolbar.expanded_view=Expanderad vy -toolbar.mark_all_as_read=Markera alla som lästa -toolbar.mark_all_older_12_hours=Poster äldre än 12 timmar -toolbar.mark_all_older_day=Poster äldre än en dag -toolbar.mark_all_older_week=Poster äldre än en vecka -toolbar.mark_all_older_two_weeks=Poster äldre än två veckor -toolbar.settings=Inställningar -toolbar.profile=Profil -toolbar.admin=Administratör -toolbar.about=Om -toolbar.logout=Logga ut -toolbar.donate=Donera - -view.entry_source=från -view.entry_author=av -view.error_while_loading_feed=Fel under laddning av denna prenumeration -view.keep_unread=Håll oläst -view.no_unread_items=har inga olästa poster. -view.mark_up_to_here=Markera som läst upp till denna post -view.search_for=söker efter: -view.no_search_results=Inga resultat för valda nyckelord - -feedsearch.hint=Skriv in en prenumeration... -feedsearch.help=Använd retur-tangenten för att välja och piltangenterna för att navigera. -feedsearch.result_prefix=Dina prenumerationer: - -settings.general=Allmänt -settings.general.language=Språk -settings.general.language.contribute=Bidra med översättningar -settings.general.show_unread=Visa prenumerationer och kategorier utan olästa poster -settings.general.social_buttons=Visa delningsknappar -settings.general.scroll_marks=I expanderad vy, markera poster som lästa genom att scrolla förbi dem -settings.appearance=Utseende -settings.scroll_speed=Scrollhastighet under navigation mellan poster (i millisekunder) -settings.scroll_speed.help=ställ på 0 för att avaktivera -settings.theme=Tema -settings.submit_your_theme=Skicka in ditt tema -settings.custom_css=Anpassad CSS - -details.feed_details=Prenumerationsdetaljer -details.url=URL -details.website=Webbsida -details.name=Namn -details.category=Kategori -details.position=Position -details.last_refresh=Senaste uppdatering -details.message=Senaste uppdateringsmeddelande -details.next_refresh=Nästa uppdatering -details.queued_for_refresh=I kö för uppdatering -details.feed_url=Prenumerationens URL -details.generate_api_key_first=Skapa en API-nyckel på din profil först. -details.unsubscribe=Avprenumerera -details.unsubscribe_confirmation=Är du säker på att du vill avprenumerera? -details.delete_category_confirmation=Är du säker på att du vill ta bort denna kategori? -details.category_details=Kategoridetaljer -details.tag_details=Taggdetaljer -details.parent_category=Överordnad kategori - -profile.user_name=Användarnamn -profile.email=E-mail -profile.change_password=Ändra lösenord -profile.confirm_password=Bekräfta lösenord -profile.minimum_6_chars=Minst 6 bokstäver -profile.passwords_do_not_match=Lösenorden matchar inte -profile.api_key=API-nyckel -profile.api_key_not_generated=Inte skapad än -profile.generate_new_api_key=Skapa ny API-nyckel -profile.generate_new_api_key_info=Lösenordsbyte skapar ny API-nyckel -profile.opml_export=OPML-export -profile.delete_account=Radera konto -profile.delete_account_confirmation=Vill du ta bort ditt konto? Det försvinner för alltid! - -about.rest_api=REST-API -about.keyboard_shortcuts=Tangentbordsgenvägar -about.version=CommaFeed-version -about.line1_prefix=CommaFeed är ett open-source-projekt. Källan är tillgänglig på -about.line1_suffix=. -about.line2_prefix=Om du träffar på ett problem, meddela det på "Issues"-sidan för -about.line2_suffix=-projektet. -about.line3=Om du gillar detta projekt, avväg gärna en donation för att stötta utvecklaren och bidra till kostnaderna för att hålla denna site online. -about.line4=För er som föredrar Bitcoin, här är adressen -about.goodies=Godsaker -about.goodies.android_app=Android-app -about.goodies.subscribe_url=Prenumerations-URL -about.goodies.chrome_extension=Chrome-tillägg -about.goodies.firefox_extension=Firefox-tillägg -about.goodies.opera_extension=Opera-tillägg -about.goodies.subscribe_bookmarklet=Bokmärke för tillägg av prenumeration (klicka) -about.goodies.subscribe_bookmarklet_asc=äldst först -about.goodies.subscribe_bookmarklet_desc=nyast först -about.goodies.next_unread_bookmarklet=Bokmärke för nästa olästa post (dra till bokmärkesfält) -about.translation=Översättning -about.translation.message=Vi behöver din hjälp med att översätta CommaFeed. -about.translation.link=Se hur du kan bidra med översättningar. -about.announcements=Notiser -about.rest_api.line1=CommaFeed är byggt på JAX-RS och AngularJS. Tack vare detta är en REST-API tillgänglig. -about.rest_api.link_to_documentation=Länk till dokumentation. - -about.shortcuts.mouse_middleclick=mitten-musknapp -about.shortcuts.open_next_entry=öppna nästa post -about.shortcuts.open_previous_entry=öppna föregående post -about.shortcuts.spacebar=mellanslag/shift+mellanslag -about.shortcuts.move_page_down_up=flyttar sidan ned/upp -about.shortcuts.focus_next_entry=sätt fokus på nästa post utan att öppna -about.shortcuts.focus_previous_entry=sätt fokus på föregående post utan att öppna -about.shortcuts.open_next_feed=öppna nästa prenumeration eller kategori -about.shortcuts.open_previous_feed=öppna föregående prenumeration eller kategori -about.shortcuts.open_close_current_entry=öppna/stäng nuvarande post -about.shortcuts.open_current_entry_in_new_window=öppna nuvarande post i nytt fönster -about.shortcuts.open_current_entry_in_new_window_background=öppna nuvarande post i nytt bakgrundsfönster -about.shortcuts.star_unstar=stjärnmärk/ostjärnmärk nuvarande post -about.shortcuts.mark_current_entry=markera nuvarande post läst/oläst -about.shortcuts.mark_all_as_read=markera alla som lästa -about.shortcuts.open_in_new_tab_mark_as_read=öppna nuvarande post i ny flik och markera som läst -about.shortcuts.fullscreen=växla till/från fullskärmsläge -about.shortcuts.font_size=öka/minska teckenstorlek av nuvarande post -about.shortcuts.go_to_all=se alla poster -about.shortcuts.go_to_starred=se stjärnmärkta poster -about.shortcuts.feed_search=navigera till en prenumeration via prenumerationsnamn - diff --git a/src/main/resources/i18n/tr.properties b/src/main/resources/i18n/tr.properties deleted file mode 100644 index a463f459..00000000 --- a/src/main/resources/i18n/tr.properties +++ /dev/null @@ -1,157 +0,0 @@ -global.save=Kaydet -global.cancel=İptal -global.delete=Sil -global.required=Gerekli -global.download=İndir -global.link=Bağlantı -global.bookmark=Yer imi -global.close=Kapat -global.tags=Tags ####### Needs translation - -tree.subscribe=Abone ol -tree.import=İçe aktar -tree.new_category=Yeni kategori -tree.all=Tüm öğeler -tree.starred=Yıldızlı öğeler - -subscribe.feed_url=Yayın URL'si -subscribe.feed_name=Yayın Adı -subscribe.category=Kategori - -import.google_reader_prefix=Aboneliklerinizi -import.google_reader_suffix= hesabınızdan aktarmama izin verin. -import.google_download=Veya, subscriptions.xml dosyanızı yükleyin. -import.google_download_link=Buradan indirebilirsiniz. -import.xml_file=OPML dosyası - -new_category.name=İsim -new_category.parent=Üst - -toolbar.unread=Okunmamış -toolbar.all=Tümü -toolbar.previous_entry=Önceki ileti -toolbar.next_entry=Sonraki ileti -toolbar.refresh=Yenile -toolbar.refresh_all=Force refresh all my feeds ####### Needs translation -toolbar.sort_by_asc_desc=Tarihe göre sırala artan/azalan -toolbar.titles_only=Sadece başlıklar -toolbar.expanded_view=Genişletilmiş görünüm -toolbar.mark_all_as_read=Tümünü okundu işaretle -toolbar.mark_all_older_12_hours=Items older than 12 hours ####### Needs translation -toolbar.mark_all_older_day=Bir günden eski yazılar -toolbar.mark_all_older_week=Bir haftadan eski yazılar -toolbar.mark_all_older_two_weeks=İki haftadan eski yazılar -toolbar.settings=Ayarlar -toolbar.profile=Profil -toolbar.admin=Yönetim -toolbar.about=Hakkında -toolbar.logout=Çıkış -toolbar.donate=Bağış - -view.entry_source=from ####### Needs translation -view.entry_author=by ####### Needs translation -view.error_while_loading_feed=Bu aboneliği çekerken hata oluştu. -view.keep_unread=Okunmadı olarak sakla -view.no_unread_items=okunmamış ileti yok. -view.mark_up_to_here=Mark as read up to here ####### Needs translation -view.search_for=searching for: ####### Needs translation -view.no_search_results=No match found for the requested keywords ####### Needs translation - -feedsearch.hint=Bir abonelik yazın... -feedsearch.help=Return tuşunu seçmek için, yön tüşlarını ise gezinmek için kullanın. -feedsearch.result_prefix=Abonelikleriniz: - -settings.general=Genel -settings.general.language=Dil -settings.general.language.contribute=Çeviri katkısında bulunun -settings.general.show_unread=Okunmamış öğesi bulunan yayın ve kategorileri listele -settings.general.social_buttons=Sosyal paylaşım butonlarını göster -settings.general.scroll_marks=Genişletilmiş görünümde götüntülenen iletileri okunmuş işaretle -settings.appearance=Görünüm -settings.scroll_speed=Scrolling speed when navigating between entries (in milliseconds) ####### Needs translation -settings.scroll_speed.help=set to 0 to disable ####### Needs translation -settings.theme=Tema -settings.submit_your_theme=Tema gönder -settings.custom_css=Kişiselleştirilmiş CSS - -details.feed_details=Yayın detayları -details.url=URL -details.website=Website ####### Needs translation -details.name=İsim -details.category=Kategori -details.position=Pozisyon -details.last_refresh=Son yenileme -details.message=Last refresh message ####### Needs translation -details.next_refresh=Sonraki yenileme -details.queued_for_refresh=Yenilenmek üzere kuyrukta -details.feed_url=Yayın URL'si -details.generate_api_key_first=Öncelikle profilinizden bir API anahtarı oluşturun. -details.unsubscribe=Aboneliği iptal et -details.unsubscribe_confirmation=Are you sure you want to unsubscribe from this feed? ####### Needs translation -details.delete_category_confirmation=Are you sure you want to delete this category? ####### Needs translation -details.category_details=Kategori detayları -details.tag_details=Tag details ####### Needs translation -details.parent_category=Üst kategori - -profile.user_name=Kullanıcı adı -profile.email=E-posta -profile.change_password=Şifre değiştir -profile.confirm_password=Şifreyi doğrula -profile.minimum_6_chars=En az 6 karakter -profile.passwords_do_not_match=Şifreler uyuşmuyor -profile.api_key=API anahtarı -profile.api_key_not_generated=Henüz oluşturulmadı -profile.generate_new_api_key=Yeni bir API anahtarı oluştur -profile.generate_new_api_key_info=Şifre değiştirmek API anahtarının da değiştirilmesine neden olcak. -profile.opml_export=OPML dışa aktar -profile.delete_account=Hesabı sil -profile.delete_account_confirmation=Delete your acount? There's no turning back! ####### Needs translation - -about.rest_api=REST API -about.keyboard_shortcuts=Klavye kısayolları -about.version=CommaFeed version ####### Needs translation -about.line1_prefix=CommaFeed bir açık kaynak projedir. Kaynak dosyaları -about.line1_suffix= adresinde yayınlanır. -about.line2_prefix=Lütfen, bir hata ile karşılaşırsanız bunu -about.line2_suffix= projesinde hatalar sayfasından rapor edin. -about.line3=Eğer bu projeyi beğendiyseniz, lütfen bağış yaparak geliştiriciye bu sayfayı ayakta tutmasında yardımcı olun. -about.line4=Bitcoin'i tercih edenler için adres -about.goodies=Extralar -about.goodies.android_app=Android app ####### Needs translation -about.goodies.subscribe_url=Abonelik URL'si -about.goodies.chrome_extension=Chrome eklentisi -about.goodies.firefox_extension=Firefox eklentisi -about.goodies.opera_extension=Opera eklentisi -about.goodies.subscribe_bookmarklet=Bookmarklet'a abonelik ekle (tıklayın) -about.goodies.subscribe_bookmarklet_asc=Oldest first ####### Needs translation -about.goodies.subscribe_bookmarklet_desc=Newest first ####### Needs translation -about.goodies.next_unread_bookmarklet=Bookmarklet'daki en son okunmamış ileti (Sık kullanılan çubuğuna sürükleyin) -about.translation=Çeviri -about.translation.message=CommaFeed'i çevirmek için yardımınıza ihtiyacımız var. -about.translation.link=Nasıl çeviri katkısında bulunabileceğinizi öğrenmek için tıklayın. -about.announcements=Duyurular -about.rest_api.line1=CommaFeed, JAX-RS ve AngularJS üzerine kurulmuştur. Bu sayede, REST API desteği bulunur. -about.rest_api.link_to_documentation=Dökümantasyon için tıklayın. - -about.shortcuts.mouse_middleclick=Fare orta tuşu -about.shortcuts.open_next_entry=sonraki öğeyi görüntüle -about.shortcuts.open_previous_entry=önceki öğeyi görüntüle -about.shortcuts.spacebar=space/shift+space ####### Needs translation -about.shortcuts.move_page_down_up=moves the page down/up ####### Needs translation -about.shortcuts.focus_next_entry=sonraki öğeyi görüntülemeden işaretle -about.shortcuts.focus_previous_entry=önceki öğeyi görüntülemeden işaretle -about.shortcuts.open_next_feed=sonraki aboneliği veya kategoriyi görüntüle -about.shortcuts.open_previous_feed=önceki aboneliği veya kategoriyi görüntüle -about.shortcuts.open_close_current_entry=işeretli öğeyi aç/kapat -about.shortcuts.open_current_entry_in_new_window=görüntülenen öğeyi yeni pencerede görüntüle -about.shortcuts.open_current_entry_in_new_window_background=görüntülenen öğeyi arkaplanda yeni pencerede görüntüle -about.shortcuts.star_unstar=görüntülenen öğeye yıldız ekle/kaldır -about.shortcuts.mark_current_entry=görüntülenen öğeyi okundu/okunmadı işaretle -about.shortcuts.mark_all_as_read=tümünü okundu işaretle -about.shortcuts.open_in_new_tab_mark_as_read=öğeyi yeni bir sekmede aç ve okundu işaretle -about.shortcuts.fullscreen=toggle full screen mode ####### Needs translation -about.shortcuts.font_size=increase/decrease font size of the current entry ####### Needs translation -about.shortcuts.go_to_all=go to the All view ####### Needs translation -about.shortcuts.go_to_starred=go to the Starred view ####### Needs translation -about.shortcuts.feed_search=abonelik ismini yazarak aboneliğe git - diff --git a/src/main/resources/i18n/zh.properties b/src/main/resources/i18n/zh.properties deleted file mode 100644 index 29c2ff72..00000000 --- a/src/main/resources/i18n/zh.properties +++ /dev/null @@ -1,157 +0,0 @@ -global.save=保存 -global.cancel=取消 -global.delete=删除 -global.required=必填 -global.download=下载 -global.link=链接 -global.bookmark=书签 -global.close=关闭 -global.tags=Tags ####### Needs translation - -tree.subscribe=订阅 -tree.import=导入 -tree.new_category=新的目录 -tree.all=所有 -tree.starred=加星标的订阅 - -subscribe.feed_url=订阅地址 -subscribe.feed_name=订阅名称 -subscribe.category=目录 - -import.google_reader_prefix=从现有的 Google Reader 导入 -import.google_reader_suffix= 账号。 -import.google_download=可选的, 上传订阅列表文件(.xml)。 -import.google_download_link=从此处下载。 -import.xml_file=OPML 文件 - -new_category.name=名称 -new_category.parent=上一层 - -toolbar.unread=未读 -toolbar.all=所有 -toolbar.previous_entry=上一条目 -toolbar.next_entry=下一条目 -toolbar.refresh=刷新 -toolbar.refresh_all=刷新所有订阅 -toolbar.sort_by_asc_desc=按日期升序/降序排序 -toolbar.titles_only=仅显示标题 -toolbar.expanded_view=显示内容 -toolbar.mark_all_as_read=标记所有为已读 -toolbar.mark_all_older_12_hours=Items older than 12 hours ####### Needs translation -toolbar.mark_all_older_day=早于一天的条目 -toolbar.mark_all_older_week=早于一周的条目 -toolbar.mark_all_older_two_weeks=早于两周的条目 -toolbar.settings=设置 -toolbar.profile=配置文件 -toolbar.admin=管理 -toolbar.about=关于 -toolbar.logout=退出 -toolbar.donate=捐赠 - -view.entry_source=来自 -view.entry_author=作者 -view.error_while_loading_feed=加载该订阅出现错误 -view.keep_unread=保持未读 -view.no_unread_items=没有未读的条目。 -view.mark_up_to_here=标记为已读至本条目 -view.search_for=searching for: ####### Needs translation -view.no_search_results=No match found for the requested keywords ####### Needs translation - -feedsearch.hint=输入订阅 -feedsearch.help=使用方向键浏览,回车键选择 -feedsearch.result_prefix=你的订阅: - -settings.general=常规 -settings.general.language=语言 -settings.general.language.contribute=贡献翻译 -settings.general.show_unread=显示未读的订阅和目录条目 -settings.general.social_buttons=显示分享按钮 -settings.general.scroll_marks=在扩展视图中,可滚动条目将其标记为已读 -settings.appearance=外观 -settings.scroll_speed=Scrolling speed when navigating between entries (in milliseconds) ####### Needs translation -settings.scroll_speed.help=set to 0 to disable ####### Needs translation -settings.theme=主题 -settings.submit_your_theme=提交你的主题 -settings.custom_css=自定义 CSS 样式 - -details.feed_details=订阅详情 -details.url=地址 -details.website=站点 -details.name=名称 -details.category=目录 -details.position=位置 -details.last_refresh=上一次刷新 -details.message=Last refresh message ####### Needs translation -details.next_refresh=下一次刷新 -details.queued_for_refresh=放入等待刷新的队列 -details.feed_url=订阅地址 -details.generate_api_key_first=在您的配置文件中首先生成一个 API 密钥。 -details.unsubscribe=取消订阅 -details.unsubscribe_confirmation=Are you sure you want to unsubscribe from this feed? ####### Needs translation -details.delete_category_confirmation=Are you sure you want to delete this category? ####### Needs translation -details.category_details=目录详情 -details.tag_details=Tag details ####### Needs translation -details.parent_category=上一层目录 - -profile.user_name=用户名 -profile.email=邮箱 -profile.change_password=修改密码 -profile.confirm_password=确认密码 -profile.minimum_6_chars=最少为 6 个字母 -profile.passwords_do_not_match=密码不匹配 -profile.api_key=API 密钥 -profile.api_key_not_generated=API 密钥尚未生成 -profile.generate_new_api_key=生成一个新的 API 密钥 -profile.generate_new_api_key_info=修改密码将会生成一个新的的 API 密钥 -profile.opml_export=导出 OPML -profile.delete_account=删除帐号 -profile.delete_account_confirmation=Delete your acount? There's no turning back! ####### Needs translation - -about.rest_api=重置 API -about.keyboard_shortcuts=快捷键 -about.version=CommaFeed 版本 -about.line1_prefix=CommaFeed 是一个开源项目,项目源码保存在 -about.line1_suffix=。 -about.line2_prefix=如果遇到问题,请到问题报告页面提交 -about.line2_suffix=\ 项目。 -about.line3=如果你喜欢本项目,请考虑捐赠来支援开发人员工作以及服务器开支。 -about.line4=如果你想要使用 Bitcoin ,这里是我们的 Bitcoin 地址 -about.goodies=扩展 -about.goodies.android_app=Android 应用 -about.goodies.subscribe_url=订阅地址 -about.goodies.chrome_extension=Chrome 扩展 -about.goodies.firefox_extension=Firefox 扩展 -about.goodies.opera_extension=Opera 扩展 -about.goodies.subscribe_bookmarklet=添加一个订阅书签 (点击这) -about.goodies.subscribe_bookmarklet_asc=旧条目优先 -about.goodies.subscribe_bookmarklet_desc=新条目优先 -about.goodies.next_unread_bookmarklet=最新未读文章书签 (拖动到书签栏上) -about.translation=翻译 -about.translation.message=我们需要您来帮助翻译 CommaFeed。 -about.translation.link=查看如何贡献翻译。 -about.announcements=声明 -about.rest_api.line1=CommaFeed 基于 JAX-RS 和 AngularJS。所以,可选择重置 API。 -about.rest_api.link_to_documentation=文档链接. - -about.shortcuts.mouse_middleclick=鼠标中键点击 -about.shortcuts.open_next_entry=打开下一个条目 -about.shortcuts.open_previous_entry=打开上一个条目 -about.shortcuts.spacebar=空格/shift+空格 -about.shortcuts.move_page_down_up=将页面向下/上移动 -about.shortcuts.focus_next_entry=移动到下一个条目但不打开 -about.shortcuts.focus_previous_entry=移动到上一个条目但不打开 -about.shortcuts.open_next_feed=打开下一个订阅或目录 -about.shortcuts.open_previous_feed=打开上一个订阅或目录 -about.shortcuts.open_close_current_entry=打开/关闭当前条目 -about.shortcuts.open_current_entry_in_new_window=在新窗口中打开当前条目 -about.shortcuts.open_current_entry_in_new_window_background=在后台新窗口中打开当前条目 -about.shortcuts.star_unstar=该条目加注/取消星标 -about.shortcuts.mark_current_entry=标记当前条目为已读/未读 -about.shortcuts.mark_all_as_read=标记所有条目为已读 -about.shortcuts.open_in_new_tab_mark_as_read=在新的窗口中打开条目并标记为已读 -about.shortcuts.fullscreen=全屏模式 -about.shortcuts.font_size=增大/缩小本条目字体 -about.shortcuts.go_to_all=跳转到‘全部’页面 -about.shortcuts.go_to_starred=跳转到‘加星标’页面 -about.shortcuts.feed_search=输入订阅名称来导航至相应订阅 - diff --git a/src/main/resources/log4j.properties b/src/main/resources/log4j.properties deleted file mode 100644 index 12fe0dee..00000000 --- a/src/main/resources/log4j.properties +++ /dev/null @@ -1,9 +0,0 @@ -log4j.logger.com.commafeed=INFO, CONSOLE -log4j.logger.org=WARN, CONSOLE -log4j.logger.ro=WARN, CONSOLE -log4j.logger.com.wordnik=FATAL, CONSOLE -log4j.logger.com.codahale=WARN, CONSOLE - -log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender -log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout -log4j.appender.CONSOLE.layout.ConversionPattern=%-5p %d{ISO8601} [%c{1}\:%L] [%t] %m%n \ No newline at end of file diff --git a/src/main/resources/changelogs/db.changelog-master.xml b/src/main/resources/migrations.xml similarity index 88% rename from src/main/resources/changelogs/db.changelog-master.xml rename to src/main/resources/migrations.xml index ffa87ed6..acc1dafa 100644 --- a/src/main/resources/changelogs/db.changelog-master.xml +++ b/src/main/resources/migrations.xml @@ -1,7 +1,7 @@ + xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd"> diff --git a/src/main/script/HTMLConcat.groovy b/src/main/script/HTMLConcat.groovy deleted file mode 100644 index ae05f7df..00000000 --- a/src/main/script/HTMLConcat.groovy +++ /dev/null @@ -1,52 +0,0 @@ -import java.io.File; -import java.io.IOException; - -import org.apache.commons.io.FileUtils; -import org.apache.commons.lang.SystemUtils; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class HTMLConcat { - - private static final Pattern PATTERN = Pattern.compile('\\$\\{(.+?)\\}'); - - public void concat(String source, String prefix, String destination, String i18nPath) - throws IOException { - for(File i18n : new File(i18nPath).listFiles()) { - StringBuilder sb = new StringBuilder(); - sb.append("
"); - for (File file : new File(source).listFiles()) { - sb.append(SystemUtils.LINE_SEPARATOR); - sb.append(String.format( - ""); - sb.append(SystemUtils.LINE_SEPARATOR); - } - sb.append("
"); - String dest = destination.substring(0, destination.lastIndexOf(".")) + "." + i18n.getName().split("\\.")[0] + ".html"; - FileUtils.writeStringToFile(new File(dest), sb.toString(), "UTF-8"); - } - } - - public String translate(String content, File i18n) { - Properties props = new Properties(); - props.load(new InputStreamReader(new FileInputStream(i18n), "UTF-8")); - return replace(content, props); - } - - public String replace(String content, Properties props) { - Matcher m = PATTERN.matcher(content); - StringBuffer sb = new StringBuffer(); - while (m.find()) { - String var = m.group(1); - Object replacement = props.get(var); - m.appendReplacement(sb, replacement == null ? var : replacement.toString().split("#")[0]); - } - m.appendTail(sb); - return sb.toString(); - } -} diff --git a/src/main/script/I18nGenerator.groovy b/src/main/script/I18nGenerator.groovy deleted file mode 100644 index 2671f974..00000000 --- a/src/main/script/I18nGenerator.groovy +++ /dev/null @@ -1,52 +0,0 @@ -import java.io.File; -import java.util.ArrayList; -import java.util.List; - -import org.apache.commons.io.FileUtils; -import org.apache.commons.lang3.StringUtils; - -public class I18nGenerator { - - public void generate(String directory) throws Exception { - - File dir = new File(directory); - List enLines = FileUtils.readLines(new File(dir, - "en.properties"), "UTF-8"); - - for (File file : dir.listFiles()) { - if ("languages.properties".equals(file.getName()) - || "en.properties".equals(file.getName())) - continue; - - List newLines = new ArrayList(); - List langLines = FileUtils.readLines(file, "UTF-8"); - - int j = 0; - for (int i = 0; i < enLines.size(); i++) { - - String enLine = enLines.get(i); - String langLine = langLines.get(j); - - if (StringUtils.isNotBlank(enLine)) { - - String key = enLine.split("=")[0]; - if (langLine.startsWith(key)) { - newLines.add(langLine); - } else { - newLines.add(enLine + " ####### Needs translation"); - j--; - } - } else { - newLines.add(null); - if (StringUtils.isNotBlank(langLine)) { - j--; - } - } - j++; - } - newLines.add(null); - FileUtils.writeLines(file, "UTF-8", newLines); - - } - } -} diff --git a/src/main/tomee/conf/system.properties b/src/main/tomee/conf/system.properties deleted file mode 100644 index a5a37355..00000000 --- a/src/main/tomee/conf/system.properties +++ /dev/null @@ -1,53 +0,0 @@ -# all this properties are added at JVM system properties at startup -# here some default Apache TomEE system properties -# for more information please see http://openejb.apache.org/properties-listing.html - -# openejb.check.classloader = false -# openejb.check.classloader.verbose = false - -# tomee.jaxws.subcontext = webservices -# tomee.jaxws.oldsubcontext = false - - -# openejb.servicemanager.enabled = true - -# openejb.descriptors.output = false -# openejb.strict.interface.declaration = false -# openejb.conf.file = conf/tomee.xml -# openejb.debuggable-vm-hackery = false -# openejb.validation.skip = false -# openejb.webservices.enabled = true -# openejb.validation.output.level = MEDIUM -# openejb.user.mbeans.list = * -# openejb.deploymentId.format = {appId}/{ejbJarId}/{ejbName} -# openejb.jndiname.format = {deploymentId}{interfaceType.annotationName} -# openejb.deployments.package.include = .* -# openejb.deployments.package.exclude = -# openejb.autocreate.jta-datasource-from-non-jta-one = true -# openejb.altdd.prefix = -# org.apache.openejb.default.system.interceptors = -# openejb.jndiname.failoncollision = true -# openejb.wsAddress.format = /{ejbDeploymentId} -# org.apache.openejb.server.webservices.saaj.provider = -# openejb.nobanner = true -# openejb.offline = false -# openejb.exclude-include.order = include-exclude -# openejb.additional.exclude = -# openejb.additional.include = -# openejb.crosscontext = false -# openejb.jsessionid-support = -# openejb.myfaces.disable-default-values = true -# openejb.web.xml.major = -# openjpa.Log = -# openejb.jdbc.log = false -# javax.persistence.provider = org.apache.openjpa.persistence.PersistenceProviderImpl -# javax.persistence.transactionType = -# javax.persistence.jtaDataSource = -# javax.persistence.nonJtaDataSource = - -openejb.system.apps = false -openejb.jmx.active = false - -AsynchronousPool.CorePoolSize = 1 -AsynchronousPool.MaximumPoolSize = 100 -openejb.stats.interceptor.disable = true \ No newline at end of file diff --git a/src/main/tomee/conf/tomee.xml b/src/main/tomee/conf/tomee.xml deleted file mode 100644 index af25b662..00000000 --- a/src/main/tomee/conf/tomee.xml +++ /dev/null @@ -1,58 +0,0 @@ - - - - - jdbcDriver = org.hsqldb.jdbcDriver - jdbcUrl = jdbc:hsqldb:file:data/hsqldb;hsqldb.tx=mvcc - UserName = sa - Password = - MaxActive = 50 - DataSourceCreator bonecp - - - - - - - - - - - - PoolSize=50 - StrictPooling=false - - - InstanceLimit=50 - ResourceAdapter=JMSCommaFeedAdapter - - - - diff --git a/src/main/webapp/META-INF/jboss-deployment-structure.xml b/src/main/webapp/META-INF/jboss-deployment-structure.xml deleted file mode 100644 index 17f84b2a..00000000 --- a/src/main/webapp/META-INF/jboss-deployment-structure.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/src/main/webapp/WEB-INF/beans.xml b/src/main/webapp/WEB-INF/beans.xml deleted file mode 100644 index 55e533bf..00000000 --- a/src/main/webapp/WEB-INF/beans.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - ${cache_service.class} - - \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/scan.xml b/src/main/webapp/WEB-INF/scan.xml deleted file mode 100644 index 07374787..00000000 --- a/src/main/webapp/WEB-INF/scan.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - com.commafeed.backend - com.commafeed.frontend.rest - - \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml deleted file mode 100644 index 3f06ce33..00000000 --- a/src/main/webapp/WEB-INF/web.xml +++ /dev/null @@ -1,39 +0,0 @@ - - - - - Wicket - org.apache.wicket.protocol.http.WicketFilter - - applicationClassName - com.commafeed.frontend.CommaFeedApplication - - - - WebResourceOptimizer - ro.isdc.wro.http.WroFilter - - - i18n - com.commafeed.frontend.utils.InternationalizationDevelopmentFilter - - - - WebResourceOptimizer - /wro/* - - - Wicket - /* - - - i18n - /templates/* - - - - com.commafeed.frontend.resources.WroListener - - diff --git a/src/main/webapp/WEB-INF/wro.properties b/src/main/webapp/WEB-INF/wro.properties deleted file mode 100644 index 68e03452..00000000 --- a/src/main/webapp/WEB-INF/wro.properties +++ /dev/null @@ -1,18 +0,0 @@ -cacheUpdatePeriod=0 -modelUpdatePeriod=0 -resourceWatcherUpdatePeriod=1 - -debug=true -disableCache=false - -ignoreMissingResources=false -jmxEnabled=false -managerFactoryClassName=com.commafeed.frontend.resources.WroManagerFactory - -#List of preProcessors -preProcessors=timestamp,cssUrlRewriting,sassImport,semicolonAppender,googleClosureSimple,sassOnlyProcessor,yuiCssMin -#List of postProcessors -postProcessors= - -#hashStrategy=MD5 -#namingStrategy=hashEncoder-CRC32 \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/wro.xml b/src/main/webapp/WEB-INF/wro.xml deleted file mode 100644 index 68736c3b..00000000 --- a/src/main/webapp/WEB-INF/wro.xml +++ /dev/null @@ -1,61 +0,0 @@ - - - - - webjar:lodash.min.js - - webjar:jquery/1.11.0/jquery.min.js - webjar:jquery.mousewheel.js - - /vendor/jqueryui/*.js - /vendor/jqueryui/*.css - - webjar:bootstrap.min.js - webjar:bootstrap.min.css - - /vendor/fontawesome/css/*.css - - /vendor/select2/*.js - /vendor/select2/*.css - - webjar:mousetrap.min.js - - webjar:device.min.js - - webjar:moment.min.js - webjar:langs.min.js - - webjar:angular.min.js - webjar:angular-resource.min.js - webjar:angular-route.min.js - webjar:angular-sanitize.min.js - webjar:angular-touch.min.js - webjar:angular-animate.min.js - - webjar:angular-ui-router.min.js - webjar:ui-utils.min.js - webjar:ui-select2.js - webjar:ui-bootstrap-tpls.min.js - webjar:ng-infinite-scroll.min.js - - webjar:ng-grid.min.js - webjar:ng-grid.min.css - - /vendor/angular-loading-bar/loading-bar.0.4.0.min.js - /vendor/angular-loading-bar/loading-bar.min.css - - /vendor/zocial/*.css - - /vendor/readabilicons/css/*.css - - - - /sass/app.scss - /js/*.js - - - - lib - app - - \ No newline at end of file diff --git a/src/main/webapp/api/css/custom.css b/src/main/webapp/api/css/custom.css deleted file mode 100644 index e299efe0..00000000 --- a/src/main/webapp/api/css/custom.css +++ /dev/null @@ -1,25 +0,0 @@ -.signature-container .description span { - margin-left: 5px; -} - -.signature-container .description .model-desc { - font-weight: bold; - color: #000; - font-size: 1.1em; -} - -.signature-container .description .class-desc { - font-weight: bold; - color: #000; - font-size: 1.0em; - margin-left: 0px; -} - -.signature-container .description ul { - margin-left: 20px; - list-style: disc; -} - -.footer { - display: none; -} \ No newline at end of file diff --git a/src/main/webapp/api/css/hightlight.default.css b/src/main/webapp/api/css/hightlight.default.css deleted file mode 100644 index e417fc17..00000000 --- a/src/main/webapp/api/css/hightlight.default.css +++ /dev/null @@ -1,135 +0,0 @@ -/* - -Original style from softwaremaniacs.org (c) Ivan Sagalaev - -*/ - -pre code { - display: block; padding: 0.5em; - background: #F0F0F0; -} - -pre code, -pre .subst, -pre .tag .title, -pre .lisp .title, -pre .clojure .built_in, -pre .nginx .title { - color: black; -} - -pre .string, -pre .title, -pre .constant, -pre .parent, -pre .tag .value, -pre .rules .value, -pre .rules .value .number, -pre .preprocessor, -pre .ruby .symbol, -pre .ruby .symbol .string, -pre .aggregate, -pre .template_tag, -pre .django .variable, -pre .smalltalk .class, -pre .addition, -pre .flow, -pre .stream, -pre .bash .variable, -pre .apache .tag, -pre .apache .cbracket, -pre .tex .command, -pre .tex .special, -pre .erlang_repl .function_or_atom, -pre .markdown .header { - color: #800; -} - -pre .comment, -pre .annotation, -pre .template_comment, -pre .diff .header, -pre .chunk, -pre .markdown .blockquote { - color: #888; -} - -pre .number, -pre .date, -pre .regexp, -pre .literal, -pre .smalltalk .symbol, -pre .smalltalk .char, -pre .go .constant, -pre .change, -pre .markdown .bullet, -pre .markdown .link_url { - color: #080; -} - -pre .label, -pre .javadoc, -pre .ruby .string, -pre .decorator, -pre .filter .argument, -pre .localvars, -pre .array, -pre .attr_selector, -pre .important, -pre .pseudo, -pre .pi, -pre .doctype, -pre .deletion, -pre .envvar, -pre .shebang, -pre .apache .sqbracket, -pre .nginx .built_in, -pre .tex .formula, -pre .erlang_repl .reserved, -pre .prompt, -pre .markdown .link_label, -pre .vhdl .attribute, -pre .clojure .attribute, -pre .coffeescript .property { - color: #88F -} - -pre .keyword, -pre .id, -pre .phpdoc, -pre .title, -pre .built_in, -pre .aggregate, -pre .css .tag, -pre .javadoctag, -pre .phpdoc, -pre .yardoctag, -pre .smalltalk .class, -pre .winutils, -pre .bash .variable, -pre .apache .tag, -pre .go .typename, -pre .tex .command, -pre .markdown .strong, -pre .request, -pre .status { - font-weight: bold; -} - -pre .markdown .emphasis { - font-style: italic; -} - -pre .nginx .built_in { - font-weight: normal; -} - -pre .coffeescript .javascript, -pre .javascript .xml, -pre .tex .formula, -pre .xml .javascript, -pre .xml .vbscript, -pre .xml .css, -pre .xml .cdata { - opacity: 0.5; -} diff --git a/src/main/webapp/api/css/screen.css b/src/main/webapp/api/css/screen.css deleted file mode 100644 index 06050e76..00000000 --- a/src/main/webapp/api/css/screen.css +++ /dev/null @@ -1,1759 +0,0 @@ -html, body, div, span, applet, object, iframe, -h1, h2, h3, h4, h5, h6, p, blockquote, pre, -a, abbr, acronym, address, big, cite, code, -del, dfn, em, img, ins, kbd, q, s, samp, -small, strike, strong, sub, sup, tt, var, -b, u, i, center, -dl, dt, dd, ol, ul, li, -fieldset, form, label, legend, -table, caption, tbody, tfoot, thead, tr, th, td, -article, aside, canvas, details, embed, -figure, figcaption, footer, header, hgroup, -menu, nav, output, ruby, section, summary, -time, mark, audio, video { - margin: 0; - padding: 0; - border: 0; - font-size: 100%; - font: inherit; - vertical-align: baseline; -} - -body { - line-height: 1; -} - -ol, ul { - list-style: none; -} - -table { - border-collapse: collapse; - border-spacing: 0; -} - -caption, th, td { - text-align: left; - font-weight: normal; - vertical-align: middle; -} - -q, blockquote { - quotes: none; -} - -q:before, q:after, blockquote:before, blockquote:after { - content: ""; - content: none; -} - -a img { - border: none; -} - -article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section, summary { - display: block; -} - -h1 a, h2 a, h3 a, h4 a, h5 a, h6 a { - text-decoration: none; -} - -h1 a:hover, h2 a:hover, h3 a:hover, h4 a:hover, h5 a:hover, h6 a:hover { - text-decoration: underline; -} - -h1 span.divider, h2 span.divider, h3 span.divider, h4 span.divider, h5 span.divider, h6 span.divider { - color: #aaaaaa; -} - -h1 { - color: black; - font-size: 1.5em; - line-height: 1.3em; - padding: 10px 0 10px 0; - font-family: "Droid Sans", sans-serif; - font-weight: bold; -} - -h2 { - color: black; - font-size: 1.3em; - padding: 10px 0 10px 0; -} - -h2 a { - color: black; -} - -h2 span.sub { - font-size: 0.7em; - color: #999999; - font-style: italic; -} - -h2 span.sub a { - color: #777777; -} - -h3 { - color: black; - font-size: 1.1em; - padding: 10px 0 10px 0; -} - -.heading_with_menu { - float: none; - clear: both; - overflow: hidden; - display: block; -} - -.heading_with_menu h1, .heading_with_menu h2, .heading_with_menu h3, .heading_with_menu h4, .heading_with_menu h5, .heading_with_menu h6 { - display: block; - clear: none; - float: left; - -moz-box-sizing: border-box; - -webkit-box-sizing: border-box; - -ms-box-sizing: border-box; - box-sizing: border-box; - width: 60%; -} - -.heading_with_menu ul { - display: block; - clear: none; - float: right; - -moz-box-sizing: border-box; - -webkit-box-sizing: border-box; - -ms-box-sizing: border-box; - box-sizing: border-box; - margin-top: 10px; -} - -input.parameter { - width: 300px; - border: 1px solid #aaa; -} - -.body-textarea { - width: 300px; - height: 100px; - border: 1px solid #aaa; -} - -p { - line-height: 1.4em; - padding: 0 0 10px; - color: #333333; -} - -ol { - margin: 0px 0 10px; - padding: 0 0 0 18px; - list-style-type: decimal; -} - -ol li { - padding: 5px 0px; - font-size: 0.9em; - color: #333333; -} - -.markdown h3 { - color: #547f00; -} - -.markdown h4 { - color: #666666; -} - -.markdown pre { - font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace; - background-color: #fcf6db; - border: 1px solid #e5e0c6; - padding: 10px; - margin: 0 0 10px 0; -} - -.markdown pre code { - line-height: 1.6em; -} - -.markdown p code, .markdown li code { - font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace; - background-color: #f0f0f0; - color: black; - padding: 1px 3px; -} - -.markdown ol, .markdown ul { - font-family: "Droid Sans", sans-serif; - margin: 5px 0 10px; - padding: 0 0 0 18px; - list-style-type: disc; -} - -.markdown ol li, .markdown ul li { - padding: 3px 0px; - line-height: 1.4em; - color: #333333; -} - -div.gist { - margin: 20px 0 25px 0 !important; -} - -p.big, div.big p { - font-size: 1em; - margin-bottom: 10px; -} - -span.weak { - color: #666666; -} - -span.blank, span.empty { - color: #888888; - font-style: italic; -} - -a { - color: #547f00; -} - -b, strong { - font-family: "Droid Sans", sans-serif; - font-weight: bold; -} - -.code { - font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace; -} - -pre { - font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace; - background-color: #fcf6db; - border: 1px solid #e5e0c6; - padding: 10px; -} - -pre code { - line-height: 1.6em; -} - -.required { - font-weight: bold; -} - -table.fullwidth { - width: 100%; -} - -table thead tr th { - padding: 5px; - font-size: 0.9em; - color: #666666; - border-bottom: 1px solid #999999; -} - -table tbody tr.offset { - background-color: #f5f5f5; -} - -table tbody tr td { - padding: 6px; - font-size: 0.9em; - border-bottom: 1px solid #cccccc; - vertical-align: top; - line-height: 1.3em; -} - -table tbody tr:last-child td { - border-bottom: none; -} - -table tbody tr.offset { - background-color: #f0f0f0; -} - -form.form_box { - background-color: #ebf3f9; - border: 1px solid #c3d9ec; - padding: 10px; -} - -form.form_box label { - color: #0f6ab4 !important; -} - -form.form_box input[type=submit] { - display: block; - padding: 10px; -} - -form.form_box p { - font-size: 0.9em; - padding: 0 0 15px; - color: #7e7b6d; -} - -form.form_box p a { - color: #646257; -} - -form.form_box p strong { - color: black; -} - -form.form_box p.weak { - font-size: 0.8em; -} - -form.formtastic fieldset.inputs ol li p.inline-hints { - margin-left: 0; - font-style: italic; - font-size: 0.9em; - margin: 0; -} - -form.formtastic fieldset.inputs ol li label { - display: block; - clear: both; - width: auto; - padding: 0 0 3px; - color: #666666; -} - -form.formtastic fieldset.inputs ol li label abbr { - padding-left: 3px; - color: #888888; -} - -form.formtastic fieldset.inputs ol li.required label { - color: black; -} - -form.formtastic fieldset.inputs ol li.string input, form.formtastic fieldset.inputs ol li.url input, form.formtastic fieldset.inputs ol li.numeric input { - display: block; - padding: 4px; - width: auto; - clear: both; -} - -form.formtastic fieldset.inputs ol li.string input.title, form.formtastic fieldset.inputs ol li.url input.title, form.formtastic fieldset.inputs ol li.numeric input.title { - font-size: 1.3em; -} - -form.formtastic fieldset.inputs ol li.text textarea { - font-family: "Droid Sans", sans-serif; - height: 250px; - padding: 4px; - display: block; - clear: both; -} - -form.formtastic fieldset.inputs ol li.select select { - display: block; - clear: both; -} - -form.formtastic fieldset.inputs ol li.boolean { - float: none; - clear: both; - overflow: hidden; - display: block; -} - -form.formtastic fieldset.inputs ol li.boolean input { - display: block; - float: left; - clear: none; - margin: 0 5px 0 0; -} - -form.formtastic fieldset.inputs ol li.boolean label { - display: block; - float: left; - clear: none; - margin: 0; - padding: 0; -} - -form.formtastic fieldset.buttons { - margin: 0; - padding: 0; -} - -form.fullwidth ol li.string input, form.fullwidth ol li.url input, form.fullwidth ol li.text textarea, form.fullwidth ol li.numeric input { - width: 500px !important; -} - -body { - font-family: "Droid Sans", sans-serif; -} - -body #content_message { - margin: 10px 15px; - font-style: italic; - color: #999999; -} - -body #header { - background-color: #89bf04; - padding: 14px; -} - -body #header a#logo { - font-size: 1.5em; - font-weight: bold; - text-decoration: none; - background: transparent url(../images/logo_small.png) no-repeat left center; - padding: 20px 0 20px 40px; - color: white; -} - -body #header form#api_selector { - display: block; - clear: none; - float: right; -} - -body #header form#api_selector .input { - display: block; - clear: none; - float: left; - margin: 0 10px 0 0; -} - -body #header form#api_selector .input input { - font-size: 0.9em; - padding: 3px; - margin: 0; -} - -body #header form#api_selector .input input#input_baseUrl { - width: 400px; -} - -body #header form#api_selector .input input#input_apiKey { - width: 200px; -} - -body #header form#api_selector .input a#explore { - display: block; - text-decoration: none; - font-weight: bold; - padding: 6px 8px; - font-size: 0.9em; - color: white; - background-color: #547f00; - -moz-border-radius: 4px; - -webkit-border-radius: 4px; - -o-border-radius: 4px; - -ms-border-radius: 4px; - -khtml-border-radius: 4px; - border-radius: 4px; -} - -body #header form#api_selector .input a#explore:hover { - background-color: #547f00; -} - -body p#colophon { - margin: 0 15px 40px 15px; - padding: 10px 0; - font-size: 0.8em; - border-top: 1px solid #dddddd; - font-family: "Droid Sans", sans-serif; - color: #999999; - font-style: italic; -} - -body p#colophon a { - text-decoration: none; - color: #547f00; -} - -body ul#resources { - font-family: "Droid Sans", sans-serif; - font-size: 0.9em; -} - -body ul#resources li.resource { - border-bottom: 1px solid #dddddd; -} - -body ul#resources li.resource:last-child { - border-bottom: none; -} - -body ul#resources li.resource div.heading { - border: 1px solid transparent; - float: none; - clear: both; - overflow: hidden; - display: block; -} - -body ul#resources li.resource div.heading h2 { - color: #999999; - padding-left: 0; - display: block; - clear: none; - float: left; - font-family: "Droid Sans", sans-serif; - font-weight: bold; -} - -body ul#resources li.resource div.heading h2 a { - color: #999999; -} - -body ul#resources li.resource div.heading h2 a:hover { - color: black; -} - -body ul#resources li.resource div.heading ul.options { - overflow: hidden; - padding: 0; - display: block; - clear: none; - float: right; - margin: 14px 10px 0 0; -} - -body ul#resources li.resource div.heading ul.options li { - float: left; - clear: none; - margin: 0; - padding: 2px 10px; - border-right: 1px solid #dddddd; -} - -body ul#resources li.resource div.heading ul.options li:first-child, body ul#resources li.resource div.heading ul.options li.first { - padding-left: 0; -} - -body ul#resources li.resource div.heading ul.options li:last-child, body ul#resources li.resource div.heading ul.options li.last { - padding-right: 0; - border-right: none; -} - -body ul#resources li.resource div.heading ul.options li { - color: #666666; - font-size: 0.9em; -} - -body ul#resources li.resource div.heading ul.options li a { - color: #aaaaaa; - text-decoration: none; -} - -body ul#resources li.resource div.heading ul.options li a:hover { - text-decoration: underline; - color: black; -} - -body ul#resources li.resource:hover div.heading h2 a, body ul#resources li.resource.active div.heading h2 a { - color: black; -} - -body ul#resources li.resource:hover div.heading ul.options li a, body ul#resources li.resource.active div.heading ul.options li a { - color: #555555; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get { - float: none; - clear: both; - overflow: hidden; - display: block; - margin: 0 0 10px; - padding: 0; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading { - float: none; - clear: both; - overflow: hidden; - display: block; - margin: 0; - padding: 0; - background-color: #e7f0f7; - border: 1px solid #c3d9ec; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading h3 { - display: block; - clear: none; - float: left; - width: auto; - margin: 0; - padding: 0; - line-height: 1.1em; - color: black; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading h3 span { - margin: 0; - padding: 0; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading h3 span.http_method a { - text-transform: uppercase; - background-color: #0f6ab4; - text-decoration: none; - color: white; - display: inline-block; - width: 50px; - font-size: 0.7em; - text-align: center; - padding: 7px 0 4px 0; - -moz-border-radius: 2px; - -webkit-border-radius: 2px; - -o-border-radius: 2px; - -ms-border-radius: 2px; - -khtml-border-radius: 2px; - border-radius: 2px; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading h3 span.path { - padding-left: 10px; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading h3 span.path a { - color: black; - text-decoration: none; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading h3 span.path a:hover { - text-decoration: underline; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options { - overflow: hidden; - padding: 0; - display: block; - clear: none; - float: right; - margin: 6px 10px 0 0; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li { - float: left; - clear: none; - margin: 0; - padding: 2px 10px; - border-right: 1px solid #dddddd; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li:first-child, body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li.first { - padding-left: 0; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li:last-child, body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li.last { - padding-right: 0; - border-right: none; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li { - border-right-color: #c3d9ec; - color: #0f6ab4; - font-size: 0.9em; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li a { - color: #0f6ab4; - text-decoration: none; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li a:hover, body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li a:active, body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li a.active { - text-decoration: underline; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content { - background-color: #ebf3f9; - border: 1px solid #c3d9ec; - border-top: none; - padding: 10px; - -moz-border-radius-bottomleft: 6px; - -webkit-border-bottom-left-radius: 6px; - -o-border-bottom-left-radius: 6px; - -ms-border-bottom-left-radius: 6px; - -khtml-border-bottom-left-radius: 6px; - border-bottom-left-radius: 6px; - -moz-border-radius-bottomright: 6px; - -webkit-border-bottom-right-radius: 6px; - -o-border-bottom-right-radius: 6px; - -ms-border-bottom-right-radius: 6px; - -khtml-border-bottom-right-radius: 6px; - border-bottom-right-radius: 6px; - margin: 0 0 20px; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content h4 { - color: #0f6ab4; - font-size: 1.1em; - margin: 0; - padding: 15px 0 5px; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content form input[type='text'].error { - outline: 2px solid black; - outline-color: #cc0000; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content div.sandbox_header { - float: none; - clear: both; - overflow: hidden; - display: block; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content div.sandbox_header input.submit { - display: block; - clear: none; - float: left; - padding: 6px 8px; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content div.sandbox_header img { - display: block; - clear: none; - float: right; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content div.sandbox_header a { - padding: 4px 0 0 10px; - color: #6fa5d2; - display: inline-block; - font-size: 0.9em; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content div.response div.block pre { - font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace; - padding: 10px; - font-size: 0.9em; - max-height: 400px; - overflow-y: auto; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post { - float: none; - clear: both; - overflow: hidden; - display: block; - margin: 0 0 10px; - padding: 0; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading { - float: none; - clear: both; - overflow: hidden; - display: block; - margin: 0; - padding: 0; - background-color: #e7f6ec; - border: 1px solid #c3e8d1; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading h3 { - display: block; - clear: none; - float: left; - width: auto; - margin: 0; - padding: 0; - line-height: 1.1em; - color: black; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading h3 span { - margin: 0; - padding: 0; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading h3 span.http_method a { - text-transform: uppercase; - background-color: #10a54a; - text-decoration: none; - color: white; - display: inline-block; - width: 50px; - font-size: 0.7em; - text-align: center; - padding: 7px 0 4px 0; - -moz-border-radius: 2px; - -webkit-border-radius: 2px; - -o-border-radius: 2px; - -ms-border-radius: 2px; - -khtml-border-radius: 2px; - border-radius: 2px; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading h3 span.path { - padding-left: 10px; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading h3 span.path a { - color: black; - text-decoration: none; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading h3 span.path a:hover { - text-decoration: underline; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options { - overflow: hidden; - padding: 0; - display: block; - clear: none; - float: right; - margin: 6px 10px 0 0; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li { - float: left; - clear: none; - margin: 0; - padding: 2px 10px; - border-right: 1px solid #dddddd; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li:first-child, body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li.first { - padding-left: 0; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li:last-child, body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li.last { - padding-right: 0; - border-right: none; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li { - border-right-color: #c3e8d1; - color: #10a54a; - font-size: 0.9em; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li a { - color: #10a54a; - text-decoration: none; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li a:hover, body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li a:active, body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li a.active { - text-decoration: underline; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content { - background-color: #ebf7f0; - border: 1px solid #c3e8d1; - border-top: none; - padding: 10px; - -moz-border-radius-bottomleft: 6px; - -webkit-border-bottom-left-radius: 6px; - -o-border-bottom-left-radius: 6px; - -ms-border-bottom-left-radius: 6px; - -khtml-border-bottom-left-radius: 6px; - border-bottom-left-radius: 6px; - -moz-border-radius-bottomright: 6px; - -webkit-border-bottom-right-radius: 6px; - -o-border-bottom-right-radius: 6px; - -ms-border-bottom-right-radius: 6px; - -khtml-border-bottom-right-radius: 6px; - border-bottom-right-radius: 6px; - margin: 0 0 20px; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content h4 { - color: #10a54a; - font-size: 1.1em; - margin: 0; - padding: 15px 0 5px; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content form input[type='text'].error { - outline: 2px solid black; - outline-color: #cc0000; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content div.sandbox_header { - float: none; - clear: both; - overflow: hidden; - display: block; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content div.sandbox_header input.submit { - display: block; - clear: none; - float: left; - padding: 6px 8px; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content div.sandbox_header img { - display: block; - clear: none; - float: right; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content div.sandbox_header a { - padding: 4px 0 0 10px; - color: #6fc992; - display: inline-block; - font-size: 0.9em; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content div.response div.block pre { - font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace; - padding: 10px; - font-size: 0.9em; - max-height: 400px; - overflow-y: auto; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put { - float: none; - clear: both; - overflow: hidden; - display: block; - margin: 0 0 10px; - padding: 0; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading { - float: none; - clear: both; - overflow: hidden; - display: block; - margin: 0; - padding: 0; - background-color: #f9f2e9; - border: 1px solid #f0e0ca; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading h3 { - display: block; - clear: none; - float: left; - width: auto; - margin: 0; - padding: 0; - line-height: 1.1em; - color: black; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading h3 span { - margin: 0; - padding: 0; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading h3 span.http_method a { - text-transform: uppercase; - background-color: #c5862b; - text-decoration: none; - color: white; - display: inline-block; - width: 50px; - font-size: 0.7em; - text-align: center; - padding: 7px 0 4px; - -moz-border-radius: 2px; - -webkit-border-radius: 2px; - -o-border-radius: 2px; - -ms-border-radius: 2px; - -khtml-border-radius: 2px; - border-radius: 2px; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading h3 span.path { - padding-left: 10px; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading h3 span.path a { - color: black; - text-decoration: none; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading h3 span.path a:hover { - text-decoration: underline; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options { - overflow: hidden; - padding: 0; - display: block; - clear: none; - float: right; - margin: 6px 10px 0 0; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li { - float: left; - clear: none; - margin: 0; - padding: 2px 10px; - border-right: 1px solid #dddddd; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li:first-child, body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li.first { - padding-left: 0; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li:last-child, body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li.last { - padding-right: 0; - border-right: none; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li { - border-right-color: #f0e0ca; - color: #c5862b; - font-size: 0.9em; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li a { - color: #c5862b; - text-decoration: none; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li a:hover, body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li a:active, body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li a.active { - text-decoration: underline; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content { - background-color: #faf5ee; - border: 1px solid #f0e0ca; - border-top: none; - padding: 10px; - -moz-border-radius-bottomleft: 6px; - -webkit-border-bottom-left-radius: 6px; - -o-border-bottom-left-radius: 6px; - -ms-border-bottom-left-radius: 6px; - -khtml-border-bottom-left-radius: 6px; - border-bottom-left-radius: 6px; - -moz-border-radius-bottomright: 6px; - -webkit-border-bottom-right-radius: 6px; - -o-border-bottom-right-radius: 6px; - -ms-border-bottom-right-radius: 6px; - -khtml-border-bottom-right-radius: 6px; - border-bottom-right-radius: 6px; - margin: 0 0 20px; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content h4 { - color: #c5862b; - font-size: 1.1em; - margin: 0; - padding: 15px 0 5px; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content form input[type='text'].error { - outline: 2px solid black; - outline-color: #cc0000; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content div.sandbox_header { - float: none; - clear: both; - overflow: hidden; - display: block; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content div.sandbox_header input.submit { - display: block; - clear: none; - float: left; - padding: 6px 8px; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content div.sandbox_header img { - display: block; - clear: none; - float: right; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content div.sandbox_header a { - padding: 4px 0 0 10px; - color: #dcb67f; - display: inline-block; - font-size: 0.9em; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content div.response div.block pre { - font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace; - padding: 10px; - font-size: 0.9em; - max-height: 400px; - overflow-y: auto; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch { - float: none; - clear: both; - overflow: hidden; - display: block; - margin: 0 0 10px; - padding: 0; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading { - float: none; - clear: both; - overflow: hidden; - display: block; - margin: 0; - padding: 0; - background-color: #FCE9E3; - border: 1px solid #F5D5C3; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading h3 { - display: block; - clear: none; - float: left; - width: auto; - margin: 0; - padding: 0; - line-height: 1.1em; - color: black; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading h3 span { - margin: 0; - padding: 0; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading h3 span.http_method a { - text-transform: uppercase; - background-color: #D38042; - text-decoration: none; - color: white; - display: inline-block; - width: 50px; - font-size: 0.7em; - text-align: center; - padding: 7px 0 4px 0; - -moz-border-radius: 2px; - -webkit-border-radius: 2px; - -o-border-radius: 2px; - -ms-border-radius: 2px; - -khtml-border-radius: 2px; - border-radius: 2px; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading h3 span.path { - padding-left: 10px; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading h3 span.path a { - color: black; - text-decoration: none; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading h3 span.path a:hover { - text-decoration: underline; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options { - overflow: hidden; - padding: 0; - display: block; - clear: none; - float: right; - margin: 6px 10px 0 0; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li { - float: left; - clear: none; - margin: 0; - padding: 2px 10px; - border-right: 1px solid #dddddd; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li:first-child, body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li.first { - padding-left: 0; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li:last-child, body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li.last { - padding-right: 0; - border-right: none; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li { - border-right-color: #f0cecb; - color: #D38042; - font-size: 0.9em; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li a { - color: #D38042; - text-decoration: none; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li a:hover, body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li a:active, body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li a.active { - text-decoration: underline; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content { - background-color: #faf0ef; - border: 1px solid #f0cecb; - border-top: none; - padding: 10px; - -moz-border-radius-bottomleft: 6px; - -webkit-border-bottom-left-radius: 6px; - -o-border-bottom-left-radius: 6px; - -ms-border-bottom-left-radius: 6px; - -khtml-border-bottom-left-radius: 6px; - border-bottom-left-radius: 6px; - -moz-border-radius-bottomright: 6px; - -webkit-border-bottom-right-radius: 6px; - -o-border-bottom-right-radius: 6px; - -ms-border-bottom-right-radius: 6px; - -khtml-border-bottom-right-radius: 6px; - border-bottom-right-radius: 6px; - margin: 0 0 20px; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content h4 { - color: #D38042; - font-size: 1.1em; - margin: 0; - padding: 15px 0 5px; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content form input[type='text'].error { - outline: 2px solid black; - outline-color: #F5D5C3; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content div.sandbox_header { - float: none; - clear: both; - overflow: hidden; - display: block; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content div.sandbox_header input.submit { - display: block; - clear: none; - float: left; - padding: 6px 8px; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content div.sandbox_header img { - display: block; - clear: none; - float: right; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content div.sandbox_header a { - padding: 4px 0 0 10px; - color: #dcb67f; - display: inline-block; - font-size: 0.9em; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content div.response div.block pre { - font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace; - padding: 10px; - font-size: 0.9em; - max-height: 400px; - overflow-y: auto; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head { - float: none; - clear: both; - overflow: hidden; - display: block; - margin: 0 0 10px 0; - padding: 0 0 0 0px; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading { - float: none; - clear: both; - overflow: hidden; - display: block; - margin: 0 0 0 0; - padding: 0; - background-color: #fcffcd; - border: 1px solid black; - border-color: #ffd20f; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading h3 { - display: block; - clear: none; - float: left; - width: auto; - margin: 0; - padding: 0; - line-height: 1.1em; - color: black; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading h3 span { - margin: 0; - padding: 0; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading h3 span.http_method a { - text-transform: uppercase; - background-color: #ffd20f; - text-decoration: none; - color: white; - display: inline-block; - width: 50px; - font-size: 0.7em; - text-align: center; - padding: 7px 0 4px 0; - -moz-border-radius: 2px; - -webkit-border-radius: 2px; - -o-border-radius: 2px; - -ms-border-radius: 2px; - -khtml-border-radius: 2px; - border-radius: 2px; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading h3 span.path { - padding-left: 10px; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading h3 span.path a { - color: black; - text-decoration: none; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading h3 span.path a:hover { - text-decoration: underline; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options { - float: none; - clear: both; - overflow: hidden; - margin: 0; - padding: 0; - display: block; - clear: none; - float: right; - margin: 6px 10px 0 0; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li { - float: left; - clear: none; - margin: 0; - padding: 2px 10px; - border-right: 1px solid #dddddd; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li:first-child, body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li.first { - padding-left: 0; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li:last-child, body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li.last { - padding-right: 0; - border-right: none; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li { - border-right-color: #ffd20f; - color: #ffd20f; - font-size: 0.9em; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li a { - color: #ffd20f; - text-decoration: none; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li a:hover, body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li a:active, body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li a.active { - text-decoration: underline; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content { - background-color: #fcffcd; - border: 1px solid black; - border-color: #ffd20f; - border-top: none; - padding: 10px; - -moz-border-radius-bottomleft: 6px; - -webkit-border-bottom-left-radius: 6px; - -o-border-bottom-left-radius: 6px; - -ms-border-bottom-left-radius: 6px; - -khtml-border-bottom-left-radius: 6px; - border-bottom-left-radius: 6px; - -moz-border-radius-bottomright: 6px; - -webkit-border-bottom-right-radius: 6px; - -o-border-bottom-right-radius: 6px; - -ms-border-bottom-right-radius: 6px; - -khtml-border-bottom-right-radius: 6px; - border-bottom-right-radius: 6px; - margin: 0 0 20px 0; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content h4 { - color: #ffd20f; - font-size: 1.1em; - margin: 0; - padding: 15px 0 5px 0px; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content form input[type='text'].error { - outline: 2px solid black; - outline-color: #cc0000; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content div.sandbox_header { - float: none; - clear: both; - overflow: hidden; - display: block; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content div.sandbox_header input.submit { - display: block; - clear: none; - float: left; - padding: 6px 8px; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content div.sandbox_header img { - display: block; - display: block; - clear: none; - float: right; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content div.sandbox_header a { - padding: 4px 0 0 10px; - color: #6fc992; - display: inline-block; - font-size: 0.9em; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content div.response div.block { - background-color: #fcf6db; - border: 1px solid black; - border-color: #e5e0c6; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content div.response div.block pre { - font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace; - padding: 10px; - font-size: 0.9em; - max-height: 400px; - overflow-y: auto; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete { - float: none; - clear: both; - overflow: hidden; - display: block; - margin: 0 0 10px; - padding: 0; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading { - float: none; - clear: both; - overflow: hidden; - display: block; - margin: 0; - padding: 0; - background-color: #f5e8e8; - border: 1px solid #e8c6c7; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading h3 { - display: block; - clear: none; - float: left; - width: auto; - margin: 0; - padding: 0; - line-height: 1.1em; - color: black; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading h3 span { - margin: 0; - padding: 0; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading h3 span.http_method a { - text-transform: uppercase; - background-color: #a41e22; - text-decoration: none; - color: white; - display: inline-block; - width: 50px; - font-size: 0.7em; - text-align: center; - padding: 7px 0 4px 0; - -moz-border-radius: 2px; - -webkit-border-radius: 2px; - -o-border-radius: 2px; - -ms-border-radius: 2px; - -khtml-border-radius: 2px; - border-radius: 2px; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading h3 span.path { - padding-left: 10px; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading h3 span.path a { - color: black; - text-decoration: none; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading h3 span.path a:hover { - text-decoration: underline; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options { - overflow: hidden; - padding: 0; - display: block; - clear: none; - float: right; - margin: 6px 10px 0 0; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li { - float: left; - clear: none; - margin: 0; - padding: 2px 10px; - border-right: 1px solid #dddddd; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li:first-child, body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li.first { - padding-left: 0; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li:last-child, body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li.last { - padding-right: 0; - border-right: none; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li { - border-right-color: #e8c6c7; - color: #a41e22; - font-size: 0.9em; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li a { - color: #a41e22; - text-decoration: none; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li a:hover, body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li a:active, body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li a.active { - text-decoration: underline; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content { - background-color: #f7eded; - border: 1px solid #e8c6c7; - border-top: none; - padding: 10px; - -moz-border-radius-bottomleft: 6px; - -webkit-border-bottom-left-radius: 6px; - -o-border-bottom-left-radius: 6px; - -ms-border-bottom-left-radius: 6px; - -khtml-border-bottom-left-radius: 6px; - border-bottom-left-radius: 6px; - -moz-border-radius-bottomright: 6px; - -webkit-border-bottom-right-radius: 6px; - -o-border-bottom-right-radius: 6px; - -ms-border-bottom-right-radius: 6px; - -khtml-border-bottom-right-radius: 6px; - border-bottom-right-radius: 6px; - margin: 0 0 20px 0; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content h4 { - color: #a41e22; - font-size: 1.1em; - margin: 0; - padding: 15px 0 5px; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content form input[type='text'].error { - outline: 2px solid black; - outline-color: #cc0000; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content div.sandbox_header { - float: none; - clear: both; - overflow: hidden; - display: block; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content div.sandbox_header input.submit { - display: block; - clear: none; - float: left; - padding: 6px 8px; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content div.sandbox_header img { - display: block; - clear: none; - float: right; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content div.sandbox_header a { - padding: 4px 0 0 10px; - color: #c8787a; - display: inline-block; - font-size: 0.9em; -} - -body ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content div.response div.block pre { - font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace; - padding: 10px; - font-size: 0.9em; - max-height: 400px; - overflow-y: auto; -} - - -.model-signature { - font-family: "Droid Sans", sans-serif; - font-size: 1em; - line-height: 1.5em; -} - -.model-signature .description div { - font-size: 0.9em; - line-height: 1.5em; - margin-left: 1em; -} - -.model-signature .description .strong { - font-weight: bold; - color: #000; - font-size: .9em; -} - -.model-signature .description .stronger { - font-weight: bold; - color: #000; -} - -.model-signature .signature-nav a { - text-decoration: none; - color: #AAA; -} - -.model-signature pre { - font-size: .85em; - line-height: 1.2em; - overflow: auto; - max-height: 200px; - cursor: pointer; -} - -.model-signature pre:hover { - background-color: #ffffdd; -} - -.model-signature .snippet small { - font-size: 0.75em; -} - -.model-signature .signature-container { - clear: both; -} - -.model-signature .signature-nav a:hover { - text-decoration: underline; - color: black; -} - -.model-signature .signature-nav .selected { - color: black; - text-decoration: none; -} - -.model-signature ul.signature-nav { - display: block; - margin: 0; - padding: 0; -} - -.model-signature ul.signature-nav li { - float: left; - margin: 0 5px 5px 0; - padding: 2px 5px 2px 0; - border-right: 1px solid #ddd; -} - -.model-signature ul.signature-nav li:last-child { - padding-right: 0; - border-right: none; -} - -.model-signature .propName { - font-weight: bold; -} -.model-signature .propType { - color: #5555aa; -} -.model-signature .propOptKey { - font-style: italic; -} -.model-signature .propOpt { - color: #555; -} - -pre code { - background: none; -} - -.content pre { - font-size: 12px; - margin-top: 5px; - padding: 5px; -} - -.content > .content-type > div > label { - clear: both; - display: block; - color: #0F6AB4; - font-size: 1.1em; - margin: 0; - padding: 15px 0 5px; -} - -.swagger-ui-wrap { - max-width: 960px; - margin-left: auto; - margin-right: auto; -} - -.icon-btn { - cursor: pointer; -} - -#message-bar { - min-height: 30px; - text-align: center; - padding-top: 10px; -} - -.message-success { - color: #89BF04; -} - -.message-fail { - color: #cc0000; -} \ No newline at end of file diff --git a/src/main/webapp/api/images/pet_store_api.png b/src/main/webapp/api/images/pet_store_api.png deleted file mode 100644 index f9f9cd4aeb35a108c4b2f1dddb59977d56c595d8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 824 zcmV-81IPS{P)n=Rd;8mVwQNY4k4xJQ%YT}s;WA7;r!W@XgqjG_4og} z8w>{OB9REiMa8-B85td+y}bji^~2KA`Md4j-u{zw=H%Da@83%_8qEnl9k1WK;pWX- zb-lg)pQYAreK@>)*5Clqni{IZVYGG+NY67Bp-^bn;L{Nbh44I6CIK+n7p8#U?;fCA zYMFcy%UEjup4fgnli%NyzSe*@419QuU9lJ|T$?f9w?HIQ$RwEJGK7^!y7LhxIgVJp z9c!kB{0aydM1epU1NJ=h(}2X?Y{qn70yEN$dwm~favs=VbQ+T?!AvSl{P~PE zS&zsJbTQttne>kdM4$jBhLMFy@I1)3u-4cAzrY*l!o9eK^w%+jqY!oi(Ri8sMauvK zwnCP#%3hEH#FtNqq{iT(?=_JA_8XC>5Y8Y@!wmxKb|A87ZbpHA`+%v~0pt{5Nko1L zLKR^25YExt1lH7L1{t{|P z@n)yHyZf~3>LZ@#&CNw1rA#OlY^|)UJQKUrlKKO&x%wPhH}6&e0000K^a6u zQ3;5MiU^7p6*M3qDk!2=YEcHMQ>nzEYP;R`e2C@r+U+?#XaC*&gKPcB#k$`o&;7mu zYNhYYXe|Uo84#4ZIko#rcU5K8*yFL{qT47O&^5fZH$ zVZ@%(l~vVHjnm;H@KL8@r%yUHoo;rbHI_4lIH(_nsTT>S2`DFOD~uCb9_dF4`#QgI zy7ldMcLs+A_s%|e1pRPrbX-tpeNP!9(IpMFTce`t_5U%lP99z%&i6`1d~ zWeM!Rxc50<+d$e^9LT`?B+aMK~apR zHm?q;p<7{wN2g|I^aGlSws;VP84j(z%aQwvAWv83Z$}p(% zZ^?2;gxg(ey_`V5J7{;!o;o;KslW@z5EP~JGs|U)J7dF&(ff#A=6vU?cGQ$-4+;Jf z-ggJEa!yStn`_EWvl)#yhm6XVs}UUbsi;+agri;mCfjH^Uy;lH+Zw^h)4N?oZgZz4 zJk(fTZ|Bi^;+s_M=~+d#vyoxEPzTlOS=mX@sbl*uRj>=MaMr}cFIY8i?UM61>86uB zV$DlOUCiUJwbzJMP@D$urzK|lL2-PC!p1l47V-ZG<5Ev0Z5h~Kx?`KOp7gkAjV93A z-Gc7MrlxTf?wF;CbNc@tCHJH{TB3c;#{SVu%97}tyAM2n&|9W_?qv}$*Jt*%7Yxb# zV0;d;7|lDEltJYS+U)#aiJO};?_Jyy_4%syQ(uy?-J-Yx-9O5nKRk@@XSS~X<(2u~ zV-LamWm~!iqtH9wkpf8mAXZhOD&L#aA_%)4h2M;1M5jt zIR>Us+%W-GXa_f^opKg=DSrAs)AXeRa;Hp0aC1OgbxQ%Qr_QvTleM1jkR!2mkcX$3 ztsR8~G9iqh(-FJ@F_rQBIYDXV_6s7G9SxaVF^laZqcx$!D97m|7t16j6@Jt6UdDRy49Qyvs|c>RuA|@b%}`*wU}2^7q;&Vtc6@lb zcXl)T!6nYDzmMJ~%n$KNXyNlCG)GkJ4!82;v6@d3>s5r~E+3!O?049JDr14Y^PeMI02R`0lJ^=oJ zYd|*u9|SU(j7hY?+<=(?fP*mtV*zFhOrz6%{VA?ozdm&(Jf^V zMfPZ?>l`mS3{Uq8IM;e!+1YjJy2!mzK$O|wPeU{*QSbs9m+@`f5KxO3PBnQ=%RsZg%go*fJ`*w9TL{-WgZVIA$!YV}3BRcfeXaR$x#b zW)Tpd#8E4)^MyYdkH;4_;ChJuw%n+Be7Ko4;w-nHvyo$d_0e-YiF78Df&)_)(}fcr_r0mPH(4RRYWIu+d@t0&Ss@O^s! zOKyX&13)%N@83r^;QsgN{rl(!0|RF1FA)b1{CRXAy&1ySz@>olPiR4r$aMdq&_=nK zq|cFs8phWJ1@%dZ-gXd{zDbTILD>)qEvH-NU*Rf1b2J1Ri79`rBFl@ z8E^0I)OqEi{pH(a24b9YPG;Kz@t-qZW;3Mpe`MRlmYx{7bH-XZ&`RQ7Rb^%}gc&X| zd}Q-FZf|RWxHU?PR!(C?80zu(^l>*h{#ulSiid(O!J(8P-41bNM3tnX@U6NS5yo0? zdcF)~xFE&+&|gZ$23dV5t~?$$&ymZ;F8j7GGMncGSsDo%>J`26=&l=X#rSKv_64;0 zr;k6no@=gV`P)K!=kaHl>q?!`X>(A;84tg^Md<`zA%qbRLby1Z=fn*ZRdNqs%Tq|3 zOt}lZu0q9oKJhgz&+^7PCt$=UFW=R*w?a1)ePoL*`R$Gxj?TU@12tTHsT$giHQU+sqf;fS0FpT!< z z#UR4L_rT;lfRLVo8|3$7cmuxwjY5rmYs&kR6z_LRhf9-=4QalKQYEWw^4-EBI3j$& zA>$Im_{ZA>0`)E_&m%x6a)BThkx=e|aMkOrK9zb1YzqpQ&WZ^$)2T>CwTCuYRn5y) z3fVXg-@R5&Bf4?WUTyD|hBDe2>xEh|o-y}o5Se~+Ob!5xN>CaAN!<4)F zwNh!Y7B?@AigokFYNJL`0Vz&-ekrY95-n3M<%GR<;SzXRmO7(zd+gf|$Thb%;pby2 zyd{5TJ?|JYUgpSlJ0=LB@k6#d&opuPGq^qJAIumfhigC2qAX0OEnYnT@O;bA?X1O5 zpLe9|%_H+Yki!Rv$7Kvjv8r7Z?$<>G)g*%D*V#s&kz>Z3V1 z3!ZKh9H8Nl9IdhEW_rY#oYdDCLTe+nQ{(d2pBX8%CmxL+1`|b#Vb!?IY!kT7$PDWAP9$FY=e9KSK{DEH|408! zl-$lv)U8$EB{~es&j>rYg%{{JRvIl8@NK}L=xDAEVv(o#W@3LUDc*m?yKSPR0O|nY zAh;*QuBdpja8HzP8Uw`ce-r*LrUA47ZvZ)ff3k4^>;dFcof}9eXeeM<0OVj&CKDVK zpUKKIF%hSmry!pwK68UX>zOF@dv}B4Gg)^2GQmN7@A?zG!xO6dT*Cq0+r{eY6}AfU zf`|~y!?^R*nB0!iTcg|CgM}ou^H*s~5)%h;Xh;PYOM!|Yhfk$w;@`1Dx1y!EZrM&^zMat!^Wz# z=Z{;Pa0w21oA1X3*9=`*c7o3ePa^k%Vzu>2C_7DaZJ8FW5GJv|t>`Ym;_S>7g_3XI zdRb!Ppd`ErK`pUDHRsJd9@)bu>}s1)nKsyAR7h21<1u{DX1gd_Vf;^zdUpFPeSHHR z7AMgw^{FlFlK91CGMafKt`$FLhq#^=->@Uok7pqW6&#Zs4*E(i5-jog43A*qC@!(8 z8&F}pofRcMVmcJd=f;fvlfAR!ZqeaTE?#TQ^jQM0ioaJf8m^!Kdv^`f5kEsD0=gX#4={QE1$3A4K~V$ITKEd){XVLx?i6K*D>JF6E=i znqF^X#&UX}rfB|#A9%y|sR5i6B5gyk>8@Q+xHg|^5iz7C2}YkGF)nuP4LX#k2tRBP z=!VnWnXea(K#Wvg2&0f{!mXuuWaPpsoZ)3TSaEp;i|_)CvP=4wjI; zH%7tcLM8dQXsHW*#|}%TG9yiGpyjBltpcpXkpl8zg~x zD{QG)2Z8x$vfjgDc(J6i|OHoLX&!<+m^<$S3DtA8Mf!{ z7;g1}0uqJ0Mxuy%=#BFX5;Xh9JkrA$d}neS9T;$F$kXn}ss zF{Jn}9EDk=>h)sMy$YXfhKIDxr7U@3xl+uI|N5y!>?{aVn703L1Qgb$ql%JT^lsGD%)~)(H?Spj$zNt)h)Raob z@KyVB@&ngE0rtMW4!UTqGX>{&KHJAWqb)oYq9O)e)nmN0jVa;LNbKXx04a+8&O;q) zHBzGejrqt7Dk$Z2VR%%K#`!((pXE*MR{jGtv|q$p5#v9N0f^6B9IB!Q6(y$TmHRLM zsYXm2jn3f{9T)KVVzotDx=Ng8q0Z*VDZOkd5C!p0PRoFt>NyVEc9*%YR&2>Nq~$AI zXOQfjJ&wpGMe~I8y=cC(QR4=W2GWccFK(3`d&gN+)qWtW-`*}mZI%KDRl4@rUv1%d zxFO82lhW$xQyYxJg8tOZyXm1As%kEFNn)eW{R61M>af@wr(YW{R@+eL2 zx?SovK+867$F%T;Dfeajw|kiQ81GcOnS$Y4+hp8g_w1P8_~79d9p$*M1_Ei81$H$Ti6oi?ZW)&tmsJa7RV1LKddm7R*qL54L7j zvCr1Mrb;l!=m^TbJun-C_6$7w81E1eAQC^6s4>rZ4&I5+yyu$kha%Z&d+|S7Ki#{2 zy}%Giz|eR|G?ychX%%=eL`W(aLarb(L4jd>J+wlX;xMV9H8J!l&i?~Mw7)jlIuLD% zyq+AK92j#kC`ycv$SJ|E7!FBParx#v<3_rZ-DLQ@>`#sdl5}immok8&`{YgF|+< z`tB>e%6G{=B4?V-be>`&*}0d*f?$yBX@w+rJht@O+=^zttqB2p=IiA17#YD$4-fih z@$gJ95mGmFhN!d;3Ag4#>3o`>%L{G=9<}qOJ$wDN)%)MN6bVsAPG4oKB3+8r6!Qf9 z3m8?jIpWcEJbt6|f?Y4nMXK(--YZ|GA2_aRS!do%J9S7?Q&4FYL@sPilq}e4tlYa& z?f+we^=FH^Z9|dnXZghblW!IYGIAT{``58&7vZBybh+GuIPP{h*J?&vf7i8rv6qgx zab9~l+K`tvC7pWtlS!5lt(n#Yl}PAR(v01oXjc0F?T0w>+*p#PtE?Tf_hMrEaZ!^V zbv_>=4xibc0TUxg^I>TS?HR4fdiWl`@6{7|WU9G68l7tOz2p>oIe~NNr!>Q&PHm`4 z98R?g(IT*nl#{_|*WO_h0X78;WwMp?A^Zi)W@BX5q==TdOl?~J6HK(0b(xD6?m3e3 z#+zMaSJb(W$h5+d+6vujSjyi_R80c9>7h;0YlUFDvN`iNGu&5HQ5^e>6x?&JSc4V$6_I1jJ4vnCVbkU`Gz=Uy#~OI( zlL-$UAE$pVCsD_rICM#Q!ltzcqDphp5L|ZrqUm>=H%x!RjMrF#*?BN2shvUg=H;)& zy~_xWl*k$~9Hl6PIq({dELPE-r4*YNs7?5{>dlC`EcK~lPKB_8V)G@H)UZFF8$tXT z@^raW#Hq4OJGFL2Aye|HU&_NL%dYans6?ltqEBz`Q|m=@Zh4=-p2r;}q(Nbsk$fUI zP|(Ns2>MDvZi1H7<55frlQn#%?`WY3g`+fRuC#UJx%#d!zxEu3=}zF514S=6f@?~$ zeuSB=6E7r3ya|; z@K7M3VBrls6c{M*M_{AB_fVjgQ|F(FuK(@=1eWeVMSpLglllqV6Rg-L_46;?^IskS z)x6|SR1^gGl6amWjkb1dX}^8DumNXNmhsfxKA#;bBBIZE@0gma5yQY(FX>|N~Y^mgq`xc zdxOf6r{9u#_e0gV3(fdBTdV2Sc4SN5ZmP?cB4?KRdvj&>@zN_HP5m0E=+A=efDBI*IG*Gy%%< zz@yc%2XvGm)QQv5k^ZC6!9MwX8BCmQ{3eAX|GTwn#>(PS6PoB=$Pwn*?wz?%Tx2gwJ4apoy`A15D=>?%}hj`fV*p=6XW=YR(sp))`dxTnqHE&{&; zPdeO}SVkf*6_$c45W3Z}u|Z&a8{r!6ZNY62S>5{jAd)Hkjg@h%@c)c#BvZK2lmGw| z`Vh+%ECkF{t=)XpF3Z1bj=Pe9LpHbnQwjeTU#=4hB76#52DU2P2Ouj~^lRWwRd%eN zBw_z%FL0CUlk!`s2!`>QG&H__i_)I9=AuA=jn40z>;@hRsg)>J(58cx;l;h_zE*-R7Wbz6Ff#1Mss*)zTImU4`2@?a7y;v4 zH=lJ_PM5Rkw*AU`Cmq6aa>chASJ&Z3Ebj`y;w$MM!fa6`13VU7Kc|T5Xl#7ecj?mp zREV-nBJ6C)`?&}QDe_(KM>BrlN|iF{7-90j+J>N0^vY=LK;8!^9Y_m*aRPX{!S6ag zgRw(13pJvt`;{^S-vgUk?8pV_Vh4a4P7~}uHT)ENFMqd71QIOl8Q6+24TM_+158z) z54U-*C{M)S&!2Bfu&`?Ti6;WojY;%6+I;uCof+*T2iUMz!7Eg<{}#DJSx)C$5f zP(oSf>_s1t06cJ-U3?<9poS4O{Go>H>hro^ks;r3mm1Ehfq?m(_YE8UiVUgG%W9ZY z!@O^}KR%JW*0e=66rUYj5BP~=x%$^x92-m_ - - -Swagger UI - - - - - - - - - - - - - - - - - - - - - -
 
- -

Authentication is required to access the REST API. Use HTTP Basic Authentication to authenticate - yourself.

-

- The base URL of the API is - - . -

-
- - - - diff --git a/src/main/webapp/api/lib/backbone-min.js b/src/main/webapp/api/lib/backbone-min.js deleted file mode 100644 index c1c0d4ff..00000000 --- a/src/main/webapp/api/lib/backbone-min.js +++ /dev/null @@ -1,38 +0,0 @@ -// Backbone.js 0.9.2 - -// (c) 2010-2012 Jeremy Ashkenas, DocumentCloud Inc. -// Backbone may be freely distributed under the MIT license. -// For all details and documentation: -// http://backbonejs.org -(function(){var l=this,y=l.Backbone,z=Array.prototype.slice,A=Array.prototype.splice,g;g="undefined"!==typeof exports?exports:l.Backbone={};g.VERSION="0.9.2";var f=l._;!f&&"undefined"!==typeof require&&(f=require("underscore"));var i=l.jQuery||l.Zepto||l.ender;g.setDomLibrary=function(a){i=a};g.noConflict=function(){l.Backbone=y;return this};g.emulateHTTP=!1;g.emulateJSON=!1;var p=/\s+/,k=g.Events={on:function(a,b,c){var d,e,f,g,j;if(!b)return this;a=a.split(p);for(d=this._callbacks||(this._callbacks= -{});e=a.shift();)f=(j=d[e])?j.tail:{},f.next=g={},f.context=c,f.callback=b,d[e]={tail:g,next:j?j.next:f};return this},off:function(a,b,c){var d,e,h,g,j,q;if(e=this._callbacks){if(!a&&!b&&!c)return delete this._callbacks,this;for(a=a?a.split(p):f.keys(e);d=a.shift();)if(h=e[d],delete e[d],h&&(b||c))for(g=h.tail;(h=h.next)!==g;)if(j=h.callback,q=h.context,b&&j!==b||c&&q!==c)this.on(d,j,q);return this}},trigger:function(a){var b,c,d,e,f,g;if(!(d=this._callbacks))return this;f=d.all;a=a.split(p);for(g= -z.call(arguments,1);b=a.shift();){if(c=d[b])for(e=c.tail;(c=c.next)!==e;)c.callback.apply(c.context||this,g);if(c=f){e=c.tail;for(b=[b].concat(g);(c=c.next)!==e;)c.callback.apply(c.context||this,b)}}return this}};k.bind=k.on;k.unbind=k.off;var o=g.Model=function(a,b){var c;a||(a={});b&&b.parse&&(a=this.parse(a));if(c=n(this,"defaults"))a=f.extend({},c,a);b&&b.collection&&(this.collection=b.collection);this.attributes={};this._escapedAttributes={};this.cid=f.uniqueId("c");this.changed={};this._silent= -{};this._pending={};this.set(a,{silent:!0});this.changed={};this._silent={};this._pending={};this._previousAttributes=f.clone(this.attributes);this.initialize.apply(this,arguments)};f.extend(o.prototype,k,{changed:null,_silent:null,_pending:null,idAttribute:"id",initialize:function(){},toJSON:function(){return f.clone(this.attributes)},get:function(a){return this.attributes[a]},escape:function(a){var b;if(b=this._escapedAttributes[a])return b;b=this.get(a);return this._escapedAttributes[a]=f.escape(null== -b?"":""+b)},has:function(a){return null!=this.get(a)},set:function(a,b,c){var d,e;f.isObject(a)||null==a?(d=a,c=b):(d={},d[a]=b);c||(c={});if(!d)return this;d instanceof o&&(d=d.attributes);if(c.unset)for(e in d)d[e]=void 0;if(!this._validate(d,c))return!1;this.idAttribute in d&&(this.id=d[this.idAttribute]);var b=c.changes={},h=this.attributes,g=this._escapedAttributes,j=this._previousAttributes||{};for(e in d){a=d[e];if(!f.isEqual(h[e],a)||c.unset&&f.has(h,e))delete g[e],(c.silent?this._silent: -b)[e]=!0;c.unset?delete h[e]:h[e]=a;!f.isEqual(j[e],a)||f.has(h,e)!=f.has(j,e)?(this.changed[e]=a,c.silent||(this._pending[e]=!0)):(delete this.changed[e],delete this._pending[e])}c.silent||this.change(c);return this},unset:function(a,b){(b||(b={})).unset=!0;return this.set(a,null,b)},clear:function(a){(a||(a={})).unset=!0;return this.set(f.clone(this.attributes),a)},fetch:function(a){var a=a?f.clone(a):{},b=this,c=a.success;a.success=function(d,e,f){if(!b.set(b.parse(d,f),a))return!1;c&&c(b,d)}; -a.error=g.wrapError(a.error,b,a);return(this.sync||g.sync).call(this,"read",this,a)},save:function(a,b,c){var d,e;f.isObject(a)||null==a?(d=a,c=b):(d={},d[a]=b);c=c?f.clone(c):{};if(c.wait){if(!this._validate(d,c))return!1;e=f.clone(this.attributes)}a=f.extend({},c,{silent:!0});if(d&&!this.set(d,c.wait?a:c))return!1;var h=this,i=c.success;c.success=function(a,b,e){b=h.parse(a,e);if(c.wait){delete c.wait;b=f.extend(d||{},b)}if(!h.set(b,c))return false;i?i(h,a):h.trigger("sync",h,a,c)};c.error=g.wrapError(c.error, -h,c);b=this.isNew()?"create":"update";b=(this.sync||g.sync).call(this,b,this,c);c.wait&&this.set(e,a);return b},destroy:function(a){var a=a?f.clone(a):{},b=this,c=a.success,d=function(){b.trigger("destroy",b,b.collection,a)};if(this.isNew())return d(),!1;a.success=function(e){a.wait&&d();c?c(b,e):b.trigger("sync",b,e,a)};a.error=g.wrapError(a.error,b,a);var e=(this.sync||g.sync).call(this,"delete",this,a);a.wait||d();return e},url:function(){var a=n(this,"urlRoot")||n(this.collection,"url")||t(); -return this.isNew()?a:a+("/"==a.charAt(a.length-1)?"":"/")+encodeURIComponent(this.id)},parse:function(a){return a},clone:function(){return new this.constructor(this.attributes)},isNew:function(){return null==this.id},change:function(a){a||(a={});var b=this._changing;this._changing=!0;for(var c in this._silent)this._pending[c]=!0;var d=f.extend({},a.changes,this._silent);this._silent={};for(c in d)this.trigger("change:"+c,this,this.get(c),a);if(b)return this;for(;!f.isEmpty(this._pending);){this._pending= -{};this.trigger("change",this,a);for(c in this.changed)!this._pending[c]&&!this._silent[c]&&delete this.changed[c];this._previousAttributes=f.clone(this.attributes)}this._changing=!1;return this},hasChanged:function(a){return!arguments.length?!f.isEmpty(this.changed):f.has(this.changed,a)},changedAttributes:function(a){if(!a)return this.hasChanged()?f.clone(this.changed):!1;var b,c=!1,d=this._previousAttributes,e;for(e in a)if(!f.isEqual(d[e],b=a[e]))(c||(c={}))[e]=b;return c},previous:function(a){return!arguments.length|| -!this._previousAttributes?null:this._previousAttributes[a]},previousAttributes:function(){return f.clone(this._previousAttributes)},isValid:function(){return!this.validate(this.attributes)},_validate:function(a,b){if(b.silent||!this.validate)return!0;var a=f.extend({},this.attributes,a),c=this.validate(a,b);if(!c)return!0;b&&b.error?b.error(this,c,b):this.trigger("error",this,c,b);return!1}});var r=g.Collection=function(a,b){b||(b={});b.model&&(this.model=b.model);b.comparator&&(this.comparator=b.comparator); -this._reset();this.initialize.apply(this,arguments);a&&this.reset(a,{silent:!0,parse:b.parse})};f.extend(r.prototype,k,{model:o,initialize:function(){},toJSON:function(a){return this.map(function(b){return b.toJSON(a)})},add:function(a,b){var c,d,e,g,i,j={},k={},l=[];b||(b={});a=f.isArray(a)?a.slice():[a];c=0;for(d=a.length;c=b))this.iframe=i('