<commit_before># This software and any associated files are copyright 2010 Brian Carver and
# Michael Lissner.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

import settings
from django.core.management import setup_environ
setup_environ(settings)

from userHandling.models import UserProfile
from userHandling.models import FREQUENCY
from search.views import preparseQuery
from alertSystem.models import Document
from django.template import loader, Context
from django.core.mail import send_mail, EmailMultiAlternatives

import calendar
import datetime
import time
from optparse import OptionParser

def emailer(rate, verbose, simulate):
    """This will load all the users each day/week/month, and send them
    emails."""
    # remap the FREQUENCY variable from the model so the human keys relate
    # back to the indices
    rates = {}
    for r in FREQUENCY:
        rates[r[1].lower()] = r[0]
    RATE = rates[rate]

    # sphinx likes time in UnixTime format, which the below accomplishes.
    # There doesn't appear to be an easier way to do this. The output can be
    # tested in the shell with: date --date="2010-04-16" +%s
    # Unfortunately, Sphinx gets confused with negative dates, which is what
    # UnixTimes do before 1970. Thus, we add about 500 years.
    today = datetime.date.today()
    todayInt = today.toordinal() + 365
    dateIntsPastWeek = []
    dateIntsPastMonth = []
    i = 0
    while i < 7:
        dateIntsPastWeek.append(todayInt - (1 * i))
        i += 1
    i = 0
    while i < calendar.mdays[datetime.date.today().month]:
        dateIntsPastMonth.append(todayInt - (1 * i))
        i += 1

    EMAIL_SUBJECT = 'New hits for your alert at CourtListener.com'
    EMAIL_SENDER = 'no-reply@courtlistener.com'

    # query all users with alerts of the desired frequency
    # use the distinct method to only return one instance of each person.
    userProfiles = UserProfile.objects.filter(alert__alertFrequency = RATE)\
        .distinct()

    if verbose:
        print "todayInt: " + str(todayInt)
        print "dateIntsPastWeek: " + str(dateIntsPastWeek)
        print "dateIntsPastMonth: " + str(dateIntsPastMonth)
        print "userProfiles (with " + rate + " alerts): " + str(userProfiles)

    # for each user with a daily, weekly or monthly alert...
    for userProfile in userProfiles:
        #...get their alerts...
        alerts = userProfile.alert.filter(alertFrequency = RATE)
        if verbose:
            print "\n\n" + rate + " alerts for user " + userProfile.user\
                .email + ": " + str(alerts)

        hits = []
        # ...and iterate over their alerts.
        for alert in alerts:
            query = preparseQuery(alert.alertText)

            try:
                if verbose:
                    print "Now running the query: " + query
                if RATE == 'dly':
                    # query the alert
                    if verbose:
                        "Now running the search for: " + query
                    queryset = Document.search.query(query)
                    results = queryset.set_options(
                        mode="SPH_MATCH_EXTENDED2")\
                        .filter(datefiled=todayInt)
                elif RATE == 'wly' and today.weekday() == 6:
                    # if it's a weekly alert and today is Sunday
                    if verbose:
                        "Now running the search for: " + query
                    queryset = Document.search.query(query)
                    results = queryset.set_options(
                        mode="SPH_MATCH_EXTENDED2")\
                        .filter(datefiled=dateIntsPastWeek)
                elif RATE == 'mly' and today.day == 1:
                    # if it's a monthly alert and today is the first of the
                    # month
                    if verbose:
                        "Now running the search for: " + query
                    queryset = Document.search.query(query)
                    results = queryset.set_options(
                        mode="SPH_MATCH_EXTENDED2")\
                        .filter(datefiled=dateIntsPastMonth)
                elif RATE == "off":
                    pass
            except:
                # search occasionally fails. We need to log this.
                print "Search for this alert failed: " + query
                continue

            if verbose:
                print "The value of results is: " + str(results)
                print "The value of results.count() is: " + \
                    str(results.count())
                print "There were " + str(results.count()) + \
                " hits for the alert \"" + query + \
                "\". Here are the first 0-20: " + str(results)

            # hits is a multidimensional array. Ugh. It consists of alerts,
            # paired with a list of documents, of the form:
            # [[alert1, [hit1, hit2, hit3, hit4]], [alert2, [hit1, hit2]]]
            try:
                if results.count() > 0:
                    # very important! if you don't do the slicing here, you'll
                    # only get the first 20 hits. also very frustrating!
                    alertWithResults = [alert, results[0:results.count()]]
                    hits.append(alertWithResults)
                    # set the hit date to today
                    alert.lastHitDate = datetime.date.today()
                    alert.save()
                    if verbose:
                        print "alertWithResults: " + str(alertWithResults)
                        print "hits: " + str(hits)

                elif alert.sendNegativeAlert:
                    # if they want an alert even when no hits.
                    alertWithResults = [alert, "None"]
                    hits.append(alertWithResults)

                    if verbose:
                        print "Sending results for negative alert, " + \
                            query + "."
                        print "alertWithResults: " + str(alertWithResults)
                        print "hits: " + str(hits)
            except Exception,e:
                print "Search barfed on this alert: " + query
		print e

        if len(hits) > 0:
            # either the hits var has the value "None", or it has hits.
            if userProfile.plaintextPreferred:
                # send a plaintext email.
                txtTemplate = loader.get_template('emails/email.txt')
                c = Context({
                    'hits': hits,
                })
                email_text = txtTemplate.render(c)

                if verbose and simulate:
                    print "email_text: " + str(email_text)

                if not simulate:
                    send_mail(
                        EMAIL_SUBJECT,
                        email_text,
                        EMAIL_SENDER,
                        [userProfile.user.email],
                        fail_silently=False)
            else:
                # send a multi-part email
                txtTemplate = loader.get_template('emails/email.txt')
                htmlTemplate = loader.get_template('emails/email.html')
                c = Context({
                    'hits': hits,
                })
                email_text = txtTemplate.render(c)
                html_text = htmlTemplate.render(c)

                if verbose and simulate:
                    print "email_text: " + str(email_text)
                    print "html_text: " + str(html_text)

                if not simulate:
                    msg = EmailMultiAlternatives(EMAIL_SUBJECT, email_text,
                        EMAIL_SENDER, [userProfile.user.email])
                    msg.attach_alternative(html_text, "text/html")
                    msg.send(fail_silently=False)
        elif verbose:
            print "Not sending mail for this alert."

    return "Done"

def main():
    usage = "usage: %prog -r RATE [--verbose] [--simulate]"
    parser = OptionParser(usage)
    parser.add_option('-r', '--rate', dest='rate', metavar='RATE',
        help="The rate to send emails")
    parser.add_option('-v', '--verbose', action="store_true", dest='verbose',
        default=False, help="Display variable values during execution")
    parser.add_option('-s', '--simulate', action="store_true",
        dest='simulate', default=False, help="Simulate the emails that " +\
        "would be sent, using the console backend")
    (options, args) = parser.parse_args()
    if not options.rate:
        parser.error("You must specify a rate")

    rate = options.rate
    verbose = options.verbose
    simulate = options.simulate

    if simulate:
        print "******************"
        print "* NO EMAILS SENT *"
        print "******************"

    return emailer(rate, verbose, simulate)

if __name__ == '__main__':
    main()

<commit_msg>Fix to the sending script.<commit_after># This software and any associated files are copyright 2010 Brian Carver and
# Michael Lissner.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

import settings
from django.core.management import setup_environ
setup_environ(settings)

from userHandling.models import UserProfile
from userHandling.models import FREQUENCY
from search.views import preparseQuery
from alertSystem.models import Document
from django.template import loader, Context
from django.core.mail import send_mail, EmailMultiAlternatives

import calendar
import datetime
import time
from optparse import OptionParser

