<commit_before>import json
from msc_apps import *

def get_balancedata(address):
    addr = re.sub(r'\W+', '', address) #check alphanumeric
    ROWS=dbSelect("""select
                       f1.propertyid, sp.propertytype, f1.balanceavailable, f1.pendingpos, f1.pendingneg
                     from
                       (select
                          COALESCE(s1.propertyid,s2.propertyid) as propertyid, COALESCE(s1.balanceavailable,0) as balanceavailable,
                          COALESCE(s2.pendingpos,0) as pendingpos,COALESCE(s2.pendingneg,0) as pendingneg
                        from
                          (select propertyid,balanceavailable
                           from addressbalances
                           where address=%s) s1
                        full join
                          (SELECT atx.propertyid,
                             sum(CASE WHEN atx.balanceavailablecreditdebit > 0 THEN atx.balanceavailablecreditdebit ELSE 0 END) AS pendingpos,
                             sum(CASE WHEN atx.balanceavailablecreditdebit < 0 THEN atx.balanceavailablecreditdebit ELSE 0 END) AS pendingneg
                           from
                             addressesintxs atx, transactions tx
                           where
                             atx.txdbserialnum=tx.txdbserialnum
                             and tx.txstate='pending'
                             and tx.txdbserialnum<-1
                             and atx.address=%s
                           group by
                             atx.propertyid) s2
                        on s1.propertyid=s2.propertyid) f1
                     inner join smartproperties sp
                     on f1.propertyid=sp.propertyid and (sp.protocol='Mastercoin' or sp.protocol='Bitcoin')
                     order by f1.propertyid""",(addr,addr))

    balance_data = { 'balance': [] }
    #out, err = run_command(TIMEOUT+ 'sx balance -j ' + addr )
    #out, err = run_command(TIMEOUT+"curl -s http://btc.blockr.io/api/v1/address/balance/"+addr)
    ret = bc_getbalance(addr)
    out = ret['bal']
    err = ret['error']
    for balrow in ROWS:
        cID = str(int(balrow[0])) #currency id
        sym_t = ('BTC' if cID == '0' else ('MSC' if cID == '1' else ('TMSC' if cID == '2' else 'SP' + cID) ) ) #symbol template
        #1 = new indivisible property, 2=new divisible property (per spec)
        divi = True if int(balrow[1]) == 2 else False
        res = { 'symbol' : sym_t, 'divisible' : divi, 'id' : cID }
        res['pendingpos'] = ('%.8f' % float(balrow[3])).rstrip('0').rstrip('.')
        res['pendingneg'] = ('%.8f' % float(balrow[4])).rstrip('0').rstrip('.')
        if cID == '0':
          #get btc balance from sx
          if err != None or out == '':
            btc_balance[ 'value' ] = int(-555)
          else:
            try:
              if balrow[4] < 0:
                #res['value'] = int( json.loads( out )[0][ 'paid' ]) + int(balrow[4])
                #res['value'] = int( json.loads( out )['data']['balance']*1e8) + int(balrow[4])
                res['value'] = int( out ) + int(balrow[4])
              else:
                #res['value'] = int( json.loads( out )[0][ 'paid' ])
                #res['value'] = int( json.loads( out )['data']['balance']*1e8)
                res['value'] = int( out )
            except ValueError:
              btc_balance[ 'value' ] = int(-555)
        else:
          #get regular balance from db
          if balrow[4] < 0:
            #update the 'available' balance immediately when the sender sent something. prevent double spend
            res['value'] = ('%.8f' % float( (balrow[2]+balrow[4]) )).rstrip('0').rstrip('.')
          else:
            res['value'] = ('%.8f' % float(balrow[2])).rstrip('0').rstrip('.')

        #res['reserved_balance'] = ('%.8f' % float(balrow[5])).rstrip('0').rstrip('.')
        balance_data['balance'].append(res)

    #check if we got BTC data from DB, if not trigger manually add
    addbtc=True
    for x in balance_data['balance']:
      if "BTC" in x['symbol']:
        addbtc=False

    if addbtc:
      btc_balance = { 'symbol': 'BTC', 'divisible': True, 'id' : 0 }
      if err != None or out == '':
        btc_balance[ 'value' ] = int(-555)
      else:
        try:
          #btc_balance[ 'value' ] = int( json.loads( out )[0][ 'paid' ])
          #btc_balance[ 'value' ] = int( json.loads( out )['data']['balance']*1e8 )
          btc_balance[ 'value' ] = int( out )
        except ValueError:
          btc_balance[ 'value' ] = int(-555)
      btc_balance['pendingpos'] = int(0)
      btc_balance['pendingneg'] = int(0)
      balance_data['balance'].append(btc_balance)

    return balance_data

def get_bulkbalancedata(addresses):
    list=""
    for a in addresses:
      if list == "":
        list = a
      else:
        list += ","+a

    baldata=bc_getbulkbalance(list)
    btclist = baldata['bal']
    if btclist == None:
      #do something snazzy

    retval = {}

    for address in addresses:
      addr = re.sub(r'\W+', '', address) #check alphanumeric
      ROWS=dbSelect("""select
                       f1.propertyid, sp.propertytype, f1.balanceavailable, f1.pendingpos, f1.pendingneg
                     from
                       (select
                          COALESCE(s1.propertyid,s2.propertyid) as propertyid, COALESCE(s1.balanceavailable,0) as balanceavailable,
                          COALESCE(s2.pendingpos,0) as pendingpos,COALESCE(s2.pendingneg,0) as pendingneg
                        from
                          (select propertyid,balanceavailable
                           from addressbalances
                           where address=%s) s1
                        full join
                          (SELECT atx.propertyid,
                             sum(CASE WHEN atx.balanceavailablecreditdebit > 0 THEN atx.balanceavailablecreditdebit ELSE 0 END) AS pendingpos,
                             sum(CASE WHEN atx.balanceavailablecreditdebit < 0 THEN atx.balanceavailablecreditdebit ELSE 0 END) AS pendingneg
                           from
                             addressesintxs atx, transactions tx
                           where
                             atx.txdbserialnum=tx.txdbserialnum
                             and tx.txstate='pending'
                             and tx.txdbserialnum<-1
                             and atx.address=%s
                           group by
                             atx.propertyid) s2
                        on s1.propertyid=s2.propertyid) f1
                     inner join smartproperties sp
                     on f1.propertyid=sp.propertyid and (sp.protocol='Mastercoin' or sp.protocol='Bitcoin')
                     order by f1.propertyid""",(addr,addr))

      balance_data = { 'balance': [] }
      #out, err = run_command(TIMEOUT+ 'sx balance -j ' + addr )
      #out, err = run_command(TIMEOUT+"curl -s http://btc.blockr.io/api/v1/address/balance/"+addr)
      if address in btclist:
        out = btclist[address]
        err = None
      else:
        out = ''
        err = "Missing"

      for balrow in ROWS:
        cID = str(int(balrow[0])) #currency id
        sym_t = ('BTC' if cID == '0' else ('MSC' if cID == '1' else ('TMSC' if cID == '2' else 'SP' + cID) ) ) #symbol template
        #1 = new indivisible property, 2=new divisible property (per spec)
        divi = True if int(balrow[1]) == 2 else False
        res = { 'symbol' : sym_t, 'divisible' : divi, 'id' : cID }
        res['pendingpos'] = ('%.8f' % float(balrow[3])).rstrip('0').rstrip('.')
        res['pendingneg'] = ('%.8f' % float(balrow[4])).rstrip('0').rstrip('.')
        if cID == '0':
          #get btc balance from sx
          if err != None or out == '':
            btc_balance[ 'value' ] = int(-555)
          else:
            try:
              if balrow[4] < 0:
                #res['value'] = int( json.loads( out )[0][ 'paid' ]) + int(balrow[4])
                res['value'] = int( out ) + int(balrow[4])
              else:
                #res['value'] = int( json.loads( out )[0][ 'paid' ])
                res['value'] = int( out )
            except ValueError:
              btc_balance[ 'value' ] = int(-555)
        else:
          #get regular balance from db
          if balrow[4] < 0:
            #update the 'available' balance immediately when the sender sent something. prevent double spend
            res['value'] = ('%.8f' % float( (balrow[2]+balrow[4]) )).rstrip('0').rstrip('.')
          else:
            res['value'] = ('%.8f' % float(balrow[2])).rstrip('0').rstrip('.')

        #res['reserved_balance'] = ('%.8f' % float(balrow[5])).rstrip('0').rstrip('.')
        balance_data['balance'].append(res)

      #check if we got BTC data from DB, if not trigger manually add
      addbtc=True
      for x in balance_data['balance']:
        if "BTC" in x['symbol']:
          addbtc=False

      if addbtc:
        btc_balance = { 'symbol': 'BTC', 'divisible': True, 'id' : 0 }
        if err != None or out == '':
          btc_balance[ 'value' ] = int(-555)
        else:
          try:
            #btc_balance[ 'value' ] = int( json.loads( out )[0][ 'paid' ])
            btc_balance[ 'value' ] = int(  out )
          except ValueError:
            btc_balance[ 'value' ] = int(-555)
        btc_balance['pendingpos'] = int(0)
        btc_balance['pendingneg'] = int(0)
        balance_data['balance'].append(btc_balance)

      retval[address]=balance_data
    return retval
<commit_msg>Add import for new calls<commit_after>import json
from msc_apps import *
from blockchain_utils import *

def get_balancedata(address):
    addr = re.sub(r'\W+', '', address) #check alphanumeric
    ROWS=dbSelect("""select
                       f1.propertyid, sp.propertytype, f1.balanceavailable, f1.pendingpos, f1.pendingneg
                     from
                       (select
                          COALESCE(s1.propertyid,s2.propertyid) as propertyid, COALESCE(s1.balanceavailable,0) as balanceavailable,
                          COALESCE(s2.pendingpos,0) as pendingpos,COALESCE(s2.pendingneg,0) as pendingneg
                        from
                          (select propertyid,balanceavailable
                           from addressbalances
                           where address=%s) s1
                        full join
                          (SELECT atx.propertyid,
                             sum(CASE WHEN atx.balanceavailablecreditdebit > 0 THEN atx.balanceavailablecreditdebit ELSE 0 END) AS pendingpos,
                             sum(CASE WHEN atx.balanceavailablecreditdebit < 0 THEN atx.balanceavailablecreditdebit ELSE 0 END) AS pendingneg
                           from
                             addressesintxs atx, transactions tx
                           where
                             atx.txdbserialnum=tx.txdbserialnum
                             and tx.txstate='pending'
                             and tx.txdbserialnum<-1
                             and atx.address=%s
                           group by
                             atx.propertyid) s2
                        on s1.propertyid=s2.propertyid) f1
                     inner join smartproperties sp
                     on f1.propertyid=sp.propertyid and (sp.protocol='Mastercoin' or sp.protocol='Bitcoin')
                     order by f1.propertyid""",(addr,addr))

    balance_data = { 'balance': [] }
    #out, err = run_command(TIMEOUT+ 'sx balance -j ' + addr )
    #out, err = run_command(TIMEOUT+"curl -s http://btc.blockr.io/api/v1/address/balance/"+addr)
    ret = bc_getbalance(addr)
    out = ret['bal']
    err = ret['error']
    for balrow in ROWS:
        cID = str(int(balrow[0])) #currency id
        sym_t = ('BTC' if cID == '0' else ('MSC' if cID == '1' else ('TMSC' if cID == '2' else 'SP' + cID) ) ) #symbol template
        #1 = new indivisible property, 2=new divisible property (per spec)
        divi = True if int(balrow[1]) == 2 else False
        res = { 'symbol' : sym_t, 'divisible' : divi, 'id' : cID }
        res['pendingpos'] = ('%.8f' % float(balrow[3])).rstrip('0').rstrip('.')
        res['pendingneg'] = ('%.8f' % float(balrow[4])).rstrip('0').rstrip('.')
        if cID == '0':
          #get btc balance from sx
          if err != None or out == '':
            btc_balance[ 'value' ] = int(-555)
          else:
            try:
              if balrow[4] < 0:
                #res['value'] = int( json.loads( out )[0][ 'paid' ]) + int(balrow[4])
                #res['value'] = int( json.loads( out )['data']['balance']*1e8) + int(balrow[4])
                res['value'] = int( out ) + int(balrow[4])
              else:
                #res['value'] = int( json.loads( out )[0][ 'paid' ])
                #res['value'] = int( json.loads( out )['data']['balance']*1e8)
                res['value'] = int( out )
            except ValueError:
              btc_balance[ 'value' ] = int(-555)
        else:
          #get regular balance from db
          if balrow[4] < 0:
            #update the 'available' balance immediately when the sender sent something. prevent double spend
            res['value'] = ('%.8f' % float( (balrow[2]+balrow[4]) )).rstrip('0').rstrip('.')
          else:
            res['value'] = ('%.8f' % float(balrow[2])).rstrip('0').rstrip('.')

        #res['reserved_balance'] = ('%.8f' % float(balrow[5])).rstrip('0').rstrip('.')
        balance_data['balance'].append(res)

    #check if we got BTC data from DB, if not trigger manually add
    addbtc=True
    for x in balance_data['balance']:
      if "BTC" in x['symbol']:
        addbtc=False

    if addbtc:
      btc_balance = { 'symbol': 'BTC', 'divisible': True, 'id' : 0 }
      if err != None or out == '':
        btc_balance[ 'value' ] = int(-555)
      else:
        try:
          #btc_balance[ 'value' ] = int( json.loads( out )[0][ 'paid' ])
          #btc_balance[ 'value' ] = int( json.loads( out )['data']['balance']*1e8 )
          btc_balance[ 'value' ] = int( out )
        except ValueError:
          btc_balance[ 'value' ] = int(-555)
      btc_balance['pendingpos'] = int(0)
      btc_balance['pendingneg'] = int(0)
      balance_data['balance'].append(btc_balance)

    return balance_data

