Compare commits
21 Commits
Author | SHA1 | Date | |
---|---|---|---|
b969854592 | |||
4e21b41ba6 | |||
db9cb09c68 | |||
d424febfeb | |||
defa5abd18 | |||
26858f01b7 | |||
3bb35d0ab8 | |||
38e4c7c937 | |||
312b0a276a | |||
32361a0e70 | |||
b26402412b | |||
d5f2996704 | |||
d1143bad3e | |||
c64e24d80d | |||
446d31d807 | |||
145d512aa7 | |||
bf63148852 | |||
812d911195 | |||
f0031d44b2 | |||
5660f4b606 | |||
6b6a5310f8 |
25568
package-lock.json
generated
25568
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,5 @@
|
||||
import logging
|
||||
from html.parser import HTMLParser
|
||||
|
||||
from flask import request, current_app
|
||||
from pillar.api.utils import gravatar
|
||||
@ -7,6 +8,15 @@ from pillar.auth import current_user
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class CommentHTMLParser(HTMLParser):
|
||||
def __init__(self):
|
||||
HTMLParser.__init__(self)
|
||||
self.data = []
|
||||
|
||||
def handle_data(self, data):
|
||||
self.data.append(data)
|
||||
|
||||
|
||||
def notification_parse(notification):
|
||||
activities_collection = current_app.data.driver.db['activities']
|
||||
activities_subscriptions_collection = \
|
||||
@ -30,9 +40,14 @@ def notification_parse(notification):
|
||||
object_type = 'comment'
|
||||
object_name = ''
|
||||
object_id = activity['object']
|
||||
context_object_type = node['parent']['node_type']
|
||||
|
||||
# If node_type is 'dillo_post', just call it 'post'
|
||||
node_type = 'post' if context_object_type.endswith('_post') else \
|
||||
context_object_type
|
||||
|
||||
if node['parent']['user'] == current_user.user_id:
|
||||
owner = "your {0}".format(node['parent']['node_type'])
|
||||
owner = f"your {node_type}"
|
||||
else:
|
||||
parent_comment_user = users_collection.find_one(
|
||||
{'_id': node['parent']['user']})
|
||||
@ -40,10 +55,22 @@ def notification_parse(notification):
|
||||
user_name = 'their'
|
||||
else:
|
||||
user_name = "{0}'s".format(parent_comment_user['username'])
|
||||
owner = "{0} {1}".format(user_name, node['parent']['node_type'])
|
||||
|
||||
context_object_type = node['parent']['node_type']
|
||||
context_object_name = owner
|
||||
owner = f"{user_name} {node_type}"
|
||||
|
||||
context_object_name = f"{node['parent']['name'][:50]}..."
|
||||
if context_object_type == 'comment':
|
||||
# Parse the comment content, which might be HTML and extract
|
||||
# some text from it.
|
||||
parser = CommentHTMLParser()
|
||||
# Trim the comment content to 50 chars, the parser will handle it
|
||||
parser.feed(node['properties']['content'][:50])
|
||||
try:
|
||||
comment_content = parser.data[0]
|
||||
except KeyError:
|
||||
comment_content = '...'
|
||||
# Trim the parsed text down to 15 charss
|
||||
context_object_name = f"{comment_content[:50]}..."
|
||||
context_object_id = activity['context_object']
|
||||
if activity['verb'] == 'replied':
|
||||
action = 'replied to'
|
||||
@ -52,13 +79,15 @@ def notification_parse(notification):
|
||||
else:
|
||||
action = activity['verb']
|
||||
|
||||
action = f'{action} {owner}'
|
||||
|
||||
lookup = {
|
||||
'user': current_user.user_id,
|
||||
'context_object_type': 'node',
|
||||
'context_object': context_object_id,
|
||||
}
|
||||
subscription = activities_subscriptions_collection.find_one(lookup)
|
||||
if subscription and subscription['notifications']['web'] == True:
|
||||
if subscription and subscription['notifications']['web'] is True:
|
||||
is_subscribed = True
|
||||
else:
|
||||
is_subscribed = False
|
||||
|
@ -13,7 +13,8 @@ from pillar.web.utils import pretty_date
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
blueprint = Blueprint('nodes_api', __name__)
|
||||
ROLES_FOR_SHARING = ROLES_FOR_COMMENTING = {'subscriber', 'demo'}
|
||||
# TODO(fsiddi) Propose changes to make commenting roles a configuration value.
|
||||
ROLES_FOR_SHARING = ROLES_FOR_COMMENTING = set()
|
||||
|
||||
|
||||
@blueprint.route('/<node_id>/share', methods=['GET', 'POST'])
|
||||
|
@ -69,6 +69,22 @@ def before_replacing_node(item, original):
|
||||
check_permissions('nodes', original, 'PUT')
|
||||
update_file_name(item)
|
||||
|
||||
# XXX Dillo specific feature (for Graphicall)
|
||||
if 'download' in original['properties']:
|
||||
# Check if the file referenced in the download property was updated.
|
||||
# If so, mark the old file as deleted. A cronjob will take care of
|
||||
# removing the actual file based on the _delete status of file docs.
|
||||
original_file_id = original['properties']['download']
|
||||
new_file_id = item['properties']['download']
|
||||
|
||||
if original_file_id == new_file_id:
|
||||
return
|
||||
|
||||
# Mark the original file as _deleted
|
||||
files = current_app.data.driver.db['files']
|
||||
files.update_one({'_id': original_file_id}, {'$set': {'_deleted': True}})
|
||||
log.info('Marking file %s as _deleted' % original_file_id)
|
||||
|
||||
|
||||
def after_replacing_node(item, original):
|
||||
"""Push an update to the Algolia index when a node item is updated. If the
|
||||
|
@ -53,7 +53,7 @@ def find_for_comment(project, node):
|
||||
'_deleted': {'$ne': True}
|
||||
}}, api=api)
|
||||
except ResourceNotFound:
|
||||
log.warning(
|
||||
log.debug(
|
||||
'url_for_node(node_id=%r): Unable to find parent node %r',
|
||||
node['_id'], parent.parent)
|
||||
raise ValueError('Unable to find parent node %r' % parent.parent)
|
||||
|
@ -50,6 +50,7 @@ def iter_node_properties(node_type):
|
||||
@functools.lru_cache(maxsize=1)
|
||||
def tag_choices() -> typing.List[typing.Tuple[str, str]]:
|
||||
"""Return (value, label) tuples for the NODE_TAGS config setting."""
|
||||
#TODO(fsiddi) consider allowing tags based on custom_properties in the project.
|
||||
tags = current_app.config.get('NODE_TAGS') or []
|
||||
return [(tag, tag.title()) for tag in tags] # (value, label) tuples
|
||||
|
||||
@ -70,9 +71,7 @@ def add_form_properties(form_class, node_type):
|
||||
# Recursive call if detects a dict
|
||||
field_type = schema_prop['type']
|
||||
|
||||
if prop_name == 'tags' and field_type == 'list':
|
||||
field = SelectMultipleField(choices=tag_choices())
|
||||
elif field_type == 'dict':
|
||||
if field_type == 'dict':
|
||||
assert prop_name == 'attachments'
|
||||
field = attachments.attachment_form_group_create(schema_prop)
|
||||
elif field_type == 'list':
|
||||
|
@ -72,6 +72,9 @@ def oauth_callback(provider):
|
||||
# Find or create user
|
||||
user_info = {'id': oauth_user.id, 'email': oauth_user.email, 'full_name': ''}
|
||||
db_user = find_user_in_db(user_info, provider=provider)
|
||||
if '_deleted' in db_user and db_user['_deleted'] is True:
|
||||
log.debug('User has been deleted and will not be logge in')
|
||||
return redirect(next_after_login)
|
||||
db_id, status = upsert_user(db_user)
|
||||
|
||||
# TODO(Sybren): If the user doesn't have any badges, but the access token
|
||||
|
@ -137,6 +137,7 @@
|
||||
|
||||
& .nc-text
|
||||
width: 90%
|
||||
white-space: normal
|
||||
|
||||
& .nc-date
|
||||
display: block
|
||||
|
Loading…
x
Reference in New Issue
Block a user