def emailer(rate, verbose, simulate):
    """This will load all the users each day/week/month, and send them
    emails."""
    # remap the FREQUENCY variable from the model so the human keys relate
    # back to the indices
    rates = {}
    for r in FREQUENCY:
        rates[r[1].lower()] = r[0]
    RATE = rates[rate]

    # sphinx likes time in UnixTime format, which the below accomplishes.
    # There doesn't appear to be an easier way to do this. The output can be
    # tested in the shell with: date --date="2010-04-16" +%s
    # Unfortunately, Sphinx gets confused with negative dates, which is what
    # UnixTimes do before 1970. Thus, we add about 500 years.
    today = datetime.date.today()
    todayInt = today.toordinal() + 365
    dateIntsPastWeek = []
    dateIntsPastMonth = []
    i = 0
    while i < 7:
        dateIntsPastWeek.append(todayInt - (1 * i))
        i += 1
    i = 0
    while i < calendar.mdays[datetime.date.today().month]:
        dateIntsPastMonth.append(todayInt - (1 * i))
        i += 1

    EMAIL_SUBJECT = 'New hits for your alert at CourtListener.com'
    EMAIL_SENDER = 'no-reply@courtlistener.com'

    # query all users with alerts of the desired frequency
    # use the distinct method to only return one instance of each person.
    userProfiles = UserProfile.objects.filter(alert__alertFrequency = RATE)\
        .distinct()

    if verbose:
        print "todayInt: " + str(todayInt)
        print "dateIntsPastWeek: " + str(dateIntsPastWeek)
        print "dateIntsPastMonth: " + str(dateIntsPastMonth)
        print "userProfiles (with " + rate + " alerts): " + str(userProfiles)

    # for each user with a daily, weekly or monthly alert...
    for userProfile in userProfiles:
        #...get their alerts...
        alerts = userProfile.alert.filter(alertFrequency = RATE)
        if verbose:
            print "\n\n" + rate + " alerts for user " + userProfile.user\
                .email + ": " + str(alerts)

        hits = []
        # ...and iterate over their alerts.
        for alert in alerts:
            query = preparseQuery(alert.alertText)

            try:
                if verbose:
                    print "Now running the query: " + query
                if RATE == 'dly':
                    # query the alert
                    if verbose:
                        "Now running the search for: " + query
                    queryset = Document.search.query(query)
                    results = queryset.set_options(
                        mode="SPH_MATCH_EXTENDED2")\
                        .filter(dateFiled=todayInt)
                elif RATE == 'wly' and today.weekday() == 6:
                    # if it's a weekly alert and today is Sunday
                    if verbose:
                        "Now running the search for: " + query
                    queryset = Document.search.query(query)
                    results = queryset.set_options(
                        mode="SPH_MATCH_EXTENDED2")\
                        .filter(dateFiled=dateIntsPastWeek)
                elif RATE == 'mly' and today.day == 1:
                    # if it's a monthly alert and today is the first of the
                    # month
                    if verbose:
                        "Now running the search for: " + query
                    queryset = Document.search.query(query)
                    results = queryset.set_options(
                        mode="SPH_MATCH_EXTENDED2")\
                        .filter(dateFiled=dateIntsPastMonth)
                elif RATE == "off":
                    pass
            except:
                # search occasionally fails. We need to log this.
                print "Search for this alert failed: " + query
                continue

            if verbose:
                print "The value of results is: " + str(results)
                print "The value of results.count() is: " + \
                    str(results.count())
                print "There were " + str(results.count()) + \
                " hits for the alert \"" + query + \
                "\". Here are the first 0-20: " + str(results)

            # hits is a multidimensional array. Ugh. It consists of alerts,
            # paired with a list of documents, of the form:
            # [[alert1, [hit1, hit2, hit3, hit4]], [alert2, [hit1, hit2]]]
            try:
                if results.count() > 0:
                    # very important! if you don't do the slicing here, you'll
                    # only get the first 20 hits. also very frustrating!
                    alertWithResults = [alert, results[0:results.count()]]
                    hits.append(alertWithResults)
                    # set the hit date to today
                    alert.lastHitDate = datetime.date.today()
                    alert.save()
                    if verbose:
                        print "alertWithResults: " + str(alertWithResults)
                        print "hits: " + str(hits)

                elif alert.sendNegativeAlert:
                    # if they want an alert even when no hits.
                    alertWithResults = [alert, "None"]
                    hits.append(alertWithResults)

                    if verbose:
                        print "Sending results for negative alert, " + \
                            query + "."
                        print "alertWithResults: " + str(alertWithResults)
                        print "hits: " + str(hits)
            except Exception,e:
                print "Search barfed on this alert: " + query
		print e

        if len(hits) > 0:
            # either the hits var has the value "None", or it has hits.
            if userProfile.plaintextPreferred:
                # send a plaintext email.
                txtTemplate = loader.get_template('emails/email.txt')
                c = Context({
                    'hits': hits,
                })
                email_text = txtTemplate.render(c)

                if verbose and simulate:
                    print "email_text: " + str(email_text)

                if not simulate:
                    send_mail(
                        EMAIL_SUBJECT,
                        email_text,
                        EMAIL_SENDER,
                        [userProfile.user.email],
                        fail_silently=False)
            else:
                # send a multi-part email
                txtTemplate = loader.get_template('emails/email.txt')
                htmlTemplate = loader.get_template('emails/email.html')
                c = Context({
                    'hits': hits,
                })
                email_text = txtTemplate.render(c)
                html_text = htmlTemplate.render(c)

                if verbose and simulate:
                    print "email_text: " + str(email_text)
                    print "html_text: " + str(html_text)

                if not simulate:
                    msg = EmailMultiAlternatives(EMAIL_SUBJECT, email_text,
                        EMAIL_SENDER, [userProfile.user.email])
                    msg.attach_alternative(html_text, "text/html")
                    msg.send(fail_silently=False)
        elif verbose:
            print "Not sending mail for this alert."

    return "Done"

def main():
    usage = "usage: %prog -r RATE [--verbose] [--simulate]"
    parser = OptionParser(usage)
    parser.add_option('-r', '--rate', dest='rate', metavar='RATE',
        help="The rate to send emails")
    parser.add_option('-v', '--verbose', action="store_true", dest='verbose',
        default=False, help="Display variable values during execution")
    parser.add_option('-s', '--simulate', action="store_true",
        dest='simulate', default=False, help="Simulate the emails that " +\
        "would be sent, using the console backend")
    (options, args) = parser.parse_args()
    if not options.rate:
        parser.error("You must specify a rate")

    rate = options.rate
    verbose = options.verbose
    simulate = options.simulate

    if simulate:
        print "******************"
        print "* NO EMAILS SENT *"
        print "******************"

    return emailer(rate, verbose, simulate)

if __name__ == '__main__':
    main()

<|endoftext|>


<commit_before>from django.utils.translation import ugettext as _
from django.utils import timezone
from django.core.urlresolvers import reverse
from django.db import models
from django.core.exceptions import ValidationError
from django.db.models.aggregates import Sum
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.conf import settings
from django.contrib.auth.models import AnonymousUser

from django_extensions.db.fields import AutoSlugField

from datetime import timedelta

from jury.models import Jury

class DeckBaseManager(models.Manager):
    def cached_authors(self):
        return super(DeckBaseManager, self).select_related('author')

    def published_ones(self):
        return self.cached_authors().filter(is_published=True)

class DeckBaseModel(models.Model):
    title = models.CharField(_('Title'), max_length=200)
    slug = AutoSlugField(populate_from='title', overwrite=True,
                         max_length=200, unique=True, db_index=True)
    description = models.TextField(_('Description'), max_length=400)
    created_at = models.DateTimeField(_('Created At'), auto_now_add=True)
    is_published = models.BooleanField(_('Publish'), default=False)

    # relations
    author = models.ForeignKey(to=settings.AUTH_USER_MODEL,
                               related_name='%(class)ss')

    # managers
    objects = DeckBaseManager()

    class Meta:
        abstract = True

    def __unicode__(self):
        return unicode(self.title)

class Vote(models.Model):
    ANGRY, SLEEPY, SAD, HAPPY, LAUGHING = range(-1, 4)
    VOTE_RATES = ((ANGRY, 'angry'),
                  (SAD, 'sad'),
                  (SLEEPY, 'sleepy'),
                  (HAPPY, 'happy'),
                  (LAUGHING, 'laughing'))
    rate = models.SmallIntegerField(_('Rate Index'), null=True, blank=True,
                                    choices=VOTE_RATES)

    proposal = models.ForeignKey(to='deck.Proposal', related_name='votes')
    user = models.ForeignKey(to=settings.AUTH_USER_MODEL, related_name='votes')

    class Meta:
        verbose_name = _('Vote')
        verbose_name_plural = _('Votes')
        unique_together = (('proposal', 'user'),)

    def __unicode__(self):
        return u"{0.user}: {0.rate} in {0.proposal}".format(self)

    def save(self, *args, **kwargs):
        validation_message = None

        user_is_in_jury = self.proposal.event.jury.users.filter(
            pk=self.user.pk).exists()
        if (self.user.is_superuser or user_is_in_jury):
            pass
        elif self.user == self.proposal.author:
            validation_message = 'You cannot Rate your own proposals.'
        elif not self.proposal.event.allow_public_voting:
            validation_message = "Proposal doesn't accept Public Voting."
        elif self.proposal.user_already_votted(self.user):
            validation_message = 'Proposal already Rated by you.'

        if validation_message:
            raise ValidationError(_(validation_message))

        return super(Vote, self).save(*args, **kwargs)

class Proposal(DeckBaseModel):
    # relations
    event = models.ForeignKey(to='deck.Event', related_name='proposals')

    class Meta:
        verbose_name = _('Proposal')
        verbose_name_plural = _('Proposals')

    def save(self, *args, **kwargs):
        if self.event.due_date_is_passed:
            raise ValidationError(
                _("This Event doesn't accept Proposals anymore."))
        return super(Proposal, self).save(*args, **kwargs)

    @property
    def rate(self):
        return self.votes.aggregate(Sum('rate'))['rate__sum'] or 0

    def user_already_votted(self, user):
        if isinstance(user, AnonymousUser):
            return False
        return self.votes.filter(user=user).exists()

    def user_can_vote(self, user):
        can_vote = False
        if self.user_already_votted(user) or \
           (self.author == user and not self.event.author == user):
            pass
        elif self.event.allow_public_voting:
            can_vote = True
        elif user.is_superuser:
            can_vote = True
        elif self.event.jury.users.filter(pk=user.pk).exists():
            can_vote = True
        return can_vote

    def get_absolute_url(self):
        return reverse('view_event', kwargs={'slug': self.event.slug})

class Event(DeckBaseModel):
    allow_public_voting = models.BooleanField(_('Allow Public Voting'),
                                              default=True)
    due_date = models.DateTimeField(null=True, blank=True)

    # relations
    jury = models.OneToOneField(to='jury.Jury', related_name='event',
                                null=True, blank=True)

    class Meta:
        ordering = ['-created_at']
        verbose_name = _('Event')
        verbose_name_plural = _('Events')

    def get_absolute_url(self):
        return reverse('view_event', kwargs={'slug': self.slug})

    @property
    def due_date_is_passed(self):
        if not self.due_date:
            return False
        yesterday = timezone.now() - timedelta(hours=24)
        return yesterday > self.due_date

    def user_can_see_proposals(self, user):
        can_see_proposals = False
        if user.is_superuser or self.author == user:
            can_see_proposals = True
        elif self.allow_public_voting:
            can_see_proposals = True
        elif (not user.is_anonymous() and
              self.jury.users.filter(pk=user.pk).exists()):
            can_see_proposals = True
        return can_see_proposals

