示例#1
0
    def __init__(self, hub, name):
        self.name = name
        self.badges = {}
        self.hub = hub
        self.DBSession = None
        ENABLED = 'fedmsg.consumers.badges.{0}.enabled'.format(self.name)
        if not asbool(hub.config.get(ENABLED, False)):
            log.info('fedmsg.consumers.badges.{0} disabled'.format(self.name))
            return

        global_settings = hub.config.get("badges_global")

        database_uri = global_settings.get('database_uri', '')
        if database_uri == '':
            raise Exception('Badges consumer requires a database uri')
            return
        self.tahrir = TahrirDatabase(database_uri)
        self.DBSession = self.tahrir.session_maker
        issuer = global_settings.get('badge_issuer')
        self.issuer_id = self.tahrir.add_issuer(issuer.get('issuer_origin'),
                                                issuer.get('issuer_name'),
                                                issuer.get('issuer_org'),
                                                issuer.get('issuer_contact'))

        badges_settings = hub.config.get("{0}_badges".format(self.name))
        for badge in badges_settings:
            self.tahrir.add_badge(badge.get('badge_name'),
                                  badge.get('badge_image'),
                                  badge.get('badge_desc'),
                                  badge.get('badge_criteria'), self.issuer_id)
        return super(FedoraBadgesConsumer, self).__init__(hub)
示例#2
0
    def setUp(self):
        check_output(['touch', 'testdb.db'])
        sqlalchemy_uri = "sqlite:///testdb.db"
        engine = create_engine(sqlalchemy_uri)
        DBSession.configure(bind=engine)
        DeclarativeBase.metadata.create_all(engine)

        self.api = TahrirDatabase(sqlalchemy_uri)
        self._create_test_data()
def main():
    if len(sys.argv) < 4:
        usage()
        exit()
    db = TahrirDatabase(sys.argv[1])
    issuer_id = db.add_issuer(
            "http://coderwall.com",
            "coderwall",
            "http://coderwall.com",
            "*****@*****.**"
            )
    db.add_person(hash(sys.argv[3]), sys.argv[3])
    cw = CoderWall(sys.argv[2])
    for badge in cw.badges:
        db.add_badge(
                badge.name,
                badge.image_uri,
                badge.description,
                "http://coderwall.com",
                issuer_id)
        db.add_assertion(
                badge.name.lower(),
                sys.argv[3],
                None
                )

    print "Awarded {0} badges to {1}".format(len(cw.badges), sys.argv[3])
示例#4
0
    def setUp(self):
        check_output(['touch', 'testdb.db'])
        sqlalchemy_uri = "sqlite:///testdb.db"
        engine = create_engine(sqlalchemy_uri)
        DBSession.configure(bind=engine)
        DeclarativeBase.metadata.create_all(engine)

        self.api = TahrirDatabase(sqlalchemy_uri)
示例#5
0
 def get_db(request):
     """ Database retrieval function to be added to the request for
         calling anywhere.
     """
     session = session_cls()
     return TahrirDatabase(session=session,
                           autocommit=False,
                           notification_callback=notifications.callback)
示例#6
0
    def __init__(self, dburi, salt):
        self.dburi = dburi
        self.salt = salt

        self.database = TahrirDatabase(self.dburi)
        self.app = Flask(__name__)

        self.routes = {
                "/badges/<uid>": (self.badges_uid, {'methods': ['GET', 'DELETE']}),
                "/badges/": (self.add_badge, {'methods': ['POST']}),
                "/people/<uid>": (self.people, {'methods': ['GET', 'DELETE']}),
                "/people/": (self.add_person, {'methods': ['POST']}),
                "/issuers/<uid>": (self.issuers, {'methods': ['GET', 'DELETE']}),
                "/issuers/": (self.add_issuer, {'methods': ['POST']}),
                "/assertions/<email>": (self.assertions, {'methods': ['GET']}),
                "/assertions/": (self.add_assertion, {'methods': ['POST']}),
                }
        map(
            lambda route: self.app.route(route, **self.routes[route][1])(
                self.routes[route][0]
            ),
            self.routes
        )
示例#7
0
    def __init__(self, hub, name):
        self.name = name
        self.badges = {}
        self.hub = hub
        self.DBSession = None
        ENABLED = "fedmsg.consumers.badges.{0}.enabled".format(self.name)
        if not asbool(hub.config.get(ENABLED, False)):
            log.info("fedmsg.consumers.badges.{0} disabled".format(self.name))
            return

        global_settings = hub.config.get("badges_global")

        database_uri = global_settings.get("database_uri", "")
        if database_uri == "":
            raise Exception("Badges consumer requires a database uri")
            return
        self.tahrir = TahrirDatabase(database_uri)
        self.DBSession = self.tahrir.session_maker
        issuer = global_settings.get("badge_issuer")
        self.issuer_id = self.tahrir.add_issuer(
            issuer.get("issuer_origin"),
            issuer.get("issuer_name"),
            issuer.get("issuer_org"),
            issuer.get("issuer_contact"),
        )

        badges_settings = hub.config.get("{0}_badges".format(self.name))
        for badge in badges_settings:
            self.tahrir.add_badge(
                badge.get("badge_name"),
                badge.get("badge_image"),
                badge.get("badge_desc"),
                badge.get("badge_criteria"),
                self.issuer_id,
            )
        return super(FedoraBadgesConsumer, self).__init__(hub)
