89 lines
3.3 KiB
Python
89 lines
3.3 KiB
Python
|
import json
|
||
|
|
||
|
from contextlib import contextmanager
|
||
|
|
||
|
from app import app, notification_queue
|
||
|
from data import model
|
||
|
from auth.auth_context import get_authenticated_user, get_validated_oauth_token
|
||
|
|
||
|
DEFAULT_BATCH_SIZE = 1000
|
||
|
|
||
|
|
||
|
def build_repository_event_data(namespace_name, repo_name, extra_data=None, subpage=None):
|
||
|
""" Builds the basic repository data for an event, including the repository's name, Docker URL
|
||
|
and homepage. If extra_data is specified, it is appended to the dictionary before it is
|
||
|
returned.
|
||
|
"""
|
||
|
repo_string = '%s/%s' % (namespace_name, repo_name)
|
||
|
homepage = '%s://%s/repository/%s' % (app.config['PREFERRED_URL_SCHEME'],
|
||
|
app.config['SERVER_HOSTNAME'], repo_string)
|
||
|
|
||
|
if subpage:
|
||
|
if not subpage.startswith('/'):
|
||
|
subpage = '/' + subpage
|
||
|
|
||
|
homepage = homepage + subpage
|
||
|
|
||
|
event_data = {
|
||
|
'repository': repo_string,
|
||
|
'namespace': namespace_name,
|
||
|
'name': repo_name,
|
||
|
'docker_url': '%s/%s' % (app.config['SERVER_HOSTNAME'], repo_string),
|
||
|
'homepage': homepage,
|
||
|
}
|
||
|
|
||
|
event_data.update(extra_data or {})
|
||
|
return event_data
|
||
|
|
||
|
|
||
|
def build_notification_data(notification, event_data, performer_data=None):
|
||
|
if not performer_data:
|
||
|
performer_data = {}
|
||
|
|
||
|
oauth_token = get_validated_oauth_token()
|
||
|
if oauth_token:
|
||
|
performer_data['oauth_token_id'] = oauth_token.id
|
||
|
performer_data['oauth_token_application_id'] = oauth_token.application.client_id
|
||
|
performer_data['oauth_token_application'] = oauth_token.application.name
|
||
|
|
||
|
performer_user = get_authenticated_user()
|
||
|
if performer_user:
|
||
|
performer_data['entity_id'] = performer_user.id
|
||
|
performer_data['entity_name'] = performer_user.username
|
||
|
|
||
|
return {
|
||
|
'notification_uuid': notification.uuid,
|
||
|
'event_data': event_data,
|
||
|
'performer_data': performer_data,
|
||
|
}
|
||
|
|
||
|
|
||
|
@contextmanager
|
||
|
def notification_batch(batch_size=DEFAULT_BATCH_SIZE):
|
||
|
"""
|
||
|
Context manager implementation which returns a target callable with the same signature
|
||
|
as spawn_notification. When the the context block exits the notifications generated by
|
||
|
the callable will be bulk inserted into the queue with the specified batch size.
|
||
|
"""
|
||
|
with notification_queue.batch_insert(batch_size) as queue_put:
|
||
|
|
||
|
def spawn_notification_batch(repo, event_name, extra_data=None, subpage=None, pathargs=None,
|
||
|
performer_data=None):
|
||
|
event_data = build_repository_event_data(repo.namespace_name, repo.name,
|
||
|
extra_data=extra_data, subpage=subpage)
|
||
|
|
||
|
notifications = model.notification.list_repo_notifications(repo.namespace_name, repo.name,
|
||
|
event_name=event_name)
|
||
|
path = [repo.namespace_name, repo.name, event_name] + (pathargs or [])
|
||
|
for notification in list(notifications):
|
||
|
notification_data = build_notification_data(notification, event_data, performer_data)
|
||
|
queue_put(path, json.dumps(notification_data))
|
||
|
|
||
|
yield spawn_notification_batch
|
||
|
|
||
|
|
||
|
def spawn_notification(repo, event_name, extra_data=None, subpage=None, pathargs=None,
|
||
|
performer_data=None):
|
||
|
with notification_batch(1) as batch_spawn:
|
||
|
batch_spawn(repo, event_name, extra_data, subpage, pathargs, performer_data)
|