def get_bulkbalancedata(addresses):
    list=""
    for a in addresses:
      if list == "":
        list = a
      else:
        list += ","+a

    baldata=bc_getbulkbalance(list)
    btclist = baldata['bal']
    if btclist == None:
      #do something snazzy

    retval = {}

    for address in addresses:
      addr = re.sub(r'\W+', '', address) #check alphanumeric
      ROWS=dbSelect("""select
                       f1.propertyid, sp.propertytype, f1.balanceavailable, f1.pendingpos, f1.pendingneg
                     from
                       (select
                          COALESCE(s1.propertyid,s2.propertyid) as propertyid, COALESCE(s1.balanceavailable,0) as balanceavailable,
                          COALESCE(s2.pendingpos,0) as pendingpos,COALESCE(s2.pendingneg,0) as pendingneg
                        from
                          (select propertyid,balanceavailable
                           from addressbalances
                           where address=%s) s1
                        full join
                          (SELECT atx.propertyid,
                             sum(CASE WHEN atx.balanceavailablecreditdebit > 0 THEN atx.balanceavailablecreditdebit ELSE 0 END) AS pendingpos,
                             sum(CASE WHEN atx.balanceavailablecreditdebit < 0 THEN atx.balanceavailablecreditdebit ELSE 0 END) AS pendingneg
                           from
                             addressesintxs atx, transactions tx
                           where
                             atx.txdbserialnum=tx.txdbserialnum
                             and tx.txstate='pending'
                             and tx.txdbserialnum<-1
                             and atx.address=%s
                           group by
                             atx.propertyid) s2
                        on s1.propertyid=s2.propertyid) f1
                     inner join smartproperties sp
                     on f1.propertyid=sp.propertyid and (sp.protocol='Mastercoin' or sp.protocol='Bitcoin')
                     order by f1.propertyid""",(addr,addr))

      balance_data = { 'balance': [] }
      #out, err = run_command(TIMEOUT+ 'sx balance -j ' + addr )
      #out, err = run_command(TIMEOUT+"curl -s http://btc.blockr.io/api/v1/address/balance/"+addr)
      if address in btclist:
        out = btclist[address]
        err = None
      else:
        out = ''
        err = "Missing"

      for balrow in ROWS:
        cID = str(int(balrow[0])) #currency id
        sym_t = ('BTC' if cID == '0' else ('MSC' if cID == '1' else ('TMSC' if cID == '2' else 'SP' + cID) ) ) #symbol template
        #1 = new indivisible property, 2=new divisible property (per spec)
        divi = True if int(balrow[1]) == 2 else False
        res = { 'symbol' : sym_t, 'divisible' : divi, 'id' : cID }
        res['pendingpos'] = ('%.8f' % float(balrow[3])).rstrip('0').rstrip('.')
        res['pendingneg'] = ('%.8f' % float(balrow[4])).rstrip('0').rstrip('.')
        if cID == '0':
          #get btc balance from sx
          if err != None or out == '':
            btc_balance[ 'value' ] = int(-555)
          else:
            try:
              if balrow[4] < 0:
                #res['value'] = int( json.loads( out )[0][ 'paid' ]) + int(balrow[4])
                res['value'] = int( out ) + int(balrow[4])
              else:
                #res['value'] = int( json.loads( out )[0][ 'paid' ])
                res['value'] = int( out )
            except ValueError:
              btc_balance[ 'value' ] = int(-555)
        else:
          #get regular balance from db
          if balrow[4] < 0:
            #update the 'available' balance immediately when the sender sent something. prevent double spend
            res['value'] = ('%.8f' % float( (balrow[2]+balrow[4]) )).rstrip('0').rstrip('.')
          else:
            res['value'] = ('%.8f' % float(balrow[2])).rstrip('0').rstrip('.')

        #res['reserved_balance'] = ('%.8f' % float(balrow[5])).rstrip('0').rstrip('.')
        balance_data['balance'].append(res)

      #check if we got BTC data from DB, if not trigger manually add
      addbtc=True
      for x in balance_data['balance']:
        if "BTC" in x['symbol']:
          addbtc=False

      if addbtc:
        btc_balance = { 'symbol': 'BTC', 'divisible': True, 'id' : 0 }
        if err != None or out == '':
          btc_balance[ 'value' ] = int(-555)
        else:
          try:
            #btc_balance[ 'value' ] = int( json.loads( out )[0][ 'paid' ])
            btc_balance[ 'value' ] = int(  out )
          except ValueError:
            btc_balance[ 'value' ] = int(-555)
        btc_balance['pendingpos'] = int(0)
        btc_balance['pendingneg'] = int(0)
        balance_data['balance'].append(btc_balance)

      retval[address]=balance_data
    return retval
<|endoftext|>


<commit_before>from django.conf import settings
from django.core.urlresolvers import reverse
from django.db import models
from django.utils.translation import ugettext_lazy as _

from mymoney.core.utils.currencies import get_currencies

class BankAccountManager(models.Manager):

    def get_user_bankaccounts(self, user):

        if not hasattr(user, '_cache_bankaccounts'):
            user._cache_bankaccounts = user.bankaccounts.order_by('label')

        return user._cache_bankaccounts

    def delete_orphans(self):
        """
        Delete bank account which have no more owners.
        """
        self.filter(owners__isnull=True).delete()

class BankAccount(models.Model):

    label = models.CharField(max_length=255, verbose_name=_('Label'))
    balance = models.DecimalField(
        max_digits=10,
        decimal_places=2,
        default=0,
        verbose_name=_('Balance'),
    )
    balance_initial = models.DecimalField(
        max_digits=10,
        decimal_places=2,
        default=0,
        verbose_name=_('Initial balance'),
        help_text=_('Initial balance will automatically update the balance.'),
    )
    currency = models.CharField(
        max_length=3,
        choices=get_currencies(),
        verbose_name=_('Currency'),
    )
    owners = models.ManyToManyField(
        settings.AUTH_USER_MODEL,
        limit_choices_to={'is_staff': False, 'is_superuser': False},
        verbose_name=_('Owners'),
        related_name='bankaccounts',
        db_table='bankaccounts_owners',
    )

    objects = BankAccountManager()

    class Meta:
        db_table = 'bankaccounts'
        permissions = (("administer_owners", "Administer owners"),)

    def __str__(self):
        return self.label

    def save(self, *args, **kwargs):

        # Init balance. Merge both just in case.
        if self.pk is None:
            self.balance += self.balance_initial
        # Otherwise update it with the new delta.
        else:
            original = BankAccount.objects.get(pk=self.pk)
            self.balance += self.balance_initial - original.balance_initial

        super(BankAccount, self).save(*args, **kwargs)

    def get_absolute_url(self):
        return reverse('bankaccounts:list')
<commit_msg>change bank account create and edit redirect after post<commit_after>from django.conf import settings
from django.core.urlresolvers import reverse
from django.db import models
from django.utils.translation import ugettext_lazy as _

from mymoney.core.utils.currencies import get_currencies

class BankAccountManager(models.Manager):

    def get_user_bankaccounts(self, user):

        if not hasattr(user, '_cache_bankaccounts'):
            user._cache_bankaccounts = user.bankaccounts.order_by('label')

        return user._cache_bankaccounts

    def delete_orphans(self):
        """
        Delete bank account which have no more owners.
        """
        self.filter(owners__isnull=True).delete()

class BankAccount(models.Model):

    label = models.CharField(max_length=255, verbose_name=_('Label'))
    balance = models.DecimalField(
        max_digits=10,
        decimal_places=2,
        default=0,
        verbose_name=_('Balance'),
    )
    balance_initial = models.DecimalField(
        max_digits=10,
        decimal_places=2,
        default=0,
        verbose_name=_('Initial balance'),
        help_text=_('Initial balance will automatically update the balance.'),
    )
    currency = models.CharField(
        max_length=3,
        choices=get_currencies(),
        verbose_name=_('Currency'),
    )
    owners = models.ManyToManyField(
        settings.AUTH_USER_MODEL,
        limit_choices_to={'is_staff': False, 'is_superuser': False},
        verbose_name=_('Owners'),
        related_name='bankaccounts',
        db_table='bankaccounts_owners',
    )

    objects = BankAccountManager()

    class Meta:
        db_table = 'bankaccounts'
        permissions = (("administer_owners", "Administer owners"),)

    def __str__(self):
        return self.label

    def save(self, *args, **kwargs):

        # Init balance. Merge both just in case.
        if self.pk is None:
            self.balance += self.balance_initial
        # Otherwise update it with the new delta.
        else:
            original = BankAccount.objects.get(pk=self.pk)
            self.balance += self.balance_initial - original.balance_initial

        super(BankAccount, self).save(*args, **kwargs)

    def get_absolute_url(self):
        return reverse('banktransactions:list', kwargs={
            'bankaccount_pk': self.pk,
        })
<|endoftext|>


<commit_before>import urlparse

import requests
import logging

from website import settings

logger = logging.getLogger(__name__)

def get_varnish_servers():
    #  TODO: this should get the varnish servers from HAProxy or a setting
    return settings.VARNISH_SERVERS

    #  fields_changed will eventually let us ban even more accurately
def get_bannable_urls(instance, fields_changed):
    bannable_urls = []
    parsed_absolute_url = {}

    # add instance url
    for host in get_varnish_servers():
        varnish_parsed_url = urlparse.urlparse(host)
        parsed_absolute_url = urlparse.urlparse(instance.absolute_api_v2_url)
        url_string = '{scheme}://{netloc}{path}.*'.format(scheme=varnish_parsed_url.scheme,
                                                          netloc=varnish_parsed_url.netloc,
                                                          path=parsed_absolute_url.path)
        bannable_urls.append(url_string)

    return bannable_urls, parsed_absolute_url.hostname

def ban_url(instance, fields_changed):
    timeout = 0.3  # 300ms timeout for bans
    if settings.ENABLE_VARNISH:
        bannable_urls, hostname = get_bannable_urls(instance, fields_changed)

        for url_to_ban in bannable_urls:
            try:
                response = requests.request('BAN', url_to_ban, timeout=timeout, headers=dict(
                    Host=hostname
                ))
            except Exception as ex:
                logger.error('Banning {} failed: {}'.format(
                    url_to_ban,
                    ex.message
                ))
            else:
                if not response.ok:
                    logger.error('Banning {} failed: {}'.format(
                        url_to_ban,
                        response.text
                    ))
                else:
                    logger.info('Banning {} succeeded'.format(
                        url_to_ban
                    ))