示例#8
0
class FedoraBadgesConsumer(FedmsgConsumer):
    """
    The Base class for creating fedmsg consumers that issue open badges
    Provides a base that does all of the heavy lifting related to issuing badges.
    All the subclass needs to do is have a topic, a name, and implement consume(self, msg)

    :type hub: Moksha Hub
    :param hub: the moksha hub we are getting our messages from

    :type name: str
    :param name: name of this consumer, used to get details from the config file
    """

    def __init__(self, hub, name):
        self.name = name
        self.badges = {}
        self.hub = hub
        self.DBSession = None
        ENABLED = "fedmsg.consumers.badges.{0}.enabled".format(self.name)
        if not asbool(hub.config.get(ENABLED, False)):
            log.info("fedmsg.consumers.badges.{0} disabled".format(self.name))
            return

        global_settings = hub.config.get("badges_global")

        database_uri = global_settings.get("database_uri", "")
        if database_uri == "":
            raise Exception("Badges consumer requires a database uri")
            return
        self.tahrir = TahrirDatabase(database_uri)
        self.DBSession = self.tahrir.session_maker
        issuer = global_settings.get("badge_issuer")
        self.issuer_id = self.tahrir.add_issuer(
            issuer.get("issuer_origin"),
            issuer.get("issuer_name"),
            issuer.get("issuer_org"),
            issuer.get("issuer_contact"),
        )

        badges_settings = hub.config.get("{0}_badges".format(self.name))
        for badge in badges_settings:
            self.tahrir.add_badge(
                badge.get("badge_name"),
                badge.get("badge_image"),
                badge.get("badge_desc"),
                badge.get("badge_criteria"),
                self.issuer_id,
            )
        return super(FedoraBadgesConsumer, self).__init__(hub)

    def award_badge(self, email, badge_id, issued_on=None):
        """
        A high level way to issue a badge to a Person
        It adds the person if they don't exist, and creates an assertion for them

        :type email: str
        :param email: This person's email addr

        :type badge_id: str
        :param badge_id: the id of the badge being awarded

        :type issued_on: DateTime
        :param issued_on: A datetime object with the time this badge was issued
        """

        self.tahrir.add_person(email)
        self.tahrir.add_assertion(badge_id, email, issued_on)

    def consume(self, msg):
        """
        Consume a single message, we pass here because every subclass is going
        to want to parse this slightly differently

        :type msg: dict
        :param msg: The message to be parsed
        """
        pass
示例#9
0
class TestDBInit(object):

    def setUp(self):
        check_output(['touch', 'testdb.db'])
        sqlalchemy_uri = "sqlite:///testdb.db"
        engine = create_engine(sqlalchemy_uri)
        DBSession.configure(bind=engine)
        DeclarativeBase.metadata.create_all(engine)

        self.callback_calls = []
        self.api = TahrirDatabase(
            sqlalchemy_uri,
            notification_callback=self.callback)

    def callback(self, *args, **kwargs):
        self.callback_calls.append((args, kwargs))

    def test_add_badges(self):
        self.api.add_badge(
            "TestBadge",
            "TestImage",
            "A test badge for doing unit tests",
            "TestCriteria",
            1337
        )

        assert self.api.badge_exists("testbadge") is True

    def test_add_team(self):
        self.api.create_team("TestTeam")

        assert self.api.team_exists("testteam") is True

    def test_add_series(self):
        team_id = self.api.create_team("TestTeam")

        self.api.create_series("TestSeries",
                               "A test series",
                               team_id,
                               "test, series")

        assert self.api.series_exists("testseries") is True

    def test_add_milestone(self):
        team_id = self.api.create_team("TestTeam")

        series_id = self.api.create_series("TestSeries",
                                           "A test series",
                                           team_id,
                                           "test, series")

        badge_id_1 = self.api.add_badge(
            "TestBadge-1",
            "TestImage-2",
            "A test badge for doing 10 unit tests",
            "TestCriteria",
            1337
        )

        badge_id_2 = self.api.add_badge(
            "TestBadge-2",
            "TestImage-2",
            "A test badge for doing 100 unit tests",
            "TestCriteria",
            1337
        )

        milestone_id_1 = self.api.create_milestone(1,
                                         badge_id_1,
                                         series_id)

        milestone_id_2 = self.api.create_milestone(2,
                                         badge_id_2,
                                         series_id)

        assert self.api.milestone_exists(milestone_id_1) is True
        assert self.api.milestone_exists(milestone_id_2) is True

    def test_add_person(self):
        self.api.add_person("*****@*****.**")
        assert self.api.person_exists("*****@*****.**") is True

    def test_add_issuer(self):
        _id = self.api.add_issuer(
            "TestOrigin",
            "TestName",
            "TestOrg",
            "TestContact"
        )
        assert self.api.issuer_exists("TestOrigin", "TestName") is True

    def test_add_invitation(self):
        badge_id = self.api.add_badge(
            "TestBadge",
            "TestImage",
            "A test badge for doing unit tests",
            "TestCriteria",
            1337
        )
        _id = self.api.add_invitation(
            badge_id,
        )

        assert self.api.invitation_exists(_id)

    def test_last_login(self):
        email = "*****@*****.**"
        person_id = self.api.add_person(email)
        person = self.api.get_person(person_id)
        assert not person.last_login
        self.api.note_login(nickname=person.nickname)
        assert person.last_login

    def test_add_assertion(self):
        issuer_id = self.api.add_issuer(
            "TestOrigin",
            "TestName",
            "TestOrg",
            "TestContact"
        )
        badge_id = self.api.add_badge(
            "TestBadge",
            "TestImage",
            "A test badge for doing unit tests",
            "TestCriteria",
            issuer_id,
        )
        email = "*****@*****.**"
        person_id = self.api.add_person(email)
        assertion_id = self.api.add_assertion(badge_id, email, None, 'link')
        assert self.api.assertion_exists(badge_id, email)

        badge = self.api.get_badge(badge_id)
        assert badge.assertions[0].issued_for == 'link'

        # Ensure that we would have published two fedmsg messages for that.
        assert len(self.callback_calls) == 2

        # Ensure that the first message had a 'badge_id' in the message.
        assert 'badge_id' in self.callback_calls[0][1]['msg']['badge']

    def test_get_badges_from_tags(self):
        issuer_id = self.api.add_issuer(
            "TestOrigin",
            "TestName",
            "TestOrg",
            "TestContact"
        )

        # Badge tagged with "test"
        self.api.add_badge(
            "TestBadgeA",
            "TestImage",
            "A test badge for doing unit tests",
            "TestCriteria",
            issuer_id,
            tags="test"
        )

        # Badge tagged with "tester"
        self.api.add_badge(
            "TestBadgeB",
            "TestImage",
            "A second test badge for doing unit tests",
            "TestCriteria",
            issuer_id,
            tags="tester"
        )

        # Badge tagged with both "test" and "tester"
        self.api.add_badge(
            "TestBadgeC",
            "TestImage",
            "A third test badge for doing unit tests",
            "TestCriteria",
            issuer_id,
            tags="test, tester"
        )

        tags = ['test', 'tester']
        badges_any = self.api.get_badges_from_tags(tags, match_all=False)
        assert len(badges_any) == 3
        badges_all = self.api.get_badges_from_tags(tags, match_all=True)
        assert len(badges_all) == 1

    def tearDown(self):
        check_output(['rm', 'testdb.db'])
        self.callback_calls = []
