123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150 |
- import celery
- import flask
- import pagure
- import requests
- import urllib.parse
- from .. import activitypub
- from .. import model
- from .. import settings
- from . import broker
- from . import broker_url
- from . import database_session
- log = celery.utils.log.get_task_logger(__name__)
- log.setLevel(settings.LOG_LEVEL)
- @broker.task
- def handle_incoming_activity(project_id, activity):
- """
- A person has received a new Activity in its INBOX. This task is scheduled
- in order to triage the activity and decide how the actor should react to it.
- """
-
- activity = activitypub.Document(activity)
-
- with database_session() as (pagure_db, forgefed_db):
-
- project = pagure_db.query(model.Project) \
- .filter(model.Project.id == project_id) \
- .one_or_none()
-
- log.debug('Project {} now handling Activity {}'.format(project.local_uri, activity['id']))
-
- if not project:
- log.info('Actor id(' + project_id + ') doesn\'t exist. Incoming '
- 'Activity will be ignored.')
- return
-
- if activity['type'] == 'Create':
- """
- The Project has received a Create Activity.
- """
-
- # Dereference the actor
- # actor = activitypub.fetch(activity['actor'])
-
- # Retrieve the object of the Activity
- object = activity.node('object')
-
- if object['type'] == 'Note':
- log.debug('Somebody has Created a new Note.')
-
- # We're only interested in Notes that have a "context" property
- # because that contains the URI of the Ticket or MergeRequest
- if 'context' not in object:
- log.debug('The Note does not contain a "context". Ignoring.')
- return
-
- model.test_or_set_remote_comment(pagure_db, forgefed_db, object['id'])
-
- # DONE
- if activity['type'] == 'Follow':
- """
- Actor has received a Follow Aactivity. Somebody wants to follow this Project?
- """
-
- if activity['object'] != project.local_uri:
- log.info('Actor ' + project.local_uri + ' has received a Follow '
- 'request but the "object" is not this actor. '
- 'Activity will be ignored.')
- return
-
- # Check if the remote actor is already following the local actor
- if forgefed_db.query(
- forgefed_db.query(database.Collection) \
- .filter(database.Collection.uri == project.followers_uri) \
- .filter(database.Collection.item == activity['actor']) \
- .exists()
- ).scalar():
-
- log.info('Actor {} is already following {}. Will ignore Follow request.'.format(project.local_uri, activity['actor']))
- return
-
- # Add the remote object to our followers collection
- forgefed_db.add(database.Collection(uri = project.followers_uri, item = activity['actor']))
-
- # Commit before accepting the Activity because we want the new
- # follower in the Followers collection before sending out the
- # Accept Activity.
- forgefed_db.commit()
-
- # Automatically accept Follow requests.
- project.accept(activity)
-
- if activity['type'] == 'Offer':
- """
- Somebody is offering something to the Project, for example a Ticket.
- """
-
- # Retrieve the object of the Offer
- object = activity.node('object')
-
- if object['type'] == 'Ticket':
- log.debug('Request to create a new Ticket.')
-
- # Make sure we have a local actor representing the remote actor
- actor = model.test_or_set_remote_actor(pagure_db, forgefed_db, activity['actor'])
-
- # Create a new local issue in Pagure
- issue = pagure.lib.query.new_issue(
- pagure_db,
- project,
- object['summary'],
- object['content'],
- actor.username)
-
- # Send an "Accept" request to notify the remote actor that the
- # ticket was created
- issue_uri = '{}/issue/{}'.format(project.local_uri, issue.id)
-
- project.accept(
- activity,
- to=activity['actor'],
- result=issue_uri)
-
- if activity['type'] == 'Resolve' \
- and activity.node('object')['type'] == 'Ticket':
- """
- Somebody has resolved a Ticket.
- """
-
- # Retrieve the Ticket object
- ticket = model.from_local_uri(pagure_db, activity['object']['id'])
-
- if not ticket:
- log.debug('Ticket is not local: {}'.format(activity['object']['id']))
- return
-
- # Create a new object (or retrieve existing one) for the remote user
- actor = model.test_or_set_remote_actor(pagure_db, forgefed_db, activity['actor'])
-
- log.debug('Ticket resolved: {}'.format(activity['object']['id']))
-
- # Edit the pagure Issue object
- pagure.lib.query.edit_issue(
- session=pagure_db,
- issue=ticket,
- user=actor.username,
- status='Closed')
|