<commit_msg>Adding target and root_target cache busting for comments.<commit_after>import urlparse

import requests
import logging
from website.project.model import Comment

from website import settings

logger = logging.getLogger(__name__)

def get_varnish_servers():
    #  TODO: this should get the varnish servers from HAProxy or a setting
    return settings.VARNISH_SERVERS

    #  fields_changed will eventually let us ban even more accurately
def get_bannable_urls(instance, fields_changed):
    bannable_urls = []
    parsed_absolute_url = {}

    for host in get_varnish_servers():
        # add instance url
        varnish_parsed_url = urlparse.urlparse(host)
        parsed_absolute_url = urlparse.urlparse(instance.absolute_api_v2_url)
        url_string = '{scheme}://{netloc}{path}.*'.format(scheme=varnish_parsed_url.scheme,
                                                          netloc=varnish_parsed_url.netloc,
                                                          path=parsed_absolute_url.path)
        bannable_urls.append(url_string)

        if isinstance(instance, Comment):
            parsed_target_url = urlparse.urlparse(instance.target.referent.absolute_api_v2_url)
            url_string = '{scheme}://{netloc}{path}.*'.format(scheme=varnish_parsed_url.scheme,
                                                              netloc=varnish_parsed_url.netloc,
                                                              path=parsed_target_url.path)
            bannable_urls.append(url_string)
            parsed_root_target_url = urlparse.urlparse(instance.root_target.referent.absolute_api_v2_url)
            url_string = '{scheme}://{netloc}{path}.*'.format(scheme=varnish_parsed_url.scheme,
                                                              netloc=varnish_parsed_url.netloc,
                                                              path=parsed_root_target_url.path)
            bannable_urls.append(url_string)

    return bannable_urls, parsed_absolute_url.hostname

def ban_url(instance, fields_changed):
    # TODO: Refactor; Pull url generation into postcommit_task handling so we only ban urls once per request
    timeout = 0.3  # 300ms timeout for bans
    if settings.ENABLE_VARNISH:
        bannable_urls, hostname = get_bannable_urls(instance, fields_changed)

        for url_to_ban in set(bannable_urls):
            try:
                response = requests.request('BAN', url_to_ban, timeout=timeout, headers=dict(
                    Host=hostname
                ))
            except Exception as ex:
                logger.error('Banning {} failed: {}'.format(
                    url_to_ban,
                    ex.message
                ))
            else:
                if not response.ok:
                    logger.error('Banning {} failed: {}'.format(
                        url_to_ban,
                        response.text
                    ))
                else:
                    logger.info('Banning {} succeeded'.format(
                        url_to_ban
                    ))
<|endoftext|>


<commit_before>import csv
import os
from myuw_mobile.dao.enrollment import get_current_quarter_enrollment
from myuw_mobile.dao.gws import is_grad_student

DEGREE_TYPE_COLUMN_MAP = {"major": 2,
                          "minor": 3,
                          "gradmajor": 4}
CALENDAR_ID_COL = 5
CALENDAR_URL_COL = 6

def get_calendars_for_current_user(request):
    return _get_calendars(_get_enrollments(request))

def _get_calendars(enrollments):
    calendars = {}

    minor_cals = get_calendars_for_minors(enrollments['minors'])
    calendars = dict(calendars.items() + minor_cals.items())
    if enrollments['is_grad']:
        grad_cals = get_calendars_for_gradmajors(enrollments['majors'])
        calendars = dict(calendars.items() + grad_cals.items())
    else:
        major_cals = get_calendars_for_majors(enrollments['majors'])
        calendars = dict(calendars.items() + major_cals.items())
    return calendars

def _get_enrollments(request):
    majors = []
    minors = []

    enrollment = get_current_quarter_enrollment(request)
    if enrollment is not None:
        if len(enrollment.majors) > 0:
            for major in enrollment.majors:
                majors.append(major.degree_abbr)

        if len(enrollment.minors) > 0:
            for minor in enrollment.minors:
                minors.append(minor.abbr)

    return {'is_grad': is_grad_student(),
            'majors': majors,
            'minors': minors}

def get_calendars_for_majors(majors):
    return _get_calendars_by_name_and_type(majors, 'major')

def get_calendars_for_minors(minors):
    return _get_calendars_by_name_and_type(minors, 'minor')

def get_calendars_for_gradmajors(gradmajors):
    return _get_calendars_by_name_and_type(gradmajors, 'gradmajor')

def _get_calendars_by_name_and_type(major_name, major_type):
    calendars = {}
    degree_column = DEGREE_TYPE_COLUMN_MAP[major_type]

    path = os.path.join(
        os.path.dirname(__file__),
        '..', 'data', 'calendar_major_mapping.csv')
    with open(path, 'rbU') as csvfile:
        reader = csv.reader(csvfile, delimiter=',', quotechar='"')
        for row in reader:
            if row[degree_column] in major_name and \
                    len(row[CALENDAR_ID_COL]) > 0:
                base_url = None
                if len(row[CALENDAR_URL_COL]) > 0:
                    base_url = row[CALENDAR_URL_COL]
                calendars[row[CALENDAR_ID_COL]] = base_url
    return calendars
<commit_msg>changing major name field to match spreadsheet<commit_after>import csv
import os
from myuw_mobile.dao.enrollment import get_current_quarter_enrollment
from myuw_mobile.dao.gws import is_grad_student

DEGREE_TYPE_COLUMN_MAP = {"major": 2,
                          "minor": 3,
                          "gradmajor": 4}
CALENDAR_ID_COL = 5
CALENDAR_URL_COL = 6

def get_calendars_for_current_user(request):
    return _get_calendars(_get_enrollments(request))

def _get_calendars(enrollments):
    calendars = {}

    minor_cals = get_calendars_for_minors(enrollments['minors'])
    calendars = dict(calendars.items() + minor_cals.items())
    if enrollments['is_grad']:
        grad_cals = get_calendars_for_gradmajors(enrollments['majors'])
        calendars = dict(calendars.items() + grad_cals.items())
    else:
        major_cals = get_calendars_for_majors(enrollments['majors'])
        calendars = dict(calendars.items() + major_cals.items())
    return calendars

def _get_enrollments(request):
    majors = []
    minors = []

    enrollment = get_current_quarter_enrollment(request)
    if enrollment is not None:
        if len(enrollment.majors) > 0:
            for major in enrollment.majors:
                majors.append(major.degree_name)

        if len(enrollment.minors) > 0:
            for minor in enrollment.minors:
                minors.append(minor.short_name)

    return {'is_grad': is_grad_student(),
            'majors': majors,
            'minors': minors}

def get_calendars_for_majors(majors):
    return _get_calendars_by_name_and_type(majors, 'major')

def get_calendars_for_minors(minors):
    return _get_calendars_by_name_and_type(minors, 'minor')

def get_calendars_for_gradmajors(gradmajors):
    return _get_calendars_by_name_and_type(gradmajors, 'gradmajor')

def _get_calendars_by_name_and_type(major_name, major_type):
    calendars = {}
    degree_column = DEGREE_TYPE_COLUMN_MAP[major_type]

    path = os.path.join(
        os.path.dirname(__file__),
        '..', 'data', 'calendar_major_mapping.csv')
    with open(path, 'rbU') as csvfile:
        reader = csv.reader(csvfile, delimiter=',', quotechar='"')
        for row in reader:
            if row[degree_column] in major_name and \
                    len(row[CALENDAR_ID_COL]) > 0:
                base_url = None
                if len(row[CALENDAR_URL_COL]) > 0:
                    base_url = row[CALENDAR_URL_COL]
                calendars[row[CALENDAR_ID_COL]] = base_url
    return calendars
<|endoftext|>


<commit_before>
__all__ = ['oscillator_strength', 'calculateDipoleCenter']

# ==========> Standard libraries and third-party <===============
from functools import partial
import numpy as np

# ==================> Internal modules <====================
from .overlapIntegral import calcMtxOverlapP
from .multipoleIntegrals import calcMtxMultipoleP
from nac.common import triang2mtx
# ==================================<>=========================================
# x,y,z exponents value for the dipole
exponents = [{'e': 1, 'f': 0, 'g': 0}, {'e': 0, 'f': 1, 'g': 0},
             {'e': 0, 'f': 0, 'g': 1}]

def transform2Spherical(mtx, trans_mtx):
    """
    Transform a matrix containing integrals in cartesian coordinates to a matrix
    in spherical coordinates.
    """
    trr = np.transpose(trans_mtx)

    return np.dot(trans_mtx, np.dot(mtx, trr))

def computeIntegralSum(arrT, arr, mtx):
    """
    Calculate the operation sum(arr^t mtx arr)
    """
    return np.sum(np.dot(arrT, np.dot(mtx, arr)))

def calculateDipoleCenter(atoms, cgfsN, css, overlap, trans_mtx):
    """
    Calculate the point where the dipole is centered.
    :param atoms: Atomic label and cartesian coordinates
    type atoms: List of namedTuples
    :param cgfsN: Contracted gauss functions normalized, represented as
    a list of tuples of coefficients and Exponents.
    type cgfsN: [(Coeff, Expo)]

    To calculate the origin of the dipole we use the following property,

    ..math::
    \braket{\Psi_i \mid \hat{x_0} \mid \Psi_i} =
                       - \braket{\Psi_i \mid \hat{x} \mid \Psi_i}
    """
    rc = (0, 0, 0)

    dimSpher, dimCart = trans_mtx.shape

    mtx_triang_cart = [calcMtxMultipoleP(atoms, cgfsN, rc, **kw)
                       for kw in exponents]
    mtx_integrals_cart = [triang2mtx(xs, dimCart)
                          for xs in mtx_triang_cart]
    mtx_integrals_spher = [transform2Spherical(x, trans_mtx) for x
                           in mtx_integrals_cart]

    cssT = np.transpose(css)
    xs_sum = list(map(partial(computeIntegralSum, cssT, css),
                      mtx_integrals_spher))

    return tuple(map(lambda x: - x / overlap, xs_sum))

def  oscillator_strength(atoms, cgfsN, css_i, css_j, energy, trans_mtx):
    """
    :param atoms: Atomic label and cartesian coordinates
    type atoms: List of namedTuples
    :param cgfsN: Contracted gauss functions normalized, represented as
    a list of tuples of coefficients and Exponents.
    type cgfsN: [(Coeff, Expo)]
    :param css_i: MO coefficients of initial state
    :type coeffs: Numpy Matrix.
    :param css_j: MO coefficients of final state
    :type coeffs: Numpy Matrix.
    :param energy: MO energy.
    :type energy: Double
    :param trans_mtx: Transformation matrix to translate from Cartesian
    to Sphericals.
    :type trans_mtx: Numpy Matrix
    :returns: Oscillator strength (float)
    """
    dimSpher, dimCart = trans_mtx.shape
    # Overlap matrix calculated as a flatten triangular matrix
    overlap_triang = calcMtxOverlapP(atoms, cgfsN)
    # Expand the flatten triangular array to a matrix
    overlap_cart = triang2mtx(overlap_triang, dimCart)
    # transform from Cartesian coordinates to Spherical
    overlap = transform2Spherical(overlap_cart, trans_mtx)
    css_i_T = np.transpose(css_i)
    overlap_sum = computeIntegralSum(css_i_T, css_i, overlap)
    rc = calculateDipoleCenter(atoms, cgfsN, css_i, overlap_sum, trans_mtx)

    print("Dipole center is: ", rc)
    mtx_integrals_triang = tuple(calcMtxMultipoleP(atoms, cgfsN, rc, **kw)
                            for kw in exponents)
    mtx_integrals_cart = tuple(triang2mtx(xs, dimCart)
                          for xs in mtx_integrals_triang)
    mtx_integrals_spher = tuple(transform2Spherical(x, trans_mtx) for x
                           in mtx_integrals_cart)
    sum_integrals = sum(x ** 2 for x in
                        map(partial(computeIntegralSum, css_i_T, css_j),
                            mtx_integrals_spher))

    return (2 / 3) * energy * sum_integrals