@receiver(post_save, sender=Event)
def create_initial_jury(sender, instance, signal, created, **kwargs):
    if not created:
        return
    jury = Jury()
    jury.save()
    jury.users.add(instance.author)
    instance.jury = jury
    instance.save()
<commit_msg>Increase max_length (10000) to description field<commit_after>from django.utils.translation import ugettext as _
from django.utils import timezone
from django.core.urlresolvers import reverse
from django.db import models
from django.core.exceptions import ValidationError
from django.db.models.aggregates import Sum
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.conf import settings
from django.contrib.auth.models import AnonymousUser

from django_extensions.db.fields import AutoSlugField

from datetime import timedelta

from jury.models import Jury

class DeckBaseManager(models.Manager):
    def cached_authors(self):
        return super(DeckBaseManager, self).select_related('author')

    def published_ones(self):
        return self.cached_authors().filter(is_published=True)

class DeckBaseModel(models.Model):
    title = models.CharField(_('Title'), max_length=200)
    slug = AutoSlugField(populate_from='title', overwrite=True,
                         max_length=200, unique=True, db_index=True)
    description = models.TextField(_('Description'), max_length=10000)
    created_at = models.DateTimeField(_('Created At'), auto_now_add=True)
    is_published = models.BooleanField(_('Publish'), default=False)

    # relations
    author = models.ForeignKey(to=settings.AUTH_USER_MODEL,
                               related_name='%(class)ss')

    # managers
    objects = DeckBaseManager()

    class Meta:
        abstract = True

    def __unicode__(self):
        return unicode(self.title)

class Vote(models.Model):
    ANGRY, SLEEPY, SAD, HAPPY, LAUGHING = range(-1, 4)
    VOTE_RATES = ((ANGRY, 'angry'),
                  (SAD, 'sad'),
                  (SLEEPY, 'sleepy'),
                  (HAPPY, 'happy'),
                  (LAUGHING, 'laughing'))
    rate = models.SmallIntegerField(_('Rate Index'), null=True, blank=True,
                                    choices=VOTE_RATES)

    proposal = models.ForeignKey(to='deck.Proposal', related_name='votes')
    user = models.ForeignKey(to=settings.AUTH_USER_MODEL, related_name='votes')

    class Meta:
        verbose_name = _('Vote')
        verbose_name_plural = _('Votes')
        unique_together = (('proposal', 'user'),)

    def __unicode__(self):
        return u"{0.user}: {0.rate} in {0.proposal}".format(self)

    def save(self, *args, **kwargs):
        validation_message = None

        user_is_in_jury = self.proposal.event.jury.users.filter(
            pk=self.user.pk).exists()
        if (self.user.is_superuser or user_is_in_jury):
            pass
        elif self.user == self.proposal.author:
            validation_message = 'You cannot Rate your own proposals.'
        elif not self.proposal.event.allow_public_voting:
            validation_message = "Proposal doesn't accept Public Voting."
        elif self.proposal.user_already_votted(self.user):
            validation_message = 'Proposal already Rated by you.'

        if validation_message:
            raise ValidationError(_(validation_message))

        return super(Vote, self).save(*args, **kwargs)

class Proposal(DeckBaseModel):
    # relations
    event = models.ForeignKey(to='deck.Event', related_name='proposals')

    class Meta:
        verbose_name = _('Proposal')
        verbose_name_plural = _('Proposals')

    def save(self, *args, **kwargs):
        if self.event.due_date_is_passed:
            raise ValidationError(
                _("This Event doesn't accept Proposals anymore."))
        return super(Proposal, self).save(*args, **kwargs)

    @property
    def rate(self):
        return self.votes.aggregate(Sum('rate'))['rate__sum'] or 0

    def user_already_votted(self, user):
        if isinstance(user, AnonymousUser):
            return False
        return self.votes.filter(user=user).exists()

    def user_can_vote(self, user):
        can_vote = False
        if self.user_already_votted(user) or \
           (self.author == user and not self.event.author == user):
            pass
        elif self.event.allow_public_voting:
            can_vote = True
        elif user.is_superuser:
            can_vote = True
        elif self.event.jury.users.filter(pk=user.pk).exists():
            can_vote = True
        return can_vote

    def get_absolute_url(self):
        return reverse('view_event', kwargs={'slug': self.event.slug})

class Event(DeckBaseModel):
    allow_public_voting = models.BooleanField(_('Allow Public Voting'),
                                              default=True)
    due_date = models.DateTimeField(null=True, blank=True)

    # relations
    jury = models.OneToOneField(to='jury.Jury', related_name='event',
                                null=True, blank=True)

    class Meta:
        ordering = ['-created_at']
        verbose_name = _('Event')
        verbose_name_plural = _('Events')

    def get_absolute_url(self):
        return reverse('view_event', kwargs={'slug': self.slug})

    @property
    def due_date_is_passed(self):
        if not self.due_date:
            return False
        yesterday = timezone.now() - timedelta(hours=24)
        return yesterday > self.due_date

    def user_can_see_proposals(self, user):
        can_see_proposals = False
        if user.is_superuser or self.author == user:
            can_see_proposals = True
        elif self.allow_public_voting:
            can_see_proposals = True
        elif (not user.is_anonymous() and
              self.jury.users.filter(pk=user.pk).exists()):
            can_see_proposals = True
        return can_see_proposals

@receiver(post_save, sender=Event)
def create_initial_jury(sender, instance, signal, created, **kwargs):
    if not created:
        return
    jury = Jury()
    jury.save()
    jury.users.add(instance.author)
    instance.jury = jury
    instance.save()
<|endoftext|>


<commit_before># UPowerManger Class Copyright (C) 2017 Oscar Svensson (wogscpar) under MIT licence from upower-python

"""Displays battery status, remaining percentage and charging information.

Parameters:
    * battery-upower.warning      : Warning threshold in % of remaining charge (defaults to 20)
    * battery-upower.critical     : Critical threshold in % of remaining charge (defaults to 10)
    * battery-upower.showremaining : If set to true (default) shows the remaining time until the batteries are completely discharged
"""

import dbus
import logging

import bumblebee.input
import bumblebee.output
import bumblebee.engine
import bumblebee.util

class UPowerManager():

    def __init__(self):
        self.UPOWER_NAME = "org.freedesktop.UPower"
        self.UPOWER_PATH = "/org/freedesktop/UPower"

        self.DBUS_PROPERTIES = "org.freedesktop.DBus.Properties"
        self.bus = dbus.SystemBus()

    def detect_devices(self):
        upower_proxy = self.bus.get_object(self.UPOWER_NAME, self.UPOWER_PATH)
        upower_interface = dbus.Interface(upower_proxy, self.UPOWER_NAME)

        devices = upower_interface.EnumerateDevices()
        return devices

    def get_display_device(self):
        upower_proxy = self.bus.get_object(self.UPOWER_NAME, self.UPOWER_PATH)
        upower_interface = dbus.Interface(upower_proxy, self.UPOWER_NAME)

        dispdev = upower_interface.GetDisplayDevice()
        return dispdev

    def get_critical_action(self):
        upower_proxy = self.bus.get_object(self.UPOWER_NAME, self.UPOWER_PATH)
        upower_interface = dbus.Interface(upower_proxy, self.UPOWER_NAME)

        critical_action = upower_interface.GetCriticalAction()
        return critical_action

    def get_device_percentage(self, battery):
        battery_proxy = self.bus.get_object(self.UPOWER_NAME, battery)
        battery_proxy_interface = dbus.Interface(battery_proxy, self.DBUS_PROPERTIES)

        return battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "Percentage")

    def get_full_device_information(self, battery):
        battery_proxy = self.bus.get_object(self.UPOWER_NAME, battery)
        battery_proxy_interface = dbus.Interface(battery_proxy, self.DBUS_PROPERTIES)

        hasHistory = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "HasHistory")
        hasStatistics = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "HasStatistics")
        isPresent = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "IsPresent")
        isRechargable = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "IsRechargeable")
        online = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "Online")
        powersupply = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "PowerSupply")
        capacity = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "Capacity")
        energy = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "Energy")
        energyempty = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "EnergyEmpty")
        energyfull = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "EnergyFull")
        energyfulldesign = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "EnergyFullDesign")
        energyrate = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "EnergyRate")
        luminosity = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "Luminosity")
        percentage = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "Percentage")
        temperature = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "Temperature")
        voltage = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "Voltage")
        timetoempty = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "TimeToEmpty")
        timetofull = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "TimeToFull")
        iconname = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "IconName")
        model = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "Model")
        nativepath = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "NativePath")
        serial = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "Serial")
        vendor = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "Vendor")
        state = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "State")
        technology = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "Technology")
        battype = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "Type")
        warninglevel = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "WarningLevel")
        updatetime = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "UpdateTime")

        information_table = {
            'HasHistory': hasHistory,
            'HasStatistics': hasStatistics,
            'IsPresent': isPresent,
            'IsRechargeable': isRechargable,
            'Online': online,
            'PowerSupply': powersupply,
            'Capacity': capacity,
            'Energy': energy,
            'EnergyEmpty': energyempty,
            'EnergyFull': energyfull,
            'EnergyFullDesign': energyfulldesign,
            'EnergyRate': energyrate,
            'Luminosity': luminosity,
            'Percentage': percentage,
            'Temperature': temperature,
            'Voltage': voltage,
            'TimeToEmpty': timetoempty,
            'TimeToFull': timetofull,
            'IconName': iconname,
            'Model': model,
            'NativePath': nativepath,
            'Serial': serial,
            'Vendor': vendor,
            'State': state,
            'Technology': technology,
            'Type': battype,
            'WarningLevel': warninglevel,
            'UpdateTime': updatetime
        }

        return information_table

    def is_lid_present(self):
        upower_proxy = self.bus.get_object(self.UPOWER_NAME, self.UPOWER_PATH)
        upower_interface = dbus.Interface(upower_proxy, self.DBUS_PROPERTIES)

        is_lid_present = bool(upower_interface.Get(self.UPOWER_NAME, 'LidIsPresent'))
        return is_lid_present

    def is_lid_closed(self):
        upower_proxy = self.bus.get_object(self.UPOWER_NAME, self.UPOWER_PATH)
        upower_interface = dbus.Interface(upower_proxy, self.DBUS_PROPERTIES)

        is_lid_closed = bool(upower_interface.Get(self.UPOWER_NAME, 'LidIsClosed'))
        return is_lid_closed

    def on_battery(self):
        upower_proxy = self.bus.get_object(self.UPOWER_NAME, self.UPOWER_PATH)
        upower_interface = dbus.Interface(upower_proxy, self.DBUS_PROPERTIES)

        on_battery = bool(upower_interface.Get(self.UPOWER_NAME, 'OnBattery'))
        return on_battery

    def has_wakeup_capabilities(self):
        upower_proxy = self.bus.get_object(self.UPOWER_NAME, self.UPOWER_PATH + "/Wakeups")
        upower_interface = dbus.Interface(upower_proxy, self.DBUS_PROPERTIES)

        has_wakeup_capabilities = bool(upower_interface.Get(self.UPOWER_NAME + '.Wakeups', 'HasCapability'))
        return has_wakeup_capabilities

    def get_wakeups_data(self):
        upower_proxy = self.bus.get_object(self.UPOWER_NAME, self.UPOWER_PATH + "/Wakeups")
        upower_interface = dbus.Interface(upower_proxy, self.UPOWER_NAME + '.Wakeups')

        data = upower_interface.GetData()
        return data

    def get_wakeups_total(self):
        upower_proxy = self.bus.get_object(self.UPOWER_NAME, self.UPOWER_PATH + "/Wakeups")
        upower_interface = dbus.Interface(upower_proxy, self.UPOWER_NAME + '.Wakeups')

        data = upower_interface.GetTotal()
        return data

    def is_loading(self, battery):
        battery_proxy = self.bus.get_object(self.UPOWER_NAME, battery)
        battery_proxy_interface = dbus.Interface(battery_proxy, self.DBUS_PROPERTIES)

        state = int(battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "State"))

        if (state == 1):
            return True
        else:
            return False

    def get_state(self, battery):
        battery_proxy = self.bus.get_object(self.UPOWER_NAME, battery)
        battery_proxy_interface = dbus.Interface(battery_proxy, self.DBUS_PROPERTIES)

        state = int(battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "State"))

        if (state == 0):
            return "Unknown"
        elif (state == 1):
            return "Loading"
        elif (state == 2):
            return "Discharging"
        elif (state == 3):
            return "Empty"
        elif (state == 4):
            return "Fully charged"
        elif (state == 5):
            return "Pending charge"
        elif (state == 6):
            return "Pending discharge"

