<commit_before>"""
stringjumble.py
Author: Billy
Credit: http://stackoverflow.com/questions/18455222/how-to-count-the-number-of-letters-in-a-string-without-the-spaces, David, Ryan, Bill(my dad), http://www.tutorialspoint.com/python/list_reverse.htm, https://www.safaribooksonline.com/library/view/python-cookbook-3rd/9781449357337/ch02s14.html

Assignment:

The purpose of this challenge is to gain proficiency with
manipulating lists.

Write and submit a Python program that accepts a string from
the user and prints it back in three different ways:

* With all letters in reverse.
* With words in reverse order, but letters within each word in
  the correct order.
* With all words in correct order, but letters reversed within
  the words.

Output of your program should look like this:

Please enter a string of text (the bigger the better): There are a few techniques or tricks that you may find handy
You entered "There are a few techniques or tricks that you may find handy". Now jumble it:
ydnah dnif yam uoy taht skcirt ro seuqinhcet wef a era erehT
handy find may you that tricks or techniques few a are There
erehT era a wef seuqinhcet ro skcirt taht uoy yam dnif ydnah
"""

userInput = input("Enter a sentence, word or paragraph.")

print(len(userInput))

"""
from collections import Counter

rev= ""
"""
word= ""

words = []

for s in userInput:
        if s == " ":
            print("space")
            print(word)
            words.append(word)
            word=""
        else:
            word = word + s

print(word)
words.append(word)
print(words)
print(len(words))
print(' '.join(words))
print(' '.join(words.reverse()))

"""
    rev = s + rev

print(rev)
rev= ""
for s in userInput:
    rev = s + rev:
        if s== " ":

print(rev)
"""<commit_msg>Updated from Brython Server: 3/16/2016 9:16:39 PM<commit_after>"""
stringjumble.py
Author: Billy
Credit: http://stackoverflow.com/questions/18455222/how-to-count-the-number-of-letters-in-a-string-without-the-spaces, David, Ryan, Bill(my dad), http://www.tutorialspoint.com/python/list_reverse.htm, https://www.safaribooksonline.com/library/view/python-cookbook-3rd/9781449357337/ch02s14.html

Assignment:

The purpose of this challenge is to gain proficiency with
manipulating lists.

Write and submit a Python program that accepts a string from
the user and prints it back in three different ways:

* With all letters in reverse.
* With words in reverse order, but letters within each word in
  the correct order.
* With all words in correct order, but letters reversed within
  the words.

Output of your program should look like this:

Please enter a string of text (the bigger the better): There are a few techniques or tricks that you may find handy
You entered "There are a few techniques or tricks that you may find handy". Now jumble it:
ydnah dnif yam uoy taht skcirt ro seuqinhcet wef a era erehT
handy find may you that tricks or techniques few a are There
erehT era a wef seuqinhcet ro skcirt taht uoy yam dnif ydnah
"""

userInput = input("Enter a sentence, word or paragraph.")

print(len(userInput))

"""
from collections import Counter

rev= ""
"""
word= ""

words = []

for s in userInput:
        if s == " ":
            print("space")
            print(word)
            words.append(word)
            word=""
        else:
            word = word + s

print(word)
words.append(word)
print(words)
print(len(words))
print(' '.join(words))
for i in range(0, len(words), -1):
    print(i)
print(wordsReverse)

"""
    rev = s + rev

print(rev)
rev= ""
for s in userInput:
    rev = s + rev:
        if s== " ":

print(rev)
"""<|endoftext|>


<commit_before>"""
stringjumble.py
Author: Dimitri
Credit: http://stackoverflow.com/questions/931092/reverse-a-string-in-python, http://stackoverflow.com/questions/12794141/reverse-input-in-python

Assignment:

The purpose of this challenge is to gain proficiency with
manipulating lists.

Write and submit a Python program that accepts a string from
the user and prints it back in three different ways:

* With all letters in reverse.
* With words in reverse order, but letters within each word in
  the correct order.
* With all words in correct order, but letters reversed within
  the words.

Output of your program should look like this:

Please enter a string of text (the bigger the better): There are a few techniques or tricks that you may find handy
You entered "There are a few techniques or tricks that you may find handy". Now jumble it:
ydnah dnif yam uoy taht skcirt ro seuqinhcet wef a era erehT
handy find may you that tricks or techniques few a are There
erehT era a wef seuqinhcet ro skcirt taht uoy yam dnif ydnah
"""
s = str(input("Please enter a string of text (the bigger the better): "))