<commit_msg>refactoring of the oscillator strength function<commit_after>
__all__ = ['oscillator_strength', 'calculateDipoleCenter']

# ==========> Standard libraries and third-party <===============
from functools import partial
import numpy as np

# ==================> Internal modules <====================
from .overlapIntegral import calcMtxOverlapP
from .multipoleIntegrals import calcMtxMultipoleP
from nac.common import triang2mtx
# ==================================<>=========================================
# x,y,z exponents value for the dipole
exponents = [{'e': 1, 'f': 0, 'g': 0}, {'e': 0, 'f': 1, 'g': 0},
             {'e': 0, 'f': 0, 'g': 1}]

def transform2Spherical(mtx, trans_mtx):
    """
    Transform a matrix containing integrals in cartesian coordinates to a matrix
    in spherical coordinates.
    """
    trr = np.transpose(trans_mtx)

    return np.dot(trans_mtx, np.dot(mtx, trr))

def computeIntegralSum(arrT, arr, mtx):
    """
    Calculate the operation sum(arr^t mtx arr)
    """
    return np.sum(np.dot(arrT, np.dot(mtx, arr)))

def flattenCartesian2MtxSpherical(atoms, cgfsN, rc, trans_mtx):
    """
    Compute the Multipole matrix in cartesian coordinates and
    expand it to a matrix and finally convert it to spherical coordinates.
    """
    dimSpher, dimCart = trans_mtx.shape
    mtx_integrals_triang = tuple(calcMtxMultipoleP(atoms, cgfsN, rc, **kw)
                                 for kw in exponents)
    mtx_integrals_cart = tuple(triang2mtx(xs, dimCart)
                               for xs in mtx_integrals_triang)
    return tuple(transform2Spherical(x, trans_mtx) for x
                 in mtx_integrals_cart)

def calculateDipoleCenter(atoms, cgfsN, css, trans_mtx):
    """
    Calculate the point where the dipole is centered.
    :param atoms: Atomic label and cartesian coordinates
    type atoms: List of namedTuples
    :param cgfsN: Contracted gauss functions normalized, represented as
    a list of tuples of coefficients and Exponents.
    type cgfsN: [(Coeff, Expo)]

    To calculate the origin of the dipole we use the following property,

    ..math::
    \braket{\Psi_i \mid \hat{x_0} \mid \Psi_i} =
                       - \braket{\Psi_i \mid \hat{x} \mid \Psi_i}
    """
    rc = (0, 0, 0)

    dimSpher, dimCart = trans_mtx.shape
    # Overlap matrix calculated as a flatten triangular matrix
    overlap_triang = calcMtxOverlapP(atoms, cgfsN)
    # Expand the flatten triangular array to a matrix
    overlap_cart = triang2mtx(overlap_triang, dimCart)
    # transform from Cartesian coordinates to Spherical
    overlap_spher = transform2Spherical(overlap_cart, trans_mtx)
    css_T = np.transpose(css)
    overlap = computeIntegralSum(css_T, css, overlap_spher)

    mtx_integrals_spher = flattenCartesian2MtxSpherical(atoms, cgfsN, rc,
                                                        trans_mtx)
    cssT = np.transpose(css)
    xs_sum = list(map(partial(computeIntegralSum, cssT, css),
                      mtx_integrals_spher))

    return tuple(map(lambda x: - x / overlap, xs_sum))

def  oscillator_strength(atoms, cgfsN, css_i, css_j, energy, trans_mtx):
    """
    :param atoms: Atomic label and cartesian coordinates
    type atoms: List of namedTuples
    :param cgfsN: Contracted gauss functions normalized, represented as
    a list of tuples of coefficients and Exponents.
    type cgfsN: [(Coeff, Expo)]
    :param css_i: MO coefficients of initial state
    :type coeffs: Numpy Matrix.
    :param css_j: MO coefficients of final state
    :type coeffs: Numpy Matrix.
    :param energy: MO energy.
    :type energy: Double
    :param trans_mtx: Transformation matrix to translate from Cartesian
    to Sphericals.
    :type trans_mtx: Numpy Matrix
    :returns: Oscillator strength (float)
    """
    dimSpher, dimCart = trans_mtx.shape
    # Dipole center
    rc = calculateDipoleCenter(atoms, cgfsN, css_i, trans_mtx)

    print("Dipole center is: ", rc)
    mtx_integrals_spher = flattenCartesian2MtxSpherical(atoms, cgfsN, rc,
                                                        trans_mtx)
    css_i_T = np.transpose(css_i)
    sum_integrals = sum(x ** 2 for x in
                        map(partial(computeIntegralSum, css_i_T, css_j),
                            mtx_integrals_spher))

    return (2 / 3) * energy * sum_integrals

<|endoftext|>


<commit_before>import os

import json
import mock
from mock import call
from django.test import TestCase
from django.db.models import Model
from django.conf import settings
from celery.task import task

from nailgun import tasks
from nailgun import models
from nailgun import exceptions
from nailgun import task_helpers
from nailgun.helpers import DeployGenerator

class TestTasks(TestCase):

    fixtures = ['default_cluster']

    def setUp(self):
        self.node = models.Node(id="080000000001",
                    cluster_id=1,
                    name="test.example.com",
                    ip="127.0.0.1",
                    metadata={})
        self.node.save()

        self.recipe = models.Recipe()
        self.recipe.recipe = 'cookbook::recipe@2.1'
        self.recipe.save()

        self.role = models.Role()
        self.role.save()
        self.role.recipes = [self.recipe]
        self.role.name = "My role"
        self.role.save()

        self.node.roles = [self.role]
        self.node.save()

    def tearDown(self):
        self.node.delete()
        self.role.delete()
        self.recipe.delete()

    @mock.patch('nailgun.tasks.tcp_ping')
    @mock.patch('nailgun.tasks.SshConnect')
    @mock.patch('nailgun.tasks._provision_node')
    def test_bootstrap_node(self, pn_mock, ssh_mock, tp_mock):
        ssh = ssh_mock.return_value
        ssh.run.return_value = True
        pn_mock.return_value = True
        tp_mock.return_value = True

        self.assertEquals(self.node.status, "ready")
        res = tasks.bootstrap_node.delay(self.node.id)
        self.assertEquals(res.state, "SUCCESS")
        node = models.Node.objects.get(id=self.node.id)
        self.assertEquals(node.status, "ready")

    @mock.patch('nailgun.tasks.tcp_ping')
    @mock.patch('nailgun.tasks.SshConnect')
    def test_bootstrap_calls_provision_and_ssh(self, ssh_mock, tp_mock):
        ssh = ssh_mock.return_value
        ssh.run = mock.MagicMock(return_value=True)
        tp_mock.return_value = True

        tasks._provision_node = mock.MagicMock(return_value=None)
        tasks.bootstrap_node(self.node.id)
        self.assertEquals(tasks._provision_node.call_args_list,
                [call(self.node.id)])
        self.assertEquals(ssh.run.call_args_list,
                [call('/opt/nailgun/bin/deploy')])

    @mock.patch('nailgun.tasks.tcp_ping')
    @mock.patch('nailgun.tasks.SshConnect')
    def test_bootstrap_does_not_call_provision(self, ssh_mock, tp_mock):
        ssh = ssh_mock.return_value
        ssh.run.return_value = True
        tp_mock.return_value = True
        tasks._provision_node = mock.MagicMock(return_value=None)

        tasks.bootstrap_node(self.node.id, installed=True)
        self.assertEquals(tasks._provision_node.call_args_list, [])

    @mock.patch('nailgun.tasks.tcp_ping')
    @mock.patch('nailgun.tasks.SshConnect')
    @mock.patch('nailgun.tasks._provision_node')
    def test_bootstrap_raises_deploy_error(self, pn_mock, ssh_mock, tp_mock):
        ssh = ssh_mock.return_value
        ssh.run.return_value = False
        pn_mock.return_value = True
        tp_mock.return_value = True

        with self.assertRaises(exceptions.DeployError):
            tasks.bootstrap_node(self.node.id)

    @mock.patch('nailgun.tasks.tcp_ping')
    @mock.patch('nailgun.tasks.SshConnect')
    @mock.patch('nailgun.tasks._provision_node')
    def test_bootstrap_puts_error_in_task(self, pn_mock, ssh_mock, tp_mock):
        ssh = ssh_mock.return_value
        ssh.run.return_value = False
        pn_mock.return_value = True
        tp_mock.return_value = True

        self.assertEquals(self.node.status, "ready")
        res = tasks.bootstrap_node.delay(self.node.id)
        self.assertEquals(res.state, "FAILURE")
        self.assertIsInstance(res.result, exceptions.DeployError)
        self.assertTrue(res.ready)
        node = models.Node.objects.get(id=self.node.id)
        self.assertEquals(node.status, "error")

    @mock.patch('nailgun.tasks.TaskPool')
    def test_one_recipe_deploy_cluster(self, tp):
        tasks.deploy_cluster('1')
        expected = [
            call(),
            call().push_task(tasks.create_solo, ('1', self.recipe.id)),
            call().push_task([{'args': [self.node.id],
                    'func': tasks.bootstrap_node, 'kwargs': {}}]),
            call().push_task(tasks.update_cluster_status, ('1',)),
            call().apply_async()
        ]
        self.assertEquals(tasks.TaskPool.mock_calls, expected)

    @mock.patch('nailgun.tasks.TaskPool')
    def test_deploy_cluster_with_recipe_deps(self, tp):
        # 0: 1,2;  1: 2;  2: ;  3: 2
        # Rigth order: 2,1,0,3
        rcps = [models.Recipe() for x in range(4)]
        for i, rec in enumerate(rcps):
            rec.recipe = 'cookbook::recipe%s@0.1' % i
            rec.save()

        rcps[0].depends = [rcps[1], rcps[2]]
        rcps[1].depends = [rcps[2]]
        rcps[2].depends = []
        rcps[3].depends = [rcps[2]]
        map(lambda r: r.save(), rcps)

        roles = [models.Role() for x in range(3)]
        for i, role in enumerate(roles):
            role.name = "Role%s" % i
            role.save()

        roles[0].recipes = [rcps[0], rcps[2]]
        roles[1].recipes = [rcps[3]]
        roles[2].recipes = [rcps[1]]
        map(lambda r: r.save(), roles)

        nodes = [models.Node() for x in range(2)]
        for i, node in enumerate(nodes):
            node.name = "Node-%s" % i
            node.id = "FF000000000%s" % i
            node.ip = "127.0.0.%s" % i
            node.cluster_id = 1
            node.save()
        nodes[0].roles = [roles[0]]
        nodes[1].roles = [roles[1], roles[2]]

        tasks.deploy_cluster('1')
        expected = [
            # init
            call(),
            # first recipe, no deps, defined in setUp
            call().push_task(tasks.create_solo, ('1', self.recipe.id)),
            call().push_task([{'args': [self.node.id],
                    'func': tasks.bootstrap_node, 'kwargs': {}}]),
            # Applying in order 2-> 1-> 0-> 3
            call().push_task(tasks.create_solo, ('1', rcps[2].id)),
            call().push_task([{'args': [nodes[0].id],
                    'func': tasks.bootstrap_node, 'kwargs': {}}]),
            call().push_task(tasks.create_solo, ('1', rcps[1].id)),
            call().push_task([{'args': [nodes[1].id],
                    'func': tasks.bootstrap_node, 'kwargs': {}}]),
            call().push_task(tasks.create_solo, ('1', rcps[0].id)),
            call().push_task([{'args': [nodes[0].id, True],
                    'func': tasks.bootstrap_node, 'kwargs': {}}]),
            call().push_task(tasks.create_solo, ('1', rcps[3].id)),
            call().push_task([{'args': [nodes[1].id, True],
                    'func': tasks.bootstrap_node, 'kwargs': {}}]),
            # Last task for chord to succeed
            call().push_task(tasks.update_cluster_status, ('1',)),
            call().apply_async()
        ]
        self.assertEquals(tasks.TaskPool.mock_calls, expected)

    def test_deploy_cluster_error_when_recipe_not_in_cluster(self):
        rcps = [models.Recipe() for x in range(4)]
        for i, rec in enumerate(rcps):
            rec.recipe = 'cookbook::recipe%s@0.1' % i
            rec.save()
        rcps[0].depends = [rcps[1], rcps[2]]
        rcps[1].depends = [rcps[2]]
        rcps[2].depends = [rcps[3]]
        rcps[3].depends = []
        map(lambda r: r.save(), rcps)

        roles = [models.Role() for x in range(3)]
        for i, role in enumerate(roles):
            role.name = "Role%s" % i
            role.save()

        roles[0].recipes = [rcps[0], rcps[3]]
        roles[1].recipes = [rcps[2]]
        map(lambda r: r.save(), roles)
        self.node.roles = roles
        self.node.save()

        graph = {}
        for recipe in models.Recipe.objects.filter(
                    recipe__in=DeployGenerator.recipes(1)):
            graph[recipe.recipe] = [r.recipe for r in recipe.depends.all()]

        self.assertRaises(exceptions.DeployError, tasks.deploy_cluster, '1')

    @mock.patch('nailgun.tasks.TaskPool')
    def test_deploy_cluster_takes_right_cluster(self, tp):
        node = models.Node()
        node.id = "010000000007"
        node.ip = "127.0.0.1"
        # It will be node from other cluster
        node.cluster_id = 2
        node.save()
        node.roles = [self.role]
        node.save()

        tasks.deploy_cluster('1')
        expected = [
            call(),
            call().push_task(tasks.create_solo, ('1', self.recipe.id)),
            call().push_task([{'args': [self.node.id],
                    'func': tasks.bootstrap_node, 'kwargs': {}}]),
            call().push_task(tasks.update_cluster_status, ('1',)),
            call().apply_async()
        ]
        self.assertEquals(tasks.TaskPool.mock_calls, expected)

    @mock.patch('nailgun.tasks.TaskPool')
    def test_deploy_cluster_nodes_with_same_recipes_generates_group(self, tp):
        # Adding second node with same recipes/roles
        node = models.Node()
        node.id = "FFF000000007"
        node.ip = "127.0.0.1"
        node.cluster_id = 1
        node.save()
        node.roles = [self.role]
        node.save()

        tasks.deploy_cluster('1')
        expected = [
            call(),
            call().push_task(tasks.create_solo, ('1', self.recipe.id)),
            call().push_task([{'args': [self.node.id],
                    'func': tasks.bootstrap_node, 'kwargs': {}},
                              {'args': [node.id],
                    'func': tasks.bootstrap_node, 'kwargs': {}}]),
            call().push_task(tasks.update_cluster_status, ('1',)),
            call().apply_async()
        ]
        self.assertEquals(tasks.TaskPool.mock_calls, expected)

    def test_create_solo_task(self):
        dummy_list = []
        tasks.create_solo(dummy_list, 1, self.recipe.id)
        with open(
            os.path.join(
                settings.CHEF_CONF_FOLDER,
                "".join([self.node.id, ".json"])
            ),
            "r"
        ) as entity:
            solo = entity.read()

        expected = {
            "cluster_id": 1,
            "components_dict": {
                self.node.id: {
                    "node_ips": {}
                }
            },
            "components_list": [
                {
                    "node_id": self.node.id,
                    "node_ips": {}
                }
            ],
            "run_list": [
                "recipe[%s]" % self.recipe.recipe
            ]
        }
        self.assertEquals(expected, json.loads(solo))