示例#10
0
from tahrir_api.dbapi import TahrirDatabase


db = TahrirDatabase("backend://*****:*****@localhost/badges")

badge_id = "fossbox"
person_email = "*****@*****.**"
issued_on = None

db.add_person(person_email)
db.add_assertion(badge_id, person_email, issued_on)
示例#11
0
from tahrir_api.dbapi import TahrirDatabase

db = TahrirDatabase('backend://*****:*****@localhost/badges')

origin = 'http://foss.rit.edu/badges'
issuer_name = 'FOSS@RIT'
org = 'http://foss.rit.edu'
contact = '*****@*****.**'

issuer_id = db.add_issuer(origin, issuer_name, org, contact)

badge_name = 'fossbox'
image = 'http://foss.rit.edu/files/fossboxbadge.png'
desc = 'Welcome to the FOSSBox. A member is you!'
criteria = 'http://foss.rit.edu'

db.add_badge(badge_name, image, desc, criteria, issuer_id)
示例#12
0
from tahrir_api.dbapi import TahrirDatabase


db = TahrirDatabase("backend://*****:*****@localhost/badges")

origin = "http://foss.rit.edu/badges"
issuer_name = "FOSS@RIT"
org = "http://foss.rit.edu"
contact = "*****@*****.**"

issuer_id = db.add_issuer(origin, issuer_name, org, contact)


badge_name = "fossbox"
image = "http://foss.rit.edu/files/fossboxbadge.png"
desc = "Welcome to the FOSSBox. A member is you!"
criteria = "http://foss.rit.edu"

db.add_badge(badge_name, image, desc, criteria, issuer_id)
示例#13
0
class FedoraBadgesConsumer(FedmsgConsumer):
    """
    The Base class for creating fedmsg consumers that issue open badges
    Provides a base that does all of the heavy lifting related to issuing badges.
    All the subclass needs to do is have a topic, a name, and implement consume(self, msg)

    :type hub: Moksha Hub
    :param hub: the moksha hub we are getting our messages from

    :type name: str
    :param name: name of this consumer, used to get details from the config file
    """
    def __init__(self, hub, name):
        self.name = name
        self.badges = {}
        self.hub = hub
        self.DBSession = None
        ENABLED = 'fedmsg.consumers.badges.{0}.enabled'.format(self.name)
        if not asbool(hub.config.get(ENABLED, False)):
            log.info('fedmsg.consumers.badges.{0} disabled'.format(self.name))
            return

        global_settings = hub.config.get("badges_global")

        database_uri = global_settings.get('database_uri', '')
        if database_uri == '':
            raise Exception('Badges consumer requires a database uri')
            return
        self.tahrir = TahrirDatabase(database_uri)
        self.DBSession = self.tahrir.session_maker
        issuer = global_settings.get('badge_issuer')
        self.issuer_id = self.tahrir.add_issuer(issuer.get('issuer_origin'),
                                                issuer.get('issuer_name'),
                                                issuer.get('issuer_org'),
                                                issuer.get('issuer_contact'))

        badges_settings = hub.config.get("{0}_badges".format(self.name))
        for badge in badges_settings:
            self.tahrir.add_badge(badge.get('badge_name'),
                                  badge.get('badge_image'),
                                  badge.get('badge_desc'),
                                  badge.get('badge_criteria'), self.issuer_id)
        return super(FedoraBadgesConsumer, self).__init__(hub)

    def award_badge(self, email, badge_id, issued_on=None):
        """
        A high level way to issue a badge to a Person
        It adds the person if they don't exist, and creates an assertion for them

        :type email: str
        :param email: This person's email addr

        :type badge_id: str
        :param badge_id: the id of the badge being awarded

        :type issued_on: DateTime
        :param issued_on: A datetime object with the time this badge was issued
        """

        self.tahrir.add_person(email)
        self.tahrir.add_assertion(badge_id, email, issued_on)

    def consume(self, msg):
        """
        Consume a single message, we pass here because every subclass is going
        to want to parse this slightly differently

        :type msg: dict
        :param msg: The message to be parsed
        """
        pass
