Skip to content
This repository has been archived by the owner on May 5, 2021. It is now read-only.

Commit

Permalink
Merge pull request #18 from gvangool/pr7
Browse files Browse the repository at this point in the history
Enhancement to support user agnostic Hook events.

If you want a Hook to be triggered for all users, add '+' to built-in Hooks or pass user_override=False for custom_hook events.
  • Loading branch information
avelis committed Aug 12, 2015
2 parents 50f96ee + 84c7480 commit 4a07157
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 16 deletions.
9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ INSTALLED_APPS = (
HOOK_EVENTS = {
# 'any.event.name': 'App.Model.Action' (created/updated/deleted)
'book.added': 'bookstore.Book.created',
'book.changed': 'bookstore.Book.updated',
'book.changed': 'bookstore.Book.updated+',
'book.removed': 'bookstore.Book.deleted',
# and custom events, no extra meta data needed
'book.read': 'bookstore.Book.read',
Expand All @@ -87,6 +87,9 @@ HOOK_EVENTS = {
class Book(models.Model):
# NOTE: it is important to have a user property
# as we use it to help find and trigger each Hook
# which is specific to users. If you want a Hook to
# be triggered for all users, add '+' to built-in Hooks
# or pass user_override=False for custom_hook events
user = models.ForeignKey('auth.User')
# maybe user is off a related object, so try...
# user = property(lambda self: self.intermediary.user)
Expand Down Expand Up @@ -348,9 +351,9 @@ HOOK_DELIVERER = 'path.to.tasks.deliver_hook_wrapper'
### tasks.py ###

from celery.task import Task
import requests

from django.utils import simplejson as json
import json
import requests


class DeliverHook(Task):
Expand Down
39 changes: 26 additions & 13 deletions rest_hooks/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,23 +30,33 @@ def find_and_fire_hook(event_name, instance, user_override=None):
from django.contrib.auth.models import User
from rest_hooks.models import Hook, HOOK_EVENTS

if user_override:
user = user_override
elif hasattr(instance, 'user'):
user = instance.user
elif isinstance(instance, User):
user = instance
else:
raise Exception(
'{} has no `user` property. REST Hooks needs this.'.format(repr(instance))
)

if not event_name in HOOK_EVENTS.keys():
raise Exception(
'"{}" does not exist in `settings.HOOK_EVENTS`.'.format(event_name)
)

hooks = Hook.objects.filter(user=user, event=event_name)
filters = {'event': event_name}

# Ignore the user if the user_override is False
if user_override is not False:
if user_override:
filters['user'] = user_override
elif hasattr(instance, 'user'):
filters['user'] = instance.user
elif isinstance(instance, User):
filters['user'] = instance
else:
raise Exception(
'{} has no `user` property. REST Hooks needs this.'.format(repr(instance))
)

# NOTE: This is probably up for discussion, but I think, in this
# case, instead of raising an error, we should fire the hook for
# all users/accounts it is subscribed to. That would be a genuine
# usecase rather than erroring because no user is associated with
# this event.

hooks = Hook.objects.filter(**filters)
for hook in hooks:
hook.deliver_hook(instance)

Expand All @@ -65,8 +75,11 @@ def distill_model_event(instance, model, action, user_override=None):
if auto:
# break auto into App.Model, Action
maybe_model, maybe_action = auto.rsplit('.', 1)
if model == maybe_model and action == maybe_action:
maybe_action = maybe_action.rsplit('+', 1)
if model == maybe_model and action == maybe_action[0]:
event_name = maybe_event_name
if len(maybe_action) == 2:
user_override = True

if event_name:
find_and_fire_hook(event_name, instance, user_override=user_override)

0 comments on commit 4a07157

Please sign in to comment.