<commit_msg>unit tests repaired<commit_after>import os

import json
import mock
from mock import call
from django.test import TestCase
from django.db.models import Model
from django.conf import settings
from celery.task import task

from nailgun import tasks
from nailgun import models
from nailgun import exceptions
from nailgun import task_helpers
from nailgun.helpers import DeployGenerator

class TestTasks(TestCase):

    fixtures = ['default_cluster']

    def setUp(self):
        self.node = models.Node(id="080000000001",
                    cluster_id=1,
                    name="test.example.com",
                    ip="127.0.0.1",
                    metadata={})
        self.node.save()

        self.recipe = models.Recipe()
        self.recipe.recipe = 'cookbook::recipe@2.1'
        self.recipe.save()

        self.role = models.Role()
        self.role.save()
        self.role.recipes = [self.recipe]
        self.role.name = "My role"
        self.role.save()

        self.node.roles = [self.role]
        self.node.save()

    def tearDown(self):
        self.node.delete()
        self.role.delete()
        self.recipe.delete()

    @mock.patch('nailgun.tasks.tcp_ping')
    @mock.patch('nailgun.tasks.SshConnect')
    @mock.patch('nailgun.tasks._provision_node')
    def test_bootstrap_node(self, pn_mock, ssh_mock, tp_mock):
        ssh = ssh_mock.return_value
        ssh.run.return_value = True
        pn_mock.return_value = True
        tp_mock.return_value = True

        self.assertEquals(self.node.status, "ready")
        res = tasks.bootstrap_node.delay(self.node.id)
        self.assertEquals(res.state, "SUCCESS")
        node = models.Node.objects.get(id=self.node.id)
        self.assertEquals(node.status, "ready")

    @mock.patch('nailgun.tasks.tcp_ping')
    @mock.patch('nailgun.tasks.SshConnect')
    def test_bootstrap_calls_provision_and_ssh(self, ssh_mock, tp_mock):
        ssh = ssh_mock.return_value
        ssh.run = mock.MagicMock(return_value=True)
        tp_mock.return_value = True
        self.node.status = "discover"
        self.node.save()

        tasks._provision_node = mock.MagicMock(return_value=None)
        tasks.bootstrap_node(self.node.id)
        self.assertEquals(tasks._provision_node.call_args_list,
                [call(self.node.id)])
        self.assertEquals(ssh.run.call_args_list,
                [call('/opt/nailgun/bin/deploy')])

    @mock.patch('nailgun.tasks.tcp_ping')
    @mock.patch('nailgun.tasks.SshConnect')
    def test_bootstrap_does_not_call_provision(self, ssh_mock, tp_mock):
        ssh = ssh_mock.return_value
        ssh.run.return_value = True
        tp_mock.return_value = True
        tasks._provision_node = mock.MagicMock(return_value=None)

        tasks.bootstrap_node(self.node.id)
        self.assertEquals(tasks._provision_node.call_args_list, [])

    @mock.patch('nailgun.tasks.tcp_ping')
    @mock.patch('nailgun.tasks.SshConnect')
    @mock.patch('nailgun.tasks._provision_node')
    def test_bootstrap_raises_deploy_error(self, pn_mock, ssh_mock, tp_mock):
        ssh = ssh_mock.return_value
        ssh.run.return_value = False
        pn_mock.return_value = True
        tp_mock.return_value = True

        with self.assertRaises(exceptions.DeployError):
            tasks.bootstrap_node(self.node.id)

    @mock.patch('nailgun.tasks.tcp_ping')
    @mock.patch('nailgun.tasks.SshConnect')
    @mock.patch('nailgun.tasks._provision_node')
    def test_bootstrap_puts_error_in_task(self, pn_mock, ssh_mock, tp_mock):
        ssh = ssh_mock.return_value
        ssh.run.return_value = False
        pn_mock.return_value = True
        tp_mock.return_value = True

        self.assertEquals(self.node.status, "ready")
        res = tasks.bootstrap_node.delay(self.node.id)
        self.assertEquals(res.state, "FAILURE")
        self.assertIsInstance(res.result, exceptions.DeployError)
        self.assertTrue(res.ready)
        node = models.Node.objects.get(id=self.node.id)
        self.assertEquals(node.status, "error")

    @mock.patch('nailgun.tasks.TaskPool')
    def test_one_recipe_deploy_cluster(self, tp):
        tasks.deploy_cluster('1')
        expected = [
            call(),
            call().push_task(tasks.create_solo, ('1', self.recipe.id)),
            call().push_task([{'args': [self.node.id],
                    'func': tasks.bootstrap_node, 'kwargs': {}}]),
            call().push_task(tasks.update_cluster_status, ('1',)),
            call().apply_async()
        ]
        self.assertEquals(tasks.TaskPool.mock_calls, expected)

    @mock.patch('nailgun.tasks.TaskPool')
    def test_deploy_cluster_with_recipe_deps(self, tp):
        # 0: 1,2;  1: 2;  2: ;  3: 2
        # Rigth order: 2,1,0,3
        rcps = [models.Recipe() for x in range(4)]
        for i, rec in enumerate(rcps):
            rec.recipe = 'cookbook::recipe%s@0.1' % i
            rec.save()

        rcps[0].depends = [rcps[1], rcps[2]]
        rcps[1].depends = [rcps[2]]
        rcps[2].depends = []
        rcps[3].depends = [rcps[2]]
        map(lambda r: r.save(), rcps)

        roles = [models.Role() for x in range(3)]
        for i, role in enumerate(roles):
            role.name = "Role%s" % i
            role.save()

        roles[0].recipes = [rcps[0], rcps[2]]
        roles[1].recipes = [rcps[3]]
        roles[2].recipes = [rcps[1]]
        map(lambda r: r.save(), roles)

        nodes = [models.Node() for x in range(2)]
        for i, node in enumerate(nodes):
            node.name = "Node-%s" % i
            node.id = "FF000000000%s" % i
            node.ip = "127.0.0.%s" % i
            node.cluster_id = 1
            node.save()
        nodes[0].roles = [roles[0]]
        nodes[1].roles = [roles[1], roles[2]]

        tasks.deploy_cluster('1')
        expected = [
            # init
            call(),
            # first recipe, no deps, defined in setUp
            call().push_task(tasks.create_solo, ('1', self.recipe.id)),
            call().push_task([{'args': [self.node.id],
                    'func': tasks.bootstrap_node, 'kwargs': {}}]),
            # Applying in order 2-> 1-> 0-> 3
            call().push_task(tasks.create_solo, ('1', rcps[2].id)),
            call().push_task([{'args': [nodes[0].id],
                    'func': tasks.bootstrap_node, 'kwargs': {}}]),
            call().push_task(tasks.create_solo, ('1', rcps[1].id)),
            call().push_task([{'args': [nodes[1].id],
                    'func': tasks.bootstrap_node, 'kwargs': {}}]),
            call().push_task(tasks.create_solo, ('1', rcps[0].id)),
            call().push_task([{'args': [nodes[0].id],
                    'func': tasks.bootstrap_node, 'kwargs': {}}]),
            call().push_task(tasks.create_solo, ('1', rcps[3].id)),
            call().push_task([{'args': [nodes[1].id],
                    'func': tasks.bootstrap_node, 'kwargs': {}}]),
            # Last task for chord to succeed
            call().push_task(tasks.update_cluster_status, ('1',)),
            call().apply_async()
        ]
        self.assertEquals(tasks.TaskPool.mock_calls, expected)

    def test_deploy_cluster_error_when_recipe_not_in_cluster(self):
        rcps = [models.Recipe() for x in range(4)]
        for i, rec in enumerate(rcps):
            rec.recipe = 'cookbook::recipe%s@0.1' % i
            rec.save()
        rcps[0].depends = [rcps[1], rcps[2]]
        rcps[1].depends = [rcps[2]]
        rcps[2].depends = [rcps[3]]
        rcps[3].depends = []
        map(lambda r: r.save(), rcps)

        roles = [models.Role() for x in range(3)]
        for i, role in enumerate(roles):
            role.name = "Role%s" % i
            role.save()

        roles[0].recipes = [rcps[0], rcps[3]]
        roles[1].recipes = [rcps[2]]
        map(lambda r: r.save(), roles)
        self.node.roles = roles
        self.node.save()

        graph = {}
        for recipe in models.Recipe.objects.filter(
                    recipe__in=DeployGenerator.recipes(1)):
            graph[recipe.recipe] = [r.recipe for r in recipe.depends.all()]

        self.assertRaises(exceptions.DeployError, tasks.deploy_cluster, '1')

    @mock.patch('nailgun.tasks.TaskPool')
    def test_deploy_cluster_takes_right_cluster(self, tp):
        node = models.Node()
        node.id = "010000000007"
        node.ip = "127.0.0.1"
        # It will be node from other cluster
        node.cluster_id = 2
        node.save()
        node.roles = [self.role]
        node.save()

        tasks.deploy_cluster('1')
        expected = [
            call(),
            call().push_task(tasks.create_solo, ('1', self.recipe.id)),
            call().push_task([{'args': [self.node.id],
                    'func': tasks.bootstrap_node, 'kwargs': {}}]),
            call().push_task(tasks.update_cluster_status, ('1',)),
            call().apply_async()
        ]
        self.assertEquals(tasks.TaskPool.mock_calls, expected)

    @mock.patch('nailgun.tasks.TaskPool')
    def test_deploy_cluster_nodes_with_same_recipes_generates_group(self, tp):
        # Adding second node with same recipes/roles
        node = models.Node()
        node.id = "FFF000000007"
        node.ip = "127.0.0.1"
        node.cluster_id = 1
        node.save()
        node.roles = [self.role]
        node.save()

        tasks.deploy_cluster('1')
        expected = [
            call(),
            call().push_task(tasks.create_solo, ('1', self.recipe.id)),
            call().push_task([{'args': [self.node.id],
                    'func': tasks.bootstrap_node, 'kwargs': {}},
                              {'args': [node.id],
                    'func': tasks.bootstrap_node, 'kwargs': {}}]),
            call().push_task(tasks.update_cluster_status, ('1',)),
            call().apply_async()
        ]
        self.assertEquals(tasks.TaskPool.mock_calls, expected)

    def test_create_solo_task(self):
        dummy_list = []
        tasks.create_solo(dummy_list, 1, self.recipe.id)
        with open(
            os.path.join(
                settings.CHEF_CONF_FOLDER,
                "".join([self.node.id, ".json"])
            ),
            "r"
        ) as entity:
            solo = entity.read()

        expected = {
            "cluster_id": 1,
            "components_dict": {
                self.node.id: {
                    "node_ips": {}
                }
            },
            "components_list": [
                {
                    "node_id": self.node.id,
                    "node_ips": {}
                }
            ],
            "run_list": [
                "recipe[%s]" % self.recipe.recipe
            ]
        }
        self.assertEquals(expected, json.loads(solo))