class Module(bumblebee.engine.Module):
    def __init__(self, engine, config):
        super(Module, self).__init__(engine, config, bumblebee.output.Widget(full_text=self.capacity))
        try:
            self.power = UPowerManager()
            self.device = self.power.get_display_device()
        except Exception as e:
            logging.exception("unable to get battery display device: {}".format(str(e)))
        engine.input.register_callback(self, button=bumblebee.input.LEFT_MOUSE,
                                       cmd="gnome-power-statistics")

        self._showremaining = bumblebee.util.asbool(
            self.parameter("showremaining", True))

    def capacity(self, widget):
        widget.set("capacity", -1)
        widget.set("ac", False)
        output = "n/a"
        try:
            capacity = int(self.power.get_device_percentage(self.device))
            capacity = capacity if capacity < 100 else 100
            widget.set("capacity", capacity)
            output = "{}%".format(capacity)
            widget.set("theme.minwidth", "100%")
        except Exception as e:
            logging.exception("unable to get battery capacity: {}".format(str(e)))

        if self._showremaining:
            try:
                p = self.power # an alias to make each line of code shorter
                proxy = p.bus.get_object(p.UPOWER_NAME, self.device)
                interface = dbus.Interface(proxy, p.DBUS_PROPERTIES)
                state = int(interface.Get(p.UPOWER_NAME+".Device", "State"))
                # state: 1 => charging, 2 => discharging, other => don't care
                remain = int(interface.Get(
                    p.UPOWER_NAME+".Device", ["TimeToFull", "TimeToEmpty"][state-1]))
                remain = bumblebee.util.durationfmt(remain, shorten=True, suffix=True)
                output = "{} {}".format(output, remain)
            except IndexError:
                pass
            except Exception as e:
                logging.exception("unable to get battery remaining time: {}".format(str(e)))

        return output

    def state(self, widget):
        state = []
        capacity = widget.get("capacity", -1)
        if capacity < 0:
            return ["critical", "unknown"]

        if capacity < int(self.parameter("critical", 10)):
            state.append("critical")
        elif capacity < int(self.parameter("warning", 20)):
            state.append("warning")

        if widget.get("ac"):
            state.append("AC")
        else:
            charge = "Unknown"
            try:
                charge = self.power.get_state(self.device)
            except Exception as e:
                logging.exception("unable to get charge value: {}".format(str(e)))
            if charge == "Discharging":
                state.append("discharging-{}".format(min([10, 25, 50, 80, 100], key=lambda i: abs(i - capacity))))
            elif charge == "Unknown":
                state.append("unknown-{}".format(min([10, 25, 50, 80, 100], key=lambda i: abs(i - capacity))))
            else:
                if capacity > 95:
                    state.append("charged")
                else:
                    state.append("charging")
        return state

# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
<commit_msg>[modules/upower] Update to latest API<commit_after># UPowerManger Class Copyright (C) 2017 Oscar Svensson (wogscpar) under MIT licence from upower-python

"""Displays battery status, remaining percentage and charging information.

Parameters:
    * battery-upower.warning      : Warning threshold in % of remaining charge (defaults to 20)
    * battery-upower.critical     : Critical threshold in % of remaining charge (defaults to 10)
    * battery-upower.showremaining : If set to true (default) shows the remaining time until the batteries are completely discharged
"""

import dbus
import logging

import core.module
import core.widget
import core.input

import util.format

class UPowerManager():
    def __init__(self):
        self.UPOWER_NAME = "org.freedesktop.UPower"
        self.UPOWER_PATH = "/org/freedesktop/UPower"

        self.DBUS_PROPERTIES = "org.freedesktop.DBus.Properties"
        self.bus = dbus.SystemBus()

    def detect_devices(self):
        upower_proxy = self.bus.get_object(self.UPOWER_NAME, self.UPOWER_PATH)
        upower_interface = dbus.Interface(upower_proxy, self.UPOWER_NAME)

        devices = upower_interface.EnumerateDevices()
        return devices

    def get_display_device(self):
        upower_proxy = self.bus.get_object(self.UPOWER_NAME, self.UPOWER_PATH)
        upower_interface = dbus.Interface(upower_proxy, self.UPOWER_NAME)

        dispdev = upower_interface.GetDisplayDevice()
        return dispdev

    def get_critical_action(self):
        upower_proxy = self.bus.get_object(self.UPOWER_NAME, self.UPOWER_PATH)
        upower_interface = dbus.Interface(upower_proxy, self.UPOWER_NAME)

        critical_action = upower_interface.GetCriticalAction()
        return critical_action

    def get_device_percentage(self, battery):
        battery_proxy = self.bus.get_object(self.UPOWER_NAME, battery)
        battery_proxy_interface = dbus.Interface(battery_proxy, self.DBUS_PROPERTIES)

        return battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "Percentage")

    def get_full_device_information(self, battery):
        battery_proxy = self.bus.get_object(self.UPOWER_NAME, battery)
        battery_proxy_interface = dbus.Interface(battery_proxy, self.DBUS_PROPERTIES)

        hasHistory = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "HasHistory")
        hasStatistics = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "HasStatistics")
        isPresent = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "IsPresent")
        isRechargable = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "IsRechargeable")
        online = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "Online")
        powersupply = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "PowerSupply")
        capacity = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "Capacity")
        energy = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "Energy")
        energyempty = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "EnergyEmpty")
        energyfull = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "EnergyFull")
        energyfulldesign = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "EnergyFullDesign")
        energyrate = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "EnergyRate")
        luminosity = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "Luminosity")
        percentage = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "Percentage")
        temperature = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "Temperature")
        voltage = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "Voltage")
        timetoempty = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "TimeToEmpty")
        timetofull = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "TimeToFull")
        iconname = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "IconName")
        model = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "Model")
        nativepath = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "NativePath")
        serial = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "Serial")
        vendor = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "Vendor")
        state = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "State")
        technology = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "Technology")
        battype = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "Type")
        warninglevel = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "WarningLevel")
        updatetime = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "UpdateTime")

        information_table = {
            'HasHistory': hasHistory,
            'HasStatistics': hasStatistics,
            'IsPresent': isPresent,
            'IsRechargeable': isRechargable,
            'Online': online,
            'PowerSupply': powersupply,
            'Capacity': capacity,
            'Energy': energy,
            'EnergyEmpty': energyempty,
            'EnergyFull': energyfull,
            'EnergyFullDesign': energyfulldesign,
            'EnergyRate': energyrate,
            'Luminosity': luminosity,
            'Percentage': percentage,
            'Temperature': temperature,
            'Voltage': voltage,
            'TimeToEmpty': timetoempty,
            'TimeToFull': timetofull,
            'IconName': iconname,
            'Model': model,
            'NativePath': nativepath,
            'Serial': serial,
            'Vendor': vendor,
            'State': state,
            'Technology': technology,
            'Type': battype,
            'WarningLevel': warninglevel,
            'UpdateTime': updatetime
        }

        return information_table

    def is_lid_present(self):
        upower_proxy = self.bus.get_object(self.UPOWER_NAME, self.UPOWER_PATH)
        upower_interface = dbus.Interface(upower_proxy, self.DBUS_PROPERTIES)

        is_lid_present = bool(upower_interface.Get(self.UPOWER_NAME, 'LidIsPresent'))
        return is_lid_present

    def is_lid_closed(self):
        upower_proxy = self.bus.get_object(self.UPOWER_NAME, self.UPOWER_PATH)
        upower_interface = dbus.Interface(upower_proxy, self.DBUS_PROPERTIES)

        is_lid_closed = bool(upower_interface.Get(self.UPOWER_NAME, 'LidIsClosed'))
        return is_lid_closed

    def on_battery(self):
        upower_proxy = self.bus.get_object(self.UPOWER_NAME, self.UPOWER_PATH)
        upower_interface = dbus.Interface(upower_proxy, self.DBUS_PROPERTIES)

        on_battery = bool(upower_interface.Get(self.UPOWER_NAME, 'OnBattery'))
        return on_battery

    def has_wakeup_capabilities(self):
        upower_proxy = self.bus.get_object(self.UPOWER_NAME, self.UPOWER_PATH + "/Wakeups")
        upower_interface = dbus.Interface(upower_proxy, self.DBUS_PROPERTIES)

        has_wakeup_capabilities = bool(upower_interface.Get(self.UPOWER_NAME + '.Wakeups', 'HasCapability'))
        return has_wakeup_capabilities

    def get_wakeups_data(self):
        upower_proxy = self.bus.get_object(self.UPOWER_NAME, self.UPOWER_PATH + "/Wakeups")
        upower_interface = dbus.Interface(upower_proxy, self.UPOWER_NAME + '.Wakeups')

        data = upower_interface.GetData()
        return data

    def get_wakeups_total(self):
        upower_proxy = self.bus.get_object(self.UPOWER_NAME, self.UPOWER_PATH + "/Wakeups")
        upower_interface = dbus.Interface(upower_proxy, self.UPOWER_NAME + '.Wakeups')

        data = upower_interface.GetTotal()
        return data

    def is_loading(self, battery):
        battery_proxy = self.bus.get_object(self.UPOWER_NAME, battery)
        battery_proxy_interface = dbus.Interface(battery_proxy, self.DBUS_PROPERTIES)

        state = int(battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "State"))

        if (state == 1):
            return True
        else:
            return False

    def get_state(self, battery):
        battery_proxy = self.bus.get_object(self.UPOWER_NAME, battery)
        battery_proxy_interface = dbus.Interface(battery_proxy, self.DBUS_PROPERTIES)

        state = int(battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "State"))

        if (state == 0):
            return "Unknown"
        elif (state == 1):
            return "Loading"
        elif (state == 2):
            return "Discharging"
        elif (state == 3):
            return "Empty"
        elif (state == 4):
            return "Fully charged"
        elif (state == 5):
            return "Pending charge"
        elif (state == 6):
            return "Pending discharge"