示例#14
0
class TestDBInit(object):
    def setUp(self):
        check_output(['touch', 'testdb.db'])
        sqlalchemy_uri = "sqlite:///testdb.db"
        engine = create_engine(sqlalchemy_uri)
        DBSession.configure(bind=engine)
        DeclarativeBase.metadata.create_all(engine)

        self.callback_calls = []
        self.api = TahrirDatabase(sqlalchemy_uri,
                                  notification_callback=self.callback)

    def callback(self, *args, **kwargs):
        self.callback_calls.append((args, kwargs))

    def test_add_badges(self):
        self.api.add_badge("TestBadge", "TestImage",
                           "A test badge for doing unit tests", "TestCriteria",
                           1337)

        assert self.api.badge_exists("testbadge") is True

    def test_add_team(self):
        self.api.create_team("TestTeam")

        assert self.api.team_exists("testteam") is True

    def test_add_series(self):
        team_id = self.api.create_team("TestTeam")

        self.api.create_series("TestSeries", "A test series", team_id,
                               "test, series")

        assert self.api.series_exists("testseries") is True

    def test_add_milestone(self):
        team_id = self.api.create_team("TestTeam")

        series_id = self.api.create_series("TestSeries", "A test series",
                                           team_id, "test, series")

        badge_id_1 = self.api.add_badge(
            "TestBadge-1", "TestImage-2",
            "A test badge for doing 10 unit tests", "TestCriteria", 1337)

        badge_id_2 = self.api.add_badge(
            "TestBadge-2", "TestImage-2",
            "A test badge for doing 100 unit tests", "TestCriteria", 1337)

        milestone_id_1 = self.api.create_milestone(1, badge_id_1, series_id)

        milestone_id_2 = self.api.create_milestone(2, badge_id_2, series_id)

        assert self.api.milestone_exists(milestone_id_1) is True
        assert self.api.milestone_exists(milestone_id_2) is True

    def test_add_person(self):
        self.api.add_person("*****@*****.**")
        assert self.api.person_exists("*****@*****.**") is True

    def test_add_issuer(self):
        _id = self.api.add_issuer("TestOrigin", "TestName", "TestOrg",
                                  "TestContact")
        assert self.api.issuer_exists("TestOrigin", "TestName") is True

    def test_add_invitation(self):
        badge_id = self.api.add_badge("TestBadge", "TestImage",
                                      "A test badge for doing unit tests",
                                      "TestCriteria", 1337)
        _id = self.api.add_invitation(badge_id, )

        assert self.api.invitation_exists(_id)

    def test_last_login(self):
        email = "*****@*****.**"
        person_id = self.api.add_person(email)
        person = self.api.get_person(person_id)
        assert not person.last_login
        self.api.note_login(nickname=person.nickname)
        assert person.last_login

    def test_add_assertion(self):
        issuer_id = self.api.add_issuer("TestOrigin", "TestName", "TestOrg",
                                        "TestContact")
        badge_id = self.api.add_badge(
            "TestBadge",
            "TestImage",
            "A test badge for doing unit tests",
            "TestCriteria",
            issuer_id,
        )
        email = "*****@*****.**"
        person_id = self.api.add_person(email)
        assertion_id = self.api.add_assertion(badge_id, email, None, 'link')
        assert self.api.assertion_exists(badge_id, email)

        badge = self.api.get_badge(badge_id)
        assert badge.assertions[0].issued_for == 'link'

        # Ensure that we would have published two fedmsg messages for that.
        assert len(self.callback_calls) == 2

        # Ensure that the first message had a 'badge_id' in the message.
        assert 'badge_id' in self.callback_calls[0][1]['msg']['badge']

    def test_get_badges_from_tags(self):
        issuer_id = self.api.add_issuer("TestOrigin", "TestName", "TestOrg",
                                        "TestContact")

        # Badge tagged with "test"
        self.api.add_badge("TestBadgeA",
                           "TestImage",
                           "A test badge for doing unit tests",
                           "TestCriteria",
                           issuer_id,
                           tags="test")

        # Badge tagged with "tester"
        self.api.add_badge("TestBadgeB",
                           "TestImage",
                           "A second test badge for doing unit tests",
                           "TestCriteria",
                           issuer_id,
                           tags="tester")

        # Badge tagged with both "test" and "tester"
        self.api.add_badge("TestBadgeC",
                           "TestImage",
                           "A third test badge for doing unit tests",
                           "TestCriteria",
                           issuer_id,
                           tags="test, tester")

        tags = ['test', 'tester']
        badges_any = self.api.get_badges_from_tags(tags, match_all=False)
        assert len(badges_any) == 3
        badges_all = self.api.get_badges_from_tags(tags, match_all=True)
        assert len(badges_all) == 1

    def tearDown(self):
        check_output(['rm', 'testdb.db'])
        self.callback_calls = []