<|endoftext|>


<commit_before># Author: Braedy Kuzma
from django.conf.urls import url
from . import views

urlpatterns = [
    url(r'^posts/(?P<pid>[0-9a-fA-F\-]+)/$', views.PostView.as_view(),
        name='post'),
    url(r'^posts/$', views.PostsView.as_view(), name='posts'),
    url(r'^author/(?P<aid>[0-9a-fA-F\-]+)/$', views.AuthorView.as_view(),
        name='author')
]
<commit_msg>Add comments url.<commit_after># Author: Braedy Kuzma
from django.conf.urls import url
from . import views

urlpatterns = [
    url(r'^posts/(?P<pid>[0-9a-fA-F\-]+)/$', views.PostView.as_view(),
        name='post'),
    url(r'^posts/$', views.PostsView.as_view(), name='posts'),
    url(r'^author/(?P<aid>[0-9a-fA-F\-]+)/$', views.AuthorView.as_view(),
        name='author'),
    url(r'^posts/(?P<pid>[0-9a-fA-F\-]+)/comments/$',
        views.CommentView.as_view(), name='comments')
]
<|endoftext|>


<commit_before>import jsonpickle
import re
import tabulate

import BotpySE as bp

class Tag:
    def __init__(self, name, regex, user_id, user_name):
        _ = re.compile(regex)

        self.name = name
        self.regex = regex
        self.user_id = user_id
        self.user_name = user_name

        self.format = "[tag:" + self.name + "]"

class TagManager:
    def __init__(self, filename='./tags.json'):
        self.tags = list()
        self.filename = filename

        try:
            with open(filename, 'r') as file_handle:
                tags = jsonpickle.decode(file_handle.read())
            self.tags = tags
        except FileNotFoundError:
            pass

    def add(self, tag):
        self.tags.append(tag)
        self.save()

    def remove(self, name):
        for tag in self.tags:
            if tag.name == name:
                self.tags.remove(tag)
                self.save()
                return True
        return False

    def filter_post(self, post):
        tags = list()
        for tag in self.tags:
            if re.search(tag.regex, post):
                tags.append(tag.format)
        return " ".join(tags) + post

    def list(self):
        for tag in self.tags:
            yield tag

    def save(self):
        encoded = jsonpickle.encode(self.tags)
        with open(self.filename, "w") as file_handle:
            file_handle.write(encoded)

class CommandListTags(bp.Command):
    @staticmethod
    def usage():
        return ["listtags", "list tags", "tags", "all tags"]

    def run(self):
        print("RUNNING")
        tag_list = list()
        for tag in self.command_manager.tags.list():
            tag_list.append([tag.name, tag.regex, tag.user_name])

        table = tabulate.tabulate(tag_list, headers=["Name", "Regex", "Added By"], tablefmt="orgtbl")

        self.post("    " + re.sub('\n', '\n    ', table), False)

class CommandAddTag(bp.Command):
    @staticmethod
    def usage():
        # Regexes may have a space; thus last part of usage is always "..."
        return ["addtag * ...", "add tag * ...", "add tag with name * and regex ...", "add tag * matching ...", "add tag * for ..."]

    def privileges(self):
        return 1

    def run(self):
        user_id = self.message.user.id
        user_name = self.message.user.name

        tag_name = self.arguments[0]
        regex = ' '.join(self.arguments[1:])

        try:
            self.command_manager.tags.add(Tag(tag_name, regex, user_id, user_name))
            self.reply("Added [tag:{0}] for regex {1}".format(tag_name, regex))
        except re.error as err:
            self.reply("Could not add tag for regex {0}: {1}".format(regex, err))

class CommandRemoveTag(bp.Command):
    @staticmethod
    def usage():
        return ["removetag *", "remove tag *", "delete tag *", "destroy tag *", "poof tag *"]

    def privileges(self):
        return 1

    def run(self):
        tag_name = self.arguments[0]

        if self.command_manager.tags.remove(tag_name):
            self.reply("Removed [tag:{0}] successfully.".format(tag_name))
        else:
            self.reply("The specified tag does not exist; have you made a typo or specified that tag in a different case?")
<commit_msg>Remove debug print<commit_after>import jsonpickle
import re
import tabulate

import BotpySE as bp

class Tag:
    def __init__(self, name, regex, user_id, user_name):
        _ = re.compile(regex)

        self.name = name
        self.regex = regex
        self.user_id = user_id
        self.user_name = user_name

        self.format = "[tag:" + self.name + "]"

class TagManager:
    def __init__(self, filename='./tags.json'):
        self.tags = list()
        self.filename = filename

        try:
            with open(filename, 'r') as file_handle:
                tags = jsonpickle.decode(file_handle.read())
            self.tags = tags
        except FileNotFoundError:
            pass

    def add(self, tag):
        self.tags.append(tag)
        self.save()

    def remove(self, name):
        for tag in self.tags:
            if tag.name == name:
                self.tags.remove(tag)
                self.save()
                return True
        return False

    def filter_post(self, post):
        tags = list()
        for tag in self.tags:
            if re.search(tag.regex, post):
                tags.append(tag.format)
        return " ".join(tags) + post

    def list(self):
        for tag in self.tags:
            yield tag

    def save(self):
        encoded = jsonpickle.encode(self.tags)
        with open(self.filename, "w") as file_handle:
            file_handle.write(encoded)

class CommandListTags(bp.Command):
    @staticmethod
    def usage():
        return ["listtags", "list tags", "tags", "all tags"]

    def run(self):
        tag_list = list()
        for tag in self.command_manager.tags.list():
            tag_list.append([tag.name, tag.regex, tag.user_name])

        table = tabulate.tabulate(tag_list, headers=["Name", "Regex", "Added By"], tablefmt="orgtbl")

        self.post("    " + re.sub('\n', '\n    ', table), False)

class CommandAddTag(bp.Command):
    @staticmethod
    def usage():
        # Regexes may have a space; thus last part of usage is always "..."
        return ["addtag * ...", "add tag * ...", "add tag with name * and regex ...", "add tag * matching ...", "add tag * for ..."]

    def privileges(self):
        return 1

    def run(self):
        user_id = self.message.user.id
        user_name = self.message.user.name

        tag_name = self.arguments[0]
        regex = ' '.join(self.arguments[1:])

        try:
            self.command_manager.tags.add(Tag(tag_name, regex, user_id, user_name))
            self.reply("Added [tag:{0}] for regex {1}".format(tag_name, regex))
        except re.error as err:
            self.reply("Could not add tag for regex {0}: {1}".format(regex, err))

class CommandRemoveTag(bp.Command):
    @staticmethod
    def usage():
        return ["removetag *", "remove tag *", "delete tag *", "destroy tag *", "poof tag *"]

    def privileges(self):
        return 1

    def run(self):
        tag_name = self.arguments[0]

        if self.command_manager.tags.remove(tag_name):
            self.reply("Removed [tag:{0}] successfully.".format(tag_name))
        else:
            self.reply("The specified tag does not exist; have you made a typo or specified that tag in a different case?")
<|endoftext|>


<commit_before>from TexSoup.utils import to_buffer, Buffer, TokenWithPosition
from TexSoup.data import *
import TexSoup.data as data
import string

__all__ = ['tokenize', 'read_tex']

COMMAND_TOKENS = {'\\'}
MATH_TOKENS = {'$'}
ARG_START_TOKENS = {arg.delims()[0] for arg in data.args}
ARG_END_TOKENS = {arg.delims()[1] for arg in data.args}
ARG_TOKENS = ARG_START_TOKENS | ARG_END_TOKENS
ALL_TOKENS = COMMAND_TOKENS | ARG_TOKENS | MATH_TOKENS
SKIP_ENVS = ('verbatim', 'equation', 'lstlisting')
BRACKETS_DELIMITERS = {'(', ')', '<', '>', '\[', '[', ']', '{',
                       '\{', '\}', '.' '|', '\langle', '\rangle',
                       '\lfloor', '\rfloor', '\lceil', '\rceil',
                       r'\ulcorner', r'\urcorner', '\lbrack', '\rbrack'}
PUNCTUATION_COMMANDS = {command + bracket
                        for command in ('left', 'right')
                        for bracket in BRACKETS_DELIMITERS.union({'|', '.'})}

#############
# Tokenizer #
#############

@to_buffer
def next_token(text):
    r"""Returns the next possible token, advancing the iterator to the next
    position to start processing from.

    :param (str, iterator, Buffer) text: LaTeX to process
    :return str: the token

    >>> b = Buffer(r'\textbf{Do play\textit{nice}.}   $$\min_w \|w\|_2^2$$')
    >>> print(next_token(b), next_token(b), next_token(b), next_token(b))
    \textbf { Do play \textit
    >>> print(next_token(b), next_token(b), next_token(b), next_token(b))
    { nice } .
    >>> print(next_token(b))
    }
    >>> print(next_token(Buffer('.}')))
    .
    >>> next_token(b)
    '   '
    >>> next_token(b)
    '$$\\min_w \\|w\\|_2^2$$'
    >>> next_token(b)
    """
    while text.hasNext():
        for name, f in tokenizers:
            token = f(text)
            if token is not None:
                return token

@to_buffer
def tokenize(text):
    r"""Generator for LaTeX tokens on text, ignoring comments.

    :param (str, iterator, Buffer) text: LaTeX to process

    >>> print(*tokenize(r'\textbf{Do play \textit{nice}.}'))
    \textbf { Do play  \textit { nice } . }
    >>> print(*tokenize(r'\begin{tabular} 0 & 1 \\ 2 & 0 \end{tabular}'))
    \begin { tabular }  0 & 1 \\ 2 & 0  \end { tabular }
    >>> print(*tokenize(r'$$\min_x \|Xw-y\|_2^2$$'))
    $$\min_x \|Xw-y\|_2^2$$
    """
    token = next_token(text)
    while token is not None:
        yield token
        token = next_token(text)