class Module(core.module.Module):
    def __init__(self, config):
        super().__init__(config, core.widget.Widget(self.capacity))

        try:
            self.power = UPowerManager()
            self.device = self.power.get_display_device()
        except Exception as e:
            logging.exception("unable to get battery display device: {}".format(str(e)))
        core.input.register(self, button=core.input.LEFT_MOUSE,
            cmd="gnome-power-statistics")

        self._showremaining = util.format.asbool(
            self.parameter("showremaining", True))

    def capacity(self, widget):
        widget.set("capacity", -1)
        widget.set("ac", False)
        output = "n/a"
        try:
            capacity = int(self.power.get_device_percentage(self.device))
            capacity = capacity if capacity < 100 else 100
            widget.set("capacity", capacity)
            output = "{}%".format(capacity)
            widget.set("theme.minwidth", "100%")
        except Exception as e:
            logging.exception("unable to get battery capacity: {}".format(str(e)))

        if self._showremaining:
            try:
                p = self.power # an alias to make each line of code shorter
                proxy = p.bus.get_object(p.UPOWER_NAME, self.device)
                interface = dbus.Interface(proxy, p.DBUS_PROPERTIES)
                state = int(interface.Get(p.UPOWER_NAME+".Device", "State"))
                # state: 1 => charging, 2 => discharging, other => don't care
                remain = int(interface.Get(
                    p.UPOWER_NAME+".Device", ["TimeToFull", "TimeToEmpty"][state-1]))
                remain = util.format.duration(remain, compact=True, unit=True)
                output = "{} {}".format(output, remain)
            except IndexError:
                pass
            except Exception as e:
                logging.exception("unable to get battery remaining time: {}".format(str(e)))

        return output

    def state(self, widget):
        state = []
        capacity = widget.get("capacity", -1)
        if capacity < 0:
            return ["critical", "unknown"]

        if capacity < int(self.parameter("critical", 10)):
            state.append("critical")
        elif capacity < int(self.parameter("warning", 20)):
            state.append("warning")

        if widget.get("ac"):
            state.append("AC")
        else:
            charge = "Unknown"
            try:
                charge = self.power.get_state(self.device)
            except Exception as e:
                logging.exception("unable to get charge value: {}".format(str(e)))
            if charge == "Discharging":
                state.append("discharging-{}".format(min([10, 25, 50, 80, 100], key=lambda i: abs(i - capacity))))
            elif charge == "Unknown":
                state.append("unknown-{}".format(min([10, 25, 50, 80, 100], key=lambda i: abs(i - capacity))))
            else:
                if capacity > 95:
                    state.append("charged")
                else:
                    state.append("charging")
        return state

# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
<|endoftext|>


<commit_before>from nipype.interfaces.base import File, traits
from nipype.interfaces import ants

class ANTSInputSpecRPT(ants.ANTSInputSpec):
    generate_report = traits.Bool(
        desc="Set to true to enable report generation for node"
    )

class ANTSOutputSpecRPT(ants.ANTSOutputSpec):
    html_report = File(desc="Filename of report generated by node")

class ANTSRPT(ants.ANTS):

    input_spec = ANTSInputSpecRPT
    output_spec = ANTSOutputSpecRPT

    def _generate_report(self):
        raise NotImplementedError
<commit_msg>Added a few FSL interfaces to the overloaded interfaces in interfaces/reports.py<commit_after>from nipype.interfaces.base import File, traits
from nipype.interfaces import ants, fsl

class ANTSInputSpecRPT(ants.ANTSInputSpec):
    generate_report = traits.Bool(
        desc="Set to true to enable report generation for node"
    )

class ANTSOutputSpecRPT(ants.ANTSOutputSpec):
    html_report = File(desc="Filename of report generated by node")

class ANTSRPT(ants.ANTS):
    input_spec = ANTSInputSpecRPT
    output_spec = ANTSOutputSpecRPT

    def _generate_report(self):
        raise NotImplementedError

class FASTInputSpecRPT(fsl.FASTInputSpec):
    generate_report = traits.Bool(
        desc="Set to true to enable report generation for node"
    )

class FASTOutputSpecRPT(fsl.FASTOutputSpec):
    html_report = File(desc="Filename of report generated by node")

class FASTRPT(fsl.FAST):
    input_spec = FASTInputSpecRPT
    output_spec = FASTOutputSpecRPT

    def _generate_report(self):
        raise NotImplementedError

class BETInputSpecRPT(fsl.BETInputSpec):
    generate_report = traits.Bool(
        desc="Set to true to enable report generation for node"
    )

class BETOutputSpecRPT(fsl.BETOutputSpec):
    html_report = File(desc="Filename of report generated by node")

class BETRPT(fsl.BET):
    input_spec = BETInputSpecRPT
    output_spec = BETOutputSpecRPT

    def _generate_report(self):
        raise NotImplementedError

class FASTInputSpecRPT(fsl.FASTInputSpec):
    generate_report = traits.Bool(
        desc="Set to true to enable report generation for node"
    )

class FASTOutputSpecRPT(fsl.FASTOutputSpec):
    html_report = File(desc="Filename of report generated by node")

class FASTRPT(fsl.FAST):
    input_spec = FASTInputSpecRPT
    output_spec = FASTOutputSpecRPT

    def _generate_report(self):
        raise NotImplementedError

class FLIRTInputSpecRPT(fsl.FLIRTInputSpec):
    generate_report = traits.Bool(
        desc="Set to true to enable report generation for node"
    )

class FLIRTOutputSpecRPT(fsl.FLIRTOutputSpec):
    html_report = File(desc="Filename of report generated by node")

class FLIRTRPT(fsl.FLIRT):
    input_spec = FLIRTInputSpecRPT
    output_spec = FLIRTOutputSpecRPT

    def _generate_report(self):
        raise NotImplementedError

<|endoftext|>


<commit_before>from __future__ import absolute_import
from myhdl import *

WIDTH=4

clk = Signal(bool(0))
x   = Signal(modbv(0)[WIDTH:])
y   = Signal(modbv(0)[WIDTH:])
z   = Signal(modbv(0)[WIDTH:])

@always(delay(5))
def tb_clk_gen():
    clk.next = not clk

@always(clk.posedge)
def inc():
    y.next = x + 1

@always(clk.posedge)
def dec():
    z.next = x - 1

@instance
def tb_stimulus():
    # My logic happens on posedge, so I'll perform all checks on negedge.
    yield clk.negedge
    for x_val in xrange(-2**WIDTH, 2**WIDTH):
        #print('x_val={} x.next={}'.format(x_val, x_val % 2**WIDTH))
        x.next = x_val % 2**WIDTH
        yield clk.negedge
        assert y==(x_val+1)%2**WIDTH, 'y={} but expected {}'.format(y, (x_val+1)%2**WIDTH)
        assert z==(x_val-1)%2**WIDTH, 'z={} but expected {}'.format(z, (x_val-1)%2**WIDTH)
    print('OK!')
    raise StopSimulation

