diff --git a/client/html/pool_input.tpl b/client/html/pool_input.tpl
index 0c2a3fd9..483e7905 100644
--- a/client/html/pool_input.tpl
+++ b/client/html/pool_input.tpl
@@ -1,7 +1,6 @@
-
diff --git a/client/html/pool_summary.tpl b/client/html/pool_summary.tpl
index 8f4e27d0..2b70d270 100644
--- a/client/html/pool_summary.tpl
+++ b/client/html/pool_summary.tpl
@@ -6,12 +6,12 @@
- Aliases:
- <% for (let name of ctx.pool.names.slice(1)) { %>- <%= ctx.makePoolLink(ctx.pool.id, false, false, ctx.pool, name) %>
<% } %>
+ Aliases:
+
+ <% for (let name of ctx.pool.names.slice(1)) { %>
+ - <%= ctx.makePoolLink(ctx.pool.id, false, false, ctx.pool, name) %>
+ <% } %>
+
diff --git a/client/js/controllers/pool_controller.js b/client/js/controllers/pool_controller.js
index e243cd89..22920f09 100644
--- a/client/js/controllers/pool_controller.js
+++ b/client/js/controllers/pool_controller.js
@@ -54,8 +54,7 @@ class PoolController {
this._view.addEventListener('submit', e => this._evtUpdate(e));
this._view.addEventListener('merge', e => this._evtMerge(e));
this._view.addEventListener('delete', e => this._evtDelete(e));
- },
- error => {
+ }, error => {
this._view = new EmptyView();
this._view.showError(error.message);
});
@@ -68,9 +67,7 @@ class PoolController {
_evtSaved(e, section) {
misc.disableExitConfirmation();
if (this._name !== e.detail.pool.names[0]) {
- router.replace(
- uri.formatClientLink('pool', e.detail.pool.id, section),
- null, false);
+ router.replace(uri.formatClientLink('pool', e.detail.pool.id, section), null, false);
}
}
@@ -87,9 +84,9 @@ class PoolController {
e.detail.pool.description = e.detail.description;
}
if (e.detail.posts !== undefined) {
- e.detail.pool.posts.clear()
+ e.detail.pool.posts.clear();
for (let post_id of e.detail.posts) {
- e.detail.pool.posts.add(Post.fromResponse({ id: parseInt(post_id) }))
+ e.detail.pool.posts.add(Post.fromResponse({ id: parseInt(post_id) }));
}
}
e.detail.pool.save().then(() => {
diff --git a/client/js/controllers/pool_create_controller.js b/client/js/controllers/pool_create_controller.js
index ef6dded2..0684693e 100644
--- a/client/js/controllers/pool_create_controller.js
+++ b/client/js/controllers/pool_create_controller.js
@@ -16,8 +16,7 @@ class PoolCreateController {
return;
}
- PoolCategoryList.get()
- .then(poolCategoriesResponse => {
+ PoolCategoryList.get().then(poolCategoriesResponse => {
const categories = {};
for (let category of poolCategoriesResponse.results) {
categories[category.name] = category.name;
diff --git a/client/js/controls/pool_input_control.js b/client/js/controls/pool_input_control.js
index a8272066..95dfc5cb 100644
--- a/client/js/controls/pool_input_control.js
+++ b/client/js/controls/pool_input_control.js
@@ -81,105 +81,105 @@ class PoolInputControl extends events.EventTarget {
return Promise.resolve();
}
- this.pools.add(pool, false)
+ this.pools.add(pool, false)
- const listItemNode = this._createListItemNode(pool);
- if (!pool.category) {
- listItemNode.classList.add('new');
- }
- this._poolListNode.prependChild(listItemNode);
- _fadeOutListItemNodeStatus(listItemNode);
+ const listItemNode = this._createListItemNode(pool);
+ if (!pool.category) {
+ listItemNode.classList.add('new');
+ }
+ this._poolListNode.prependChild(listItemNode);
+ _fadeOutListItemNodeStatus(listItemNode);
- this.dispatchEvent(new CustomEvent('add', {
- detail: {pool: pool, source: source},
- }));
- this.dispatchEvent(new CustomEvent('change'));
+ this.dispatchEvent(new CustomEvent('add', {
+ detail: {pool: pool, source: source},
+ }));
+ this.dispatchEvent(new CustomEvent('change'));
- return Promise.resolve();
+ return Promise.resolve();
}
- deletePool(pool) {
- if (!this.pools.hasPoolId(pool.id)) {
- return;
+ deletePool(pool) {
+ if (!this.pools.hasPoolId(pool.id)) {
+ return;
+ }
+ this.pools.removeById(pool.id);
+ this._hideAutoComplete();
+
+ this._deleteListItemNode(pool);
+
+ this.dispatchEvent(new CustomEvent('remove', {
+ detail: {pool: pool},
+ }));
+ this.dispatchEvent(new CustomEvent('change'));
}
- this.pools.removeById(pool.id);
- this._hideAutoComplete();
- this._deleteListItemNode(pool);
+ _createListItemNode(pool) {
+ const className = pool.category ?
+ misc.makeCssName(pool.category, 'pool') :
+ null;
- this.dispatchEvent(new CustomEvent('remove', {
- detail: {pool: pool},
- }));
- this.dispatchEvent(new CustomEvent('change'));
- }
+ const poolLinkNode = document.createElement('a');
+ if (className) {
+ poolLinkNode.classList.add(className);
+ }
+ poolLinkNode.setAttribute(
+ 'href', uri.formatClientLink('pool', pool.names[0]));
- _createListItemNode(pool) {
- const className = pool.category ?
- misc.makeCssName(pool.category, 'pool') :
- null;
+ const poolIconNode = document.createElement('i');
+ poolIconNode.classList.add('fa');
+ poolIconNode.classList.add('fa-pool');
+ poolLinkNode.appendChild(poolIconNode);
- const poolLinkNode = document.createElement('a');
- if (className) {
- poolLinkNode.classList.add(className);
+ const searchLinkNode = document.createElement('a');
+ if (className) {
+ searchLinkNode.classList.add(className);
+ }
+ searchLinkNode.setAttribute(
+ 'href', uri.formatClientLink(
+ 'posts', {query: "pool:" + pool.id}));
+ searchLinkNode.textContent = pool.names[0] + ' ';
+
+ const usagesNode = document.createElement('span');
+ usagesNode.classList.add('pool-usages');
+ usagesNode.setAttribute('data-pseudo-content', pool.postCount);
+
+ const removalLinkNode = document.createElement('a');
+ removalLinkNode.classList.add('remove-pool');
+ removalLinkNode.setAttribute('href', '');
+ removalLinkNode.setAttribute('data-pseudo-content', '×');
+ removalLinkNode.addEventListener('click', e => {
+ e.preventDefault();
+ this.deletePool(pool);
+ });
+
+ const listItemNode = document.createElement('li');
+ listItemNode.appendChild(removalLinkNode);
+ listItemNode.appendChild(poolLinkNode);
+ listItemNode.appendChild(searchLinkNode);
+ listItemNode.appendChild(usagesNode);
+ for (let name of pool.names) {
+ this._poolToListItemNode.set(name, listItemNode);
+ }
+ return listItemNode;
}
- poolLinkNode.setAttribute(
- 'href', uri.formatClientLink('pool', pool.names[0]));
- const poolIconNode = document.createElement('i');
- poolIconNode.classList.add('fa');
- poolIconNode.classList.add('fa-pool');
- poolLinkNode.appendChild(poolIconNode);
-
- const searchLinkNode = document.createElement('a');
- if (className) {
- searchLinkNode.classList.add(className);
+ _deleteListItemNode(pool) {
+ const listItemNode = this._getListItemNode(pool);
+ if (listItemNode) {
+ listItemNode.parentNode.removeChild(listItemNode);
+ }
+ for (let name of pool.names) {
+ this._poolToListItemNode.delete(name);
+ }
}
- searchLinkNode.setAttribute(
- 'href', uri.formatClientLink(
- 'posts', {query: "pool:" + pool.id}));
- searchLinkNode.textContent = pool.names[0] + ' ';
- const usagesNode = document.createElement('span');
- usagesNode.classList.add('pool-usages');
- usagesNode.setAttribute('data-pseudo-content', pool.postCount);
-
- const removalLinkNode = document.createElement('a');
- removalLinkNode.classList.add('remove-pool');
- removalLinkNode.setAttribute('href', '');
- removalLinkNode.setAttribute('data-pseudo-content', '×');
- removalLinkNode.addEventListener('click', e => {
- e.preventDefault();
- this.deletePool(pool);
- });
-
- const listItemNode = document.createElement('li');
- listItemNode.appendChild(removalLinkNode);
- listItemNode.appendChild(poolLinkNode);
- listItemNode.appendChild(searchLinkNode);
- listItemNode.appendChild(usagesNode);
- for (let name of pool.names) {
- this._poolToListItemNode.set(name, listItemNode);
+ _getListItemNode(pool) {
+ return this._poolToListItemNode.get(pool.names[0]);
}
- return listItemNode;
- }
- _deleteListItemNode(pool) {
- const listItemNode = this._getListItemNode(pool);
- if (listItemNode) {
- listItemNode.parentNode.removeChild(listItemNode);
+ _hideAutoComplete() {
+ this._autoCompleteControl.hide();
}
- for (let name of pool.names) {
- this._poolToListItemNode.delete(name);
- }
- }
-
- _getListItemNode(pool) {
- return this._poolToListItemNode.get(pool.names[0]);
- }
-
- _hideAutoComplete() {
- this._autoCompleteControl.hide();
- }
}
module.exports = PoolInputControl;
diff --git a/client/js/models/pool_category.js b/client/js/models/pool_category.js
index 4cdb68e6..a77302c2 100644
--- a/client/js/models/pool_category.js
+++ b/client/js/models/pool_category.js
@@ -17,7 +17,7 @@ class PoolCategory extends events.EventTarget {
get name() { return this._name; }
get color() { return this._color; }
- get poolCount() { return this._poolCount; }
+ get poolCount() { return this._poolCount; }
get isDefault() { return this._isDefault; }
get isTransient() { return !this._origName; }
diff --git a/server/alembic.ini b/server/alembic.ini
index 98ab83d4..6a4e5ff4 100644
--- a/server/alembic.ini
+++ b/server/alembic.ini
@@ -3,7 +3,6 @@ script_location = szurubooru/migrations
# overriden by szurubooru's config
sqlalchemy.url =
-revision_environment = true
[loggers]
keys = root,sqlalchemy,alembic
diff --git a/server/config.yaml.dist b/server/config.yaml.dist
index baf3a34e..37e877f1 100644
--- a/server/config.yaml.dist
+++ b/server/config.yaml.dist
@@ -4,7 +4,7 @@
# shown in the website title and on the front page
name: szurubooru
# full url to the homepage of this szurubooru site, with no trailing slash
-domain: localhost # example: http://example.com
+domain: # example: http://example.com
# used to salt the users' password hashes and generate filenames for static content
secret: change
@@ -49,9 +49,6 @@ enable_safety: yes
tag_name_regex: ^\S+$
tag_category_name_regex: ^[^\s%+#/]+$
-pool_name_regex: ^\S+$
-pool_category_name_regex: ^[^\s%+#/]+$
-
# don't make these more restrictive unless you want to annoy people; if you do
# customize them, make sure to update the instructions in the registration form
# template as well.
@@ -61,72 +58,72 @@ user_name_regex: '^[a-zA-Z0-9_-]{1,32}$'
default_rank: regular
privileges:
- 'users:create:self': anonymous # Registration permission
- 'users:create:any': administrator
- 'users:list': regular
- 'users:view': regular
- 'users:edit:any:name': moderator
- 'users:edit:any:pass': moderator
- 'users:edit:any:email': moderator
- 'users:edit:any:avatar': moderator
- 'users:edit:any:rank': moderator
- 'users:edit:self:name': regular
- 'users:edit:self:pass': regular
- 'users:edit:self:email': regular
- 'users:edit:self:avatar': regular
- 'users:edit:self:rank': moderator # one can't promote themselves or anyone to upper rank than their own.
- 'users:delete:any': administrator
- 'users:delete:self': regular
+ 'users:create:self': anonymous # Registration permission
+ 'users:create:any': administrator
+ 'users:list': regular
+ 'users:view': regular
+ 'users:edit:any:name': moderator
+ 'users:edit:any:pass': moderator
+ 'users:edit:any:email': moderator
+ 'users:edit:any:avatar': moderator
+ 'users:edit:any:rank': moderator
+ 'users:edit:self:name': regular
+ 'users:edit:self:pass': regular
+ 'users:edit:self:email': regular
+ 'users:edit:self:avatar': regular
+ 'users:edit:self:rank': moderator # one can't promote themselves or anyone to upper rank than their own.
+ 'users:delete:any': administrator
+ 'users:delete:self': regular
- 'user_tokens:list:any': administrator
- 'user_tokens:list:self': regular
- 'user_tokens:create:any': administrator
- 'user_tokens:create:self': regular
- 'user_tokens:edit:any': administrator
- 'user_tokens:edit:self': regular
- 'user_tokens:delete:any': administrator
- 'user_tokens:delete:self': regular
+ 'user_tokens:list:any': administrator
+ 'user_tokens:list:self': regular
+ 'user_tokens:create:any': administrator
+ 'user_tokens:create:self': regular
+ 'user_tokens:edit:any': administrator
+ 'user_tokens:edit:self': regular
+ 'user_tokens:delete:any': administrator
+ 'user_tokens:delete:self': regular
- 'posts:create:anonymous': regular
- 'posts:create:identified': regular
- 'posts:list': anonymous
- 'posts:reverse_search': regular
- 'posts:view': anonymous
- 'posts:view:featured': anonymous
- 'posts:edit:content': power
- 'posts:edit:flags': regular
- 'posts:edit:notes': regular
- 'posts:edit:relations': regular
- 'posts:edit:safety': power
- 'posts:edit:source': regular
- 'posts:edit:tags': regular
- 'posts:edit:thumbnail': power
- 'posts:feature': moderator
- 'posts:delete': moderator
- 'posts:score': regular
- 'posts:merge': moderator
- 'posts:favorite': regular
- 'posts:bulk-edit:tags': power
- 'posts:bulk-edit:safety': power
+ 'posts:create:anonymous': regular
+ 'posts:create:identified': regular
+ 'posts:list': anonymous
+ 'posts:reverse_search': regular
+ 'posts:view': anonymous
+ 'posts:view:featured': anonymous
+ 'posts:edit:content': power
+ 'posts:edit:flags': regular
+ 'posts:edit:notes': regular
+ 'posts:edit:relations': regular
+ 'posts:edit:safety': power
+ 'posts:edit:source': regular
+ 'posts:edit:tags': regular
+ 'posts:edit:thumbnail': power
+ 'posts:feature': moderator
+ 'posts:delete': moderator
+ 'posts:score': regular
+ 'posts:merge': moderator
+ 'posts:favorite': regular
+ 'posts:bulk-edit:tags': power
+ 'posts:bulk-edit:safety': power
- 'tags:create': regular
- 'tags:edit:names': power
- 'tags:edit:category': power
- 'tags:edit:description': power
- 'tags:edit:implications': power
- 'tags:edit:suggestions': power
- 'tags:list': regular
- 'tags:view': anonymous
- 'tags:merge': moderator
- 'tags:delete': moderator
+ 'tags:create': regular
+ 'tags:edit:names': power
+ 'tags:edit:category': power
+ 'tags:edit:description': power
+ 'tags:edit:implications': power
+ 'tags:edit:suggestions': power
+ 'tags:list': regular
+ 'tags:view': anonymous
+ 'tags:merge': moderator
+ 'tags:delete': moderator
- 'tag_categories:create': moderator
- 'tag_categories:edit:name': moderator
- 'tag_categories:edit:color': moderator
- 'tag_categories:list': anonymous
- 'tag_categories:view': anonymous
- 'tag_categories:delete': moderator
- 'tag_categories:set_default': moderator
+ 'tag_categories:create': moderator
+ 'tag_categories:edit:name': moderator
+ 'tag_categories:edit:color': moderator
+ 'tag_categories:list': anonymous
+ 'tag_categories:view': anonymous
+ 'tag_categories:delete': moderator
+ 'tag_categories:set_default': moderator
'pools:create': regular
'pools:edit:names': power
@@ -146,19 +143,19 @@ privileges:
'pool_categories:delete': moderator
'pool_categories:set_default': moderator
- 'comments:create': regular
- 'comments:delete:any': moderator
- 'comments:delete:own': regular
- 'comments:edit:any': moderator
- 'comments:edit:own': regular
- 'comments:list': regular
- 'comments:view': regular
- 'comments:score': regular
+ 'comments:create': regular
+ 'comments:delete:any': moderator
+ 'comments:delete:own': regular
+ 'comments:edit:any': moderator
+ 'comments:edit:own': regular
+ 'comments:list': regular
+ 'comments:view': regular
+ 'comments:score': regular
- 'snapshots:list': power
+ 'snapshots:list': power
- 'uploads:create': regular
- 'uploads:use_downloader': power
+ 'uploads:create': regular
+ 'uploads:use_downloader': power
## ONLY SET THESE IF DEPLOYING OUTSIDE OF DOCKER
#debug: 0 # generate server logs?
diff --git a/server/requirements.txt b/server/requirements.txt
index 8a337f9e..810452e0 100644
--- a/server/requirements.txt
+++ b/server/requirements.txt
@@ -9,4 +9,3 @@ pillow>=4.3.0
pynacl>=1.2.1
pytz>=2018.3
pyRFC3339>=1.0
-youtube_dl>=2020.5.3
diff --git a/server/szurubooru/db.py b/server/szurubooru/db.py
index bd300420..561b7484 100644
--- a/server/szurubooru/db.py
+++ b/server/szurubooru/db.py
@@ -34,22 +34,3 @@ def _bump_query_count() -> None:
sa.event.listen(_engine, 'after_execute', lambda *args: _bump_query_count())
-
-import time
-import logging
-
-logger = logging.getLogger("myapp.sqltime")
-logger.setLevel(logging.INFO)
-
-def before_cursor_execute(conn, cursor, statement,
- parameters, context, executemany):
- conn.info.setdefault('query_start_time', []).append(time.time())
- logger.info("Start Query: %s" % statement)
-
-def after_cursor_execute(conn, cursor, statement,
- parameters, context, executemany):
- total = time.time() - conn.info['query_start_time'].pop(-1)
- logger.info("Total Time: %f" % total)
-
-sa.event.listen(_engine, "before_cursor_execute", before_cursor_execute)
-sa.event.listen(_engine, "after_cursor_execute", after_cursor_execute)
diff --git a/server/szurubooru/func/pool_categories.py b/server/szurubooru/func/pool_categories.py
index eca934a9..83305de0 100644
--- a/server/szurubooru/func/pool_categories.py
+++ b/server/szurubooru/func/pool_categories.py
@@ -195,5 +195,5 @@ def delete_category(category: model.PoolCategory) -> None:
if (category.pool_count or 0) > 0:
raise PoolCategoryIsInUseError(
'Pool category has some usages and cannot be deleted. ' +
- 'Please remove this category from relevant pools first..')
+ 'Please remove this category from relevant pools first.')
db.session.delete(category)
diff --git a/server/szurubooru/func/pools.py b/server/szurubooru/func/pools.py
index 1d279296..90dede22 100644
--- a/server/szurubooru/func/pools.py
+++ b/server/szurubooru/func/pools.py
@@ -77,6 +77,7 @@ def _duplicates(a: List[int]) -> List[int]:
dupes.append(x)
return dupes
+
def sort_pools(pools: List[model.Pool]) -> List[model.Pool]:
default_category_name = pool_categories.get_default_category_name()
return sorted(
@@ -131,8 +132,7 @@ class PoolSerializer(serialization.BaseSerializer):
def serialize_posts(self) -> Any:
return [post for post in
- [posts.serialize_micro_post(rel, None)
- for rel in self.pool.posts]]
+ [posts.serialize_micro_post(rel, None) for rel in self.pool.posts]]
def serialize_pool(
@@ -221,7 +221,7 @@ def merge_pools(source_pool: model.Pool, target_pool: model.Pool) -> None:
if source_pool.pool_id == target_pool.pool_id:
raise InvalidPoolRelationError('Cannot merge pool with itself.')
- def merge_posts(source_pool_id: int, target_pool_id: int) -> None:
+ def merge_pool_posts(source_pool_id: int, target_pool_id: int) -> None:
alias1 = model.PoolPost
alias2 = sa.orm.util.aliased(model.PoolPost)
update_stmt = (
@@ -236,7 +236,7 @@ def merge_pools(source_pool: model.Pool, target_pool: model.Pool) -> None:
update_stmt = update_stmt.values(pool_id=target_pool_id)
db.session.execute(update_stmt)
- merge_posts(source_pool.pool_id, target_pool.pool_id)
+ merge_pool_posts(source_pool.pool_id, target_pool.pool_id)
delete(source_pool)
@@ -304,8 +304,6 @@ def update_pool_posts(pool: model.Pool, post_ids: List[int]) -> None:
assert pool
dupes = _duplicates(post_ids)
if len(dupes) > 0:
- print(str(dupes))
- print(str(post_ids))
dupes = ', '.join(list(str(x) for x in dupes))
raise InvalidPoolDuplicateError('Duplicate post(s) in pool: ' + dupes)
ret = posts.get_posts_by_ids(post_ids)
diff --git a/server/szurubooru/func/posts.py b/server/szurubooru/func/posts.py
index 723a4668..62458d8e 100644
--- a/server/szurubooru/func/posts.py
+++ b/server/szurubooru/func/posts.py
@@ -300,7 +300,7 @@ class PostSerializer(serialization.BaseSerializer):
self.post.comments,
key=lambda comment: comment.creation_time)]
- def serialize_pools(self) -> Any:
+ def serialize_pools(self) -> List[Any]:
return [
pools.serialize_pool(pool)
for pool in sorted(
@@ -343,7 +343,7 @@ def get_post_by_id(post_id: int) -> model.Post:
return post
-def get_posts_by_ids(ids: List[int]) -> List[model.Pool]:
+def get_posts_by_ids(ids: List[int]) -> List[model.Post]:
if len(ids) == 0:
return []
posts = (