##########
# Tokens #
##########

tokenizers = []

def token(name):
    """Marker for a token

    :param str name: Name of tokenizer
    """
    def wrap(f):
        tokenizers.append((name, f))
        return f
    return wrap

@token('punctuation_command')
def tokenize_punctuation_command(text):
    """Process command that augments or modifies punctuation.

    This is important to the tokenization of a string, as opening or closing
    punctuation is not supposed to match.

    :param Buffer text: iterator over text, with current position
    """
    if text.peek() == '\\':
        for string in PUNCTUATION_COMMANDS:
            if text.peek((1, len(string) + 1)) == string:
                return text.forward(len(string) + 1)

@token('command')
def tokenize_command(text):
    """Process command, but ignore line breaks. (double backslash)

    :param Buffer text: iterator over line, with current position
    """
    if text.peek() == '\\':
        c = text.forward(1)
        tokens = string.punctuation + string.whitespace
        while text.hasNext() and text.peek() not in tokens:
            c += text.forward(1)
        return c

@token('line_comment')
def tokenize_line_comment(text):
    r"""Process a line comment

    :param Buffer text: iterator over line, with current position

    >>> tokenize_line_comment(Buffer('hello %world'))
    >>> tokenize_line_comment(Buffer('%hello world'))
    '%hello world'
    >>> tokenize_line_comment(Buffer('%hello\n world'))
    '%hello'
    """
    result = TokenWithPosition('', text.position)
    if text.peek() == '%':
        result += text.forward(1)
        while text.peek() != '\n' and text.hasNext():
            result += text.forward(1)
        return result

@token('argument')
def tokenize_argument(text):
    """Process both optional and required arguments.

    :param Buffer text: iterator over line, with current position
    """
    for delim in ARG_TOKENS:
        if text.startswith(delim):
            return text.forward(len(delim))

@token('math')
def tokenize_math(text):
    r"""Prevents math from being tokenized.

    :param Buffer text: iterator over line, with current position

    >>> b = Buffer('$$\min_x$$ \command')
    >>> tokenize_math(b)
    '$$\\min_x$$'
    """

    def escaped_dollar():
        return text.peek() == '$' and result[-1] == '\\'

    def end_detected():
        return (text.peek((0, len(starter))) == starter
                and not escaped_dollar())

    result = TokenWithPosition('', text.position)
    if text.startswith('$'):
        starter = '$$' if text.startswith('$$') else '$'
        result += text.forward(len(starter))
        while text.hasNext() and not end_detected():
            result += next(text)
        if not text.startswith(starter):
            raise EOFError('Expecting %s. Instead got %s' % (
                starter, text.peek((0, 5))))
        result += text.forward(len(starter))
        return result

@token('string')
def tokenize_string(text, delimiters=ALL_TOKENS):
    r"""Process a string of text

    :param Buffer text: iterator over line, with current position

    >>> tokenize_string(Buffer('hello'))
    'hello'
    >>> b = Buffer('hello again\command')
    >>> tokenize_string(b)
    'hello again'
    >>> print(b.peek())
    \
    >>> print(tokenize_string(Buffer('0 & 1 \\\\\command')))
    0 & 1 \\
    """
    result = TokenWithPosition('', text.position)
    for c in text:
        if c == '\\' and str(text.peek()) in delimiters:
            c += next(text)
        elif str(c) in delimiters:  # assumes all tokens are single characters
            text.backward(1)
            return result
        result += c
        if text.peek((0, 2)) == '\\\\':
            result += text.forward(2)
    return result

##########
# Mapper #
##########

def read_tex(src):
    r"""Read next expression from buffer

    :param Buffer src: a buffer of tokens
    """
    c = next(src)
    if c.startswith('$'):
        name = '$$' if c.startswith('$$') else '$'
        return TexEnv(name, [c[len(name):-len(name)]], nobegin=True)
    if c.startswith('\\'):
        command = TokenWithPosition(c[1:], src.position)
        if command == 'item':
            extra = src.forward_until({'\n', '\end', '\item'})
            mode, expr = 'command', TexCmd(command, (),
                TokenWithPosition.join(extra.split(' '), glue=' ').strip())
        elif command == 'begin':
            mode, expr, _ = 'begin', TexEnv(src.peek(1)), src.forward(3)
        else:
            mode, expr = 'command', TexCmd(command)

        # TODO: allow this whitespace between arguments
        # TODO: allow only one line break
        whitespace = src.forward_until_not(set(string.whitespace))
        while src.peek() in ARG_START_TOKENS:
            expr.args.append(read_tex(src))
        if mode == 'begin':
            read_env(src, expr, whitespace=whitespace)  # TODO: hacky fix. use src.backward instead
        return expr
    if c in ARG_START_TOKENS:
        return read_arg(src, c)
    return c

def read_env(src, expr, whitespace=''):
    r"""Read the environment from buffer.

    Advances the buffer until right after the end of the environment. Adds
    parsed content to the expression automatically.

    :param Buffer src: a buffer of tokens
    :param TexExpr expr: expression for the environment
    """
    contents = []
    if expr.name in SKIP_ENVS:
        contents = [whitespace + src.forward_until({'\\end'})]
    while src.hasNext() and not src.startswith('\\end{%s}' % expr.name):
        contents.append(read_tex(src))
    if not src.startswith('\\end{%s}' % expr.name):
        raise EOFError('Expecting \\end{%s}. Instead got %s' % (
            expr.name, src.peek((0, 5))))
    else:
        src.forward(4)
    expr.add_contents(*contents)
    return expr

def read_arg(src, c):
    """Read the argument from buffer.

    Advances buffer until right before the end of the argument.

    :param Buffer src: a buffer of tokens
    :param str c: argument token (starting token)
    :return: the parsed argument
    """
    content = [c]
    while src.hasNext():
        if src.peek() in ARG_END_TOKENS:
            content.append(next(src))
            break
        elif src.peek() in ALL_TOKENS:
            content.append(read_tex(src))
        else:
            content.append(next(src))
    return Arg.parse(content)
<commit_msg>clearer 'unfinished' env error<commit_after>from TexSoup.utils import to_buffer, Buffer, TokenWithPosition
from TexSoup.data import *
import TexSoup.data as data
import string

__all__ = ['tokenize', 'read_tex']

COMMAND_TOKENS = {'\\'}
MATH_TOKENS = {'$'}
ARG_START_TOKENS = {arg.delims()[0] for arg in data.args}
ARG_END_TOKENS = {arg.delims()[1] for arg in data.args}
ARG_TOKENS = ARG_START_TOKENS | ARG_END_TOKENS
ALL_TOKENS = COMMAND_TOKENS | ARG_TOKENS | MATH_TOKENS
SKIP_ENVS = ('verbatim', 'equation', 'lstlisting')
BRACKETS_DELIMITERS = {'(', ')', '<', '>', '\[', '[', ']', '{',
                       '\{', '\}', '.' '|', '\langle', '\rangle',
                       '\lfloor', '\rfloor', '\lceil', '\rceil',
                       r'\ulcorner', r'\urcorner', '\lbrack', '\rbrack'}
PUNCTUATION_COMMANDS = {command + bracket
                        for command in ('left', 'right')
                        for bracket in BRACKETS_DELIMITERS.union({'|', '.'})}

#############
# Tokenizer #
#############

@to_buffer
def next_token(text):
    r"""Returns the next possible token, advancing the iterator to the next
    position to start processing from.

    :param (str, iterator, Buffer) text: LaTeX to process
    :return str: the token

    >>> b = Buffer(r'\textbf{Do play\textit{nice}.}   $$\min_w \|w\|_2^2$$')
    >>> print(next_token(b), next_token(b), next_token(b), next_token(b))
    \textbf { Do play \textit
    >>> print(next_token(b), next_token(b), next_token(b), next_token(b))
    { nice } .
    >>> print(next_token(b))
    }
    >>> print(next_token(Buffer('.}')))
    .
    >>> next_token(b)
    '   '
    >>> next_token(b)
    '$$\\min_w \\|w\\|_2^2$$'
    >>> next_token(b)
    """
    while text.hasNext():
        for name, f in tokenizers:
            token = f(text)
            if token is not None:
                return token

@to_buffer
def tokenize(text):
    r"""Generator for LaTeX tokens on text, ignoring comments.

    :param (str, iterator, Buffer) text: LaTeX to process

    >>> print(*tokenize(r'\textbf{Do play \textit{nice}.}'))
    \textbf { Do play  \textit { nice } . }
    >>> print(*tokenize(r'\begin{tabular} 0 & 1 \\ 2 & 0 \end{tabular}'))
    \begin { tabular }  0 & 1 \\ 2 & 0  \end { tabular }
    >>> print(*tokenize(r'$$\min_x \|Xw-y\|_2^2$$'))
    $$\min_x \|Xw-y\|_2^2$$
    """
    token = next_token(text)
    while token is not None:
        yield token
        token = next_token(text)

##########
# Tokens #
##########

tokenizers = []

def token(name):
    """Marker for a token

    :param str name: Name of tokenizer
    """
    def wrap(f):
        tokenizers.append((name, f))
        return f
    return wrap

@token('punctuation_command')
def tokenize_punctuation_command(text):
    """Process command that augments or modifies punctuation.

    This is important to the tokenization of a string, as opening or closing
    punctuation is not supposed to match.

    :param Buffer text: iterator over text, with current position
    """
    if text.peek() == '\\':
        for string in PUNCTUATION_COMMANDS:
            if text.peek((1, len(string) + 1)) == string:
                return text.forward(len(string) + 1)

@token('command')
def tokenize_command(text):
    """Process command, but ignore line breaks. (double backslash)

    :param Buffer text: iterator over line, with current position
    """
    if text.peek() == '\\':
        c = text.forward(1)
        tokens = string.punctuation + string.whitespace
        while text.hasNext() and text.peek() not in tokens:
            c += text.forward(1)
        return c

@token('line_comment')
def tokenize_line_comment(text):
    r"""Process a line comment

    :param Buffer text: iterator over line, with current position

    >>> tokenize_line_comment(Buffer('hello %world'))
    >>> tokenize_line_comment(Buffer('%hello world'))
    '%hello world'
    >>> tokenize_line_comment(Buffer('%hello\n world'))
    '%hello'
    """
    result = TokenWithPosition('', text.position)
    if text.peek() == '%':
        result += text.forward(1)
        while text.peek() != '\n' and text.hasNext():
            result += text.forward(1)
        return result

@token('argument')
def tokenize_argument(text):
    """Process both optional and required arguments.

    :param Buffer text: iterator over line, with current position
    """
    for delim in ARG_TOKENS:
        if text.startswith(delim):
            return text.forward(len(delim))

@token('math')
def tokenize_math(text):
    r"""Prevents math from being tokenized.

    :param Buffer text: iterator over line, with current position

    >>> b = Buffer('$$\min_x$$ \command')
    >>> tokenize_math(b)
    '$$\\min_x$$'
    """

    def escaped_dollar():
        return text.peek() == '$' and result[-1] == '\\'

    def end_detected():
        return (text.peek((0, len(starter))) == starter
                and not escaped_dollar())

    result = TokenWithPosition('', text.position)
    if text.startswith('$'):
        starter = '$$' if text.startswith('$$') else '$'
        result += text.forward(len(starter))
        while text.hasNext() and not end_detected():
            result += next(text)
        if not text.startswith(starter):
            raise EOFError('Expecting %s. Instead got %s' % (
                starter, text.peek((0, 5))))
        result += text.forward(len(starter))
        return result