tb = instances()

def test_bug_44():
    print(instances())
    Simulation(tb).run()

<commit_msg>xrange -> range<commit_after>from __future__ import absolute_import
from myhdl import *

WIDTH=4

clk = Signal(bool(0))
x   = Signal(modbv(0)[WIDTH:])
y   = Signal(modbv(0)[WIDTH:])
z   = Signal(modbv(0)[WIDTH:])

@always(delay(5))
def tb_clk_gen():
    clk.next = not clk

@always(clk.posedge)
def inc():
    y.next = x + 1

@always(clk.posedge)
def dec():
    z.next = x - 1

@instance
def tb_stimulus():
    # My logic happens on posedge, so I'll perform all checks on negedge.
    yield clk.negedge
    for x_val in range(-2**WIDTH, 2**WIDTH):
        #print('x_val={} x.next={}'.format(x_val, x_val % 2**WIDTH))
        x.next = x_val % 2**WIDTH
        yield clk.negedge
        assert y==(x_val+1)%2**WIDTH, 'y={} but expected {}'.format(y, (x_val+1)%2**WIDTH)
        assert z==(x_val-1)%2**WIDTH, 'z={} but expected {}'.format(z, (x_val-1)%2**WIDTH)
    print('OK!')
    raise StopSimulation

tb = instances()

def test_bug_44():
    print(instances())
    Simulation(tb).run()

<|endoftext|>


<commit_before>
def deco_logger(log, length=None):
    length = 10 if length is None else length
    def log_function(f):
        def wrapped(*args, **kwargs):
            log.info(u"{} args:{}, kwargs:{}".format(
                f.__name__,
                ','.join([str(arg)[0:length] for arg in args]),
                ','.join([str(arg)[0:length] for arg in kwargs]),
                ))
            return f(*args, **kwargs)

        return wrapped

    return log_function
<commit_msg>deco_logger now supports unicode<commit_after>
def deco_logger(log, length=None):
    length = 10 if length is None else length
    def log_function(f):
        def wrapped(*args, **kwargs):
            log.info(u"{} args:{}, kwargs:{}".format(
                f.__name__,
                u','.join([str(arg)[0:length] for arg in args]),
                u','.join([str(arg)[0:length] for arg in kwargs]),
                ))
            return f(*args, **kwargs)

        return wrapped

    return log_function
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*-
# vi: set ft=python sts=4 ts=4 sw=4 et:
"""
Slice-Timing Correction (STC) of BOLD images
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. autofunction:: init_bold_stc_wf

"""
from nipype import logging
from nipype.pipeline import engine as pe
from nipype.interfaces import utility as niu, afni
from niworkflows.interfaces.utils import CopyXForm

from ...engine import Workflow

DEFAULT_MEMORY_MIN_GB = 0.01
LOGGER = logging.getLogger('nipype.workflow')

# pylint: disable=R0914
def init_bold_stc_wf(metadata, name='bold_stc_wf'):
    """
    This workflow performs :abbr:`STC (slice-timing correction)` over the input
    :abbr:`BOLD (blood-oxygen-level dependent)` image.

    .. workflow::
        :graph2use: orig
        :simple_form: yes

        from fmriprep.workflows.bold import init_bold_stc_wf
        wf = init_bold_stc_wf(
            metadata={"RepetitionTime": 2.0,
                      "SliceTiming": [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]},
            )

    **Parameters**

        metadata : dict
            BIDS metadata for BOLD file
        name : str
            Name of workflow (default: ``bold_stc_wf``)

    **Inputs**

        bold_file
            BOLD series NIfTI file
        skip_vols
            Number of non-steady-state volumes detected at beginning of ``bold_file``

    **Outputs**

        stc_file
            Slice-timing corrected BOLD series NIfTI file

    """
    workflow = Workflow(name=name)
    workflow.__desc__ = """\
BOLD runs were slice-time corrected using `3dTshift` from
AFNI {afni_ver} [@afni, RRID:SCR_005927].
""".format(afni_ver=''.join(list(afni.TShift().version or '<ver>')))
    inputnode = pe.Node(niu.IdentityInterface(fields=['bold_file', 'skip_vols']), name='inputnode')
    outputnode = pe.Node(niu.IdentityInterface(fields=['stc_file']), name='outputnode')

    LOGGER.log(25, 'Slice-timing correction will be included.')

    # It would be good to fingerprint memory use of afni.TShift
    slice_timing_correction = pe.Node(
        afni.TShift(outputtype='NIFTI_GZ',
                    tr='{}s'.format(metadata["RepetitionTime"]),
                    slice_timing=metadata['SliceTiming']),
        name='slice_timing_correction')
    if 'SliceEncodingDirection' in metadata:
        slice_timing_correction.inputs.slice_encoding_direction = metadata['SliceEncodingDirection']

    copy_xform = pe.Node(CopyXForm(), name='copy_xform', mem_gb=0.1)

    workflow.connect([
        (inputnode, slice_timing_correction, [('bold_file', 'in_file'),
                                              ('skip_vols', 'ignore')]),
        (slice_timing_correction, copy_xform, [('out_file', 'in_file')]),
        (inputnode, copy_xform, [('bold_file', 'hdr_file')]),
        (copy_xform, outputnode, [('out_file', 'stc_file')]),
    ])

    return workflow
<commit_msg>removed empty line<commit_after># -*- coding: utf-8 -*-
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*-
# vi: set ft=python sts=4 ts=4 sw=4 et:
"""
Slice-Timing Correction (STC) of BOLD images
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. autofunction:: init_bold_stc_wf

"""
from nipype import logging
from nipype.pipeline import engine as pe
from nipype.interfaces import utility as niu, afni
from niworkflows.interfaces.utils import CopyXForm

from ...engine import Workflow

DEFAULT_MEMORY_MIN_GB = 0.01
LOGGER = logging.getLogger('nipype.workflow')

# pylint: disable=R0914
def init_bold_stc_wf(metadata, name='bold_stc_wf'):
    """
    This workflow performs :abbr:`STC (slice-timing correction)` over the input
    :abbr:`BOLD (blood-oxygen-level dependent)` image.

    .. workflow::
        :graph2use: orig
        :simple_form: yes

        from fmriprep.workflows.bold import init_bold_stc_wf
        wf = init_bold_stc_wf(
            metadata={"RepetitionTime": 2.0,
                      "SliceTiming": [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]},
            )

    **Parameters**

        metadata : dict
            BIDS metadata for BOLD file
        name : str
            Name of workflow (default: ``bold_stc_wf``)

    **Inputs**

        bold_file
            BOLD series NIfTI file
        skip_vols
            Number of non-steady-state volumes detected at beginning of ``bold_file``

    **Outputs**

        stc_file
            Slice-timing corrected BOLD series NIfTI file

    """
    workflow = Workflow(name=name)
    workflow.__desc__ = """\
BOLD runs were slice-time corrected using `3dTshift` from
AFNI {afni_ver} [@afni, RRID:SCR_005927].
""".format(afni_ver=''.join(list(afni.TShift().version or '<ver>')))
    inputnode = pe.Node(niu.IdentityInterface(fields=['bold_file', 'skip_vols']), name='inputnode')
    outputnode = pe.Node(niu.IdentityInterface(fields=['stc_file']), name='outputnode')

    LOGGER.log(25, 'Slice-timing correction will be included.')

    # It would be good to fingerprint memory use of afni.TShift
    slice_timing_correction = pe.Node(
        afni.TShift(outputtype='NIFTI_GZ',
                    tr='{}s'.format(metadata["RepetitionTime"]),
                    slice_timing=metadata['SliceTiming']),
        name='slice_timing_correction')
    if 'SliceEncodingDirection' in metadata:
        slice_timing_correction.inputs.slice_encoding_direction = metadata['SliceEncodingDirection']

    copy_xform = pe.Node(CopyXForm(), name='copy_xform', mem_gb=0.1)

    workflow.connect([
        (inputnode, slice_timing_correction, [('bold_file', 'in_file'),
                                              ('skip_vols', 'ignore')]),
        (slice_timing_correction, copy_xform, [('out_file', 'in_file')]),
        (inputnode, copy_xform, [('bold_file', 'hdr_file')]),
        (copy_xform, outputnode, [('out_file', 'stc_file')]),
    ])

    return workflow
<|endoftext|>


<commit_before>__author__ = "John Kirkham <kirkhamj@janelia.hhmi.org>"
__date__ = "$Jun 26, 2014 18:24:25 EDT$"

import glob

import debugging_tools

# Get the logger
logger = debugging_tools.logging.getLogger(__name__)

@debugging_tools.log_call(logger)
def expand_pathname_list(*pathnames):
    """
        Takes each pathname in those given and expands them using regex.

        Args:
            *pathnames(str):     pathnames to use regex on to expand.

        Returns:
            list:                a list of path names (without regex)

    """

    expanded_pathnames = []

    # Completes any regex
    expanded_pathnames = []
    for each_pathname in pathnames:
        expanded_pathnames.extend(glob.glob(each_pathname))

    return(expanded_pathnames)<commit_msg>nanshe/nanshe/additional_io.py: Add newline to EOF.<commit_after>__author__ = "John Kirkham <kirkhamj@janelia.hhmi.org>"
__date__ = "$Jun 26, 2014 18:24:25 EDT$"

import glob

import debugging_tools

# Get the logger
logger = debugging_tools.logging.getLogger(__name__)

