Skip to content

Commit

Permalink
Merge pull request #177 from jeremycline/namespace-pkgs
Browse files Browse the repository at this point in the history
Update the generic rule for packages to use namespaces
  • Loading branch information
jeremycline committed Apr 10, 2017
2 parents c39a6b8 + 46ac6e2 commit 61507cd
Show file tree
Hide file tree
Showing 18 changed files with 12,527 additions and 42 deletions.
1 change: 1 addition & 0 deletions dev-requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ flake8
html5lib
mock
nose
vcrpy
# Docs requirements
sphinx
sqlalchemy_schemadisplay
57 changes: 23 additions & 34 deletions fmn/rules/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,26 @@ def _get_users_of_group(config, group):
return fmn.rules.utils.get_user_of_group(config, fas, group)


def _user_package_intersection(fasnick, message, config, acls):
"""
Returns true if the user has one of the packages mentioned in the message.
Args:
fasnick (str): The user's FAS name.
message (dict): The fedmsg that might mention packages.
config (dict): The fedmsg configuration dictionary.
acls (list): A list of acls use to determine if the user is related to
the package (e.g. "watch" "commit", etc).
"""
usr_packages = fmn.rules.utils.get_packages_of_user(
config, fasnick, acls)
for namespace, packages in usr_packages.items():
namespaced_msg_packages = fmn.rules.utils.msg2packages(
message, namespace=namespace, **config)
if packages.intersection(namespaced_msg_packages):
return True


@hint(callable=_get_users_of_group)
def fas_group_member_filter(config, message, group=None, *args, **kw):
""" Messages regarding any member of a FAS group
Expand Down Expand Up @@ -82,20 +102,9 @@ def user_package_filter(config, message, fasnick=None, *args, **kw):
This rule includes messages that relate to packages where the
specified user has *either* commit ACLs or the watchcommits flag.
"""

fasnick = kw.get('fasnick', fasnick)
if fasnick:
msg_packages = fmn.rules.utils.msg2packages(message, **config)
if not msg_packages:
# If the message has no packages associated with it, there's no
# way that "one of them" is going to happen to belong to this user,
# so let's not waste our time doing the somewhat expensive call out
# to pkgdb on the next line to check.
return False
usr_packages = fmn.rules.utils.get_packages_of_user(
config, fasnick, all_acls)
return usr_packages.intersection(msg_packages)

return _user_package_intersection(fasnick, message, config, all_acls)
return False

only_commit = ['point of contact', 'co-maintained']
Expand All @@ -109,17 +118,7 @@ def user_package_commit_filter(config, message, fasnick=None, *args, **kw):

fasnick = kw.get('fasnick', fasnick)
if fasnick:
msg_packages = fmn.rules.utils.msg2packages(message, **config)
if not msg_packages:
# If the message has no packages associated with it, there's no
# way that "one of them" is going to happen to belong to this user,
# so let's not waste our time doing the somewhat expensive call out
# to pkgdb on the next line to check.
return False
usr_packages = fmn.rules.utils.get_packages_of_user(
config, fasnick, only_commit)
return usr_packages.intersection(msg_packages)

return _user_package_intersection(fasnick, message, config, only_commit)
return False


Expand All @@ -134,17 +133,7 @@ def user_package_watch_filter(config, message, fasnick=None, *args, **kw):

fasnick = kw.get('fasnick', fasnick)
if fasnick:
msg_packages = fmn.rules.utils.msg2packages(message, **config)
if not msg_packages:
# If the message has no packages associated with it, there's no
# way that "one of them" is going to happen to belong to this user,
# so let's not waste our time doing the somewhat expensive call out
# to pkgdb on the next line to check.
return False
usr_packages = fmn.rules.utils.get_packages_of_user(
config, fasnick, only_watchcommits)
return usr_packages.intersection(msg_packages)

return _user_package_intersection(fasnick, message, config, only_watchcommits)
return False


Expand Down
30 changes: 23 additions & 7 deletions fmn/rules/utils.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
""" Fedora Notifications pkgdb client """

from collections import defaultdict
import logging
import time

Expand Down Expand Up @@ -134,7 +135,7 @@ def get_packages_of_user(config, username, flags):
if not _cache.is_configured:
_cache.configure(**config['fmn.rules.cache'])

packages = []
packages = defaultdict(set)

groups = get_groups_of_user(config, get_fas(config), username)
owners = [username] + ['group::' + group for group in groups]
Expand All @@ -143,9 +144,10 @@ def get_packages_of_user(config, username, flags):
key = cache_key_generator(get_packages_of_user, owner)
creator = lambda: _get_pkgdb2_packages_for(config, owner, flags)
subset = _cache.get_or_create(key, creator)
packages.extend(subset)
for namespace in subset:
packages[namespace].update(subset[namespace])

return set(packages)
return dict(packages)


def cache_key_generator(fn, arg):
Expand All @@ -161,6 +163,16 @@ def invalidate_cache_for(config, fn, arg):


def _get_pkgdb2_packages_for(config, username, flags):
"""
Get the packages a user is associated with from pkgdb2.
Args:
config (dict): The application configuration.
username (str): The FAS username to fetch the packages for.
flags (list): The type of relationship the user should have to the
package (e.g. "watch", "point of contact", etc.). See the pkgdb2
API for details.
"""
log.debug("Requesting pkgdb2 packages for user %r" % username)
start = time.time()

Expand All @@ -173,14 +185,17 @@ def _get_pkgdb2_packages_for(config, username, flags):

if not req.status_code == 200:
log.debug('URL %s returned code %s', req.url, req.status_code)
return set()
return {}

data = req.json()

packages = defaultdict(set)

packages_of_interest = sum([data[flag] for flag in flags], [])
packages_of_interest = set([p['name'] for p in packages_of_interest])
for package in packages_of_interest:
packages[package.get('namespace', 'rpms')].add(package['name'])
log.debug("done talking with pkgdb2 for now. %0.2fs", time.time() - start)
return packages_of_interest
return dict(packages)


def get_user_of_group(config, fas, groupname):
Expand Down Expand Up @@ -249,6 +264,7 @@ def msg2packages(msg, **config):
if not _cache.is_configured:
_cache.configure(**config['fmn.rules.cache'])

key = "|".join(['packages', msg['msg_id']]).encode('utf-8')
namespace = config.get('namespace', u'')
key = u'|'.join([u'packages', namespace, msg['msg_id']]).encode('utf-8')
creator = lambda: fedmsg.meta.msg2packages(msg, **config)
return _cache.get_or_create(key, creator)
6 changes: 6 additions & 0 deletions fmn/tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker, scoped_session
import vcr

import fmn.lib.models

Expand All @@ -25,6 +26,11 @@ def setUp(self):
fmn.lib.models.BASE.query = fmn.lib.models.Session.query_property()
self.sess = fmn.lib.models.Session

cwd = os.path.dirname(os.path.realpath(__file__))
context_manager = vcr.use_cassette(os.path.join(cwd, 'fixtures/', self.id()))
self.vcr = context_manager.__enter__()
self.addCleanup(context_manager.__exit__)

self.config = {
'fmn.backends': ['irc', 'email', 'android'],
}
Expand Down

0 comments on commit 61507cd

Please sign in to comment.