project.py 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. import celery
  2. import flask
  3. import pagure
  4. import requests
  5. import urllib.parse
  6. from .. import activitypub
  7. from .. import model
  8. from .. import settings
  9. from . import broker
  10. from . import broker_url
  11. from . import database_session
  12. log = celery.utils.log.get_task_logger(__name__)
  13. log.setLevel(settings.LOG_LEVEL)
  14. @broker.task
  15. def handle_incoming_activity(project_id, activity):
  16. """
  17. A Tracker has received a new Activity in its INBOX.
  18. """
  19. with database_session() as (pagure_db, forgefed_graph):
  20. project = pagure_db.query(model.Projects) \
  21. .filter(model.Projects.id == project_id) \
  22. .one_or_none()
  23. if not project:
  24. log.info('Actor id(' + project_id + ') doesn\'t exist. Incoming '
  25. 'Activity will be ignored.')
  26. return
  27. if activity['type'] == 'Create':
  28. """
  29. The Project has received a Create Activity.
  30. """
  31. # Dereference the actor
  32. actor = activitypub.fetch(activity['actor'])
  33. # Retrieve the object of the Activity
  34. object = forgefed_graph.get_json_node(activity['object'])
  35. if object['type'] == 'Note':
  36. log.debug('Somebody has Created a new Note.')
  37. # We're only interested in Notes that have a "context" property
  38. # because that contains the URI of the Ticket or MergeRequest
  39. if 'context' not in object:
  40. log.debug('The Note does not contain a "context". Ignoring.')
  41. return
  42. model.test_or_set_remote_comment(pagure_db, forgefed_graph, activity['object'])
  43. if activity['type'] == 'Follow':
  44. """
  45. Somebody wants to follow this Project.
  46. """
  47. if activity['object'] != project.local_uri:
  48. log.info('Actor ' + project.local_uri + ' has received a Follow '
  49. 'request but the "object" doesn\'t match. '
  50. 'Activity will be ignored.')
  51. return
  52. if forgefed_graph.collection_contains(project.followers_uri,
  53. activity['actor']):
  54. log.info('Actor ' + project.local_uri + ' is already following '
  55. + activity['actor'] + '. Will ignore Follow request.')
  56. return
  57. # Add the remote object to our followers collection
  58. forgefed_graph.add_collection_item(project.followers_uri, activity['actor'])
  59. # Commit before accepting the Activity because we want the new
  60. # follower in the Followers collection before sending out the
  61. # Accept Activity.
  62. forgefed_graph.commit()
  63. # Automatically accept Follow requests.
  64. project.accept(activity['id'])
  65. if activity['type'] == 'Offer':
  66. """
  67. Somebody is offering something to the Project, for example a Ticket.
  68. """
  69. # Retrieve the object of the Offer
  70. object = forgefed_graph.get_json_node(activity['object'])
  71. if object['type'] == 'Ticket':
  72. log.debug('Request to create a new Ticket.')
  73. actor = model.test_or_set_remote_actor(pagure_db, forgefed_graph, activity['actor'])
  74. # Create a new local issue in Pagure
  75. issue = pagure.lib.query.new_issue(
  76. pagure_db,
  77. project,
  78. object['summary'],
  79. object['content'],
  80. actor.username)
  81. # Send an "Accept" request to notify the remote actor that the
  82. # ticket was created
  83. issue_uri = '{}/issue/{}'.format(project.local_uri, issue.id)
  84. project.accept(
  85. activity['id'],
  86. to=activity['actor'],
  87. result=issue_uri)
  88. if activity['type'] == 'Update':
  89. """
  90. Somebody has sent us an Update Activity.
  91. """
  92. # Retrieve the object of the Offer
  93. object = forgefed_graph.get_json_node(activity['object'])
  94. if object['type'] == 'Ticket':
  95. log.debug('Request to create a new Ticket.')
  96. actor = model.test_or_set_remote_actor(pagure_db, forgefed_graph, activity['actor'])
  97. # Create a new local issue in Pagure
  98. issue = pagure.lib.query.new_issue(
  99. pagure_db,
  100. project,
  101. object['summary'],
  102. object['content'],
  103. actor.username)
  104. # Send an "Accept" request to notify the remote actor that the
  105. # ticket was created
  106. issue_uri = '{}/issue/{}'.format(project.local_uri, issue.id)
  107. project.accept(
  108. activity['id'],
  109. to=activity['actor'],
  110. result=issue_uri)