示例#15
0
class TestRanking(object):
    def setUp(self):
        check_output(['touch', 'testdb.db'])
        sqlalchemy_uri = "sqlite:///testdb.db"
        engine = create_engine(sqlalchemy_uri)
        DBSession.configure(bind=engine)
        DeclarativeBase.metadata.create_all(engine)

        self.api = TahrirDatabase(sqlalchemy_uri)
        self._create_test_data()

    def tearDown(self):
        check_output(['rm', 'testdb.db'])

    def _create_test_data(self):
        issuer_id = self.api.add_issuer("TestOrigin", "TestName", "TestOrg",
                                        "TestContact")
        self.badge_id_1 = self.api.add_badge(
            "TestBadge1",
            "TestImage",
            "A test badge for doing unit tests",
            "TestCriteria",
            issuer_id,
        )
        self.badge_id_2 = self.api.add_badge(
            "TestBadge2",
            "TestImage",
            "A test badge for doing unit tests",
            "TestCriteria",
            issuer_id,
        )
        self.badge_id_3 = self.api.add_badge(
            "TestBadge3",
            "TestImage",
            "A test badge for doing unit tests",
            "TestCriteria",
            issuer_id,
        )
        self.email_1 = "*****@*****.**"
        person_id_1 = self.api.add_person(self.email_1)
        self.email_2 = "*****@*****.**"
        person_id_2 = self.api.add_person(self.email_2)
        self.email_3 = "*****@*****.**"
        person_id_3 = self.api.add_person(self.email_3)
        self.email_4 = "*****@*****.**"
        person_id_4 = self.api.add_person(self.email_4)

    def test_ranking_simple(self):
        self.api.add_assertion(self.badge_id_1, self.email_1, None)

        self.api.add_assertion(self.badge_id_1, self.email_4, None)
        self.api.add_assertion(self.badge_id_2, self.email_4, None)
        self.api.add_assertion(self.badge_id_3, self.email_4, None)

        person1 = self.api.get_person("*****@*****.**")
        person4 = self.api.get_person("*****@*****.**")

        eq_(person1.rank, 2)
        eq_(person4.rank, 1)

    def test_ranking_tie(self):
        self.api.add_assertion(self.badge_id_1, self.email_1, None)

        self.api.add_assertion(self.badge_id_1, self.email_2, None)
        self.api.add_assertion(self.badge_id_2, self.email_2, None)

        self.api.add_assertion(self.badge_id_1, self.email_3, None)
        self.api.add_assertion(self.badge_id_2, self.email_3, None)

        self.api.add_assertion(self.badge_id_1, self.email_4, None)
        self.api.add_assertion(self.badge_id_2, self.email_4, None)
        self.api.add_assertion(self.badge_id_3, self.email_4, None)

        person1 = self.api.get_person("*****@*****.**")
        person2 = self.api.get_person("*****@*****.**")
        person3 = self.api.get_person("*****@*****.**")
        person4 = self.api.get_person("*****@*****.**")

        eq_(person1.rank, 4)
        eq_(person2.rank, 2)
        eq_(person3.rank, 2)
        eq_(person4.rank, 1)

    def test_ranking_preexisting(self):
        """ Test that rank updating works for pre-existant users """
        person1 = self.api.get_person("*****@*****.**")
        new_assertion1 = Assertion(
            badge_id=self.badge_id_1,
            person_id=person1.id,
        )
        self.api.session.add(new_assertion1)
        new_assertion2 = Assertion(
            badge_id=self.badge_id_2,
            person_id=person1.id,
        )
        self.api.session.add(new_assertion2)
        self.api.session.flush()

        # For persons who existed *before* we added cached ranks, they should
        # have a null-rank.
        eq_(person1.rank, None)

        # But once *anyone* else gets a badge, old ranks should be updated too.
        self.api.add_assertion(self.badge_id_1, self.email_2, None)
        eq_(person1.rank, 1)

        person2 = self.api.get_person("*****@*****.**")
        eq_(person2.rank, 2)

        # but people with no badges should still be null ranked.
        person3 = self.api.get_person("*****@*****.**")
        eq_(person3.rank, None)

    def test_ranking_with_time_limits(self):
        self.api.add_assertion(self.badge_id_1, self.email_1, yesterday)

        self.api.add_assertion(self.badge_id_1, self.email_4, yesterday)
        self.api.add_assertion(self.badge_id_2, self.email_4, one_week_ago)
        self.api.add_assertion(self.badge_id_3, self.email_4, one_month_ago)

        person1 = self.api.get_person("*****@*****.**")
        person4 = self.api.get_person("*****@*****.**")

        epsilon = datetime.timedelta(hours=1)

        results = self.api._make_leaderboard(yesterday - epsilon, now)
        eq_(results[person1]['badges'], 1)
        eq_(results[person4]['badges'], 1)

        results = self.api._make_leaderboard(one_week_ago - epsilon, now)
        eq_(results[person1]['badges'], 1)
        eq_(results[person4]['badges'], 2)

        results = self.api._make_leaderboard(one_month_ago - epsilon, now)
        eq_(results[person1]['badges'], 1)
        eq_(results[person4]['badges'], 3)
