diff --git a/src/main/javascript/list.js b/src/main/javascript/list.js
deleted file mode 100644
index 61c3b81..0000000
--- a/src/main/javascript/list.js
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright 2016-2017 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License 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.
- */
-
-var Vue = require('vue');
-var CommentService = require('./services/comment-service.js');
-var updateCommentInList = require('./utils/update-comment-in-list.js');
-var removeCommentFromList = require('./utils/remove-comment-from-list.js');
-var events = require('./utils/events.js');
-
-var template = require('./list.html');
-
-var userHasScrolled = false;
-
-if (document.getElementById('platon-comment-thread') !== null) {
-
- new Vue({
- el: '#platon-comment-thread',
- render: template.render,
- staticRenderFns: template.staticRenderFns,
-
- data: {
- loading: true,
- comments: []
- },
-
- components: {
- 'platon-comment': require('./components/comment'),
- 'platon-comment-form': require('./components/comment-form')
- },
-
- methods: {
- commentPosted: function (newComment) {
- this.comments.push(newComment);
- events.bus.$emit(events.types.clearForm);
- },
- commentEdited: function (updatedComment) {
- updateCommentInList(this.comments, updatedComment);
- },
- commentDeleted: function (commentToRemove) {
- removeCommentFromList(this.comments, commentToRemove);
- }
- },
-
- created: function () {
- var vm = this;
- CommentService.getComments(window.location.pathname)
- .then(function updateModel(commentsListResult) {
- vm.comments = commentsListResult.comments;
- vm.totalCommentCount = commentsListResult.totalCommentCount;
- vm.loading = false;
-
- if (window.location.hash && window.location.hash.indexOf('#platon-comment-') >= 0) {
- Vue.nextTick(function () {
- var commentElem = document.querySelector(window.location.hash);
- if (commentElem != null && !userHasScrolled) {
- commentElem.scrollIntoView(true);
- }
- });
- }
- })
- .catch(function displayError(reason) {
- alert(reason);
- });
- }
- });
-
- window.addEventListener('scroll', scrollListener);
-}
-
-function scrollListener() {
- userHasScrolled = true;
- window.removeEventListener('scroll', scrollListener);
-}
diff --git a/src/main/javascript/platon.css b/src/main/javascript/platon.css
deleted file mode 100644
index b3be662..0000000
--- a/src/main/javascript/platon.css
+++ /dev/null
@@ -1,87 +0,0 @@
-.platon-comments {
- max-width: 40rem;
-}
-
-.platon-comment {
- clear: left;
- min-height: 48px;
-}
-
-.platon-comment > * {
- margin-left: 58px;
-}
-
-.platon-comment > .platon-comment {
- border-left: 1px solid #ccc;
- padding-left: 10px;
-}
-
-.platon-comment > .platon-avatar {
- float: left;
- margin: 0 10px 10px 0;
- width: 48px;
-}
-
-.platon-avatar img {
- width: 48px;
- height: 48px;
-}
-
-.platon-comment + .platon-comment, .platon-actions + .platon-comment, .platon-actions + .platon-form {
- margin-top: 1rem;
-}
-
-.platon-author {
- font-weight: bold;
-}
-
-.platon-text p {
- margin: 0.5rem 0;
-}
-
-.platon-meta, .platon-actions {
- font-size: 0.8rem;
-}
-
-.platon-meta {
- margin-bottom: 0.5rem;
-}
-
-.platon-actions {
- margin-top: 0.5rem;
-}
-
-.platon-form {
- clear: left;
-}
-
-.platon-form input {
- margin-bottom: 0.5rem;
-}
-
-.platon-form-text {
- display: block;
- width: 100%;
- max-width: 100%;
- min-height: 7.5rem;
- line-height: 1.5;
-}
-
-.platon-form-preview {
- border: 1px solid #ddd;
- overflow-y: auto;
- box-sizing: border-box;
- padding: 5px;
-}
-
-.platon-comment > div.platon-text {
- padding-right: -1px;
-}
-
-.platon-form-preview > * {
- margin-top: 0;
-}
-
-.platon-form-preview > *:last-child {
- margin-bottom: 0;
-}
diff --git a/src/main/javascript/platon.js b/src/main/javascript/platon.js
deleted file mode 100644
index ad3d968..0000000
--- a/src/main/javascript/platon.js
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright 2016-2017 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License 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.
- */
-
-require('./platon.css');
-
-var Vue = require('vue');
-Vue.use(require('vue-resource'));
-
-require('./list.js');
-require('./counts.js');
diff --git a/src/main/javascript/services/comment-service.js b/src/main/javascript/services/comment-service.js
deleted file mode 100644
index 15bb62b..0000000
--- a/src/main/javascript/services/comment-service.js
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright 2016-2017 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License 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.
- */
-
-var Vue = require('vue');
-
-module.exports = {
- getComments: function getComments(threadUrl) {
- return Vue.http.get('/api/comments', {
- params: {
- threadUrl: threadUrl
- }
- }).then(function handleSuccess(response) {
- return response.json();
- }, function handleError(response) {
- if (response.status === 404) {
- return Promise.resolve([]);
- } else {
- return Promise.reject(response);
- }
- });
- },
-
- postComment: function postComment(threadUrl, threadTitle, comment) {
- return Vue.http.post('/api/comments', comment, {
- params: {
- threadUrl: threadUrl,
- threadTitle: threadTitle
- }
- }).then(function handleSuccess(response) {
- if (response.status === 201) {
- var commentSignature = response.headers.get('X-Signature');
- return response.json().then(function (newComment) {
- storeSignature(newComment, commentSignature);
- return Promise.resolve(newComment);
- });
- }
- });
- },
-
- updateComment: function getCommentSignature(comment) {
- return Vue.http.put('/api/comments/' + comment.id, comment, {
- headers: {
- 'X-Signature': getSignature(comment)
- }
- });
- },
-
- deleteComment: function deleteComment(comment) {
- return Vue.http.delete('/api/comments/' + comment.id, {
- headers: {
- 'X-Signature': getSignature(comment)
- }
- });
- },
-
- canEditComment: function canEditComment(comment) {
- return !hasSignatureExpired(getSignature(comment));
- },
-
- canDeleteComment: function canDeleteComment(comment) {
- return !hasSignatureExpired(getSignature(comment));
- },
-
- countComments: function countComments(threadUrls) {
- return Vue.http.get('/api/comment-counts{?threadUrl*}', {
- params: {
- threadUrl: threadUrls
- }
- }).then(function handleSuccess(response) {
- return response.json().then(function (json) {
- return Promise.resolve(json.commentCounts);
- });
- });
- }
-};
-
-function storeSignature(comment, signature) {
- localStorage.setItem(getSignatureKey(comment), signature);
-}
-
-function getSignature(comment) {
- return localStorage.getItem(getSignatureKey(comment));
-}
-
-function getSignatureKey(comment) {
- return 'platon-comment-' + comment.id;
-}
-
-function hasSignatureExpired(signature) {
- if (!signature) {
- return true;
- }
-
- var signatureComponents = signature.split('|');
-
- if (signatureComponents.length == 3) {
- var expirationDate = Date.parse(signatureComponents[1]);
- var now = Date.now();
-
- return now > expirationDate;
- }
-
- return true;
-}
diff --git a/src/main/javascript/services/text-service.js b/src/main/javascript/services/text-service.js
deleted file mode 100644
index 140d0f6..0000000
--- a/src/main/javascript/services/text-service.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright 2016-2017 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License 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.
- */
-
-var toMarkdown = require('to-markdown');
-var toMarkdownOptions = {
- gfm: true
-};
-
-var marked = require('marked');
-marked.setOptions({
- gfm: true,
- tables: false,
- breaks: false,
- sanitize: false,
- smartLists: true,
- smartypants: true
-});
-
-module.exports = {
- markdownToHtml: marked,
- htmlToMarkdown: function (html) {
- return toMarkdown(html, toMarkdownOptions);
- }
-};
diff --git a/src/main/javascript/services/user-info-service.js b/src/main/javascript/services/user-info-service.js
deleted file mode 100644
index 5990b79..0000000
--- a/src/main/javascript/services/user-info-service.js
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright 2016-2017 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License 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.
- */
-
-var infoKey = 'platon-user-info';
-var rememberUserKey = 'platon-remember-user-key';
-
-module.exports = {
- getUserInfo: function getUserInfo() {
- var userInfo = localStorage.getItem(infoKey);
- if (userInfo === null) {
- return {};
- } else {
- return JSON.parse(userInfo)
- }
- },
- storeUserInfo: function storeUserInfo(userInfo) {
- localStorage.setItem(infoKey, JSON.stringify(userInfo));
- localStorage.setItem(rememberUserKey, true);
- },
- removeUserInfo: function removeUserInfo() {
- localStorage.removeItem(infoKey);
- localStorage.setItem(rememberUserKey, false);
- },
- getRememberUser: function getRememberUser() {
- var rememberUser = localStorage.getItem(rememberUserKey);
- return rememberUser === null || rememberUser === 'true';
- }
-};
diff --git a/src/main/javascript/utils/events.js b/src/main/javascript/utils/events.js
deleted file mode 100644
index acc5e47..0000000
--- a/src/main/javascript/utils/events.js
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright 2016-2017 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License 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.
- */
-
-var Vue = require('vue');
-
-module.exports = {
- bus: new Vue(),
- types: {
- clearForm: 'clear-form'
- }
-};
diff --git a/src/main/javascript/utils/find-by-id.js b/src/main/javascript/utils/find-by-id.js
deleted file mode 100644
index 0057716..0000000
--- a/src/main/javascript/utils/find-by-id.js
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-/*
- * Copyright 2016-2017 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License 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.
- */
-
-module.exports = function findById(array, id) {
-
- for (var i = 0; i < array.length; i++) {
- var element = array[i];
- if (element.id === id) {
- return i;
- }
- }
-
- return false;
-};
diff --git a/src/main/javascript/utils/find-thread-url-elements.js b/src/main/javascript/utils/find-thread-url-elements.js
deleted file mode 100644
index 5900357..0000000
--- a/src/main/javascript/utils/find-thread-url-elements.js
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright 2016-2017 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License 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.
- */
-
-module.exports = function findGroupedPlatonThreadUrlElements() {
-
- var groupedElements = {};
-
- function addThreadUrlAndElement(threadUrl, elem) {
- if (!(threadUrl in groupedElements)) {
- groupedElements[threadUrl] = [elem];
- } else if (groupedElements[threadUrl].indexOf(threadUrl) < 0) {
- groupedElements[threadUrl].push(elem);
- }
- }
-
- var linksToCommentThreads = document.querySelectorAll('a[href$="#platon-comment-thread"]');
-
- Array.prototype.forEach.call(linksToCommentThreads, function (linkElem) {
- addThreadUrlAndElement(linkElem.pathname, linkElem);
- });
-
- var elemsWithThreadIds = document.querySelectorAll('*[data-platon-thread-url]');
-
- Array.prototype.forEach.call(elemsWithThreadIds, function (elem) {
- addThreadUrlAndElement(elem.getAttribute('data-platon-thread-url'), elem);
- });
-
- return groupedElements;
-};
diff --git a/src/main/javascript/utils/remove-comment-from-list.js b/src/main/javascript/utils/remove-comment-from-list.js
deleted file mode 100644
index d34f049..0000000
--- a/src/main/javascript/utils/remove-comment-from-list.js
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright 2016-2017 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License 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.
- */
-
-var Vue = require('vue');
-var findById = require('./find-by-id.js');
-
-module.exports = function removeCommentFromList(list, comment) {
-
- var index = findById(list, comment.id);
-
- if (index !== false) {
- var originalReplies = list[index].replies;
-
- Vue.set(list, index, {
- id: comment.id,
- parentId: comment.parentId,
- creationDate: comment.creationDate,
- lastModificationDate: comment.lastModificationDate,
- replies: originalReplies,
- status: 'DELETED'
- });
- }
-};
diff --git a/src/main/javascript/utils/update-comment-in-list.js b/src/main/javascript/utils/update-comment-in-list.js
deleted file mode 100644
index 5cf152f..0000000
--- a/src/main/javascript/utils/update-comment-in-list.js
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright 2016-2017 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License 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.
- */
-
-var Vue = require('vue');
-var findById = require('./find-by-id.js');
-
-module.exports = function updateCommentInList(list, comment) {
-
- var index = findById(list, comment.id);
-
- if (index !== false) {
- comment.lastModificationDate = new Date().toISOString();
- Vue.set(list, index, comment);
- }
-};
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
new file mode 100644
index 0000000..d6fdabd
--- /dev/null
+++ b/src/main/resources/application.yml
@@ -0,0 +1,33 @@
+spring.datasource:
+ url: jdbc:postgresql://localhost:5432/platon
+ username: postgres
+ password: postgres
+spring.jooq.sql-dialect: postgres
+
+server:
+ compression:
+ enabled: true
+
+management:
+ endpoint:
+ prometheus:
+ enabled: true
+ server:
+ port: 9090
+ endpoints:
+ web:
+ exposure:
+ include:
+ - info
+ - health
+ - prometheus
+
+spring.freemarker.settings:
+ incompatible_improvements: 2.3.28
+ api_builtin_enabled: true
+
+platon:
+ public-self-url: https://comments.example.com/
+ feed-reader:
+ import-rules: []
+ # - feed-url: https://example.org/blog.atom
diff --git a/src/main/resources/config/application.properties b/src/main/resources/config/application.properties
deleted file mode 100644
index 099a848..0000000
--- a/src/main/resources/config/application.properties
+++ /dev/null
@@ -1,11 +0,0 @@
-# database
-spring.datasource.url = jdbc:h2:file:./platon;AUTO_SERVER=TRUE
-spring.datasource.username = sa
-spring.jooq.sql-dialect = H2
-
-# input sanitization
-platon.input.html_elements = h1, h2, h3, h4, h5, h6,\
- br, p, hr, div, span,\
- a, img, em, strong,\
- ol, ul, li,\
- blockquote, code, pre
diff --git a/src/main/resources/db/migration/V0.1.0__initial_schema.sql b/src/main/resources/db/migration/V0.1.0__initial_schema.sql
deleted file mode 100644
index 4f38767..0000000
--- a/src/main/resources/db/migration/V0.1.0__initial_schema.sql
+++ /dev/null
@@ -1,36 +0,0 @@
--- tables
-CREATE TABLE threads (
- id BIGINT PRIMARY KEY AUTO_INCREMENT,
- url VARCHAR(256) NOT NULL,
- title VARCHAR(512) NULL
-);
-
-CREATE TABLE comments (
- id BIGINT PRIMARY KEY AUTO_INCREMENT,
- thread_id BIGINT NOT NULL,
- parent_id BIGINT NULL,
- creation_date TIMESTAMP NOT NULL,
- last_modification_date TIMESTAMP NOT NULL,
- status VARCHAR(32) NOT NULL,
- text TEXT NOT NULL,
- author VARCHAR(128) NULL,
- email_hash CHAR(32) NULL,
- url VARCHAR(256) NULL,
- FOREIGN KEY (thread_id) REFERENCES threads (id),
- FOREIGN KEY (parent_id) REFERENCES comments (id)
-);
-
--- indexes
-CREATE INDEX thread_id_idx
- ON threads (id);
-CREATE INDEX thread_url_idx
- ON threads (url);
-
-CREATE INDEX comment_id_idx
- ON comments (id);
-CREATE INDEX comment_thread_id_idx
- ON comments (thread_id);
-CREATE INDEX comment_creation_date_idx
- ON comments (creation_date);
-CREATE INDEX comment_status_idx
- ON comments (status);
diff --git a/src/main/resources/db/migration/V0.2.0__persistent_secret_key.sql b/src/main/resources/db/migration/V0.2.0__persistent_secret_key.sql
deleted file mode 100644
index d58124d..0000000
--- a/src/main/resources/db/migration/V0.2.0__persistent_secret_key.sql
+++ /dev/null
@@ -1,4 +0,0 @@
-CREATE TABLE properties (
- key VARCHAR(32) PRIMARY KEY,
- value VARCHAR(256) NOT NULL
-);
diff --git a/src/main/resources/db/migration/V0.2.1__singular_table_names.sql b/src/main/resources/db/migration/V0.2.1__singular_table_names.sql
deleted file mode 100644
index d5e519b..0000000
--- a/src/main/resources/db/migration/V0.2.1__singular_table_names.sql
+++ /dev/null
@@ -1,3 +0,0 @@
-ALTER TABLE comments RENAME TO comment;
-ALTER TABLE threads RENAME TO comment_thread;
-ALTER TABLE properties RENAME TO property;
diff --git a/src/main/resources/db/migration/V0.2.2018.06.11__initial_schema.sql b/src/main/resources/db/migration/V0.2.2018.06.11__initial_schema.sql
new file mode 100644
index 0000000..aa2a801
--- /dev/null
+++ b/src/main/resources/db/migration/V0.2.2018.06.11__initial_schema.sql
@@ -0,0 +1,37 @@
+-- tables
+CREATE TABLE comment_thread (
+ id BIGSERIAL PRIMARY KEY,
+ url VARCHAR(256) UNIQUE NOT NULL,
+ title VARCHAR(512) NULL
+);
+
+CREATE TABLE comment (
+ id BIGSERIAL PRIMARY KEY,
+ thread_id BIGINT NOT NULL,
+ parent_id BIGINT NULL,
+ creation_date TIMESTAMP NOT NULL,
+ last_modification_date TIMESTAMP NOT NULL,
+ status VARCHAR(32) NOT NULL,
+ text_source TEXT NOT NULL,
+ text_html TEXT NOT NULL,
+ text_reference VARCHAR(80) NOT NULL,
+ author VARCHAR(128) NOT NULL,
+ url VARCHAR(256) NULL,
+ author_hash BYTEA NOT NULL,
+ FOREIGN KEY (thread_id) REFERENCES comment_thread (id),
+ FOREIGN KEY (parent_id) REFERENCES comment (id)
+);
+
+CREATE TABLE property (
+ key VARCHAR(32) PRIMARY KEY,
+ value VARCHAR(256) NOT NULL
+);
+
+-- indexes
+CREATE INDEX idx__comment__thread_id
+ ON comment (thread_id);
+CREATE INDEX idx__comment__creation_date
+ ON comment (creation_date);
+CREATE INDEX idx__comment__status
+ ON comment (status);
+
diff --git a/src/main/resources/static/comment-count.html b/src/main/resources/static/comment-count.html
deleted file mode 100644
index 817191b..0000000
--- a/src/main/resources/static/comment-count.html
+++ /dev/null
@@ -1,8 +0,0 @@
-Comment Count Test
-
There are [loading...] on thread
- comment-count-thread-1.html.
[deleted]
-