print(str("You entered "{0}". Now jumble it:".format(s))

print(s[::-1])

s1 = (s[::-1])
print(' '.join(reversed(s.split(' '))))

print(' '.join(reversed(s1.split(' '))))<commit_msg>Updated from Brython Server: 10/28/2015 1:59:45 PM<commit_after>"""
stringjumble.py
Author: Dimitri
Credit: http://stackoverflow.com/questions/931092/reverse-a-string-in-python, http://stackoverflow.com/questions/12794141/reverse-input-in-python

Assignment:

The purpose of this challenge is to gain proficiency with
manipulating lists.

Write and submit a Python program that accepts a string from
the user and prints it back in three different ways:

* With all letters in reverse.
* With words in reverse order, but letters within each word in
  the correct order.
* With all words in correct order, but letters reversed within
  the words.

Output of your program should look like this:

Please enter a string of text (the bigger the better): There are a few techniques or tricks that you may find handy
You entered "There are a few techniques or tricks that you may find handy". Now jumble it:
ydnah dnif yam uoy taht skcirt ro seuqinhcet wef a era erehT
handy find may you that tricks or techniques few a are There
erehT era a wef seuqinhcet ro skcirt taht uoy yam dnif ydnah
"""
s = str(input("Please enter a string of text (the bigger the better): "))

print(str('You entered "{0}". Now jumble it:'.format(s))

print(s[::-1])

s1 = (s[::-1])
print(' '.join(reversed(s.split(' '))))

print(' '.join(reversed(s1.split(' '))))<|endoftext|>


<commit_before>from django_browserid import get_audience, verify, BrowserIDException
from django_browserid.auth import default_username_algo
from django_browserid.views import Verify

from django.db.models import Count
from django.core.urlresolvers import reverse
from django.contrib import auth, messages
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User
from django.http import HttpResponse
from django.shortcuts import render, redirect
from django.utils import simplejson

from moderator.moderate.mozillians import is_vouched, BadStatusCodeError
from moderator.moderate.models import MozillianProfile, Event, Question, Vote
from moderator.moderate.forms import QuestionForm

class CustomVerify(Verify):
    def form_valid(self, form):
        """Custom mozillians login form validation"""
        self.assertion = form.cleaned_data['assertion']
        self.audience = get_audience(self.request)
        result = verify(self.assertion, self.audience)

        try:
            _is_valid_login = False
            if result:
                if User.objects.filter(email=result['email']).exists():
                    _is_valid_login = True
                else:
                    data = is_vouched(result['email'])
                    if data and data['is_vouched']:
                        _is_valid_login = True
                        user = User.objects.create_user(
                            username=default_username_algo(data['email']),
                            email=data['email'])
                        user.save()
                        MozillianProfile.objects.create(
                            user=user, username=data['username'],
                            avatar_url=data['photo'])

            if _is_valid_login:
                try:
                    self.user = auth.authenticate(assertion=self.assertion,
                                                  audience=self.audience)
                    auth.login(self.request, self.user)

                except BrowserIDException as e:
                    return self.login_failure(e)

                if self.user and self.user.is_active:
                    return self.login_success()

        except BadStatusCodeError:
            msg = ('Email (%s) authenticated but unable to '
                   'connect to Mozillians to see if you are vouched'
                   % result['email'])
            messages.warning(self.request, msg)
            return self.login_failure()

        messages.error(self.request, ('Login failed. Make sure you are using '
                                      'a valid email address and you are '
                                      'a vouched Mozillian.'))
        return self.login_failure()

def main(request):
    """Render main page."""
    if request.user.is_authenticated():
        events = Event.objects.all()
        return render(request, 'index.html', {
                               'events': events,
                               'user': request.user})
    else:
        return render(request, 'index.html', {'user': request.user})

@login_required
def event(request, e_slug):
    """Render event questions."""
    event = Event.objects.get(slug=e_slug)

    questions = (Question.objects.filter(event=event)
                 .annotate(vote_count=Count('votes'))
                 .order_by('-vote_count'))

    if request.POST:
        question_form = QuestionForm(request.POST)

        if question_form.is_valid():
            question = question_form.save(commit=False)
            question.asked_by = request.user
            question.event = event
            question.save()
            return redirect(reverse('event', kwargs={'e_slug': event.slug}))
    else:
        question_form = QuestionForm()

    return render(request, 'questions.html',
                  {'user': request.user,
                   'event': event,
                   'questions': questions,
                   'q_form': question_form})

@login_required
def upvote(request, q_id):
    """Upvote question"""

    question = Question.objects.get(pk=q_id)

    if request.is_ajax():
        vote, created = Vote.objects.get_or_create(user=request.user,
                                                   question=question)
        response_dict = {}
        response_dict.update({'current_vote_count': question.votes.count()})

        return HttpResponse(simplejson.dumps(response_dict),
                            mimetype='application/javascript')

    return event(request, question.event.slug)
<commit_msg>Remove save() method from create_user.<commit_after>from django_browserid import get_audience, verify, BrowserIDException
from django_browserid.auth import default_username_algo
from django_browserid.views import Verify

from django.db.models import Count
from django.core.urlresolvers import reverse
from django.contrib import auth, messages
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User
from django.http import HttpResponse
from django.shortcuts import render, redirect
from django.utils import simplejson

from moderator.moderate.mozillians import is_vouched, BadStatusCodeError
from moderator.moderate.models import MozillianProfile, Event, Question, Vote
from moderator.moderate.forms import QuestionForm

class CustomVerify(Verify):
    def form_valid(self, form):
        """Custom mozillians login form validation"""
        self.assertion = form.cleaned_data['assertion']
        self.audience = get_audience(self.request)
        result = verify(self.assertion, self.audience)

        try:
            _is_valid_login = False
            if result:
                if User.objects.filter(email=result['email']).exists():
                    _is_valid_login = True
                else:
                    data = is_vouched(result['email'])
                    if data and data['is_vouched']:
                        _is_valid_login = True
                        user = User.objects.create_user(
                            username=default_username_algo(data['email']),
                            email=data['email'])
                        MozillianProfile.objects.create(
                            user=user, username=data['username'],
                            avatar_url=data['photo'])

            if _is_valid_login:
                try:
                    self.user = auth.authenticate(assertion=self.assertion,
                                                  audience=self.audience)
                    auth.login(self.request, self.user)

                except BrowserIDException as e:
                    return self.login_failure(e)

                if self.user and self.user.is_active:
                    return self.login_success()

        except BadStatusCodeError:
            msg = ('Email (%s) authenticated but unable to '
                   'connect to Mozillians to see if you are vouched'
                   % result['email'])
            messages.warning(self.request, msg)
            return self.login_failure()

        messages.error(self.request, ('Login failed. Make sure you are using '
                                      'a valid email address and you are '
                                      'a vouched Mozillian.'))
        return self.login_failure()

def main(request):
    """Render main page."""
    if request.user.is_authenticated():
        events = Event.objects.all()
        return render(request, 'index.html', {
                               'events': events,
                               'user': request.user})
    else:
        return render(request, 'index.html', {'user': request.user})

@login_required
def event(request, e_slug):
    """Render event questions."""
    event = Event.objects.get(slug=e_slug)

    questions = (Question.objects.filter(event=event)
                 .annotate(vote_count=Count('votes'))
                 .order_by('-vote_count'))

    if request.POST:
        question_form = QuestionForm(request.POST)

        if question_form.is_valid():
            question = question_form.save(commit=False)
            question.asked_by = request.user
            question.event = event
            question.save()
            return redirect(reverse('event', kwargs={'e_slug': event.slug}))
    else:
        question_form = QuestionForm()

    return render(request, 'questions.html',
                  {'user': request.user,
                   'event': event,
                   'questions': questions,
                   'q_form': question_form})

@login_required
def upvote(request, q_id):
    """Upvote question"""

    question = Question.objects.get(pk=q_id)

    if request.is_ajax():
        vote, created = Vote.objects.get_or_create(user=request.user,
                                                   question=question)
        response_dict = {}
        response_dict.update({'current_vote_count': question.votes.count()})

        return HttpResponse(simplejson.dumps(response_dict),
                            mimetype='application/javascript')

    return event(request, question.event.slug)
<|endoftext|>


<commit_before>"""
stringjumble.py
Author: Avery Wallis
Credit: Ethan

Assignment:

The purpose of this challenge is to gain proficiency with
manipulating lists.

Write and submit a Python program that accepts a string from
the user and prints it back in three different ways:

* With all letters in reverse.
* With words in reverse order, but letters within each word in
  the correct order.
* With all words in correct order, but letters reversed within
  the words.

Output of your program should look like this:

Please enter a string of text (the bigger the better): There are a few techniques or tricks that you may find handy
You entered "There are a few techniques or tricks that you may find handy". Now jumble it:
ydnah dnif yam uoy taht skcirt ro seuqinhcet wef a era erehT
handy find may you that tricks or techniques few a are There
erehT era a wef seuqinhcet ro skcirt taht uoy yam dnif ydnah
"""
string= list(str(input("Please enter a string of text (the bigger the better): ")))
l=(int(len(string)))

for x in range(1,l+1):
    print(string[-x],end="")

for x in range(1,l+1):
    if string[-x]==" ":
        print(string[-x+1],end="")
<commit_msg>Updated from Brython Server: 2/8/2016 2:50:10 PM<commit_after>"""
stringjumble.py
Author: Avery Wallis
Credit: Ethan

Assignment:

The purpose of this challenge is to gain proficiency with
manipulating lists.

Write and submit a Python program that accepts a string from
the user and prints it back in three different ways:

* With all letters in reverse.
* With words in reverse order, but letters within each word in
  the correct order.
* With all words in correct order, but letters reversed within
  the words.

Output of your program should look like this:

Please enter a string of text (the bigger the better): There are a few techniques or tricks that you may find handy
You entered "There are a few techniques or tricks that you may find handy". Now jumble it:
ydnah dnif yam uoy taht skcirt ro seuqinhcet wef a era erehT
handy find may you that tricks or techniques few a are There
erehT era a wef seuqinhcet ro skcirt taht uoy yam dnif ydnah
"""
string= list(str(input("Please enter a string of text (the bigger the better): ")))
l=(int(len(string)))

for x in range(1,l+1):
    print(string[-x],end="")
print()
for x in range(1,l+1):
    if string[-x]==" ":
        print(string[-x+1],end="")
<|endoftext|>


<commit_before>"""
stringjumble.py
Author: Payton Stearns
Credit: Avery, Ethan, Daniel

Assignment:

The purpose of this challenge is to gain proficiency with
manipulating lists.

Write and submit a Python program that accepts a string from
the user and prints it back in three different ways:

* With all letters in reverse.
* With words in reverse order, but letters within each word in
  the correct order.
* With all words in correct order, but letters reversed within
  the words.

Output of your program should look like this:

Please enter a string of text (the bigger the better): There are a few techniques or tricks that you may find handy
You entered "There are a few techniques or tricks that you may find handy". Now jumble it:
ydnah dnif yam uoy taht skcirt ro seuqinhcet wef a era erehT
handy find may you that tricks or techniques few a are There
erehT era a wef seuqinhcet ro skcirt taht uoy yam dnif ydnah
"""
ost = str(input("Please enter a string of text (the bigger the better): "))
print("")
print("You entered: '" + ost + "'. Now Jumble it: ")
l = list(ost)
sost = ost.split(' ')

z=0
while z<len(l):
    print(str(l[len(l)-z-1]), end="")
    z=z+1
print("")
print()
f = list(reversed(sost))
for word in f:
    print(word, end=" ")
print("")
print()

for word in sost:
    q=0
    while q<len(word):
        r = (str(word[len(word)-q-1]))
        print("{0 :<3} ".format(r))
        q=q+1<commit_msg>Updated from Brython Server: 2/11/2016 8:35:48 AM<commit_after>"""
stringjumble.py
Author: Payton Stearns
Credit: Avery, Ethan, Daniel

Assignment:

The purpose of this challenge is to gain proficiency with
manipulating lists.

Write and submit a Python program that accepts a string from
the user and prints it back in three different ways:

* With all letters in reverse.
* With words in reverse order, but letters within each word in
  the correct order.
* With all words in correct order, but letters reversed within
  the words.

Output of your program should look like this:

Please enter a string of text (the bigger the better): There are a few techniques or tricks that you may find handy
You entered "There are a few techniques or tricks that you may find handy". Now jumble it:
ydnah dnif yam uoy taht skcirt ro seuqinhcet wef a era erehT
handy find may you that tricks or techniques few a are There
erehT era a wef seuqinhcet ro skcirt taht uoy yam dnif ydnah
"""
ost = str(input("Please enter a string of text (the bigger the better): "))
print("")
print("You entered: '" + ost + "'. Now Jumble it: ")
l = list(ost)
sost = ost.split(' ')

z=0
while z<len(l):
    print(str(l[len(l)-z-1]), end="")
    z=z+1
print("")
print()
f = list(reversed(sost))
for word in f:
    print(word, end=" ")
print("")
print()

for word in sost:
    q=0
    while q<len(word):
        r = (str(word[len(word)-q-1]))
        print("{0 :<3} ".format(r), end="")
        q=q+1<|endoftext|>


<commit_before>"""He
stringjumble.py
Author: Ethan Adner
Credit: Payton Stearns

Assignment:

The purpose of this challenge is to gain proficiency with
manipulating lists.

Write and submit a Python program that accepts a string from
the user and prints it back in three different ways:

* With all letters in reverse.
* With words in reverse order, but letters within each word in
  the correct order.
* With all words in correct order, but letters reversed within
  the words.

Output of your program should look like this:

Please enter a string of text (the bigger the better): There are a few techniques or tricks that you may find handy
You entered "There are a few techniques or tricks that you may find handy". Now jumble it:
ydnah dnif yam uoy taht skcirt ro seuqinhcet wef a era erehT
handy find may you that tricks or techniques few a are There
erehT era a wef seuqinhcet ro skcirt taht uoy yam dnif ydnah
"""
x=str(input("Please enter a string of text (the bigger the better): "))
w=list(x)
z=0

#Letters in reverse
while z<len(w):
    y=w[len(w)-z-1]
    print(y,end="")
    z=z+1
print("")
######################
#words in reverse

#splits words apart into letters
z=0
a=""
b=[""]
while z<len(w):

    a=a+str(w[z])
    if w[z]==" ":
        b.append(a)
        a=""

    z=z+1
b.append(a+" ")
print(b)
b.remove("")
#print(b)
#print(w)
z=0
#reverses words

while z<len(b):
    y=b[len(b)-z-1]
    print(y,end="")
    z=z+1
print("")

##################
a=[]
for x in b:
    for y in list(x):
        a.append(list((y))
print(a)

"""
z=0
a=[]
g=""
while z< len(w):

    #if z==len(w):
     #   z=z-1
    if str(w[z])==" ":
        #print(a)
        t=0
        while t<len(a):
            y=a[len(a)-t-1]
            print(y,end="")
            t=t+1
        print("",end="")
        a=[]
    a.append(w[z])
    z=z+1
'''ethan likes to eat all the ...'''

t=0
while t<len(a):
    y=a[len(a)-t-1]
    print("{0}".format(y),end="")
    t=t+1
print("", end=" ")

#print(a)
"""<commit_msg>Updated from Brython Server: 2/24/2016 2:39:26 PM<commit_after>"""He
stringjumble.py
Author: Ethan Adner
Credit: Payton Stearns

Assignment:

The purpose of this challenge is to gain proficiency with
manipulating lists.

Write and submit a Python program that accepts a string from
the user and prints it back in three different ways:

* With all letters in reverse.
* With words in reverse order, but letters within each word in
  the correct order.
* With all words in correct order, but letters reversed within
  the words.

Output of your program should look like this:

Please enter a string of text (the bigger the better): There are a few techniques or tricks that you may find handy
You entered "There are a few techniques or tricks that you may find handy". Now jumble it:
ydnah dnif yam uoy taht skcirt ro seuqinhcet wef a era erehT
handy find may you that tricks or techniques few a are There
erehT era a wef seuqinhcet ro skcirt taht uoy yam dnif ydnah
"""
x=str(input("Please enter a string of text (the bigger the better): "))
w=list(x)
z=0

#Letters in reverse
while z<len(w):
    y=w[len(w)-z-1]
    print(y,end="")
    z=z+1
print("")
######################
#words in reverse

#splits words apart into letters
z=0
a=""
b=[""]
while z<len(w):

    a=a+str(w[z])
    if w[z]==" ":
        b.append(a)
        a=""

    z=z+1
b.append(a+" ")
print(b)
b.remove("")
#print(b)
#print(w)
z=0
#reverses words

while z<len(b):
    y=b[len(b)-z-1]
    print(y,end="")
    z=z+1
print("")

##################
a=[]
for x in b:
    for y in list(x):
        a.append(str(y))
print(a)

"""
z=0
a=[]
g=""
while z< len(w):

    #if z==len(w):
     #   z=z-1
    if str(w[z])==" ":
        #print(a)
        t=0
        while t<len(a):
            y=a[len(a)-t-1]
            print(y,end="")
            t=t+1
        print("",end="")
        a=[]
    a.append(w[z])
    z=z+1
'''ethan likes to eat all the ...'''

t=0
while t<len(a):
    y=a[len(a)-t-1]
    print("{0}".format(y),end="")
    t=t+1
print("", end=" ")

#print(a)
"""<|endoftext|>


<commit_before>import base64
import hashlib
import re

__all__ = (
    'DEFAULT_ALOGRITHM',
    'RECOGNISED_ALGORITHMS',
    'generate',
    'parse',
)

DEFAULT_ALOGRITHM = 'sha384'

RECOGNISED_ALGORITHMS = (
    'sha512',
    'sha384',
    'sha256',
)

_INTEGRITY_PATTERN = re.compile(r'''
    [ \t]*                                  # RFC 5234 (ABNF): WSP
    (?P<algorithm>%(algorithms)s)           # W3C CSP2: hash-algo
    -
    (?P<b58_digest>[a-zA-Z0-9+/]+[=]{0,2})  # W3C CSP2: base64-value
    (?P<options>\?[\041-\176]*)?            # RFC 5234 (ABNF): VCHAR
    [ \t]*                                  # RFC 5234 (ABNF): WSP
    ''' % dict(algorithms='|'.join(RECOGNISED_ALGORITHMS)),
    re.VERBOSE,
)

class Hash(object):
    def __new__(cls, algorithm, digest, options=''):
        self = object.__new__(cls)
        self._algorithm = algorithm
        self._digest = digest
        self._options = options
        return self

    @classmethod
    def fromresource(cls, resource, algorithm=DEFAULT_ALOGRITHM, options=''):
        if algorithm not in RECOGNISED_ALGORITHMS:
            raise ValueError
        hasher = hashlib.new(algorithm, resource)
        digest = hasher.digest()
        return cls(algorithm, digest, options)

    @classmethod
    def fromhash(cls, algorithm, b58_digest, options):
        digest = base64.standard_b64decode(b58_digest)
        return cls(algorithm, digest, options)

    @classmethod
    def fromhashexpr(cls, s):
        m = _INTEGRITY_PATTERN.match(s)
        if not m:
            raise ValueError
        algorithm = m.group('alogrithm')
        b58_digest = m.group('b58_digest')
        options = m.group('options')[1:] # Remove leading '?'
        return cls.fromhash(alogrithm, b58_digest, options)

    @property
    def algorithm(self):
        return self._algorithm

    @property
    def digest(self):
        return self._digest

    @property
    def options(self):
        return self._options

    @property
    def b58digest(self):
        return base64.standard_b64encode(self._digest).decode('ascii')

    def __repr__(self):
        return "%s.%s('%s', '%s', '%s')" % (self.__class__.__module__,
                                            self.__class__.__name__,
                                            self.algorithm, self.b58digest,
                                            self.options)

    def __str__(self):
        if not self.options:
            return '%s-%s' % (self.algorithm, self.b58digest)
        return '%s-%s?%s' % (self.algorithm, self.b58digest, self.options)

    def __eq__(self, other):
        if isinstance(other, Hash):
            return bool(self.algorithm == other.algorithm
                        and self.digest == other.digest
                        and self.options == other.options)
        return False

    def __hash__(self):
        return hash((self.algorithm, self.digest, self.options))

def generate(data, algorithms=(DEFAULT_ALOGRITHM,)):
    """Yields subresource integrity Hash objects for the given data &
    algorithms

    >>> for ihash in generate(b"alert('Hello, world.');"):
    ...     print ('%s %s' % (ihash.algorithm, ihash.b58digest))
    sha384 H8BRh8j48O9oYatfu5AZzq6A9RINhZO5H16dQZngK7T62em8MUt1FLm52t+eX6xO

    >>> list(generate(b"alert('Hello, world.');", ['sha256', 'sha384']))
    ... # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE
    [subresource_integrity.Hash('sha256', 'qz.../Tng=', ''),
     subresource_integrity.Hash('sha384', 'H8BR...+eX6xO', '')]
    """
    return (Hash.fromresource(data, algorithm) for algorithm in algorithms)

def render(data, algorithms=(DEFAULT_ALOGRITHM,), seperator=' '):
    """Returns a subresource integrity string for the given data &
    algorithms

    >>> data = b"alert('Hello, world.');"
    >>> render(data)
    'sha384-H8BRh8j48O9oYatfu5AZzq6A9RINhZO5H16dQZngK7T62em8MUt1FLm52t+eX6xO'

    >>> print(render(data, ['sha256', 'sha384'], seperator='\\n'))
    sha256-qznLcsROx4GACP2dm0UCKCzCG+HiZ1guq6ZZDob/Tng=
    sha384-H8BRh8j48O9oYatfu5AZzq6A9RINhZO5H16dQZngK7T62em8MUt1FLm52t+eX6xO
    """
    return seperator.join(str(ihash) for ihash in generate(data, algorithms))

def parse(integrity):
    """Returns a list of subresource integrity Hash objects parsed from a str

    >>> parse('  sha256-47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU= ')
    ... # doctest: +ELLIPSIS
    [subresource_integrity.Hash('sha256', '47DEQp...SuFU=', '')]

    Hash objects are put in descending order of algorithmic strength

    >>> parse('sha384-dOTZf16X8p34q2/kYyEFm0jh89uTjikhnzjeLeF0FHsEaYKb'
    ...       '1A1cv+Lyv4Hk8vHd'
    ...       ' '
    ...       'sha512-Q2bFTOhEALkN8hOms2FKTDLy7eugP2zFZ1T8LCvX42Fp3WoN'
    ...       'r3bjZSAHeOsHrbV1Fu9/A0EzCinRE7Af1ofPrw=='
    ... )
    ... # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE
    [subresource_integrity.Hash('sha512', 'Q2b...zCinRE7Af1ofPrw==', ''),
     subresource_integrity.Hash('sha384', 'dOT...Hk8vHd', '')]

    Unrecognised hash algorithms are discarded

    >>> parse('sha1-2jmj7l5rSw0yVb/vlWAYkK/YBwk=')
    []
    """
    matches = _INTEGRITY_PATTERN.findall(integrity)
    matches.sort(key=lambda t: RECOGNISED_ALGORITHMS.index(t[0]))
    return [Hash.fromhash(*match) for match in matches]

<commit_msg>Rename b58_digest parameters to b64digest, keep b58digest property<commit_after>import base64
import hashlib
import re

__all__ = (
    'DEFAULT_ALOGRITHM',
    'RECOGNISED_ALGORITHMS',
    'generate',
    'parse',
)

DEFAULT_ALOGRITHM = 'sha384'

RECOGNISED_ALGORITHMS = (
    'sha512',
    'sha384',
    'sha256',
)

_INTEGRITY_PATTERN = re.compile(r'''
    [ \t]*                                  # RFC 5234 (ABNF): WSP
    (?P<algorithm>%(algorithms)s)           # W3C CSP2: hash-algo
    -
    (?P<b64digest>[a-zA-Z0-9+/]+[=]{0,2})   # W3C CSP2: base64-value
    (?P<options>\?[\041-\176]*)?            # RFC 5234 (ABNF): VCHAR
    [ \t]*                                  # RFC 5234 (ABNF): WSP
    ''' % dict(algorithms='|'.join(RECOGNISED_ALGORITHMS)),
    re.VERBOSE,
)

class Hash(object):
    def __new__(cls, algorithm, digest, options=''):
        self = object.__new__(cls)
        self._algorithm = algorithm
        self._digest = digest
        self._options = options
        return self

    @classmethod
    def fromresource(cls, resource, algorithm=DEFAULT_ALOGRITHM, options=''):
        if algorithm not in RECOGNISED_ALGORITHMS:
            raise ValueError
        hasher = hashlib.new(algorithm, resource)
        digest = hasher.digest()
        return cls(algorithm, digest, options)

    @classmethod
    def fromhash(cls, algorithm, b64digest, options=''):
        digest = base64.standard_b64decode(b64digest)
        return cls(algorithm, digest, options)

    @classmethod
    def fromhashexpr(cls, s):
        m = _INTEGRITY_PATTERN.match(s)
        if not m:
            raise ValueError
        algorithm = m.group('algorithm')
        b64digest = m.group('b64digest')
        options = m.group('options')[1:] # Remove leading '?'
        return cls.fromhash(algorithm, b64digest, options)

    @property
    def algorithm(self):
        return self._algorithm

    @property
    def digest(self):
        return self._digest

    @property
    def options(self):
        return self._options

    @property
    def b64digest(self):
        return base64.standard_b64encode(self._digest).decode('ascii')

    @property
    def b58digest(self):
        return self.b64digest

    def __repr__(self):
        return "%s.%s('%s', '%s', '%s')" % (self.__class__.__module__,
                                            self.__class__.__name__,
                                            self.algorithm, self.b64digest,
                                            self.options)

    def __str__(self):
        if not self.options:
            return '%s-%s' % (self.algorithm, self.b64digest)
        return '%s-%s?%s' % (self.algorithm, self.b64digest, self.options)

    def __eq__(self, other):
        if isinstance(other, Hash):
            return bool(self.algorithm == other.algorithm
                        and self.digest == other.digest
                        and self.options == other.options)
        return False

    def __hash__(self):
        return hash((self.algorithm, self.digest, self.options))

def generate(data, algorithms=(DEFAULT_ALOGRITHM,)):
    """Yields subresource integrity Hash objects for the given data &
    algorithms

    >>> for ihash in generate(b"alert('Hello, world.');"):
    ...     print ('%s %s' % (ihash.algorithm, ihash.b64digest))
    sha384 H8BRh8j48O9oYatfu5AZzq6A9RINhZO5H16dQZngK7T62em8MUt1FLm52t+eX6xO

    >>> list(generate(b"alert('Hello, world.');", ['sha256', 'sha384']))
    ... # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE
    [subresource_integrity.Hash('sha256', 'qz.../Tng=', ''),
     subresource_integrity.Hash('sha384', 'H8BR...+eX6xO', '')]
    """
    return (Hash.fromresource(data, algorithm) for algorithm in algorithms)

def render(data, algorithms=(DEFAULT_ALOGRITHM,), seperator=' '):
    """Returns a subresource integrity string for the given data &
    algorithms

    >>> data = b"alert('Hello, world.');"
    >>> render(data)
    'sha384-H8BRh8j48O9oYatfu5AZzq6A9RINhZO5H16dQZngK7T62em8MUt1FLm52t+eX6xO'

    >>> print(render(data, ['sha256', 'sha384'], seperator='\\n'))
    sha256-qznLcsROx4GACP2dm0UCKCzCG+HiZ1guq6ZZDob/Tng=
    sha384-H8BRh8j48O9oYatfu5AZzq6A9RINhZO5H16dQZngK7T62em8MUt1FLm52t+eX6xO
    """
    return seperator.join(str(ihash) for ihash in generate(data, algorithms))

def parse(integrity):
    """Returns a list of subresource integrity Hash objects parsed from a str

    >>> parse('  sha256-47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU= ')
    ... # doctest: +ELLIPSIS
    [subresource_integrity.Hash('sha256', '47DEQp...SuFU=', '')]

    Hash objects are put in descending order of algorithmic strength

    >>> parse('sha384-dOTZf16X8p34q2/kYyEFm0jh89uTjikhnzjeLeF0FHsEaYKb'
    ...       '1A1cv+Lyv4Hk8vHd'
    ...       ' '
    ...       'sha512-Q2bFTOhEALkN8hOms2FKTDLy7eugP2zFZ1T8LCvX42Fp3WoN'
    ...       'r3bjZSAHeOsHrbV1Fu9/A0EzCinRE7Af1ofPrw=='
    ... )
    ... # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE
    [subresource_integrity.Hash('sha512', 'Q2b...zCinRE7Af1ofPrw==', ''),
     subresource_integrity.Hash('sha384', 'dOT...Hk8vHd', '')]

    Unrecognised hash algorithms are discarded

    >>> parse('sha1-2jmj7l5rSw0yVb/vlWAYkK/YBwk=')
    []
    """
    matches = _INTEGRITY_PATTERN.findall(integrity)
    matches.sort(key=lambda t: RECOGNISED_ALGORITHMS.index(t[0]))
    return [Hash.fromhash(*match) for match in matches]

<|endoftext|>


<commit_before>from switchboard.pin import Pin
from switchboard.board import Board
from bawt.base import Base

from threading import Thread

import time
import sys

class Irrigation(Base):

    def get_zone(self, zone):
        return self.irrigation['zones'][zone]

    def _get_zone_definition(self, zone):
        return self.get_zone(zone)

    def _get_zone_pin(self, zone):
        pin_number = self._get_zone_definition(zone)
        return Pin(pin_number)

    def start(self, zone):
        pin = self._get_zone_pin(zone)
        pin.on()

    def stop(self, zone):
        pin = self._get_zone_pin(zone)
        pin.off()

    def timed_run(self, zone, run_time):
        thread = Thread(target=self.start(zone))
        thread.daemon = True
        thread.start()
        time.sleep(run_time)
        self.stop(zone)
<commit_msg>Fixed pin lookup<commit_after>from switchboard.pin import Pin
from switchboard.board import Board
from bawt.base import Base

from threading import Thread

import time
import sys

class Irrigation(Base):

    def get_zone(self, zone):
        return self.irrigation['zones'][zone]

    def _get_zone_definition(self, zone):
        return self.get_zone(zone)

    def _get_zone_pin(self, zone):
        pin_number = self._get_zone_definition(zone).get('pin', None)
        return Pin(pin_number)

    def start(self, zone):
        pin = self._get_zone_pin(zone)
        pin.on()

    def stop(self, zone):
        pin = self._get_zone_pin(zone)
        pin.off()

    def timed_run(self, zone, run_time):
        thread = Thread(target=self.start(zone))
        thread.daemon = True
        thread.start()
        time.sleep(run_time)
        self.stop(zone)
<|endoftext|>


<commit_before># coding: utf-8
# Copyright 2015
# Jerry Zhou <jerryzhou@hotmail.ca> and Christian Fobel <christian@fobel.net>
import warnings

import pandas as pd
import numpy as np

from . import INKSCAPE_NSMAP
from .draw import draw_lines_svg_layer as _draw_lines_svg_layer

def extend_shapes(df_shapes, axis, distance):
    '''
    Extend shape/polygon outline away from polygon center point by absolute
    distance.
    '''
    df_shapes_i = df_shapes.copy()
    offsets = df_shapes_i[axis + '_center_offset'].copy()
    offsets[offsets < 0] -= distance
    offsets[offsets >= 0] += distance
    df_shapes_i[axis] = df_shapes_i[axis + '_center'] + offsets
    return df_shapes_i

def extract_adjacent_shapes(df_shapes, shape_i_column, extend=.5):
    '''
    Generate list of connections between "adjacent" polygon shapes based on
    geometrical "closeness".

    Parameters
    ----------
    df_shapes : pandas.DataFrame
        Table of polygon shape vertices (one row per vertex).

        Table rows with the same value in the :data:`shape_i_column` column
        are grouped together as a polygon.
    shape_i_column : str or list[str]
        Column name(s) that identify the polygon each row belongs to.
    extend : float, optional
        Extend ``x``/``y`` coords by the specified number of absolute units
        from the center point of each polygon.
        Each polygon is stretched independently in the ``x`` and ``y`` direction.
        In each direction, a polygon considered adjacent to all polygons that
        are overlapped by the extended shape.

    Returns
    -------
    pandas.DataFrame
        Adjacency list as a frame containing the columns ``source`` and
        ``target``.

        The ``source`` and ``target`` of each adjacency connection is ordered
        such that the ``source`` is less than the ``target``.
    '''
    # Find corners of each solid shape outline.
    # Extend x coords by abs units
    df_scaled_x = extend_shapes(df_shapes, 'x', extend)
    # Extend y coords by abs units
    df_scaled_y = extend_shapes(df_shapes, 'y', extend)

    df_corners = df_shapes.groupby(shape_i_column).agg({'x': ['min', 'max'],
                                                        'y': ['min', 'max']})

    # Find adjacent electrodes
    row_list = []

    for shapeNumber in df_shapes[shape_i_column].drop_duplicates():
        df_stretched = df_scaled_x[df_scaled_x[shape_i_column]
                                   .isin([shapeNumber])]
        xmin_x, xmax_x, ymin_x, ymax_x = (df_stretched.x.min(),
                                          df_stretched.x.max(),
                                          df_stretched.y.min(),
                                          df_stretched.y.max())
        df_stretched = df_scaled_y[df_scaled_y[shape_i_column]
                                   .isin([shapeNumber])]
        xmin_y, xmax_y, ymin_y, ymax_y = (df_stretched.x.min(),
                                          df_stretched.x.max(),
                                          df_stretched.y.min(),
                                          df_stretched.y.max())

        #Some conditions unnecessary if it is assumed that electrodes don't overlap
        adjacent = df_corners[
            ((df_corners.x['min'] < xmax_x) & (df_corners.x['max'] >= xmax_x)
            # Check in x stretched direction
            |(df_corners.x['min'] < xmin_x) & (df_corners.x['max'] >= xmin_x))
            # Check if y is within bounds
            & (df_corners.y['min'] < ymax_x) & (df_corners.y['max'] > ymin_x) |

            #maybe do ymax_x - df_corners.y['min'] > threshold &
            #  df_corners.y['max'] - ymin_x > threshold

            ((df_corners.y['min'] < ymax_y) & (df_corners.y['max'] >= ymax_y)
             # Checks in y stretched direction
             |(df_corners.y['min'] < ymin_y) & (df_corners.y['max'] >= ymin_y))
             # Check if x in within bounds
            & ((df_corners.x['min'] < xmax_y) & (df_corners.x['max'] > xmin_y))
        ].index.values

        for shape in adjacent:
            temp_dict = {}
            reverse_dict = {}

            temp_dict ['source'] = shapeNumber
            reverse_dict['source'] = shape
            temp_dict ['target'] = shape
            reverse_dict['target'] = shapeNumber

            if(reverse_dict not in row_list):
                row_list.append(temp_dict)

    df_connected = (pd.DataFrame(row_list)[['source', 'target']]
                    .sort_index(axis=1, ascending=True)
                    .sort_values(['source', 'target']))
    return df_connected

def get_adjacency_matrix(df_connected):
    '''
    Return matrix where $a_{i,j} = 1$ indicates polygon $i$ is connected to
    polygon $j$.

    Also, return mapping (and reverse mapping) from original keys in
    `df_connected` to zero-based integer index used for matrix rows and
    columns.
    '''
    sorted_path_keys = np.sort(np.unique(df_connected[['source', 'target']]
                                         .values.ravel()))
    indexed_paths = pd.Series(sorted_path_keys)
    path_indexes = pd.Series(indexed_paths.index, index=sorted_path_keys)

    adjacency_matrix = np.zeros((path_indexes.shape[0], ) * 2, dtype=int)
    for i_key, j_key in df_connected[['source', 'target']].values:
        i, j = path_indexes.loc[[i_key, j_key]]
        adjacency_matrix[i, j] = 1
        adjacency_matrix[j, i] = 1
    return adjacency_matrix, indexed_paths, path_indexes

def extract_connections(svg_source, shapes_canvas, line_layer='Connections',
                        line_xpath=None, namespaces=None):
    '''
    Load all lines from a layer of an SVG source.  For each line, if endpoints
    overlap distinct shapes in `shapes_canvas`, add connection between
    overlapped shapes.

    Args:

        svg_source (filepath) : Input SVG file containing connection lines.
        shapes_canvas (shapes_canvas.ShapesCanvas) : Shapes canvas containing
            shapes to compare against connection endpoints.
        line_layer (str) : Name of layer in SVG containing connection lines.
        line_xpath (str) : XPath string to iterate throught connection lines.
        namespaces (dict) : SVG namespaces (compatible with `etree.parse`).

    Returns:

        (pandas.DataFrame) : Each row corresponds to connection between two
            shapes in `shapes_canvas`, denoted `source` and `target`.
    '''
    from lxml import etree

    if namespaces is None:
        namespaces = INKSCAPE_NSMAP

    e_root = etree.parse(svg_source)
    frames = []

    if line_xpath is None:
        line_xpath = ("//svg:g[@inkscape:label='%s']/svg:line"
                      % line_layer)
    coords_columns = ['x1', 'y1', 'x2', 'y2']

    for line_i in e_root.xpath(line_xpath, namespaces=namespaces):
        line_i_dict = dict(line_i.items())
        values = ([line_i_dict.get('id', None)] +
                  [float(line_i_dict[k]) for k in coords_columns])
        frames.append(values)

    if not frames:
        return pd.DataFrame(None, columns=['source', 'target'])

    df_connection_lines = pd.DataFrame(frames, columns=['id'] + coords_columns)

    df_shape_connections_i = pd.DataFrame([[shapes_canvas.find_shape(x1, y1),
                                            shapes_canvas.find_shape(x2, y2)]
                                           for i, (x1, y1, x2, y2) in
                                           df_connection_lines[coords_columns]
                                           .iterrows()],
                                          columns=['source', 'target'])
    df_shape_connections_i.sort_index(axis=1, inplace=True)
    df_shape_connections_i['line_id'] = df_connection_lines['id']
    return df_shape_connections_i.dropna()

def draw_lines_svg_layer(df_endpoints, layer_name='Connections'):
    warnings.warn('`draw_lines_svg_layer` has been moved to `svg_model.draw`')
    return _draw_lines_svg_layer(df_endpoints, layer_name=layer_name)
<commit_msg>Support <svg:path> in extract_connections<commit_after># coding: utf-8
# Copyright 2015
# Jerry Zhou <jerryzhou@hotmail.ca> and Christian Fobel <christian@fobel.net>
import re
import warnings

import pandas as pd
import numpy as np

from . import INKSCAPE_NSMAP
from .draw import draw_lines_svg_layer as _draw_lines_svg_layer

def extend_shapes(df_shapes, axis, distance):
    '''
    Extend shape/polygon outline away from polygon center point by absolute
    distance.
    '''
    df_shapes_i = df_shapes.copy()
    offsets = df_shapes_i[axis + '_center_offset'].copy()
    offsets[offsets < 0] -= distance
    offsets[offsets >= 0] += distance
    df_shapes_i[axis] = df_shapes_i[axis + '_center'] + offsets
    return df_shapes_i

def extract_adjacent_shapes(df_shapes, shape_i_column, extend=.5):
    '''
    Generate list of connections between "adjacent" polygon shapes based on
    geometrical "closeness".

    Parameters
    ----------
    df_shapes : pandas.DataFrame
        Table of polygon shape vertices (one row per vertex).

        Table rows with the same value in the :data:`shape_i_column` column
        are grouped together as a polygon.
    shape_i_column : str or list[str]
        Column name(s) that identify the polygon each row belongs to.
    extend : float, optional
        Extend ``x``/``y`` coords by the specified number of absolute units
        from the center point of each polygon.
        Each polygon is stretched independently in the ``x`` and ``y`` direction.
        In each direction, a polygon considered adjacent to all polygons that
        are overlapped by the extended shape.

    Returns
    -------
    pandas.DataFrame
        Adjacency list as a frame containing the columns ``source`` and
        ``target``.

        The ``source`` and ``target`` of each adjacency connection is ordered
        such that the ``source`` is less than the ``target``.
    '''
    # Find corners of each solid shape outline.
    # Extend x coords by abs units
    df_scaled_x = extend_shapes(df_shapes, 'x', extend)
    # Extend y coords by abs units
    df_scaled_y = extend_shapes(df_shapes, 'y', extend)

    df_corners = df_shapes.groupby(shape_i_column).agg({'x': ['min', 'max'],
                                                        'y': ['min', 'max']})

    # Find adjacent electrodes
    row_list = []

    for shapeNumber in df_shapes[shape_i_column].drop_duplicates():
        df_stretched = df_scaled_x[df_scaled_x[shape_i_column]
                                   .isin([shapeNumber])]
        xmin_x, xmax_x, ymin_x, ymax_x = (df_stretched.x.min(),
                                          df_stretched.x.max(),
                                          df_stretched.y.min(),
                                          df_stretched.y.max())
        df_stretched = df_scaled_y[df_scaled_y[shape_i_column]
                                   .isin([shapeNumber])]
        xmin_y, xmax_y, ymin_y, ymax_y = (df_stretched.x.min(),
                                          df_stretched.x.max(),
                                          df_stretched.y.min(),
                                          df_stretched.y.max())

        #Some conditions unnecessary if it is assumed that electrodes don't overlap
        adjacent = df_corners[
            ((df_corners.x['min'] < xmax_x) & (df_corners.x['max'] >= xmax_x)
            # Check in x stretched direction
            |(df_corners.x['min'] < xmin_x) & (df_corners.x['max'] >= xmin_x))
            # Check if y is within bounds
            & (df_corners.y['min'] < ymax_x) & (df_corners.y['max'] > ymin_x) |

            #maybe do ymax_x - df_corners.y['min'] > threshold &
            #  df_corners.y['max'] - ymin_x > threshold

            ((df_corners.y['min'] < ymax_y) & (df_corners.y['max'] >= ymax_y)
             # Checks in y stretched direction
             |(df_corners.y['min'] < ymin_y) & (df_corners.y['max'] >= ymin_y))
             # Check if x in within bounds
            & ((df_corners.x['min'] < xmax_y) & (df_corners.x['max'] > xmin_y))
        ].index.values

        for shape in adjacent:
            temp_dict = {}
            reverse_dict = {}

            temp_dict ['source'] = shapeNumber
            reverse_dict['source'] = shape
            temp_dict ['target'] = shape
            reverse_dict['target'] = shapeNumber

            if(reverse_dict not in row_list):
                row_list.append(temp_dict)

    df_connected = (pd.DataFrame(row_list)[['source', 'target']]
                    .sort_index(axis=1, ascending=True)
                    .sort_values(['source', 'target']))
    return df_connected

def get_adjacency_matrix(df_connected):
    '''
    Return matrix where $a_{i,j} = 1$ indicates polygon $i$ is connected to
    polygon $j$.

    Also, return mapping (and reverse mapping) from original keys in
    `df_connected` to zero-based integer index used for matrix rows and
    columns.
    '''
    sorted_path_keys = np.sort(np.unique(df_connected[['source', 'target']]
                                         .values.ravel()))
    indexed_paths = pd.Series(sorted_path_keys)
    path_indexes = pd.Series(indexed_paths.index, index=sorted_path_keys)

    adjacency_matrix = np.zeros((path_indexes.shape[0], ) * 2, dtype=int)
    for i_key, j_key in df_connected[['source', 'target']].values:
        i, j = path_indexes.loc[[i_key, j_key]]
        adjacency_matrix[i, j] = 1
        adjacency_matrix[j, i] = 1
    return adjacency_matrix, indexed_paths, path_indexes

def extract_connections(svg_source, shapes_canvas, line_layer='Connections',
                        line_xpath=None, path_xpath=None, namespaces=None):
    '''
    Load all ``<svg:line>`` elements and ``<svg:path>`` elements from a layer
    of an SVG source.  For each element, if endpoints overlap distinct shapes
    in :data:`shapes_canvas`, add connection between overlapped shapes.

    .. versionchanged:: 0.6.post1
        Allow both ``<svg:line>`` *and* ``<svg:path>`` instances to denote
        connected/adjacent shapes.

    .. versionadded:: 0.6.post1
        :data:`path_xpath`

    Parameters
    ----------
    svg_source : filepath
        Input SVG file containing connection lines.
    shapes_canvas : shapes_canvas.ShapesCanvas
        Shapes canvas containing shapes to compare against connection
        endpoints.
    line_layer : str
        Name of layer in SVG containing connection lines.
    line_xpath : str
        XPath string to iterate through connection lines.
    path_xpath : str
        XPath string to iterate through connection paths.
    namespaces : dict
        SVG namespaces (compatible with :func:`etree.parse`).

    Returns
    -------
    pandas.DataFrame
        Each row corresponds to connection between two shapes in
        :data:`shapes_canvas`, denoted ``source`` and ``target``.
    '''
    from lxml import etree

    if namespaces is None:
        namespaces = INKSCAPE_NSMAP

    e_root = etree.parse(svg_source)
    frames = []

    if line_xpath is None:
        line_xpath = ("//svg:g[@inkscape:label='%s']/svg:line" % line_layer)
    coords_columns = ['x1', 'y1', 'x2', 'y2']

    for line_i in e_root.xpath(line_xpath, namespaces=namespaces):
        line_i_dict = dict(line_i.items())
        values = ([line_i_dict.get('id', None)] +
                  [float(line_i_dict[k]) for k in coords_columns])
        frames.append(values)

    cre_path_ends = re.compile(r'^\s*M\s*(?P<start_x>\d+(\.\d+)?),\s*'
                               r'(?P<start_y>\d+(\.\d+)?).*L\s*'
                               r'(?P<end_x>\d+(\.\d+)?),\s*'
                               r'(?P<end_y>\d+(\.\d+)?)\D*$')

    if path_xpath is None:
        path_xpath = ("//svg:g[@inkscape:label='%s']/svg:path" % line_layer)

    for path_i in e_root.xpath(path_xpath, namespaces=namespaces):
        path_i_dict = dict(path_i.items())
        match_i = cre_path_ends.match(path_i_dict['d'])
        if match_i:
            frames.append([path_i_dict['id']] + map(float,
                                                    (match_i.group('start_x'),
                                                     match_i.group('start_y'),
                                                     match_i.group('end_x'),
                                                     match_i.group('end_y'))))

    if not frames:
        return pd.DataFrame(None, columns=['source', 'target'])

    df_connection_lines = pd.DataFrame(frames, columns=['id'] + coords_columns)

    df_shape_connections_i = pd.DataFrame([[shapes_canvas.find_shape(x1, y1),
                                            shapes_canvas.find_shape(x2, y2)]
                                           for i, (x1, y1, x2, y2) in
                                           df_connection_lines[coords_columns]
                                           .iterrows()],
                                          columns=['source', 'target'])
    df_shape_connections_i.sort_index(axis=1, inplace=True)
    df_shape_connections_i['line_id'] = df_connection_lines['id']
    return df_shape_connections_i.dropna()

def draw_lines_svg_layer(df_endpoints, layer_name='Connections'):
    warnings.warn('`draw_lines_svg_layer` has been moved to `svg_model.draw`')
    return _draw_lines_svg_layer(df_endpoints, layer_name=layer_name)
<|endoftext|>


<commit_before>__version__ = '0.9.21'
VERSION = __version__
<commit_msg>bump version to 0.9.22<commit_after>__version__ = '0.9.22'
VERSION = __version__
<|endoftext|>


<commit_before># Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

import mock
from oslo_log import log as logging
from oslo_utils import timeutils

from senlin.engine import cluster as cluster_mod
from senlin.engine import event as EVENT
from senlin.objects import event as eo
from senlin.tests.unit.common import base
from senlin.tests.unit.common import utils

class TestEvent(base.SenlinTestCase):

    def setUp(self):
        super(TestEvent, self).setUp()
        self.context = utils.dummy_context()

    def test_event_init(self):
        timestamp = timeutils.utcnow(True)
        kwargs = {
            'id': 'FAKE-ID',
            'user': 'test-user',
            'project': 'test-project',
            'action': 'fake-action',
            'status': 'ACTIVE',
            'status_reason': 'Weather is clear',
            'oid': 'FAKE-OBJ-ID',
            'otype': 'CLUSTER-TYPE',
            'oname': 'fake-cluster',
            'cluster_id': 'FAKE-CLUSTER-ID',
            'metadata': {'foo': 'bar'},
        }

        event = EVENT.Event(timestamp, logging.CRITICAL, **kwargs)

        self.assertEqual(timestamp, event.timestamp)
        self.assertEqual(logging.CRITICAL, event.level)
        self.assertEqual('FAKE-ID', event.id)
        self.assertEqual('test-user', event.user)
        self.assertEqual('test-project', event.project)

        self.assertEqual('fake-action', event.action)
        self.assertEqual('ACTIVE', event.status)
        self.assertEqual('Weather is clear', event.status_reason)

        self.assertEqual('FAKE-OBJ-ID', event.oid)
        self.assertEqual('CLUSTER-TYPE', event.otype)
        self.assertEqual('fake-cluster', event.oname)
        self.assertEqual('FAKE-CLUSTER-ID', event.cluster_id)
        self.assertEqual({'foo': 'bar'}, event.metadata)

    def test_event_init_with_entity(self):
        timestamp = timeutils.utcnow(True)
        x_cluster = cluster_mod.Cluster('fake-cluster', 0, 'fake-profile',
                                        id='FAKE_CLUSTER')

        event = EVENT.Event(timestamp, logging.CRITICAL, x_cluster,
                            action="FAKE_ACTION", status="ACTIVE",
                            status_reason="Recovered just now",
                            user=self.context.user,
                            project=self.context.project)

        self.assertEqual(timestamp, event.timestamp)
        self.assertIsNone(event.id)
        self.assertEqual(logging.CRITICAL, event.level)
        self.assertEqual(self.context.user, event.user)
        self.assertEqual(self.context.project, event.project)
        self.assertEqual('FAKE_ACTION', event.action)
        self.assertEqual('ACTIVE', event.status)
        self.assertEqual('Recovered just now', event.status_reason)

        self.assertEqual('FAKE_CLUSTER', event.oid)
        self.assertEqual('fake-cluster', event.oname)
        self.assertEqual('FAKE_CLUSTER', event.cluster_id)
        self.assertEqual('CLUSTER', event.otype)

    @mock.patch('oslo_utils.reflection.get_class_name')
    def test_event__infer_entity_data_cluster(self, mock_get):
        entity = mock.Mock(id='obj-id', status='fake-status',
                           status_reason='fake-reason', target='fake-target',
                           cluster_id='cluster-id')
        entity.name = 'obj-name'
        mock_get.return_value = 'Cluster'

        event = EVENT.Event('timestamp', 'level', entity)

        self.assertEqual('timestamp', event.timestamp)
        self.assertEqual('level', event.level)
        self.assertEqual('obj-name', event.oname)
        self.assertEqual('fake-status', event.status)
        self.assertEqual('fake-reason', event.status_reason)
        self.assertEqual('CLUSTER', event.otype)
        self.assertEqual('obj-id', event.oid)
        self.assertEqual('obj-id', event.cluster_id)
        mock_get.assert_called_once_with(entity, fully_qualified=False)

    @mock.patch('oslo_utils.reflection.get_class_name')
    def test_event__infer_entity_data_node(self, mock_get):
        entity = mock.Mock(id='obj-id', status='fake-status',
                           status_reason='fake-reason', target='fake-target',
                           cluster_id='cluster-id')
        entity.name = 'obj-name'
        mock_get.return_value = 'Node'

        event = EVENT.Event('timestamp', 'level', entity)

        self.assertEqual('timestamp', event.timestamp)
        self.assertEqual('level', event.level)
        self.assertEqual('obj-name', event.oname)
        self.assertEqual('fake-status', event.status)
        self.assertEqual('fake-reason', event.status_reason)
        self.assertEqual('NODE', event.otype)
        self.assertEqual('obj-id', event.oid)
        self.assertEqual('cluster-id', event.cluster_id)
        mock_get.assert_called_once_with(entity, fully_qualified=False)

    @mock.patch('oslo_utils.reflection.get_class_name')
    def test_event__infer_entity_data_clusteraction(self, mock_get):
        entity = mock.Mock(status='fake-status', status_reason='fake-reason',
                           target='fake-cluster')
        entity.cluster = mock.Mock()
        entity.cluster.name = 'obj-name'
        mock_get.return_value = 'ClusterAction'

        event = EVENT.Event('timestamp', 'level', entity)

        self.assertEqual('timestamp', event.timestamp)
        self.assertEqual('level', event.level)
        self.assertEqual('obj-name', event.oname)
        self.assertEqual('fake-status', event.status)
        self.assertEqual('fake-reason', event.status_reason)
        self.assertEqual('CLUSTER', event.otype)
        self.assertEqual('fake-cluster', event.oid)
        self.assertEqual('fake-cluster', event.cluster_id)
        mock_get.assert_called_once_with(entity, fully_qualified=False)

    @mock.patch('oslo_utils.reflection.get_class_name')
    def test_event__infer_entity_data_nodeaction(self, mock_get):
        entity = mock.Mock(status='fake-status', status_reason='fake-reason',
                           target='fake-node')
        entity.node = mock.Mock()
        entity.node.name = 'obj-name'
        entity.node.cluster_id = 'fake-cluster'
        mock_get.return_value = 'NodeAction'

        event = EVENT.Event('timestamp', 'level', entity)

        self.assertEqual('timestamp', event.timestamp)
        self.assertEqual('level', event.level)
        self.assertEqual('obj-name', event.oname)
        self.assertEqual('fake-status', event.status)
        self.assertEqual('fake-reason', event.status_reason)
        self.assertEqual('NODE', event.otype)
        self.assertEqual('fake-node', event.oid)
        self.assertEqual('fake-cluster', event.cluster_id)
        mock_get.assert_called_once_with(entity, fully_qualified=False)

    def test_event_store(self):
        timestamp = timeutils.utcnow(True)
        kwargs = {
            'user': self.context.user,
            'project': self.context.project,
            'action': 'fake-action',
            'status': 'ACTIVE',
            'status_reason': 'Weather is clear',
            'oid': 'FAKE-CLUSTER-ID',
            'otype': 'CLUSTER TYPE',
            'oname': 'fake-cluster',
            'cluster_id': 'FAKE-CLUSTER-ID',
            'metadata': {'foo': 'bar'},
        }

        event = EVENT.Event(timestamp, logging.CRITICAL, **kwargs)
        self.assertIsNone(event.id)

        event_id = event.store(self.context)

        self.assertIsNotNone(event_id)
        self.assertEqual(event_id, event.id)

        result = eo.Event.get(self.context, event_id)

        self.assertIsNotNone(result)
        self.assertEqual(event_id, result.id)
        self.assertEqual(timestamp, result.timestamp)
        self.assertEqual(event.level, int(result.level))
        self.assertEqual(event.user, result.user)
        self.assertEqual(event.project, result.project)
        self.assertEqual(event.action, result.action)
        self.assertEqual(event.status, result.status)
        self.assertEqual(event.status_reason, result.status_reason)
        self.assertEqual(event.oid, result.oid)
        self.assertEqual(event.otype, result.otype)
        self.assertEqual(event.oname, result.oname)
        self.assertEqual(event.cluster_id, result.cluster_id)
        self.assertEqual(event.metadata, result.meta_data)
<commit_msg>Fix event unit test<commit_after># Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

import mock
from oslo_log import log as logging
from oslo_utils import timeutils

from senlin.engine import cluster as cluster_mod
from senlin.engine import event as EVENT
from senlin.objects import event as eo
from senlin.tests.unit.common import base
from senlin.tests.unit.common import utils

CLUSTER_ID = '2c5139a6-24ba-4a6f-bd53-a268f61536de'

class TestEvent(base.SenlinTestCase):

    def setUp(self):
        super(TestEvent, self).setUp()
        self.context = utils.dummy_context()

    def test_event_init(self):
        timestamp = timeutils.utcnow(True)
        kwargs = {
            'id': 'FAKE-ID',
            'user': 'test-user',
            'project': 'test-project',
            'action': 'fake-action',
            'status': 'ACTIVE',
            'status_reason': 'Weather is clear',
            'oid': 'FAKE-OBJ-ID',
            'otype': 'CLUSTER-TYPE',
            'oname': 'fake-cluster',
            'cluster_id': CLUSTER_ID,
            'metadata': {'foo': 'bar'},
        }

        event = EVENT.Event(timestamp, logging.CRITICAL, **kwargs)

        self.assertEqual(timestamp, event.timestamp)
        self.assertEqual(logging.CRITICAL, event.level)
        self.assertEqual('FAKE-ID', event.id)
        self.assertEqual('test-user', event.user)
        self.assertEqual('test-project', event.project)

        self.assertEqual('fake-action', event.action)
        self.assertEqual('ACTIVE', event.status)
        self.assertEqual('Weather is clear', event.status_reason)

        self.assertEqual('FAKE-OBJ-ID', event.oid)
        self.assertEqual('CLUSTER-TYPE', event.otype)
        self.assertEqual('fake-cluster', event.oname)
        self.assertEqual(CLUSTER_ID, event.cluster_id)
        self.assertEqual({'foo': 'bar'}, event.metadata)

    def test_event_init_with_entity(self):
        timestamp = timeutils.utcnow(True)
        x_cluster = cluster_mod.Cluster('fake-cluster', 0, 'fake-profile',
                                        id='FAKE_CLUSTER')

        event = EVENT.Event(timestamp, logging.CRITICAL, x_cluster,
                            action="FAKE_ACTION", status="ACTIVE",
                            status_reason="Recovered just now",
                            user=self.context.user,
                            project=self.context.project)

        self.assertEqual(timestamp, event.timestamp)
        self.assertIsNone(event.id)
        self.assertEqual(logging.CRITICAL, event.level)
        self.assertEqual(self.context.user, event.user)
        self.assertEqual(self.context.project, event.project)
        self.assertEqual('FAKE_ACTION', event.action)
        self.assertEqual('ACTIVE', event.status)
        self.assertEqual('Recovered just now', event.status_reason)

        self.assertEqual('FAKE_CLUSTER', event.oid)
        self.assertEqual('fake-cluster', event.oname)
        self.assertEqual('FAKE_CLUSTER', event.cluster_id)
        self.assertEqual('CLUSTER', event.otype)

    @mock.patch('oslo_utils.reflection.get_class_name')
    def test_event__infer_entity_data_cluster(self, mock_get):
        entity = mock.Mock(id='obj-id', status='fake-status',
                           status_reason='fake-reason', target='fake-target',
                           cluster_id='cluster-id')
        entity.name = 'obj-name'
        mock_get.return_value = 'Cluster'

        event = EVENT.Event('timestamp', 'level', entity)

        self.assertEqual('timestamp', event.timestamp)
        self.assertEqual('level', event.level)
        self.assertEqual('obj-name', event.oname)
        self.assertEqual('fake-status', event.status)
        self.assertEqual('fake-reason', event.status_reason)
        self.assertEqual('CLUSTER', event.otype)
        self.assertEqual('obj-id', event.oid)
        self.assertEqual('obj-id', event.cluster_id)
        mock_get.assert_called_once_with(entity, fully_qualified=False)

    @mock.patch('oslo_utils.reflection.get_class_name')
    def test_event__infer_entity_data_node(self, mock_get):
        entity = mock.Mock(id='obj-id', status='fake-status',
                           status_reason='fake-reason', target='fake-target',
                           cluster_id='cluster-id')
        entity.name = 'obj-name'
        mock_get.return_value = 'Node'

        event = EVENT.Event('timestamp', 'level', entity)

        self.assertEqual('timestamp', event.timestamp)
        self.assertEqual('level', event.level)
        self.assertEqual('obj-name', event.oname)
        self.assertEqual('fake-status', event.status)
        self.assertEqual('fake-reason', event.status_reason)
        self.assertEqual('NODE', event.otype)
        self.assertEqual('obj-id', event.oid)
        self.assertEqual('cluster-id', event.cluster_id)
        mock_get.assert_called_once_with(entity, fully_qualified=False)

    @mock.patch('oslo_utils.reflection.get_class_name')
    def test_event__infer_entity_data_clusteraction(self, mock_get):
        entity = mock.Mock(status='fake-status', status_reason='fake-reason',
                           target=CLUSTER_ID)
        entity.cluster = mock.Mock()
        entity.cluster.name = 'obj-name'
        mock_get.return_value = 'ClusterAction'

        event = EVENT.Event('timestamp', 'level', entity)

        self.assertEqual('timestamp', event.timestamp)
        self.assertEqual('level', event.level)
        self.assertEqual('obj-name', event.oname)
        self.assertEqual('fake-status', event.status)
        self.assertEqual('fake-reason', event.status_reason)
        self.assertEqual('CLUSTER', event.otype)
        self.assertEqual(CLUSTER_ID, event.oid)
        self.assertEqual(CLUSTER_ID, event.cluster_id)
        mock_get.assert_called_once_with(entity, fully_qualified=False)

    @mock.patch('oslo_utils.reflection.get_class_name')
    def test_event__infer_entity_data_nodeaction(self, mock_get):
        entity = mock.Mock(status='fake-status', status_reason='fake-reason',
                           target='fake-node')
        entity.node = mock.Mock()
        entity.node.name = 'obj-name'
        entity.node.cluster_id = CLUSTER_ID
        mock_get.return_value = 'NodeAction'

        event = EVENT.Event('timestamp', 'level', entity)

        self.assertEqual('timestamp', event.timestamp)
        self.assertEqual('level', event.level)
        self.assertEqual('obj-name', event.oname)
        self.assertEqual('fake-status', event.status)
        self.assertEqual('fake-reason', event.status_reason)
        self.assertEqual('NODE', event.otype)
        self.assertEqual('fake-node', event.oid)
        self.assertEqual(CLUSTER_ID, event.cluster_id)
        mock_get.assert_called_once_with(entity, fully_qualified=False)

    def test_event_store(self):
        timestamp = timeutils.utcnow(True)
        kwargs = {
            'user': self.context.user,
            'project': self.context.project,
            'action': 'fake-action',
            'status': 'ACTIVE',
            'status_reason': 'Weather is clear',
            'oid': CLUSTER_ID,
            'otype': 'CLUSTER TYPE',
            'oname': 'fake-cluster',
            'cluster_id': CLUSTER_ID,
            'metadata': {'foo': 'bar'},
        }

        event = EVENT.Event(timestamp, logging.CRITICAL, **kwargs)
        self.assertIsNone(event.id)

        event_id = event.store(self.context)

        self.assertIsNotNone(event_id)
        self.assertEqual(event_id, event.id)

        result = eo.Event.get(self.context, event_id)

        self.assertIsNotNone(result)
        self.assertEqual(event_id, result.id)
        self.assertEqual(timestamp, result.timestamp)
        self.assertEqual(event.level, int(result.level))
        self.assertEqual(event.user, result.user)
        self.assertEqual(event.project, result.project)
        self.assertEqual(event.action, result.action)
        self.assertEqual(event.status, result.status)
        self.assertEqual(event.status_reason, result.status_reason)
        self.assertEqual(event.oid, result.oid)
        self.assertEqual(event.otype, result.otype)
        self.assertEqual(event.oname, result.oname)
        self.assertEqual(event.cluster_id, result.cluster_id)
        self.assertEqual(event.metadata, result.meta_data)
<|endoftext|>


<commit_before>from django.conf.urls import include, url
from rest_framework import routers

from api.events.views import CategoryViewSet, EventViewSet
from api.users.views import ProfileView, UserViewSet

router = routers.DefaultRouter()
router.register('categories', CategoryViewSet)
router.register('events', EventViewSet)
# router.register('users/profile', ProfileViewSet)
router.register('users', UserViewSet)

urlpatterns = [
    url(r'^users/profile', ProfileView.as_view()),
    url(r'^', include(router.urls)),
    url(r'^docs/', include('rest_framework_swagger.urls')),
]
<commit_msg>clean up<commit_after>from django.conf.urls import include, url
from rest_framework import routers

from api.events.views import CategoryViewSet, EventViewSet
from api.users.views import ProfileView, UserViewSet

router = routers.DefaultRouter()
router.register('categories', CategoryViewSet)
router.register('events', EventViewSet)
router.register('users', UserViewSet)

urlpatterns = [
    url(r'^users/profile', ProfileView.as_view()),
    url(r'^', include(router.urls)),
    url(r'^docs/', include('rest_framework_swagger.urls')),
]
<|endoftext|>


<commit_before># Copyright (C) 2009 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import sys

from color import Coloring
from command import PagedCommand
from error import GitError
from git_command import GitCommand

class GrepColoring(Coloring):
  def __init__(self, config):
    Coloring.__init__(self, config, 'grep')
    self.project = self.printer('project', attr='bold')
    self.fail = self.printer('fail', fg='red')

class Grep(PagedCommand):
  common = True
  helpSummary = "Print lines matching a pattern"
  helpUsage = """
%prog {pattern | -e pattern} [<project>...]
"""
  helpDescription = """
Search for the specified patterns in all project files.

# Boolean Options

The following options can appear as often as necessary to express
the pattern to locate:

 -e PATTERN
 --and, --or, --not, -(, -)

Further, the -r/--revision option may be specified multiple times
in order to scan multiple trees.  If the same file matches in more
than one tree, only the first result is reported, prefixed by the
revision name it was found under.

# Examples

Look for a line that has '#define' and either 'MAX_PATH or 'PATH_MAX':

  repo grep -e '#define' --and -\\( -e MAX_PATH -e PATH_MAX \\)

Look for a line that has 'NODE' or 'Unexpected' in files that
contain a line that matches both expressions:

  repo grep --all-match -e NODE -e Unexpected

"""

  @staticmethod
  def _carry_option(_option, opt_str, value, parser):
    pt = getattr(parser.values, 'cmd_argv', None)
    if pt is None:
      pt = []
      setattr(parser.values, 'cmd_argv', pt)

    if opt_str == '-(':
      pt.append('(')
    elif opt_str == '-)':
      pt.append(')')
    else:
      pt.append(opt_str)

    if value is not None:
      pt.append(value)

  def _Options(self, p):
    g = p.add_option_group('Sources')
    g.add_option('--cached',
                 action='callback', callback=self._carry_option,
                 help='Search the index, instead of the work tree')
    g.add_option('-r', '--revision',
                 dest='revision', action='append', metavar='TREEish',
                 help='Search TREEish, instead of the work tree')

    g = p.add_option_group('Pattern')
    g.add_option('-e',
                 action='callback', callback=self._carry_option,
                 metavar='PATTERN', type='str',
                 help='Pattern to search for')
    g.add_option('-i', '--ignore-case',
                 action='callback', callback=self._carry_option,
                 help='Ignore case differences')
    g.add_option('-a', '--text',
                 action='callback', callback=self._carry_option,
                 help="Process binary files as if they were text")
    g.add_option('-I',
                 action='callback', callback=self._carry_option,
                 help="Don't match the pattern in binary files")
    g.add_option('-w', '--word-regexp',
                 action='callback', callback=self._carry_option,
                 help='Match the pattern only at word boundaries')
    g.add_option('-v', '--invert-match',
                 action='callback', callback=self._carry_option,
                 help='Select non-matching lines')
    g.add_option('-G', '--basic-regexp',
                 action='callback', callback=self._carry_option,
                 help='Use POSIX basic regexp for patterns (default)')
    g.add_option('-E', '--extended-regexp',
                 action='callback', callback=self._carry_option,
                 help='Use POSIX extended regexp for patterns')
    g.add_option('-F', '--fixed-strings',
                 action='callback', callback=self._carry_option,
                 help='Use fixed strings (not regexp) for pattern')

    g = p.add_option_group('Pattern Grouping')
    g.add_option('--all-match',
                 action='callback', callback=self._carry_option,
                 help='Limit match to lines that have all patterns')
    g.add_option('--and', '--or', '--not',
                 action='callback', callback=self._carry_option,
                 help='Boolean operators to combine patterns')
    g.add_option('-(', '-)',
                 action='callback', callback=self._carry_option,
                 help='Boolean operator grouping')

    g = p.add_option_group('Output')
    g.add_option('-n',
                 action='callback', callback=self._carry_option,
                 help='Prefix the line number to matching lines')
    g.add_option('-C',
                 action='callback', callback=self._carry_option,
                 metavar='CONTEXT', type='str',
                 help='Show CONTEXT lines around match')
    g.add_option('-B',
                 action='callback', callback=self._carry_option,
                 metavar='CONTEXT', type='str',
                 help='Show CONTEXT lines before match')
    g.add_option('-A',
                 action='callback', callback=self._carry_option,
                 metavar='CONTEXT', type='str',
                 help='Show CONTEXT lines after match')
    g.add_option('-l', '--name-only', '--files-with-matches',
                 action='callback', callback=self._carry_option,
                 help='Show only file names containing matching lines')
    g.add_option('-L', '--files-without-match',
                 action='callback', callback=self._carry_option,
                 help='Show only file names not containing matching lines')

  def Execute(self, opt, args):
    out = GrepColoring(self.manifest.manifestProject.config)

    cmd_argv = ['grep']
    if out.is_on:
      cmd_argv.append('--color')
    cmd_argv.extend(getattr(opt, 'cmd_argv', []))

    if '-e' not in cmd_argv:
      if not args:
        self.Usage()
      cmd_argv.append('-e')
      cmd_argv.append(args[0])
      args = args[1:]

    projects = self.GetProjects(args)

    full_name = False
    if len(projects) > 1:
      cmd_argv.append('--full-name')
      full_name = True

    have_rev = False
    if opt.revision:
      if '--cached' in cmd_argv:
        print('fatal: cannot combine --cached and --revision', file=sys.stderr)
        sys.exit(1)
      have_rev = True
      cmd_argv.extend(opt.revision)
    cmd_argv.append('--')

    git_failed = False
    bad_rev = False
    have_match = False

    for project in projects:
      try:
        p = GitCommand(project,
                       cmd_argv,
                       bare=False,
                       capture_stdout=True,
                       capture_stderr=True)
      except GitError as e:
        git_failed = True
        out.project('--- project %s ---' % project.relpath)
        out.nl()
        out.fail('%s', str(e))
        out.nl()
        continue

      if p.Wait() != 0:
        # no results
        #
        if p.stderr:
          if have_rev and 'fatal: ambiguous argument' in p.stderr:
            bad_rev = True
          else:
            out.project('--- project %s ---' % project.relpath)
            out.nl()
            out.fail('%s', p.stderr.strip())
            out.nl()
        continue
      have_match = True

      # We cut the last element, to avoid a blank line.
      #
      r = p.stdout.split('\n')
      r = r[0:-1]

      if have_rev and full_name:
        for line in r:
          rev, line = line.split(':', 1)
          out.write("%s", rev)
          out.write(':')
          out.project(project.relpath)
          out.write('/')
          out.write("%s", line)
          out.nl()
      elif full_name:
        for line in r:
          out.project(project.relpath)
          out.write('/')
          out.write("%s", line)
          out.nl()
      else:
        for line in r:
          print(line)

    if git_failed:
      sys.exit(1)
    elif have_match:
      sys.exit(0)
    elif have_rev and bad_rev:
      for r in opt.revision:
        print("error: can't search revision %s" % r, file=sys.stderr)
      sys.exit(1)
    else:
      sys.exit(1)
<commit_msg>grep: add --jobs support<commit_after># Copyright (C) 2009 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import functools
import multiprocessing
import sys

from color import Coloring
from command import DEFAULT_LOCAL_JOBS, PagedCommand, WORKER_BATCH_SIZE
from error import GitError
from git_command import GitCommand

class GrepColoring(Coloring):
  def __init__(self, config):
    Coloring.__init__(self, config, 'grep')
    self.project = self.printer('project', attr='bold')
    self.fail = self.printer('fail', fg='red')

class Grep(PagedCommand):
  common = True
  helpSummary = "Print lines matching a pattern"
  helpUsage = """
%prog {pattern | -e pattern} [<project>...]
"""
  helpDescription = """
Search for the specified patterns in all project files.

# Boolean Options

The following options can appear as often as necessary to express
the pattern to locate:

 -e PATTERN
 --and, --or, --not, -(, -)

Further, the -r/--revision option may be specified multiple times
in order to scan multiple trees.  If the same file matches in more
than one tree, only the first result is reported, prefixed by the
revision name it was found under.

# Examples

Look for a line that has '#define' and either 'MAX_PATH or 'PATH_MAX':

  repo grep -e '#define' --and -\\( -e MAX_PATH -e PATH_MAX \\)

Look for a line that has 'NODE' or 'Unexpected' in files that
contain a line that matches both expressions:

  repo grep --all-match -e NODE -e Unexpected

"""
  PARALLEL_JOBS = DEFAULT_LOCAL_JOBS

  @staticmethod
  def _carry_option(_option, opt_str, value, parser):
    pt = getattr(parser.values, 'cmd_argv', None)
    if pt is None:
      pt = []
      setattr(parser.values, 'cmd_argv', pt)

    if opt_str == '-(':
      pt.append('(')
    elif opt_str == '-)':
      pt.append(')')
    else:
      pt.append(opt_str)

    if value is not None:
      pt.append(value)

  def _Options(self, p):
    super()._Options(p)
    g = p.add_option_group('Sources')
    g.add_option('--cached',
                 action='callback', callback=self._carry_option,
                 help='Search the index, instead of the work tree')
    g.add_option('-r', '--revision',
                 dest='revision', action='append', metavar='TREEish',
                 help='Search TREEish, instead of the work tree')

    g = p.add_option_group('Pattern')
    g.add_option('-e',
                 action='callback', callback=self._carry_option,
                 metavar='PATTERN', type='str',
                 help='Pattern to search for')
    g.add_option('-i', '--ignore-case',
                 action='callback', callback=self._carry_option,
                 help='Ignore case differences')
    g.add_option('-a', '--text',
                 action='callback', callback=self._carry_option,
                 help="Process binary files as if they were text")
    g.add_option('-I',
                 action='callback', callback=self._carry_option,
                 help="Don't match the pattern in binary files")
    g.add_option('-w', '--word-regexp',
                 action='callback', callback=self._carry_option,
                 help='Match the pattern only at word boundaries')
    g.add_option('-v', '--invert-match',
                 action='callback', callback=self._carry_option,
                 help='Select non-matching lines')
    g.add_option('-G', '--basic-regexp',
                 action='callback', callback=self._carry_option,
                 help='Use POSIX basic regexp for patterns (default)')
    g.add_option('-E', '--extended-regexp',
                 action='callback', callback=self._carry_option,
                 help='Use POSIX extended regexp for patterns')
    g.add_option('-F', '--fixed-strings',
                 action='callback', callback=self._carry_option,
                 help='Use fixed strings (not regexp) for pattern')

    g = p.add_option_group('Pattern Grouping')
    g.add_option('--all-match',
                 action='callback', callback=self._carry_option,
                 help='Limit match to lines that have all patterns')
    g.add_option('--and', '--or', '--not',
                 action='callback', callback=self._carry_option,
                 help='Boolean operators to combine patterns')
    g.add_option('-(', '-)',
                 action='callback', callback=self._carry_option,
                 help='Boolean operator grouping')

    g = p.add_option_group('Output')
    g.add_option('-n',
                 action='callback', callback=self._carry_option,
                 help='Prefix the line number to matching lines')
    g.add_option('-C',
                 action='callback', callback=self._carry_option,
                 metavar='CONTEXT', type='str',
                 help='Show CONTEXT lines around match')
    g.add_option('-B',
                 action='callback', callback=self._carry_option,
                 metavar='CONTEXT', type='str',
                 help='Show CONTEXT lines before match')
    g.add_option('-A',
                 action='callback', callback=self._carry_option,
                 metavar='CONTEXT', type='str',
                 help='Show CONTEXT lines after match')
    g.add_option('-l', '--name-only', '--files-with-matches',
                 action='callback', callback=self._carry_option,
                 help='Show only file names containing matching lines')
    g.add_option('-L', '--files-without-match',
                 action='callback', callback=self._carry_option,
                 help='Show only file names not containing matching lines')

  def _ExecuteOne(self, cmd_argv, project):
    """Process one project."""
    try:
      p = GitCommand(project,
                     cmd_argv,
                     bare=False,
                     capture_stdout=True,
                     capture_stderr=True)
    except GitError as e:
      return (project, -1, None, str(e))

    return (project, p.Wait(), p.stdout, p.stderr)

  @staticmethod
  def _ProcessResults(out, full_name, have_rev, results):
    git_failed = False
    bad_rev = False
    have_match = False

    for project, rc, stdout, stderr in results:
      if rc < 0:
        git_failed = True
        out.project('--- project %s ---' % project.relpath)
        out.nl()
        out.fail('%s', stderr)
        out.nl()
        continue

      if rc:
        # no results
        if stderr:
          if have_rev and 'fatal: ambiguous argument' in stderr:
            bad_rev = True
          else:
            out.project('--- project %s ---' % project.relpath)
            out.nl()
            out.fail('%s', stderr.strip())
            out.nl()
        continue
      have_match = True

      # We cut the last element, to avoid a blank line.
      r = stdout.split('\n')
      r = r[0:-1]

      if have_rev and full_name:
        for line in r:
          rev, line = line.split(':', 1)
          out.write("%s", rev)
          out.write(':')
          out.project(project.relpath)
          out.write('/')
          out.write("%s", line)
          out.nl()
      elif full_name:
        for line in r:
          out.project(project.relpath)
          out.write('/')
          out.write("%s", line)
          out.nl()
      else:
        for line in r:
          print(line)

    return (git_failed, bad_rev, have_match)

  def Execute(self, opt, args):
    out = GrepColoring(self.manifest.manifestProject.config)

    cmd_argv = ['grep']
    if out.is_on:
      cmd_argv.append('--color')
    cmd_argv.extend(getattr(opt, 'cmd_argv', []))

    if '-e' not in cmd_argv:
      if not args:
        self.Usage()
      cmd_argv.append('-e')
      cmd_argv.append(args[0])
      args = args[1:]

    projects = self.GetProjects(args)

    full_name = False
    if len(projects) > 1:
      cmd_argv.append('--full-name')
      full_name = True

    have_rev = False
    if opt.revision:
      if '--cached' in cmd_argv:
        print('fatal: cannot combine --cached and --revision', file=sys.stderr)
        sys.exit(1)
      have_rev = True
      cmd_argv.extend(opt.revision)
    cmd_argv.append('--')

    process_results = functools.partial(
        self._ProcessResults, out, full_name, have_rev)
    # NB: Multiprocessing is heavy, so don't spin it up for one job.
    if len(projects) == 1 or opt.jobs == 1:
      git_failed, bad_rev, have_match = process_results(
          self._ExecuteOne(cmd_argv, x) for x in projects)
    else:
      with multiprocessing.Pool(opt.jobs) as pool:
        results = pool.imap(
            functools.partial(self._ExecuteOne, cmd_argv), projects,
            chunksize=WORKER_BATCH_SIZE)
        git_failed, bad_rev, have_match = process_results(results)

    if git_failed:
      sys.exit(1)
    elif have_match:
      sys.exit(0)
    elif have_rev and bad_rev:
      for r in opt.revision:
        print("error: can't search revision %s" % r, file=sys.stderr)
      sys.exit(1)
    else:
      sys.exit(1)
<|endoftext|>