示例#16
0
class TestRanking(object):

    def setUp(self):
        check_output(['touch', 'testdb.db'])
        sqlalchemy_uri = "sqlite:///testdb.db"
        engine = create_engine(sqlalchemy_uri)
        DBSession.configure(bind=engine)
        DeclarativeBase.metadata.create_all(engine)

        self.api = TahrirDatabase(sqlalchemy_uri)
        self._create_test_data()

    def tearDown(self):
        check_output(['rm', 'testdb.db'])

    def _create_test_data(self):
        issuer_id = self.api.add_issuer(
            "TestOrigin",
            "TestName",
            "TestOrg",
            "TestContact"
        )
        self.badge_id_1 = self.api.add_badge(
            "TestBadge1",
            "TestImage",
            "A test badge for doing unit tests",
            "TestCriteria",
            issuer_id,
        )
        self.badge_id_2 = self.api.add_badge(
            "TestBadge2",
            "TestImage",
            "A test badge for doing unit tests",
            "TestCriteria",
            issuer_id,
        )
        self.badge_id_3 = self.api.add_badge(
            "TestBadge3",
            "TestImage",
            "A test badge for doing unit tests",
            "TestCriteria",
            issuer_id,
        )
        self.email_1 = "*****@*****.**"
        person_id_1 = self.api.add_person(self.email_1)
        self.email_2 = "*****@*****.**"
        person_id_2 = self.api.add_person(self.email_2)
        self.email_3 = "*****@*****.**"
        person_id_3 = self.api.add_person(self.email_3)
        self.email_4 = "*****@*****.**"
        person_id_4 = self.api.add_person(self.email_4)

    def test_ranking_simple(self):
        self.api.add_assertion(self.badge_id_1, self.email_1, None)

        self.api.add_assertion(self.badge_id_1, self.email_4, None)
        self.api.add_assertion(self.badge_id_2, self.email_4, None)
        self.api.add_assertion(self.badge_id_3, self.email_4, None)

        person1 = self.api.get_person("*****@*****.**")
        person4 = self.api.get_person("*****@*****.**")

        eq_(person1.rank, 2)
        eq_(person4.rank, 1)

    def test_ranking_tie(self):
        self.api.add_assertion(self.badge_id_1, self.email_1, None)

        self.api.add_assertion(self.badge_id_1, self.email_2, None)
        self.api.add_assertion(self.badge_id_2, self.email_2, None)

        self.api.add_assertion(self.badge_id_1, self.email_3, None)
        self.api.add_assertion(self.badge_id_2, self.email_3, None)

        self.api.add_assertion(self.badge_id_1, self.email_4, None)
        self.api.add_assertion(self.badge_id_2, self.email_4, None)
        self.api.add_assertion(self.badge_id_3, self.email_4, None)

        person1 = self.api.get_person("*****@*****.**")
        person2 = self.api.get_person("*****@*****.**")
        person3 = self.api.get_person("*****@*****.**")
        person4 = self.api.get_person("*****@*****.**")

        eq_(person1.rank, 4)
        eq_(person2.rank, 2)
        eq_(person3.rank, 2)
        eq_(person4.rank, 1)

    def test_ranking_preexisting(self):
        """ Test that rank updating works for pre-existant users """
        person1 = self.api.get_person("*****@*****.**")
        new_assertion1 = Assertion(
            badge_id=self.badge_id_1,
            person_id=person1.id,
        )
        self.api.session.add(new_assertion1)
        new_assertion2 = Assertion(
            badge_id=self.badge_id_2,
            person_id=person1.id,
        )
        self.api.session.add(new_assertion2)
        self.api.session.flush()

        # For persons who existed *before* we added cached ranks, they should
        # have a null-rank.
        eq_(person1.rank, None)

        # But once *anyone* else gets a badge, old ranks should be updated too.
        self.api.add_assertion(self.badge_id_1, self.email_2, None)
        eq_(person1.rank, 1)

        person2 = self.api.get_person("*****@*****.**")
        eq_(person2.rank, 2)

        # but people with no badges should still be null ranked.
        person3 = self.api.get_person("*****@*****.**")
        eq_(person3.rank, None)

    def test_ranking_with_time_limits(self):
        self.api.add_assertion(self.badge_id_1, self.email_1, yesterday)

        self.api.add_assertion(self.badge_id_1, self.email_4, yesterday)
        self.api.add_assertion(self.badge_id_2, self.email_4, one_week_ago)
        self.api.add_assertion(self.badge_id_3, self.email_4, one_month_ago)

        person1 = self.api.get_person("*****@*****.**")
        person4 = self.api.get_person("*****@*****.**")

        epsilon = datetime.timedelta(hours=1)

        results = self.api._make_leaderboard(yesterday - epsilon, now)
        eq_(results[person1]['badges'], 1)
        eq_(results[person4]['badges'], 1)

        results = self.api._make_leaderboard(one_week_ago - epsilon, now)
        eq_(results[person1]['badges'], 1)
        eq_(results[person4]['badges'], 2)

        results = self.api._make_leaderboard(one_month_ago - epsilon, now)
        eq_(results[person1]['badges'], 1)
        eq_(results[person4]['badges'], 3)