@debugging_tools.log_call(logger)
def expand_pathname_list(*pathnames):
    """
        Takes each pathname in those given and expands them using regex.

        Args:
            *pathnames(str):     pathnames to use regex on to expand.

        Returns:
            list:                a list of path names (without regex)

    """

    expanded_pathnames = []

    # Completes any regex
    expanded_pathnames = []
    for each_pathname in pathnames:
        expanded_pathnames.extend(glob.glob(each_pathname))

    return(expanded_pathnames)
<|endoftext|>


<commit_before>#!/usr/bin/env python
#
# Copyright (c) 2016, PagerDuty, Inc. <info@pagerduty.com>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#     * Redistributions of source code must retain the above copyright
#       notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above copyright
#       notice, this list of conditions and the following disclaimer in the
#       documentation and/or other materials provided with the distribution.
#     * Neither the name of PagerDuty Inc nor the
#       names of its contributors may be used to endorse or promote products
#       derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL PAGERDUTY INC BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import requests
import json
import argparse

class PagerDutyREST():
    """Class to handle all calls to the PagerDuty API"""

    def __init__(self, access_token):
        self.base_url = 'https://api.pagerduty.com'
        self.headers = {
            'Accept': 'application/vnd.pagerduty+json;version=2',
            'Content-type': 'application/json',
            'Authorization': 'Token token={token}'.format(token=access_token)
        }

    def get(self, endpoint, payload=None):
        """Handle all GET requests"""

        url = '{base_url}{endpoint}'.format(
            base_url=self.base_url,
            endpoint=endpoint
        )
        r = requests.get(url, params=payload, headers=self.headers)
        if r.status_code == 200:
            return r.json()
        else:
            raise Exception(
                'There was an issue with your GET request:\nStatus code: {code}\
                \nError: {error}'.format(code=r.status_code, error=r.text)
            )

    def put(self, endpoint, payload=None):
        """Handle all PUT requests"""

        url = '{base_url}{endpoint}'.format(
            base_url=self.base_url,
            endpoint=endpoint
        )
        r = requests.put(url, data=json.dumps(payload), headers=self.headers)
        if r.status_code == 200:
            return r.json()
        else:
            raise Exception(
                'There was an issue with your PUT request:\nStatus code: {code}\
                \nError: {error}'.format(code=r.status_code, error=r.text)
            )

    def delete(self, endpoint):
        """Handle all DELETE requests"""

        url = '{base_url}{endpoint}'.format(
            base_url=self.base_url,
            endpoint=endpoint
        )
        r = requests.delete(url, headers=self.headers)
        if r.status_code == 204:
            return r.status_code
        else:
            raise Exception(
                'There was an issue with your DELETE request:\nStatus code: {code}\
                \nError: {error}'.format(code=r.status_code, error=r.text)
            )

class DeleteUser():
    """Class to handle all user deletion logic"""

    def __init__(self, user, access_token):
        self.user = user
        self.pd_rest = PagerDutyREST(access_token)

    def get_user_id(self, email):
        """Get PagerDuty user ID from user email"""

        payload = {
            'query': email
        }
        r = self.pd_rest.get('/users?limit=100', payload)
        # Handle pagination if over 100 users
        if r['more']:
            offset = 100
            output = r['users']
            while r['more']:
                r = self.pd_rest.get(
                    '/users?limit=100&offset={offset}'.format(offset=offset),
                    payload
                )
                output.append(r['users'])
                offset += 100
            r = {
                'users': output
            }
        for user in r['users']:
            if user['email'] == email:
                return user['id']
        raise ValueError(
            'Could not find user with email {email}'.format(email=email)
        )

    def list_schedules(self):
        """Outputs list of all schedules"""

        r = self.pd_rest.get('/schedules?limit=100')
        # Handle pagination if over 100 schedules
        if r['more']:
            offset = 100
            output = r['schedules']
            while r['more']:
                r = self.pd_rest.get(
                    '/schedules?limit=100&offset={offset}'.format(
                        offset=offset
                    )
                )
                output.append(r['schedules'])
                offset += 100
            r = {
                'schedules': output
            }
        return r['schedules']

    def get_schedule(self, schedule_id):
        """Get a single schedule"""

        r = self.pd_rest.get('/schedules/{id}'.format(id=schedule_id))
        return r

    def check_schedule_for_user(self, user_id, schedule):
        """Check if a schedule contains a particular user"""

        for user in schedule['users']:
            if user['id'] == user_id:
                return True
        return False

    def get_user_index(self, user_id, schedule_layer):
        """Get the index of a user on a schedule layer"""

        for i, user in enumerate(schedule_layer['users']):
            if user['id'] == user_id:
                return i
        return None

    def remove_user_from_layer(self, index, schedule_layer):
        """Remove a user from a schedule layer"""

        del schedule_layer['users'][index]
        return schedule_layer

    def cache_schedule(self, schedule, cache):
        """Adds current schedule to the cache of affected schedules"""

        cache.append({
            'id': schedule['id'],
            'name': schedule['name']
        })
        return cache

    def delete_user(self, user_id):
        """Delete user from PagerDuty"""

        r = self.pd_rest.delete('/users/{id}'.format(id=user_id))
        return r

def main(access_token, user_email):
    """Handle command-line logic to delete user"""

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Delete a user')
    parser.add_argument(
        '--access-token',
        help='PagerDuty v2 access token',
        dest='access_token',
        required=True
    )
    parser.add_argument(
        '--user-email',
        help='Email address of user to be deleted',
        dest='user_email',
        required=True
    )
<commit_msg>Finished all list logic<commit_after>#!/usr/bin/env python
#
# Copyright (c) 2016, PagerDuty, Inc. <info@pagerduty.com>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#     * Redistributions of source code must retain the above copyright
#       notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above copyright
#       notice, this list of conditions and the following disclaimer in the
#       documentation and/or other materials provided with the distribution.
#     * Neither the name of PagerDuty Inc nor the
#       names of its contributors may be used to endorse or promote products
#       derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL PAGERDUTY INC BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import requests
import json
import argparse

class PagerDutyREST():
    """Class to handle all calls to the PagerDuty API"""

    def __init__(self, access_token):
        self.base_url = 'https://api.pagerduty.com'
        self.headers = {
            'Accept': 'application/vnd.pagerduty+json;version=2',
            'Content-type': 'application/json',
            'Authorization': 'Token token={token}'.format(token=access_token)
        }

    def get(self, endpoint, payload=None):
        """Handle all GET requests"""

        url = '{base_url}{endpoint}'.format(
            base_url=self.base_url,
            endpoint=endpoint
        )
        r = requests.get(url, params=payload, headers=self.headers)
        if r.status_code == 200:
            return r.json()
        else:
            raise Exception(
                'There was an issue with your GET request:\nStatus code: {code}\
                \nError: {error}'.format(code=r.status_code, error=r.text)
            )

    def put(self, endpoint, payload=None):
        """Handle all PUT requests"""

        url = '{base_url}{endpoint}'.format(
            base_url=self.base_url,
            endpoint=endpoint
        )
        r = requests.put(url, data=json.dumps(payload), headers=self.headers)
        if r.status_code == 200:
            return r.json()
        else:
            raise Exception(
                'There was an issue with your PUT request:\nStatus code: {code}\
                \nError: {error}'.format(code=r.status_code, error=r.text)
            )

    def delete(self, endpoint):
        """Handle all DELETE requests"""

        url = '{base_url}{endpoint}'.format(
            base_url=self.base_url,
            endpoint=endpoint
        )
        r = requests.delete(url, headers=self.headers)
        if r.status_code == 204:
            return r.status_code
        else:
            raise Exception(
                'There was an issue with your DELETE request:\nStatus code: {code}\
                \nError: {error}'.format(code=r.status_code, error=r.text)
            )

class DeleteUser():
    """Class to handle all user deletion logic"""

    def __init__(self, user, access_token):
        self.user = user
        self.pd_rest = PagerDutyREST(access_token)

    def get_user_id(self, email):
        """Get PagerDuty user ID from user email"""

        payload = {
            'query': email
        }
        r = self.pd_rest.get('/users?limit=100', payload)
        # Handle pagination if over 100 users
        if r['more']:
            offset = 100
            output = r['users']
            while r['more']:
                r = self.pd_rest.get(
                    '/users?limit=100&offset={offset}'.format(offset=offset),
                    payload
                )
                output.append(r['users'])
                offset += 100
            r = {
                'users': output
            }
        for user in r['users']:
            if user['email'] == email:
                return user['id']
        raise ValueError(
            'Could not find user with email {email}'.format(email=email)
        )

    def list_schedules(self):
        """Outputs list of all schedules"""

        r = self.pd_rest.get('/schedules', {'limit': 100})
        # Handle pagination if over 100 schedules
        if r['more']:
            offset = 100
            output = r['schedules']
            while r['more']:
                r = self.pd_rest.get(
                    '/schedules', {'limit': 100, 'offset': offset}
                )
                output.append(r['schedules'])
                offset += 100
            r = {'schedules': output}
        return r['schedules']

    def list_teams(self):
        """Outputs list of all teams"""

        r = self.pd_rest.get('/teams', {'limit': 100})
        # Handle pagination if over 100 teams
        if r['more']:
            offset = 100
            output = r['teams']
            while r['more']:
                r = self.pd_rest.get(
                    '/teams', {'limit': 100, 'offset': offset}
                )
                output.append(r['teams'])
                offset += 100
            r = {'teams': output}
        return r['teams']

    def list_users_on_team(self, team_id):
        """List all users on a particular team"""

        r = self.pd_rest.get('/users', {'limit': 100, 'team_ids[]': team_id})
        # Handle pagination if over 100 users
        if r['more']:
            offset = 100
            output = r['users']
            while r['more']:
                r = self.pd_rest.get('/users', {
                    'limit': 100,
                    'offset': offset,
                    'team_ids[]': team_id
                })
                output.append(r['users'])
                offset += 100
            r = {'users': output}
        return r['users']

    def list_user_escalation_policies(self, user_id):
        """List all escalation policies user is on"""

        r = self.pd_rest.get('/escalation_policies', {
            'limit': 100,
            'user_ids[]': user_id
        })
        # Handle pagination if over 100 escalation policies
        if r['more']:
            offset = 100
            output = r['escalation_policies']
            while r['more']:
                r = self.pd_rest.get('/escalation_policies', {
                    'limit': 100,
                    'offset': offset,
                    'user_ids[]': user_id
                })
                output.append(r['escalation_policies'])
                offset += 100
            r = {'escalation_policies': output}
        return r['escalation_policies']

    def get_schedule(self, schedule_id):
        """Get a single schedule"""

        r = self.pd_rest.get('/schedules/{id}'.format(id=schedule_id))
        return r

    def check_schedule_for_user(self, user_id, schedule):
        """Check if a schedule contains a particular user"""

        for user in schedule['users']:
            if user['id'] == user_id:
                return True
        return False

    def get_user_index(self, user_id, schedule_layer):
        """Get the index of a user on a schedule layer"""

        for i, user in enumerate(schedule_layer['users']):
            if user['id'] == user_id:
                return i
        return None

    def remove_user_from_layer(self, index, schedule_layer):
        """Remove a user from a schedule layer"""

        del schedule_layer['users'][index]
        return schedule_layer

    def cache_schedule(self, schedule, cache):
        """Adds current schedule to the cache of affected schedules"""

        cache.append({
            'id': schedule['id'],
            'name': schedule['name']
        })
        return cache

    def delete_user(self, user_id):
        """Delete user from PagerDuty"""

        r = self.pd_rest.delete('/users/{id}'.format(id=user_id))
        return r