@token('string')
def tokenize_string(text, delimiters=ALL_TOKENS):
    r"""Process a string of text

    :param Buffer text: iterator over line, with current position

    >>> tokenize_string(Buffer('hello'))
    'hello'
    >>> b = Buffer('hello again\command')
    >>> tokenize_string(b)
    'hello again'
    >>> print(b.peek())
    \
    >>> print(tokenize_string(Buffer('0 & 1 \\\\\command')))
    0 & 1 \\
    """
    result = TokenWithPosition('', text.position)
    for c in text:
        if c == '\\' and str(text.peek()) in delimiters:
            c += next(text)
        elif str(c) in delimiters:  # assumes all tokens are single characters
            text.backward(1)
            return result
        result += c
        if text.peek((0, 2)) == '\\\\':
            result += text.forward(2)
    return result

##########
# Mapper #
##########

def read_tex(src):
    r"""Read next expression from buffer

    :param Buffer src: a buffer of tokens
    """
    c = next(src)
    if c.startswith('$'):
        name = '$$' if c.startswith('$$') else '$'
        return TexEnv(name, [c[len(name):-len(name)]], nobegin=True)
    if c.startswith('\\'):
        command = TokenWithPosition(c[1:], src.position)
        if command == 'item':
            extra = src.forward_until({'\n', '\end', '\item'})
            mode, expr = 'command', TexCmd(command, (),
                TokenWithPosition.join(extra.split(' '), glue=' ').strip())
        elif command == 'begin':
            mode, expr, _ = 'begin', TexEnv(src.peek(1)), src.forward(3)
        else:
            mode, expr = 'command', TexCmd(command)

        # TODO: allow this whitespace between arguments
        # TODO: allow only one line break
        whitespace = src.forward_until_not(set(string.whitespace))
        while src.peek() in ARG_START_TOKENS:
            expr.args.append(read_tex(src))
        if mode == 'begin':
            read_env(src, expr, whitespace=whitespace)  # TODO: hacky fix. use src.backward instead
        return expr
    if c in ARG_START_TOKENS:
        return read_arg(src, c)
    return c

def read_env(src, expr, whitespace=''):
    r"""Read the environment from buffer.

    Advances the buffer until right after the end of the environment. Adds
    parsed content to the expression automatically.

    :param Buffer src: a buffer of tokens
    :param TexExpr expr: expression for the environment
    """
    contents = []
    if expr.name in SKIP_ENVS:
        contents = [whitespace + src.forward_until({'\\end'})]
    while src.hasNext() and not src.startswith('\\end{%s}' % expr.name):
        contents.append(read_tex(src))
    if not src.startswith('\\end{%s}' % expr.name):
        end = src.peek((0, 5))
        explanation = 'Instead got %s' % end if end else 'Reached end of file.'
        raise EOFError('Expecting \\end{%s}. %s' % (expr.name, explanation))
    else:
        src.forward(4)
    expr.add_contents(*contents)
    return expr

def read_arg(src, c):
    """Read the argument from buffer.

    Advances buffer until right before the end of the argument.

    :param Buffer src: a buffer of tokens
    :param str c: argument token (starting token)
    :return: the parsed argument
    """
    content = [c]
    while src.hasNext():
        if src.peek() in ARG_END_TOKENS:
            content.append(next(src))
            break
        elif src.peek() in ALL_TOKENS:
            content.append(read_tex(src))
        else:
            content.append(next(src))
    return Arg.parse(content)
<|endoftext|>


<commit_before>import os

import pygtk
pygtk.require('2.0')
import gtk
import geckoembed

from sugar.shell import activity
import sugar.env

class GMailActivity(activity.Activity):
	def __init__(self):
		activity.Activity.__init__(self)

	def activity_on_connected_to_shell(self):
		profile_path = os.path.join(sugar.env.get_user_dir(), 'gmail')
		geckoembed.set_profile_path(profile_path)
		self.activity_set_tab_text("Mail")
		self.activity_set_tab_icon_name("stock_mail")
		self.activity_show_icon(True)

		plug = self.activity_get_gtk_plug()

		embed = geckoembed.Embed()
		plug.add(embed)
		embed.show()

		plug.show()

		embed.load_address("http://www.gmail.com")

	def activity_on_disconnected_from_shell(self):
		gtk.main_quit()

activity = GMailActivity()
activity.activity_connect_to_shell()

gtk.main()
<commit_msg>Fix up gmail activity for Activity object changes.<commit_after>import os

import pygtk
pygtk.require('2.0')
import gtk
import geckoembed

from sugar.shell import activity
import sugar.env

class GMailActivity(activity.Activity):
	def __init__(self):
		activity.Activity.__init__(self)

	def on_connected_to_shell(self):
		activity.Activity.on_connected_to_shell(self)

		profile_path = os.path.join(sugar.env.get_user_dir(), 'gmail')
		geckoembed.set_profile_path(profile_path)
		self.set_tab_text("Mail")
		self.set_tab_icon(name="stock_mail")
		self.set_show_icon(True)

		plug = self.gtk_plug()

		embed = geckoembed.Embed()
		plug.add(embed)
		embed.show()

		plug.show()

		embed.load_address("http://www.gmail.com")

	def on_disconnected_from_shell(self):
		activity.Activity.on_disconnected_from_shell()
		gtk.main_quit()

activity = GMailActivity()
activity.connect_to_shell()

gtk.main()
<|endoftext|>


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

from rest import views

urlpatterns = patterns('',
    url(r'^/test$', views.UsersListView.as_view()),
    url(r'^$', views.UsersListView.as_view()),
)
<commit_msg>Changed something before test<commit_after>from django.conf.urls import patterns, include, url

from rest import views

urlpatterns = patterns('',
    url(r'^', views.UsersListView.as_view()),
    url(r'^$', views.UsersListView.as_view()),
)
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-

# Copyright(C) 2012 Romain Bignon
#
# This file is part of weboob.
#
# weboob 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.
#
# weboob 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 weboob. If not, see <http://www.gnu.org/licenses/>.

from weboob.capabilities.bank import ICapBank, AccountNotFound
from weboob.tools.backend import BaseBackend, BackendConfig
from weboob.tools.ordereddict import OrderedDict
from weboob.tools.value import ValueBackendPassword, Value

from .browser import BanquePopulaire

__all__ = ['BanquePopulaireBackend']

class BanquePopulaireBackend(BaseBackend, ICapBank):
    NAME = 'banquepopulaire'
    MAINTAINER = u'Romain Bignon'
    EMAIL = 'romain@weboob.org'
    VERSION = '0.e'
    DESCRIPTION = u'Banque Populaire French bank website'
    LICENSE = 'AGPLv3+'
    website_choices = OrderedDict([(k, u'%s (%s)' % (v, k)) for k, v in sorted({
        'www.ibps.alpes.banquepopulaire.fr': u'Alpes',
        'www.ibps.alsace.banquepopulaire.fr': u'Alsace',
        'www.ibps.bpaca.banquepopulaire.fr': u'Aquitaine Centre atlantique',
        'www.ibps.atlantique.banquepopulaire.fr': u'Atlantique',
        'www.ibps.bpbfc.banquepopulaire.fr': u'Bourgogne-Franche Comté',
        'www.ibps.cotedazur.banquepopulaire.fr': u'Côte d\'azur',
        'www.ibps.loirelyonnais.banquepopulaire.fr': u'Loire et Lyonnais',
        'www.ibps.lorrainechampagne.banquepopulaire.fr': u'Lorraine Champagne',
        'www.ibps.massifcentral.banquepopulaire.fr': u'Massif central',
        'www.ibps.nord.banquepopulaire.fr': u'Nord',
        'www.ibps.occitane.banquepopulaire.fr': u'Occitane',
        'www.ibps.ouest.banquepopulaire.fr': u'Ouest',
        'www.ibps.provencecorse.banquepopulaire.fr': u'Provence et Corse',
        'www.ibps.rivesparis.banquepopulaire.fr': u'Rives de Paris',
        'www.ibps.sud.banquepopulaire.fr': u'Sud',
        'www.ibps.valdefrance.banquepopulaire.fr': u'Val de France',
        }.iteritems())])
    CONFIG = BackendConfig(Value('website',  label='Website to use', choices=website_choices),
                           ValueBackendPassword('login',    label='Account ID', masked=False),
                           ValueBackendPassword('password', label='Password'))
    BROWSER = BanquePopulaire

    def create_default_browser(self):
        return self.create_browser(self.config['website'].get(),
                                   self.config['login'].get(),
                                   self.config['password'].get())

    def iter_accounts(self):
        with self.browser:
            return self.browser.get_accounts_list()

    def get_account(self, _id):
        with self.browser:
            account = self.browser.get_account(_id)

        if account:
            return account
        else:
            raise AccountNotFound()

    def iter_history(self, account):
        with self.browser:
            return self.browser.get_history(account)
<commit_msg>add Credit Maritime regions compatibles with Banque Populaire<commit_after># -*- coding: utf-8 -*-

# Copyright(C) 2012 Romain Bignon
#
# This file is part of weboob.
#
# weboob 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.
#
# weboob 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 weboob. If not, see <http://www.gnu.org/licenses/>.

from weboob.capabilities.bank import ICapBank, AccountNotFound
from weboob.tools.backend import BaseBackend, BackendConfig
from weboob.tools.ordereddict import OrderedDict
from weboob.tools.value import ValueBackendPassword, Value

from .browser import BanquePopulaire

__all__ = ['BanquePopulaireBackend']

class BanquePopulaireBackend(BaseBackend, ICapBank):
    NAME = 'banquepopulaire'
    MAINTAINER = u'Romain Bignon'
    EMAIL = 'romain@weboob.org'
    VERSION = '0.e'
    DESCRIPTION = u'Banque Populaire French bank website'
    LICENSE = 'AGPLv3+'
    website_choices = OrderedDict([(k, u'%s (%s)' % (v, k)) for k, v in sorted({
        'www.ibps.alpes.banquepopulaire.fr': u'Alpes',
        'www.ibps.alsace.banquepopulaire.fr': u'Alsace',
        'www.ibps.bpaca.banquepopulaire.fr': u'Aquitaine Centre atlantique',
        'www.ibps.atlantique.banquepopulaire.fr': u'Atlantique',
        'www.ibps.bpbfc.banquepopulaire.fr': u'Bourgogne-Franche Comté',
        'www.ibps.bretagnenormandie.cmm.groupe.banquepopulaire.fr': u'Crédit Maritime Bretagne Normandie',
        'www.ibps.atlantique.creditmaritime.groupe.banquepopulaire.fr': u'Crédit Maritime Atlantique',
        'www.ibps.sudouest.creditmaritime.groupe.banquepopulaire.fr': u'Crédit Maritime du Littoral du Sud-Ouest',
        'www.ibps.cotedazur.banquepopulaire.fr': u'Côte d\'azur',
        'www.ibps.loirelyonnais.banquepopulaire.fr': u'Loire et Lyonnais',
        'www.ibps.lorrainechampagne.banquepopulaire.fr': u'Lorraine Champagne',
        'www.ibps.massifcentral.banquepopulaire.fr': u'Massif central',
        'www.ibps.nord.banquepopulaire.fr': u'Nord',
        'www.ibps.occitane.banquepopulaire.fr': u'Occitane',
        'www.ibps.ouest.banquepopulaire.fr': u'Ouest',
        'www.ibps.provencecorse.banquepopulaire.fr': u'Provence et Corse',
        'www.ibps.rivesparis.banquepopulaire.fr': u'Rives de Paris',
        'www.ibps.sud.banquepopulaire.fr': u'Sud',
        'www.ibps.valdefrance.banquepopulaire.fr': u'Val de France',
        }.iteritems())])
    CONFIG = BackendConfig(Value('website',  label='Website to use', choices=website_choices),
                           ValueBackendPassword('login',    label='Account ID', masked=False),
                           ValueBackendPassword('password', label='Password'))
    BROWSER = BanquePopulaire

    def create_default_browser(self):
        return self.create_browser(self.config['website'].get(),
                                   self.config['login'].get(),
                                   self.config['password'].get())

    def iter_accounts(self):
        with self.browser:
            return self.browser.get_accounts_list()

    def get_account(self, _id):
        with self.browser:
            account = self.browser.get_account(_id)

        if account:
            return account
        else:
            raise AccountNotFound()

    def iter_history(self, account):
        with self.browser:
            return self.browser.get_history(account)
<|endoftext|>