示例#17
0
class TahrirRestApp(object):
    def __init__(self, dburi, salt):
        self.dburi = dburi
        self.salt = salt

        self.database = TahrirDatabase(self.dburi)
        self.app = Flask(__name__)

        self.routes = {
                "/badges/<uid>": (self.badges_uid, {'methods': ['GET', 'DELETE']}),
                "/badges/": (self.add_badge, {'methods': ['POST']}),
                "/people/<uid>": (self.people, {'methods': ['GET', 'DELETE']}),
                "/people/": (self.add_person, {'methods': ['POST']}),
                "/issuers/<uid>": (self.issuers, {'methods': ['GET', 'DELETE']}),
                "/issuers/": (self.add_issuer, {'methods': ['POST']}),
                "/assertions/<email>": (self.assertions, {'methods': ['GET']}),
                "/assertions/": (self.add_assertion, {'methods': ['POST']}),
                }
        map(
            lambda route: self.app.route(route, **self.routes[route][1])(
                self.routes[route][0]
            ),
            self.routes
        )

    def people(self, uid):
        """
        GET: /people/<uid>
        Delete: /people/<uid>
        Get info on a person, or delete them
        """
        if request.method == 'DELETE':
            result = self.database.delete_person(uid)
            if result != False:
                log.info("DELETE Request for /people/{0} succeeded".format(uid))
                return json.dumps({'success': True, 'id': result})
            else:
                log.info("DELETE Request for /people/{0} failed",format(uid))
                return json.dumps({'success': False, 'id': uid})

        if request.method == 'GET':
            person = self.database.get_person(uid)
            if person == None:
                log.info("GET request for /people/{0} failed".format(uid))
                return json.dumps({})
            else:
                log.info("GET request for /people/{0} suceeded".format(uid))
                return json.dumps(person.__json__())

    def add_person(self):
        """
        POST: /people/
        Add a new Person
        """
        try:
            data = json.loads(request.data)
        except:
            log.info("add_person Failed: could not parse request.data")
            abort(503)
        try:
            result = self.database.add_person(
                    hash(data['email']),
                    data['email']
                    )
            log.info("Added Person: {0}".format(data['email']))
            return json.dumps({'email': result})
        except KeyError:
            log.info("add_person Failed: JSON doesn't include all required fields")
            abort(503)



    def badges_uid(self, uid):
        """
        GET: /badges/<uid>
        DELETE: /badges/<uid>
        return s a JSON blob with all the badge attributes
        Deletes a badge with the given uid
        """
        if request.method == 'DELETE':
            result = self.database.delete_badge(uid)
            if result != False:
                log.info("DELETE Request for /badges/{0} suceeded".format(uid))
                return json.dumps({'success': True, 'id': result})
            else:
                log.info("DELETE Request for /badges/{0} failed".format(uid))
                return json.dumps({'success': False, 'id': uid})

        if request.method == 'GET':
            badge = self.database.get_badge(uid)
            if badge == None:
                log.info("GET Request for /badges/{0} failed".format(uid))
                return json.dumps({})
            else:
                log.info("GET Request for /badges/{0} succeeded".format(uid))
                return json.dumps(badge.__json__())

    def add_badge(self):
        """
        POST: /badges
        accepts a json blob with all the badge attributes
        """
        try:
            data = json.loads(request.data)
        except:
            log.info("add_badge Failed: Could not parse request.data")
            abort(503)
        try:
            badge_id = self.database.add_badge(
                    data['name'],
                    data['image'],
                    data['desc'],
                    data['criteria'],
                    data['issuer_id']
                    )
            log.info("Added Badge: {0}".format(data['name']))
            return json.dumps({'id': badge_id})
        except KeyError:
            log.info("add_badge Failed: JSON does not have required fields")
            abort(503)

    def issuers(self, uid):
        """
        GET /issuers/<id>
        DELETE /issuers/<id>
        Delete or Get an issuer
        """

        if request.method == 'GET':
            issuer = self.database.get_issuer(uid)
            if issuer == None:
                log.info('GET Request for /issuers/{0} failed'.format(uid))
                return json.dumps({})
            else:
                log.info('Get Request for /issuers/{0} succeeded'.format(uid))
                return json.dumps(issuer.__json__())
        if request.method == 'DELETE':
            result = self.database.delete_issuer(uid)
            if result != False:
                log.info("DELETE Request for /issuers/{0} suceeded".format(uid))
                return json.dumps({'success': True, 'id': uid})
            else:
                log.info('DELETE Request for /issuers/{0} failed'.format(uid))
                return json.dumps({'success': False, 'id': uid})

    def add_issuer(self):
        """
        POST /issuers/
        Add a new issuer
        """

        try:
            data = json.loads(request.data)
        except:
            log.info("add_issuer Failed: Could not parse request.data")
            abort(503)
        try:
            issuer_id = self.database.add_badge(
                    data['origin'],
                    data['name'],
                    data['org'],
                    data['contact']
                    )
            log.info("Added issuer: {0}".format(data['name']))
            return json.dumps({'id': issuer_id})
        except KeyError:
            log.info("add_issuer Failed: JSON does not have required fields")
            abort(503)

    def assertions(self, email):
        """
        GET /assertions/<email>
        Return a list of all assertions awarded to the given email
        """
        results = self.database.get_assertions_by_email(email)
        if results == False:
            log.info("GET /assertions/{0} failed".format(email))
            return json.dumps({"success": False, "email": email})
        else:
            expanded_results = {
                    'success': True,
                    'assertions': [r.__json__() for r in results]}
            return json.dumps(expanded_results)

    def add_assertion(self):
        """
        POST /assertions/
        Add a new assertion
        """

        try:
            data = json.loads(request.data)
        except:
            log.info("add_assertion Failed: Could not parse request.data")
            abort(503)
        try:
            person_email, badge_id = self.database.add_assertion(
                    data['badge_id'],
                    data['person_email'],
                    data.get('issued_on', None)
                    )
            return json.dumps({
                'success': True,
                'badge_id': badge_id,
                'person_email': person_email
                })
        except KeyError:
            log.info("add_assertion Failed: JSON does not have the required fields")
            abort(503)