def main(access_token, user_email):
    """Handle command-line logic to delete user"""

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Delete a user')
    parser.add_argument(
        '--access-token',
        help='PagerDuty v2 access token',
        dest='access_token',
        required=True
    )
    parser.add_argument(
        '--user-email',
        help='Email address of user to be deleted',
        dest='user_email',
        required=True
    )
<|endoftext|>


<commit_before>#!/usr/bin/env python
# -*- coding: utf-8 -*-

# Copyright (c) 2015-2016:
#   Matthieu Estrada, ttamalfor@gmail.com
#
# This file is part of (AlignakApp).
#
# (AlignakApp) is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# (AlignakApp) is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with (AlignakApp).  If not, see <http://www.gnu.org/licenses/>.

"""
    Application logs
"""

import os
import sys

from logging import getLogger
from logging import Formatter
from logging import DEBUG
from logging.handlers import TimedRotatingFileHandler

from string import Template
from alignak_app import __name__ as __pkg_name__
import configparser

logger = getLogger(__name__)

# Application Logger
def create_logger(root_logger):  # pragma: no cover
    """
    Create the logger for Alignak-App

    :param root_logger: the main logger.
    :type root_logger: :class:`~logging.RootLogger`
    """

    path = get_alignak_home() + '/' + __pkg_name__

    filename = 'alignakapp.log'

    if not os.path.isdir(path):
        # noinspection PyBroadException
        try:  # pragma: no cover - not testable
            os.makedirs(path)
        except Exception:
            path = '.'

    if not os.access(path, os.W_OK):
        path = '.'

    formatter = Formatter('[%(asctime)s] - %(name)-12s - %(levelname)s - %(message)s')

    file_handler = TimedRotatingFileHandler(
        filename=os.path.join(path, filename),
        when="D",
        interval=1,
        backupCount=6
    )

    file_handler.setLevel(DEBUG)
    file_handler.setFormatter(formatter)

    root_logger.addHandler(file_handler)
    root_logger.setLevel(DEBUG)

# Application Home
def get_alignak_home():
    """
    Return user home.
    """

    # Get HOME and USER
    if 'linux' in sys.platform or 'sunos5' in sys.platform:
        alignak_home = os.environ['HOME']
        alignak_home += '/.local'
    elif 'win32' in sys.platform:
        alignak_home = os.environ['USERPROFILE']
        alignak_home += '\\AppData\\Roaming\\Python\\'
    else:
        sys.exit('Application can\'t find the user HOME.')

    # Prevent from root user
    if 'root' in alignak_home or not alignak_home:
        sys.exit('Application can\'t find the user HOME or maybe you are connected as ROOT.')

    return alignak_home

# Application Configuration

# Global variable, access by funtions
app_config = None

def set_app_config():
    """
    Create app_config

    """

    config_file = get_alignak_home() + '/' + __pkg_name__ + '/settings.cfg'

    global app_config  # pylint: disable=global-statement
    app_config = configparser.ConfigParser()

    logger.info('Read configuration file...')
    if os.path.isfile(config_file):
        app_config.read(config_file)
        logger.info('Configuration file is OK.')
    else:
        logger.error('Configuration file is missing in [' + config_file + '] !')
        sys.exit('Configuration file is missing in [' + config_file + '] !')

def get_app_config():
    """
    Return global application configuration

    """

    return app_config

# Application Templates
def get_template(name, values):
    """
        Return content of the choosen template with its values.

    :param name: name of the template.
    :type name: str
    :param values: dict of values to substitute.
    :type values: dict
    :return: content of a template
    :rtype: str
    """

    tpl_content = ''

    tpl_path = get_alignak_home() \
        + app_config.get('Config', 'path') \
        + app_config.get('Config', 'tpl') \
        + '/'

    try:
        tpl_file = open(tpl_path + name)
    except IOError as e:
        sys.exit('Failed open template : ' + str(e))

    if tpl_file:
        tpl = Template(tpl_file.read())
        tpl_content = tpl.safe_substitute(values)

    return tpl_content

def get_image(name):
    """
    Return the path of wanted image

    :param name: name of image
    :type name: str
    :return: path of image
    :rtype: str
    """

    img_path = get_alignak_home() \
        + app_config.get('Config', 'path') \
        + app_config.get('Config', 'img') \
        + '/'

    img = img_path + app_config.get('Images', name)

    return img
<commit_msg>Fix cyclic import...<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-

# Copyright (c) 2015-2016:
#   Matthieu Estrada, ttamalfor@gmail.com
#
# This file is part of (AlignakApp).
#
# (AlignakApp) is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# (AlignakApp) is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with (AlignakApp).  If not, see <http://www.gnu.org/licenses/>.

"""
    Application logs
"""

import os
import sys

from logging import getLogger
from logging import Formatter
from logging import DEBUG
from logging.handlers import TimedRotatingFileHandler

import configparser
from string import Template

logger = getLogger(__name__)

# Application Logger
def create_logger(root_logger):  # pragma: no cover
    """
    Create the logger for Alignak-App

    :param root_logger: the main logger.
    :type root_logger: :class:`~logging.RootLogger`
    """

    path = get_alignak_home() + '/alignak_app'

    filename = 'alignakapp.log'

    if not os.path.isdir(path):
        # noinspection PyBroadException
        try:  # pragma: no cover - not testable
            os.makedirs(path)
        except Exception:
            path = '.'

    if not os.access(path, os.W_OK):
        path = '.'

    formatter = Formatter('[%(asctime)s] - %(name)-12s - %(levelname)s - %(message)s')

    file_handler = TimedRotatingFileHandler(
        filename=os.path.join(path, filename),
        when="D",
        interval=1,
        backupCount=6
    )

    file_handler.setLevel(DEBUG)
    file_handler.setFormatter(formatter)

    root_logger.addHandler(file_handler)
    root_logger.setLevel(DEBUG)

# Application Home
def get_alignak_home():
    """
    Return user home.
    """

    # Get HOME and USER
    if 'linux' in sys.platform or 'sunos5' in sys.platform:
        alignak_home = os.environ['HOME']
        alignak_home += '/.local'
    elif 'win32' in sys.platform:
        alignak_home = os.environ['USERPROFILE']
        alignak_home += '\\AppData\\Roaming\\Python\\'
    else:
        sys.exit('Application can\'t find the user HOME.')

    # Prevent from root user
    if 'root' in alignak_home or not alignak_home:
        sys.exit('Application can\'t find the user HOME or maybe you are connected as ROOT.')

    return alignak_home

# Application Configuration

# Global variable, access by funtions
app_config = None

def set_app_config():
    """
    Create app_config

    """

    config_file = get_alignak_home() + '/alignak_app/settings.cfg'

    global app_config  # pylint: disable=global-statement
    app_config = configparser.ConfigParser()

    logger.info('Read configuration file...')
    if os.path.isfile(config_file):
        app_config.read(config_file)
        logger.info('Configuration file is OK.')
    else:
        logger.error('Configuration file is missing in [' + config_file + '] !')
        sys.exit('Configuration file is missing in [' + config_file + '] !')

def get_app_config():
    """
    Return global application configuration

    """

    return app_config

# Application Templates
def get_template(name, values):
    """
        Return content of the choosen template with its values.

    :param name: name of the template.
    :type name: str
    :param values: dict of values to substitute.
    :type values: dict
    :return: content of a template
    :rtype: str
    """

    tpl_content = ''

    tpl_path = get_alignak_home() \
        + app_config.get('Config', 'path') \
        + app_config.get('Config', 'tpl') \
        + '/'

    try:
        tpl_file = open(tpl_path + name)
    except IOError as e:
        sys.exit('Failed open template : ' + str(e))

    if tpl_file:
        tpl = Template(tpl_file.read())
        tpl_content = tpl.safe_substitute(values)

    return tpl_content

def get_image(name):
    """
    Return the path of wanted image

    :param name: name of image
    :type name: str
    :return: path of image
    :rtype: str
    """

    img_path = get_alignak_home() \
        + app_config.get('Config', 'path') \
        + app_config.get('Config', 'img') \
        + '/'

    img = img_path + app_config.get('Images', name)

    return img
<|endoftext|>