示例#18
0
from tahrir_api.dbapi import TahrirDatabase

db = TahrirDatabase('backend://*****:*****@localhost/badges')

badge_id = 'fossbox'
person_email = '*****@*****.**'
issued_on = None

db.add_person(person_email)
db.add_assertion(badge_id, person_email, issued_on)
示例#19
0
class TestDBInit(object):

    def setUp(self):
        check_output(['touch', 'testdb.db'])
        sqlalchemy_uri = "sqlite:///testdb.db"
        engine = create_engine(sqlalchemy_uri)
        DBSession.configure(bind=engine)
        DeclarativeBase.metadata.create_all(engine)

        self.api = TahrirDatabase(sqlalchemy_uri)

    def test_add_badges(self):
        self.api.add_badge(
            "TestBadge",
            "TestImage",
            "A test badge for doing unit tests",
            "TestCriteria",
            1337
        )

        assert self.api.badge_exists("testbadge") is True

    def test_add_person(self):
        self.api.add_person("*****@*****.**")
        assert self.api.person_exists("*****@*****.**") is True

    def test_add_issuer(self):
        _id = self.api.add_issuer(
            "TestOrigin",
            "TestName",
            "TestOrg",
            "TestContact"
        )
        assert self.api.issuer_exists("TestOrigin", "TestName") is True

    def test_add_invitation(self):
        badge_id = self.api.add_badge(
            "TestBadge",
            "TestImage",
            "A test badge for doing unit tests",
            "TestCriteria",
            1337
        )
        _id = self.api.add_invitation(
            badge_id,
        )

        assert self.api.invitation_exists(_id)

    def test_last_login(self):
        email = "*****@*****.**"
        person_id = self.api.add_person(email)
        person = self.api.get_person(person_id)
        assert not person.last_login
        self.api.note_login(nickname=person.nickname)
        assert person.last_login

    def test_add_assertion(self):
        issuer_id = self.api.add_issuer(
            "TestOrigin",
            "TestName",
            "TestOrg",
            "TestContact"
        )
        badge_id = self.api.add_badge(
            "TestBadge",
            "TestImage",
            "A test badge for doing unit tests",
            "TestCriteria",
            issuer_id,
        )
        email = "*****@*****.**"
        person_id = self.api.add_person(email)
        assertion_id = self.api.add_assertion(badge_id, email, None)
        assert self.api.assertion_exists(badge_id, email)

    def test_get_badges_from_tags(self):
        issuer_id = self.api.add_issuer(
            "TestOrigin",
            "TestName",
            "TestOrg",
            "TestContact"
        )

        # Badge tagged with "test"
        self.api.add_badge(
            "TestBadgeA",
            "TestImage",
            "A test badge for doing unit tests",
            "TestCriteria",
            issuer_id,
            tags="test"
        )

        # Badge tagged with "tester"
        self.api.add_badge(
            "TestBadgeB",
            "TestImage",
            "A second test badge for doing unit tests",
            "TestCriteria",
            issuer_id,
            tags="tester"
        )

        # Badge tagged with both "test" and "tester"
        self.api.add_badge(
            "TestBadgeC",
            "TestImage",
            "A third test badge for doing unit tests",
            "TestCriteria",
            issuer_id,
            tags="test, tester"
        )

        tags = ['test', 'tester']
        badges_any = self.api.get_badges_from_tags(tags, match_all=False)
        assert len(badges_any) == 3
        badges_all = self.api.get_badges_from_tags(tags, match_all=True)
        assert len(badges_all) == 1

    def tearDown(self):
        check_output(['rm', 'testdb.db'])