<commit_before>#!/usr/bin/env python

"""Insert artificial (fake) galaxies into the DECaLS imaging and reprocess
through The Tractor.

TODO:
* Model a mixture of object types.
"""
from __future__ import division, print_function

import os
import sys
import logging
import argparse
import numpy as np

import galsim
from astropy.io import fits

from projects.desi.common import *

# Global variables.
decals_dir = os.getenv('DECALS_DIR')
fake_decals_dir = os.getenv('FAKE_DECALS_DIR')

logging.basicConfig(format='%(message)s',level=logging.INFO,stream=sys.stdout)
log = logging.getLogger('decals_simulations')

def get_brickinfo(brickname=None):
    """Get info on this brick.

    """
    allbrickinfo = fits.getdata(os.path.join(decals_dir,'decals-bricks.fits'),1)
    brickinfo = allbrickinfo[np.where((allbrickinfo['brickname']==brickname)*1==1)]

    decals = Decals()
    wcs = wcs_for_brick(decals.get_brick_by_name(brickname))

    return brickinfo, wcs

def get_ccdinfo(brickwcs=None):
    """Get info on this brick and on the CCDs touching it.

    """
    allccdinfo =  fits.getdata(os.path.join(decals_dir,'decals-ccds-zeropoints.fits'))

    # Get all the CCDs that touch this brick
    decals = Decals()
    these = ccds_touching_wcs(brickwcs,decals.get_ccds())
    #ccdinfo = decals.ccds_touching_wcs(targetwcs)
    ccdinfo = allccdinfo[these]

    log.info('Got {} CCDs'.format(len(ccdinfo)))
    return ccdinfo

def build_priors(nobj=20,brickname=None,objtype='ELG',ra_range=None,
                 dec_range=None,seed=None):
    """Choose priors according to the type of object.  Will eventually generalize
       this so that a mixture of object types can be simulated.

    """

    from astropy.table import Table, Column
    rand = np.random.RandomState(seed=seed)

    # Assign central coordinates uniformly
    ra = rand.uniform(ra_range[0],ra_range[1],nobj)
    dec = rand.uniform(dec_range[0],dec_range[1],nobj)

    if objtype.upper()=='ELG':
        # Disk parameters
        disk_n_range = [1.0,1.0]
        disk_r50_range = [0.5,2.5]
        disk_ba_range = [0.2,1.0]

        disk_n = rand.uniform(disk_n_range[0],disk_n_range[1],nobj)
        disk_r50 = rand.uniform(disk_r50_range[0],disk_r50_range[1],nobj)
        disk_ba = rand.uniform(disk_ba_range[0],disk_ba_range[1],nobj)
        disk_phi = rand.uniform(0,180,nobj)

        ## Bulge parameters
        #bulge_r50_range = [0.1,1.0]
        #bulge_n_range = [3.0,5.0]
        #bdratio_range = [0.0,1.0] # bulge-to-disk ratio

        # Magnitudes and colors
        rmag_range = [18.0,24.0]
        gr_range = [-0.3,0.5]
        rz_range = [0.0,1.5]

        rmag = rand.uniform(rmag_range[0],rmag_range[1],nobj)
        gr = rand.uniform(gr_range[0],gr_range[1],nobj)
        rz = rand.uniform(rz_range[0],rz_range[1],nobj)

    # For convenience, also store the grz fluxes in nanomaggies.
    gflux = 1E9*10**(-0.4*(rmag+gr))
    rflux = 1E9*10**(-0.4*rmag)
    zflux = 1E9*10**(-0.4*(rmag-rz))

    # Pack into a Table.
    priors = Table()
    priors['ID'] = Column(np.arange(nobj,dtype='i4'))
    priors['RA'] = Column(ra,dtype='f8')
    priors['DEC'] = Column(dec,dtype='f8')
    priors['R'] = Column(rmag,dtype='f4')
    priors['GR'] = Column(gr,dtype='f4')
    priors['RZ'] = Column(rz,dtype='f4')
    priors['GFLUX'] = Column(gflux,dtype='f4')
    priors['RFLUX'] = Column(rflux,dtype='f4')
    priors['ZFLUX'] = Column(zflux,dtype='f4')
    priors['DISK_N'] = Column(disk_n,dtype='f4')
    priors['DISK_R50'] = Column(disk_r50,dtype='f4')
    priors['DISK_BA'] = Column(disk_ba,dtype='f4')
    priors['DISK_PHI'] = Column(disk_phi,dtype='f4')

    # Write out.
    outfile = os.path.join(fake_decals_dir,'priors_'+brickname+'.fits')
    log.info('Writing {}'.format(outfile))
    if os.path.isfile(outfile):
        os.remove(outfile)
    priors.write(outfile)

    return priors

def copyfiles(ccdinfo=None):
    """Copy the CP-processed images, inverse variance maps, and bad-pixel masks we
    need from DECALS_DIR to FAKE_DECALS_DIR, creating directories as necessary.

    """
    from distutils.file_util import copy_file

    allcpimage = ccdinfo['CPIMAGE']
    allcpdir = set([cpim.split('/')[1] for cpim in allcpimage])

    log.info('Creating directories...')
    for cpdir in list(allcpdir):
        outdir = os.path.join(fake_decals_dir,'images','decam',cpdir)
        if not os.path.isdir(outdir):
            log.info('   {}'.format(outdir))
            os.makedirs(outdir)

    log.info('Copying files...')
    for cpimage in list(set(allcpimage)):
        cpdir = cpimage.split('/')[1]
        indir = os.path.join(decals_dir,'images','decam',cpdir)
        outdir = os.path.join(fake_decals_dir,'images','decam',cpdir)

        imfile = cpimage.split('/')[2].split()[0]
        log.info('  {}'.format(imfile))
        copy_file(os.path.join(indir,imfile),os.path.join(outdir,imfile),update=0)

        imfile = imfile.replace('ooi','oow')
        #log.info('{}-->{}'.format(os.path.join(indir,imfile),os.path.join(outdir,imfile)))
        copy_file(os.path.join(indir,imfile),os.path.join(outdir,imfile),update=0)

        imfile = imfile.replace('oow','ood')
        #log.info('{}-->{}'.format(os.path.join(indir,imfile),os.path.join(outdir,imfile)))
        copy_file(os.path.join(indir,imfile),os.path.join(outdir,imfile),update=0)

class simobj_info():
    from tractor import psfex
    def __init__(self,ccdinfo):
        """Access everything we need about an individual CCD.

        """
        self.cpimage = ccdinfo['CPIMAGE']
        self.cpimage_hdu = ccdinfo['CPIMAGE_HDU']
        self.calname = ccdinfo['CALNAME']
        self.filter = ccdinfo['FILTER']
        self.imfile = os.path.join(fake_decals_dir,'images',self.cpimage)
        self.ivarfile = self.imfile.replace('ooi','oow')
        self.wcsfile = os.path.join(decals_dir,'calib','decam',
                                    'astrom-pv',self.calname+'.wcs.fits')
        self.psffile = os.path.join(decals_dir,'calib','decam',
                                    'psfex',self.calname+'.fits')
        self.magzpt = float(ccdinfo['CCDZPT'] + 2.5*np.log10(ccdinfo['EXPTIME']))
        self.gain = float(ccdinfo['ARAWGAIN']) # [electron/ADU]

    def getdata(self):
        """Read the CCD image and inverse variance data, and the corresponding headers.

        """
        #log.info('Reading extension {} of image {}'.format(self.ccdnum,self.imfile))
        image = galsim.fits.read(self.imfile,hdu=self.cpimage_hdu)       # [ADU]
        invvar = galsim.fits.read(self.ivarfile,hdu=self.cpimage_hdu) # [1/ADU^2]

        imhdr = galsim.fits.FitsHeader(self.imfile,hdu=self.cpimage_hdu)
        ivarhdr = galsim.fits.FitsHeader(self.ivarfile,hdu=self.cpimage_hdu)

        self.width = image.xmax
        self.height = image.ymax

        return image, invvar, imhdr, ivarhdr

    def getwcs(self):
        """Read the global WCS for this CCD."""
        wcs, origin = galsim.wcs.readFromFitsHeader(
            galsim.fits.FitsHeader(self.wcsfile))
        self.wcs = wcs

        return wcs

    def getpsf(self):
        """Read the PSF for this CCD."""
        from tractor.basics import GaussianMixtureEllipsePSF
        psf = psfex.PsfEx(self.psffile,self.width,self.height,ny=13,nx=7,
                          psfClass=GaussianMixtureEllipsePSF,K=2)
        self.psf = psf

        return psf

    def getlocalwcs(self,image_pos=None):
        """Get the local WCS, given a position."""
        localwcs = self.wcs.local(image_pos=image_pos)
        pixscale, shear, theta, flip = localwcs.getDecomposition() # get the pixel scale

        return localwcs, pixscale

    def getlocalpsf(self,image_pos=None,pixscale=0.262):
        """Get the local PSF, given a position.  Need to recentroid because this is a
        PSFeX PSF."""
        xpos = int(image_pos.x)
        ypos = int(image_pos.y)
        psfim = PsfEx.instantiateAt(self.psf,xpos,ypos)[5:-5,5:-5] # trim
        psf = galsim.InterpolatedImage(galsim.Image(psfim),scale=pixscale,flux=1.0)
        psf_centroid = psf.centroid()
        psf = psf.shift(-psf_centroid.x,-psf_centroid.y)

        return psf

    def getobjflux(self,objinfo):
        """Calculate the flux of a given object in ADU."""
        flux = objinfo[self.filter.upper()+'FLUX']
        flux *= 10**(0.4*(self.magzpt-22.5)) # [ADU]

        return float(flux)

def insert_simobj(gsparams=None,priors=None,ccdinfo=None):
    """Simulate objects and place them into individual CCDs.

    """
    stampwidth = 45 # postage stamp width [pixels, roughly 14 arcsec]
    stampbounds = galsim.BoundsI(-stampwidth,stampwidth,-stampwidth,stampwidth)
    imagebounds = galsim.BoundsI(0,2046,0,4094)

    band = np.array(['g','r','z'])

    # Calculate the g, r, and z band fluxes and stack them in an array.
    #flux = np.vstack([gflux,rflux,zflux])

    for ccd in ccdinfo:
        # Gather some basic info on this CCD and then read the data, the WCS
        # info, and initialize the PSF.
        siminfo = simobj_info(ccd)
        wcs = siminfo.getwcs()

        # Loop on each object and figure out which, if any, objects will be
        # placed on this CCD.
        onccd = []
        for iobj, objinfo in enumerate(priors):
            pos = wcs.toImage(galsim.CelestialCoord(objinfo['RA']*galsim.degrees,
                objinfo['DEC']*galsim.degrees))
            stampbounds1 = stampbounds.shift(galsim.PositionI(int(pos.x),int(pos.y)))

            overlap = stampbounds1 & imagebounds
            #if iobj<5:
            #    print(iobj, pos, stampbounds1, imagebounds, overlap)
            if (overlap.xmax>=0 and overlap.ymax>=0 and overlap.xmin<=imagebounds.xmax and
                overlap.ymin<=imagebounds.ymax and overlap.area()>0):
                onccd.append(iobj)

        nobj = len(onccd)
        if nobj>0:
            log.info('Adding {} objects to CCD {}'.format(nobj,siminfo.cpimage_hdu))

            image, invvar, imhdr, ivarhdr = siminfo.getdata()
            initpsf = siminfo.getpsf()

            for iobj in range(nobj):
                objinfo = priors[onccd[iobj]]
                pos = wcs.toImage(galsim.CelestialCoord(objinfo['RA']*galsim.degrees,
                                                        objinfo['DEC']*galsim.degrees))

                xpos = int(pos.x)
                ypos = int(pos.y)
                offset = galsim.PositionD(pos.x-xpos,pos.y-ypos)

                # Get the WCS and PSF at the center of the stamp and the integrated
                # flux of the object (in the appropriate band).
                localwcs, pixscale = siminfo.getlocalwcs(image_pos=pos)
                localpsf = siminfo.getlocalpsf(image_pos=pos,pixscale=pixscale)
                objflux = siminfo.getobjflux(objinfo)

                # Finally build the object.
                obj = galsim.Sersic(float(objinfo['DISK_N']),half_light_radius=
                                    float(objinfo['DISK_R50']),
                                    flux=objflux,gsparams=gsparams)
                obj = obj.shear(q=float(objinfo['DISK_BA']),beta=
                                float(objinfo['DISK_PHI'])*galsim.degrees)
                obj = galsim.Convolve([obj,localpsf])

                stamp = obj.drawImage(offset=offset,wcs=localwcs,method='no_pixel')
                stamp.setCenter(xpos,ypos)

                overlap = stamp.bounds & image.bounds
                if (overlap.xmax>=0 and overlap.ymax>=0 and overlap.xmin<=image.bounds.xmax and
                    overlap.ymin<=image.bounds.ymax and overlap.area()>0):
                    print(iobj, pos, stamp.bounds, image.bounds, overlap)
                    stamp = stamp[overlap]

                    # Add Poisson noise
                    varstamp = invvar[overlap].copy() # [1/ADU^2]
                    varstamp.invertSelf()             # [ADU^2]
                    medvar = np.median(varstamp.array[varstamp.array>0])
                    varstamp.array[varstamp.array<(0.2*medvar)] = medvar

                    # Convert to electrons
                    stamp *= siminfo.gain         # [electron]
                    varstamp *= (siminfo.gain**2) # [electron^2]

                    stamp.addNoise(galsim.VariableGaussianNoise(galsim.BaseDeviate(),varstamp))
                    varstamp += stamp

                    stamp /= siminfo.gain          # [ADU]
                    varstamp /= (siminfo.gain**2)  # [ADU^2]
                    varstamp.invertSelf()          # [1/ADU^2]

                    image[overlap] += stamp
                    invvar[overlap] = varstamp

            # Write out.
            log.info('Writing extension {} of image {}'.format(siminfo.cpimage_hdu,
                                                               siminfo.imfile))
            fits.update(siminfo.imfile,image.array,ext=siminfo.cpimage_hdu,
                        header=fits.Header(imhdr.items()))
            fits.update(siminfo.ivarfile,invvar.array,ext=siminfo.cpimage_hdu,
                        header=fits.Header(ivarhdr.items()))

def main():

    parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter,
                                     description='DECaLS simulations.')
    parser.add_argument('-n', '--nobj', type=long, default=None, metavar='',
                        help='number of objects to simulate (required input)')
    parser.add_argument('-b', '--brick', type=str, default='2428p117', metavar='',
                        help='simulate objects in this brick')
    parser.add_argument('-o', '--objtype', type=str, default='ELG', metavar='',
                        help='object type (ELG, LRG, PSF, MIX)')
    parser.add_argument('-s', '--seed', type=long, default=None, metavar='',
                        help='random number seed')
    parser.add_argument('--zoom', nargs=4, type=int, metavar='',
                        help='see runbrick.py (default is to populate the full brick)')
    parser.add_argument('--no-qaplots', action='store_true',
                        help='do not generate QAplots')

    args = parser.parse_args()
    if args.nobj is None:
        parser.print_help()
        sys.exit(1)

    objtype = args.objtype.upper()
    nobj = args.nobj
    brickname = args.brick

    log.info('Working on brick {}'.format(brickname))
    log.info('Simulating {} objects of objtype={}'.format(nobj,objtype))

    # Get the brick info and corresponding WCS
    brickinfo, brickwcs = get_brickinfo(brickname)

    if args.zoom is None:
        ra_range = [brickinfo['ra1'],brickinfo['ra2']]
        dec_range = [brickinfo['dec1'],brickinfo['dec2']]
    else:
        pixscale = 0.262/3600.0 # average pixel scale [deg/pixel]
        zoom = args.zoom
        dx = zoom[1]-zoom[0]
        dy = zoom[3]-zoom[2]

        ra, dec = brickwcs.pixelxy2radec(zoom[0]+dx/2,zoom[2]+dy/2)
        ra_range = [ra-dx*pixscale/2,ra+dx*pixscale/2]
        dec_range = [dec-dy*pixscale/2,dec+dy*pixscale/2]

        brickwcs = brickwcs.get_subimage(zoom[0],zoom[2],dx,dy)

    # Get the CCDs in the region of interest.
    ccdinfo = get_ccdinfo(brickwcs)

    log.info('RA range: {:.6f} to {:.6f}'.format(float(ra_range[0]),float(ra_range[1])))
    log.info('DEC range: {:.6f} to {:.6f}'.format(float(dec_range[0]),float(dec_range[1])))

    # Build the prior parameters and make some QAplots.
    log.info('Building the PRIORS table.')
    priors = build_priors(nobj,brickname,objtype,ra_range,dec_range,
                          seed=args.seed)

    # Write out some QAplots
    if args.no_qaplots is False:
        import matplotlib.pyplot as plt
        import matplotlib.cm as cm
        from matplotlib.patches import Rectangle

        color = iter(cm.rainbow(np.linspace(0,1,len(ccdinfo))))

        fig = plt.figure()
        ax = fig.gca()
        ax.get_xaxis().get_major_formatter().set_useOffset(False)
        ax.plot(priors['RA'],priors['DEC'],'gs',markersize=3)
        for ii, ccd in enumerate(ccdinfo):
            dy = ccd['WIDTH']*0.262/3600.0
            dx = ccd['HEIGHT']*0.262/3600.0
            rect = plt.Rectangle((ccd['RA']-dx/2,ccd['DEC']-dy/2),
                                 dx,dy,fill=False,lw=1,color=next(color),
                                 ls='solid')
            ax.add_patch(rect)
            rect = plt.Rectangle((brickinfo['RA1'],brickinfo['DEC1']),
                                 brickinfo['RA2']-brickinfo['RA1'],
                         brickinfo['DEC2']-brickinfo['DEC1'],fill=False,lw=3,
                                 color='b')
        ax.add_patch(rect)
        #ax.set_xlim(np.array([brickinfo['RA1'][0],brickinfo['RA2'][0]])*[0.9999,1.0001])
        ax.set_xlim(np.array([brickinfo['RA2'][0],brickinfo['RA1'][0]])*[1.0001,0.9999])
        ax.set_ylim(np.array([brickinfo['DEC1'][0],brickinfo['DEC2'][0]])*[0.99,1.01])
        ax.set_xlabel('$RA\ (deg)$',fontsize=18)
        ax.set_ylabel('$Dec\ (deg)$',fontsize=18)
        qafile = os.path.join(fake_decals_dir,'qa_'+brickname+'.pdf')

        log.info('Writing QAplot {}'.format(qafile))
        fig.savefig(qafile)

    # Copy the files we need.
    copyfiles(ccdinfo)

    # Do the simulation!
    gsparams = galsim.GSParams(maximum_fft_size=2L**30L)
    insert_simobj(gsparams=gsparams,priors=priors,ccdinfo=ccdinfo)

# python $TRACTOR_DIR/projects/desi/runbrick.py --stage image_coadds --no-write --threads 8 --gpsf --radec 242.845 11.75 --width 500 --height 500
# python decals_simulations.py -n 10 --zoom 1750 1850 1750 1850

if __name__ == "__main__":
    main()
<commit_msg>cleaned up<commit_after><|endoftext|>


<commit_before>from .grammars import *  # @UnusedWildImport
from .parsing import *  # @UnusedWildImport

__all__ = ['GrakoParser', 'GrakoGrammarGenerator']

class GrakoParserBase(Parser):

    def __init__(self, grammar_name, text, whitespace=None, comments_re=None, ignorecase=False):
        super(GrakoParserBase, self).__init__(text, whitespace=None, comments_re=None, ignorecase=False)
        self.grammar_name = grammar_name

    def parse(self, rule='grammar'):
        return super(GrakoParserBase, self).parse(rule)[rule][0]

    def _void_(self):
        self._token('()', 'void')

    def _token_(self):
        p = self._pos
        try:
            self._token("'")
            self._pattern(r"(?:[^'\\]|\\')*", 'token')
            self._token("'")
            return
        except FailedCut as e:
            raise e.nested
        except FailedParse:
            pass
        self._goto(p)
        try:
            self._token('"')
            self._pattern(r'(?:[^"\\]|\\")*', 'token')
            self._token('"')
            return
        except FailedCut as e:
            raise e.nested
        except FailedParse:
            pass
        self._goto(p)
        raise FailedParse(self._buffer, '<"> or' + "<'>")

    def _word_(self):
        self._pattern(r'[A-Za-z0-9_]+', 'word')

    def _call_(self):
        self._call('word', 'call')

    def _pattern_(self):
        self._token('?/')
        self._pattern(r'(.*?)(?=/\?)', 'pattern')
        self._token('/?')

    def _cut_(self):
        self._token('!', 'cut')

    def _subexp_(self):
        self._token('(')
        self._call('expre', 'exp')
        self._token(')')

    def _optional_(self):
        self._token('[')
        self._call('expre', 'optional')
        self._token(']')

    def _plus_(self):
        if not self._try('-', 'symbol'):
            self._token('+', 'symbol')

    def _repeat_(self):
        self._token('{')
        self._call('expre', 'repeat')
        self._token('}')
        try:
            self._call('plus', 'plus')
        except FailedParse:
            pass

    def _special_(self):
        self._token('?(')
        self._pattern(r'(.*)\)?', 'special')

    def _atom_(self):
        p = self._pos
        try:
            self._call('void', 'atom')
            return
        except FailedCut as e:
            raise e.nested
        except FailedParse:
            pass
        self._goto(p)
        try:
            self._call('cut', 'atom')
            return
        except FailedCut as e:
            raise e.nested
        except FailedParse:
            pass
        self._goto(p)
        try:
            self._call('token', 'atom')
            return
        except FailedCut as e:
            raise e.nested
        except FailedParse:
            pass
        self._goto(p)
        try:
            self._call('call', 'atom')
            return
        except FailedCut as e:
            raise e.nested
        except FailedParse:
            pass
        self._goto(p)
        try:
            self._call('pattern', 'atom')
            return
        except FailedCut as e:
            raise e.nested
        except FailedParse:
            pass
        self._goto(p)
        raise FailedParse(self._buffer, 'atom')

    def _term_(self):
        p = self._pos
        try:
            self._call('atom', 'term')
            return
        except FailedCut as e:
            raise e.nested
        except FailedParse:
            pass
        self._goto(p)
        try:
            self._call('subexp', 'term')
            return
        except FailedCut as e:
            raise e.nested
        except FailedParse:
            pass
        self._goto(p)
        try:
            self._call('repeat', 'term')
            return
        except FailedCut as e:
            raise e.nested
        except FailedParse:
            pass
        self._goto(p)
        try:
            self._call('optional', 'term')
            return
        except FailedCut as e:
            raise e.nested
        except FailedParse:
            pass
        self._goto(p)
        try:
            self._call('special', 'term')
            return
        except FailedCut as e:
            raise e.nested
        except FailedParse:
            pass
        self._goto(p)
        raise FailedParse(self._buffer, 'term')

    def _named_(self):
        self._call('word', 'name')
        self._token(':')
        try:
            self._call('term', 'value')
            return
        except FailedParse as e:
            raise FailedCut(self._buffer, e)

    def _element_(self):
        p = self._pos
        try:
            self._call('named', 'element')
            return
        except FailedCut as e:
            raise e.nested
        except FailedParse:
            pass
        self._goto(p)
        try:
            self._call('term', 'element')
            return
        except FailedCut as e:
            raise e.nested
        except FailedParse:
            pass
        self._goto(p)
        raise FailedParse(self._buffer, 'element')

    def _sequence_(self):
#        p = self._pos
#        try:
#            self._call('element', 'sequence')
#        except FailedParse:
#            self._goto(p)
#            raise
        while True:
            p = self._pos
            try:
                self._call('element', 'sequence')
            except FailedCut:
                self._goto(p)
                raise
            except FailedParse:
                self._goto(p)
                break

    def _choice_(self):
        self._call('sequence', 'options')
        while True:
            p = self._pos
            try:
                self._token('|')
                self._call('sequence', 'options')
            except FailedCut as e:
                self._goto(p)
                raise e.nested
            except FailedParse:
                self._goto(p)
                break

    def _expre_(self):
        self._call('choice', 'expre')

    def _rule_(self):
        self._call('word', 'name')
        self._token('=')
        self._call('expre', 'rhs')
        if not self._try(';'):
            self._token('.')

    def _grammar_(self):
        self._call('rule', 'rules')
        while True:
            p = self._pos
            try:
                self._call('rule', 'rules')
            except FailedParse:
                self._goto(p)
                break
        self._next_token()
        self._eof()

class AbstractGrakoParser(GrakoParserBase):
    def token(self, ast):
        return ast

    def word(self, ast):
        return ast

    def pattern(self, ast):
        return ast

    def cut(self, ast):
        return ast

    def subexp(self, ast):
        return ast

    def optional(self, ast):
        return ast

    def repeat(self, ast):
        return ast

    def special(self, ast):
        return ast

    def atom(self, ast):
        return ast

    def term(self, ast):
        return ast.term

    def named(self, ast):
        return ast

    def element(self, ast):
        return ast

    def sequence(self, ast):
        return ast

    def choice(self, ast):
        return ast

    def expre(self, ast):
        return ast

    def rule(self, ast):
        return ast

    def grammar(self, ast):
        return ast

class GrakoParser(AbstractGrakoParser):

    def token(self, ast):
        return ast

    def word(self, ast):
        return ast

    def call(self, ast):
        return ast

    def pattern(self, ast):
        return ast

    def cut(self, ast):
        return ast

    def subexp(self, ast):
        return simplify(ast.exp)

    def optional(self, ast):
        return ast

    def plus(self, ast):
        return ast

    def repeat(self, ast):
        return ast

    def special(self, ast):
        return ast

    def atom(self, ast):
        return simplify(ast.atom[0])

    def term(self, ast):
        return simplify(ast.term[0])

    def named(self, ast):
        return ast

    def element(self, ast):
        return simplify(ast.element)

    def sequence(self, ast):
        return simplify(ast.sequence)

    def choice(self, ast):
        if len(ast.options) == 1:
            return simplify(ast.options)
        return ast

    def expre(self, ast):
        return simplify(ast.expre)

    def rule(self, ast):
        return ast

    def grammar(self, ast):
        return ast

class GrakoGrammarGenerator(AbstractGrakoParser):
    def token(self, ast):
        return TokenGrammar(ast.token[0])

    def word(self, ast):
        return ast.word[0]

    def call(self, ast):
        return RuleRefGrammar(ast.call[0])

    def pattern(self, ast):
        return PatternGrammar(ast.pattern[0])

    def cut(self, ast):
        return CutGrammar()

    def subexp(self, ast):
        return GroupGrammar(ast.exp[0])

    def optional(self, ast):
        return OptionalGrammar(ast.optional[0])

    def plus(self, ast):
        return ast

    def repeat(self, ast):
        if 'plus' in ast:
            return RepeatOneGrammar(ast.repeat[0])
        return RepeatGrammar(ast.repeat[0])

    def special(self, ast):
        return SpecialGrammar(ast.special[0])

    def atom(self, ast):
        return ast.atom[0]

    def term(self, ast):
        return ast.term[0]

    def named(self, ast):
        return NamedGrammar(ast.name[0], ast.value[0])

    def element(self, ast):
        return ast.element[0]

    def sequence(self, ast):
        if len(ast.sequence) == 1:
            return simplify(ast.sequence)
        return SequenceGrammar(ast.sequence)

    def choice(self, ast):
        if len(ast.options) == 1:
            return ast.options[0]
        return ChoiceGrammar(ast.options)

    def expre(self, ast):
        return ast.expre[0]

    def rule(self, ast):
        return RuleGrammar(ast.name[0], ast.rhs[0])

    def grammar(self, ast):
        return Grammar(self.grammar_name, ast.rules)

<commit_msg>EBNF may reuse a rule name meaning that the different instances are different options.<commit_after>from .grammars import *  # @UnusedWildImport
from .parsing import *  # @UnusedWildImport

__all__ = ['GrakoParser', 'GrakoGrammarGenerator']

class GrakoParserBase(Parser):

    def __init__(self, grammar_name, text, whitespace=None, comments_re=None, ignorecase=False):
        super(GrakoParserBase, self).__init__(text, whitespace=None, comments_re=None, ignorecase=False)
        self.grammar_name = grammar_name

    def parse(self, rule='grammar'):
        return super(GrakoParserBase, self).parse(rule)[rule][0]

    def _void_(self):
        self._token('()', 'void')

    def _token_(self):
        p = self._pos
        try:
            self._token("'")
            self._pattern(r"(?:[^'\\]|\\')*", 'token')
            self._token("'")
            return
        except FailedCut as e:
            raise e.nested
        except FailedParse:
            pass
        self._goto(p)
        try:
            self._token('"')
            self._pattern(r'(?:[^"\\]|\\")*', 'token')
            self._token('"')
            return
        except FailedCut as e:
            raise e.nested
        except FailedParse:
            pass
        self._goto(p)
        raise FailedParse(self._buffer, '<"> or' + "<'>")

    def _word_(self):
        self._pattern(r'[A-Za-z0-9_]+', 'word')

    def _call_(self):
        self._call('word', 'call')

    def _pattern_(self):
        self._token('?/')
        self._pattern(r'(.*?)(?=/\?)', 'pattern')
        self._token('/?')

    def _cut_(self):
        self._token('!', 'cut')

    def _subexp_(self):
        self._token('(')
        self._call('expre', 'exp')
        self._token(')')

    def _optional_(self):
        self._token('[')
        self._call('expre', 'optional')
        self._token(']')

    def _plus_(self):
        if not self._try('-', 'symbol'):
            self._token('+', 'symbol')

    def _repeat_(self):
        self._token('{')
        self._call('expre', 'repeat')
        self._token('}')
        try:
            self._call('plus', 'plus')
        except FailedParse:
            pass

    def _special_(self):
        self._token('?(')
        self._pattern(r'(.*)\)?', 'special')

    def _atom_(self):
        p = self._pos
        try:
            self._call('void', 'atom')
            return
        except FailedCut as e:
            raise e.nested
        except FailedParse:
            pass
        self._goto(p)
        try:
            self._call('cut', 'atom')
            return
        except FailedCut as e:
            raise e.nested
        except FailedParse:
            pass
        self._goto(p)
        try:
            self._call('token', 'atom')
            return
        except FailedCut as e:
            raise e.nested
        except FailedParse:
            pass
        self._goto(p)
        try:
            self._call('call', 'atom')
            return
        except FailedCut as e:
            raise e.nested
        except FailedParse:
            pass
        self._goto(p)
        try:
            self._call('pattern', 'atom')
            return
        except FailedCut as e:
            raise e.nested
        except FailedParse:
            pass
        self._goto(p)
        raise FailedParse(self._buffer, 'atom')

    def _term_(self):
        p = self._pos
        try:
            self._call('atom', 'term')
            return
        except FailedCut as e:
            raise e.nested
        except FailedParse:
            pass
        self._goto(p)
        try:
            self._call('subexp', 'term')
            return
        except FailedCut as e:
            raise e.nested
        except FailedParse:
            pass
        self._goto(p)
        try:
            self._call('repeat', 'term')
            return
        except FailedCut as e:
            raise e.nested
        except FailedParse:
            pass
        self._goto(p)
        try:
            self._call('optional', 'term')
            return
        except FailedCut as e:
            raise e.nested
        except FailedParse:
            pass
        self._goto(p)
        try:
            self._call('special', 'term')
            return
        except FailedCut as e:
            raise e.nested
        except FailedParse:
            pass
        self._goto(p)
        raise FailedParse(self._buffer, 'term')

    def _named_(self):
        self._call('word', 'name')
        self._token(':')
        try:
            self._call('term', 'value')
            return
        except FailedParse as e:
            raise FailedCut(self._buffer, e)

    def _element_(self):
        p = self._pos
        try:
            self._call('named', 'element')
            return
        except FailedCut as e:
            raise e.nested
        except FailedParse:
            pass
        self._goto(p)
        try:
            self._call('term', 'element')
            return
        except FailedCut as e:
            raise e.nested
        except FailedParse:
            pass
        self._goto(p)
        raise FailedParse(self._buffer, 'element')

    def _sequence_(self):
#        p = self._pos
#        try:
#            self._call('element', 'sequence')
#        except FailedParse:
#            self._goto(p)
#            raise
        while True:
            p = self._pos
            try:
                self._call('element', 'sequence')
            except FailedCut:
                self._goto(p)
                raise
            except FailedParse:
                self._goto(p)
                break

    def _choice_(self):
        self._call('sequence', 'options')
        while True:
            p = self._pos
            try:
                self._token('|')
                self._call('sequence', 'options')
            except FailedCut as e:
                self._goto(p)
                raise e.nested
            except FailedParse:
                self._goto(p)
                break

    def _expre_(self):
        self._call('choice', 'expre')

    def _rule_(self):
        self._call('word', 'name')
        self._token('=')
        self._call('expre', 'rhs')
        if not self._try(';'):
            self._token('.')

    def _grammar_(self):
        self._call('rule', 'rules')
        while True:
            p = self._pos
            try:
                self._call('rule', 'rules')
            except FailedParse:
                self._goto(p)
                break
        self._next_token()
        self._eof()

class AbstractGrakoParser(GrakoParserBase):
    def token(self, ast):
        return ast

    def word(self, ast):
        return ast

    def pattern(self, ast):
        return ast

    def cut(self, ast):
        return ast

    def subexp(self, ast):
        return ast

    def optional(self, ast):
        return ast

    def repeat(self, ast):
        return ast

    def special(self, ast):
        return ast

    def atom(self, ast):
        return ast

    def term(self, ast):
        return ast.term

    def named(self, ast):
        return ast

    def element(self, ast):
        return ast

    def sequence(self, ast):
        return ast

    def choice(self, ast):
        return ast

    def expre(self, ast):
        return ast

    def rule(self, ast):
        return ast

    def grammar(self, ast):
        return ast

class GrakoParser(AbstractGrakoParser):

    def token(self, ast):
        return ast

    def word(self, ast):
        return ast

    def call(self, ast):
        return ast

    def pattern(self, ast):
        return ast

    def cut(self, ast):
        return ast

    def subexp(self, ast):
        return simplify(ast.exp)

    def optional(self, ast):
        return ast

    def plus(self, ast):
        return ast

    def repeat(self, ast):
        return ast

    def special(self, ast):
        return ast

    def atom(self, ast):
        return simplify(ast.atom[0])

    def term(self, ast):
        return simplify(ast.term[0])

    def named(self, ast):
        return ast

    def element(self, ast):
        return simplify(ast.element)

    def sequence(self, ast):
        return simplify(ast.sequence)

    def choice(self, ast):
        if len(ast.options) == 1:
            return simplify(ast.options)
        return ast

    def expre(self, ast):
        return simplify(ast.expre)

    def rule(self, ast):
        return ast

    def grammar(self, ast):
        return ast

class GrakoGrammarGenerator(AbstractGrakoParser):

    def __init__(self, grammar_name, text, whitespace=None, comments_re=None, ignorecase=False):
        super(GrakoGrammarGenerator, self).__init__(grammar_name, text, whitespace, comments_re, ignorecase)
        self.rules = {}

    def token(self, ast):
        return TokenGrammar(ast.token[0])

    def word(self, ast):
        return ast.word[0]

    def call(self, ast):
        return RuleRefGrammar(ast.call[0])

    def pattern(self, ast):
        return PatternGrammar(ast.pattern[0])

    def cut(self, ast):
        return CutGrammar()

    def subexp(self, ast):
        return GroupGrammar(ast.exp[0])

    def optional(self, ast):
        return OptionalGrammar(ast.optional[0])

    def plus(self, ast):
        return ast

    def repeat(self, ast):
        if 'plus' in ast:
            return RepeatOneGrammar(ast.repeat[0])
        return RepeatGrammar(ast.repeat[0])

    def special(self, ast):
        return SpecialGrammar(ast.special[0])

    def atom(self, ast):
        return ast.atom[0]

    def term(self, ast):
        return ast.term[0]

    def named(self, ast):
        return NamedGrammar(ast.name[0], ast.value[0])

    def element(self, ast):
        return ast.element[0]

    def sequence(self, ast):
        if len(ast.sequence) == 1:
            return simplify(ast.sequence)
        return SequenceGrammar(ast.sequence)

    def choice(self, ast):
        if len(ast.options) == 1:
            return ast.options[0]
        return ChoiceGrammar(ast.options)

    def expre(self, ast):
        return ast.expre[0]

    def rule(self, ast):
        name = ast.name[0]
        rhs = ast.rhs[0]
        if not name in self.rules:
            rule = RuleGrammar(name, rhs)
            self.rules[name] = rule
        else:
            rule = self.rules[name]
            if isinstance(rule.exp, ChoiceGrammar):
                rule.exp.options.append(rhs)
            else:
                rule.exp = ChoiceGrammar([rule.exp, rhs])
        return rule

    def grammar(self, ast):
        return Grammar(self.grammar_name, ast.rules)

<|endoftext|>


<commit_before>"""

"""
import subprocess
import psycopg2
import datetime
import pytz
MESOSITE = psycopg2.connect(database='other', host='iemdb')
mcursor = MESOSITE.cursor()

now = datetime.datetime.now()

# Do the bubbler file
mcursor.execute("""SELECT max(valid) from ss_bubbler""")
row = mcursor.fetchone()
maxts = None if row[0] is None else datetime.datetime.strptime(
                    row[0].strftime('%m/%d/%y %H:%M:%S'), '%m/%d/%y %H:%M:%S')

for line in open('/mnt/rootdocs/Bubbler.csv'):
    tokens = line.strip().split(",")
    if len(tokens) < 2 or line[0] in ['S','G'] or len(line) > 300:
        print line
        continue
    try:
        ts = datetime.datetime.strptime("%s %s" % (tokens[0], tokens[1]),
                                    '%m/%d/%Y %H:%M:%S')
    except Exception, exp:
        print exp
        print repr(line)
        continue
    if maxts and ts < maxts:
        continue
    if len(tokens) == 3:
        tokens.append( None )
    if len(tokens) == 4:
        tokens.append( None )
    mcursor.execute("""INSERT into ss_bubbler values (%s, %s, %s, %s)""" ,
                    (ts, tokens[2], tokens[3], tokens[4]))

# Do the STS_GOLD file
maxts = {}
mcursor.execute("""SELECT max(valid), site_serial from ss_logger_data
    GROUP by site_serial""")
for row in mcursor:
    maxts[ row[1] ] = datetime.datetime.strptime(row[0].strftime('%m/%d/%y %H:%M:%S'), '%m/%d/%y %H:%M:%S')

proc = subprocess.Popen("echo 'select * from logger_data' | mdb-sql -p /mnt/sts_gold/sts_gold.mdb",
                        shell=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE)

data = proc.stdout.read()
for linenum, line in enumerate(data.split("\n")):
    tokens = line.split("\t")
    if len(tokens) < 13 or linenum < 2:
        continue
    site_serial = int(tokens[1])
    ts = datetime.datetime.strptime(tokens[2], '%m/%d/%y %H:%M:%S')
    if ts > now:
        continue
    if maxts.get(site_serial) and ts < maxts.get(site_serial):
        continue
    mcursor.execute("""INSERT into ss_logger_data values (%s, %s, %s, %s, %s,
    %s, %s, %s, %s, %s,
    %s, %s, %s, %s, %s)""", tokens)
    # This won't work, sadly
    #ts = ts.replace(tzinfo=pytz.timezone("America/Chicago"))

mcursor.close()
MESOSITE.commit()
MESOSITE.close()<commit_msg>remove debug statement<commit_after>"""

"""
import subprocess
import psycopg2
import datetime
import pytz
MESOSITE = psycopg2.connect(database='other', host='iemdb')
mcursor = MESOSITE.cursor()

now = datetime.datetime.now()

# Do the bubbler file
mcursor.execute("""SELECT max(valid) from ss_bubbler""")
row = mcursor.fetchone()
maxts = None if row[0] is None else datetime.datetime.strptime(
                    row[0].strftime('%m/%d/%y %H:%M:%S'), '%m/%d/%y %H:%M:%S')

for line in open('/mnt/rootdocs/Bubbler.csv'):
    tokens = line.strip().split(",")
    if len(tokens) < 2 or line[0] in ['S','G'] or len(line) > 300:
        continue
    try:
        ts = datetime.datetime.strptime("%s %s" % (tokens[0], tokens[1]),
                                    '%m/%d/%Y %H:%M:%S')
    except Exception, exp:
        print exp
        print repr(line)
        continue
    if maxts and ts < maxts:
        continue
    if len(tokens) == 3:
        tokens.append( None )
    if len(tokens) == 4:
        tokens.append( None )
    mcursor.execute("""INSERT into ss_bubbler values (%s, %s, %s, %s)""" ,
                    (ts, tokens[2], tokens[3], tokens[4]))

# Do the STS_GOLD file
maxts = {}
mcursor.execute("""SELECT max(valid), site_serial from ss_logger_data
    GROUP by site_serial""")
for row in mcursor:
    maxts[ row[1] ] = datetime.datetime.strptime(row[0].strftime('%m/%d/%y %H:%M:%S'), '%m/%d/%y %H:%M:%S')

proc = subprocess.Popen("echo 'select * from logger_data' | mdb-sql -p /mnt/sts_gold/sts_gold.mdb",
                        shell=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE)

data = proc.stdout.read()
for linenum, line in enumerate(data.split("\n")):
    tokens = line.split("\t")
    if len(tokens) < 13 or linenum < 2:
        continue
    site_serial = int(tokens[1])
    ts = datetime.datetime.strptime(tokens[2], '%m/%d/%y %H:%M:%S')
    if ts > now:
        continue
    if maxts.get(site_serial) and ts < maxts.get(site_serial):
        continue
    mcursor.execute("""INSERT into ss_logger_data values (%s, %s, %s, %s, %s,
    %s, %s, %s, %s, %s,
    %s, %s, %s, %s, %s)""", tokens)
    # This won't work, sadly
    #ts = ts.replace(tzinfo=pytz.timezone("America/Chicago"))

mcursor.close()
MESOSITE.commit()
MESOSITE.close()<|endoftext|>


<commit_before>import allauth
import django
from django.views import generic

import core
import utils
from core.views import base
from features.associations import models as associations
from . import forms, models

class Detail(
        core.views.PermissionMixin, django.views.generic.list.MultipleObjectMixin,
        django.views.generic.DetailView):
    permission_required = 'gestalten.view'
    model = models.Gestalt
    paginate_by = 10
    template_name = 'gestalten/detail.html'

    def get_context_data(self, **kwargs):
        associations = self.object.associations.ordered_user_content(self.request.user)
        return super().get_context_data(
                associations=associations,
                gestalt=self.object,
                object_list=associations,
                **kwargs)

    def get_object(self):
        return self.object

class List(base.PermissionMixin, generic.ListView):
    permission_required = 'gestalten.view_list'
    queryset = models.Gestalt.objects.filter(public=True)
    ordering = '-score'
    paginate_by = 10
    template_name = 'gestalten/list.html'

    def get_content(self):
        return associations.Association.objects.filter(
                entity_type=models.Gestalt.content_type).can_view(self.request.user)

class Login(allauth.account.views.LoginView):
    permission_required = 'gestalten.login'
    form_class = forms.Login
    template_name = 'gestalten/login.html'

    def has_facebook_app(self):
        providers = allauth.socialaccount.providers.registry.get_list()
        for provider in providers:
            if provider.id == 'facebook' and provider.get_app(self.request):
                return True
        return False

class Update(utils.views.ActionMixin, django.views.generic.UpdateView):
    action = 'Dein Profil'
    form_class = forms.Gestalt
    menu = 'gestalt'
    message = 'Die Einstellungen wurden geändert.'
    model = models.Gestalt
    permission_required = 'entities.change_gestalt'

    def get_parent(self):
        return self.object

    def get_success_url(self):
        return self.object.get_profile_url()

class UpdateAvatar(utils.views.ActionMixin, django.views.generic.UpdateView):
    action = 'Avatar ändern'
    fields = ('avatar',)
    layout = ('avatar',)
    menu = 'gestalt'
    model = models.Gestalt
    permission_required = 'entities.change_gestalt'

    def get_parent(self):
        return self.object

    def get_success_url(self):
        return self.object.get_profile_url()

class UpdateBackground(utils.views.ActionMixin, django.views.generic.UpdateView):
    action = 'Hintergrundbild ändern'
    fields = ('background',)
    layout = ('background',)
    menu = 'gestalt'
    model = models.Gestalt
    permission_required = 'entities.change_gestalt'

    def get_parent(self):
        return self.object

    def get_success_url(self):
        return self.object.get_profile_url()
<commit_msg>Fix ordering of gestalten<commit_after>import allauth
import django
from django.views import generic

import core
import utils
from core.views import base
from features.associations import models as associations
from . import forms, models

class Detail(
        core.views.PermissionMixin, django.views.generic.list.MultipleObjectMixin,
        django.views.generic.DetailView):
    permission_required = 'gestalten.view'
    model = models.Gestalt
    paginate_by = 10
    template_name = 'gestalten/detail.html'

    def get_context_data(self, **kwargs):
        associations = self.object.associations.ordered_user_content(self.request.user)
        return super().get_context_data(
                associations=associations,
                gestalt=self.object,
                object_list=associations,
                **kwargs)

    def get_object(self):
        return self.object

class List(base.PermissionMixin, generic.ListView):
    permission_required = 'gestalten.view_list'
    queryset = models.Gestalt.objects.filter(public=True)
    ordering = ['-score', '-user__date_joined']
    paginate_by = 10
    template_name = 'gestalten/list.html'

    def get_content(self):
        return associations.Association.objects.filter(
                entity_type=models.Gestalt.content_type).can_view(self.request.user)

class Login(allauth.account.views.LoginView):
    permission_required = 'gestalten.login'
    form_class = forms.Login
    template_name = 'gestalten/login.html'

    def has_facebook_app(self):
        providers = allauth.socialaccount.providers.registry.get_list()
        for provider in providers:
            if provider.id == 'facebook' and provider.get_app(self.request):
                return True
        return False

class Update(utils.views.ActionMixin, django.views.generic.UpdateView):
    action = 'Dein Profil'
    form_class = forms.Gestalt
    menu = 'gestalt'
    message = 'Die Einstellungen wurden geändert.'
    model = models.Gestalt
    permission_required = 'entities.change_gestalt'

    def get_parent(self):
        return self.object

    def get_success_url(self):
        return self.object.get_profile_url()

class UpdateAvatar(utils.views.ActionMixin, django.views.generic.UpdateView):
    action = 'Avatar ändern'
    fields = ('avatar',)
    layout = ('avatar',)
    menu = 'gestalt'
    model = models.Gestalt
    permission_required = 'entities.change_gestalt'

    def get_parent(self):
        return self.object

    def get_success_url(self):
        return self.object.get_profile_url()

class UpdateBackground(utils.views.ActionMixin, django.views.generic.UpdateView):
    action = 'Hintergrundbild ändern'
    fields = ('background',)
    layout = ('background',)
    menu = 'gestalt'
    model = models.Gestalt
    permission_required = 'entities.change_gestalt'

    def get_parent(self):
        return self.object

    def get_success_url(self):
        return self.object.get_profile_url()
<|endoftext|>


<commit_before>#from django.shortcuts import render
from django.http import HttpResponse, HttpResponseBadRequest
from django.views.decorators.csrf import csrf_exempt
import json
import requests
from collections import Counter
from random import randrange

from depot.models import Station, Area, State
from depot.forms import EntryForm, APISearchForm, APIStationForm
from booking.forms import BookingForm
from insure.models import Device
from insure import forms as insure_forms
from drugshare import forms as drug_forms
from drugshare import models as drug_models

def add_station(request):
    form = APIStationForm(request.GET)
    if form.is_valid():
        brand_name = form.cleaned_data['brand'].upper()
        address = form.cleaned_data['address']
        state_tag = form.cleaned_data['state'].strip().lower()
        try:
            state = State.objects.get(tag__iexact=state_tag)
        except State.DoesNotExist:
            return HttpResponse('wrong state')

        #try:
        #    brand = Brand.objects.get(name=brand_name)
        #except Brand.DoesNotExist:
        #    brand = Brand.objects.create(name=brand_name)

        # Does the station already exist?
        try:
            station = Station.objects.get(
                brand=brand_name, address=address, state=state)
            return HttpResponse('station already exists')
        except Station.DoesNotExist:
            station = Station.objects.create(
                brand=brand_name, address=address, state=state)
            for name in form.cleaned_data['area']:
                area, _ = Area.objects.get_or_create(name=name)
                station.area.add(area)
            return HttpResponse('success')
    return HttpResponse('error')

def get_stations(request):
    stations = Station.objects.all()
    form = APISearchForm(request.GET)
    if form.is_valid():
        name = form.cleaned_data['name']
        state = form.cleaned_data['state']
        stations = stations.filter(
            area__name__icontains=name,
            state__tag__iexact=state)
    output = []
    for stn in stations:
        data = {
            'station_id': stn.id,
            'name': stn.brand,
            'address': stn.address,
            'num_cars': 'N/A',
            'fuel_price': 'N/A',
            'kegs': 'N/A',
            'time': 'N/A'
            }
        recent = stn.recent
        if recent:
            #kegs = 'Yes' if recent.kegs else 'No'
            data.update({
                'num_cars': recent.get_num_cars_display(),
                'fuel_price': str(recent.fuel_price) or 'N/A',
                'kegs': 'Yes' if recent.kegs else 'No',
                'time': recent.current_time.strftime('%Y-%m-%d %H:%M:%S')
            })
        output.append(data)
    return HttpResponse(json.dumps(output))

@csrf_exempt
def make_entry(request, station_id):
    station = Station.objects.get(pk=station_id)
    #import pdb;pdb.set_trace()
    if request.method == 'GET':
        form = EntryForm(request.GET)
        if form.is_valid():
            entry = form.save(commit=False)
            entry.station = station
            entry.save()
            return HttpResponse('Success')
    return HttpResponse('Error')

def booking(request):
    form = BookingForm(request.GET)
    if form.is_valid():
        obj = form.save(commit=False)
        code = randrange(10002321, 99221025)
        obj.code = code
        obj.save()
        payload = {
            'sender': 'VGCBOOK',
            'to': '234{}'.format(obj.phone[-10:]),
            'msg': "You have been booked into VGC with code: {}".format(code)
        }
        sms_url = 'http://shoutinsms.bayo.webfactional.com/api/sendmsg/'
        requests.get(sms_url, params=payload)
        return HttpResponse('A message has been sent to your visitor.')
    return HttpResponse('Error')

@csrf_exempt
def insure(request):
    form = insure_forms.EntryForm(request.POST, request.FILES)
    # import pdb;pdb.set_trace()
    if form.is_valid():
        obj = form.save(commit=False)
        uuid = request.POST.get('uuid', '')
        if uuid:
            device, _ = Device.objects.get_or_create(uuid=uuid)
            obj.device = device
        obj.save()
        return HttpResponse("Saved building information.")
    return HttpResponseBadRequest("Error")

def register_pharm(request):
    form = drug_forms.PharmacyForm(request.GET)
    #import pdb;pdb.set_trace()
    if form.is_valid():
        pharm = form.save(commit=False)
        _state = request.GET.get('state')
        state = drug_models.State.objects.get(name__iexact=_state)
        pharm.state = state
        pharm.save()
        return HttpResponse("Registered Pharmacy")
    return HttpResponseBadRequest('Unable to register pharmacy')

def add_drug(request):
    form = drug_forms.DrugForm(request.GET)
    #import pdb;pdb.set_trace()
    if form.is_valid():
        drug = form.save(commit=False)
        uuid = request.GET.get('uuid')
        try:
            pharm = drug_models.Pharmacy.objects.get(uuid=uuid)
        except drug_models.Pharmacy.DoesNotExist:
            return HttpResponseBadRequest("Please register first")
        else:
            drug.pharmacy = pharm
            drug.save()
            return HttpResponse("Drug added")
    return HttpResponseBadRequest('Unable to add the drug')

def search_drug(request):
    form = drug_forms.SearchForm(request.GET)
    drugs = []
    if form.is_valid():
        item = form.cleaned_data['name'].title()
        uuid = form.cleaned_data['uuid']
        try:
            pharmacy = drug_models.Pharmacy.objects.get(uuid=uuid)
        except drug_models.Pharmacy.DoesNotExist:
            return HttpResponseBadRequest('Please register')
        else:
            drug_models.Search.objects.create(pharmacy=pharmacy, name=item)

        for drug in drug_models.Drug.objects.filter(
                name__icontains=item).order_by('-expiry_date'):
            item = {
                'drug_id': drug.id,
                'name': drug.name,
                'area': drug.pharmacy.area,
                'cost': '{}'.format(drug.cost),
                'expiry': drug.expiry_date.strftime('%Y-%m-%d'),
                'quantity': drug.quantity
            }
            drugs.append(item)
    return HttpResponse(json.dumps(drugs))

def stock_drug(request):
    form = drug_forms.StockForm(request.GET)
    drugs = []
    if form.is_valid():
        uuid = form.cleaned_data['uuid']
        for drug in drug_models.Drug.objects.filter(
                pharmacy__uuid__iexact=uuid):
            item = {
                'drug_id': drug.id,
                'name': drug.name,
                'cost': '{}'.format(drug.cost),
                'expiry': drug.expiry_date.strftime('%Y-%m-%d'),
                'quantity': drug.quantity
            }
            drugs.append(item)
    return HttpResponse(json.dumps(drugs))

def remove_drug(request, id):
    form = drug_forms.StockForm(request.GET)
    if form.is_valid():
        uuid = form.cleaned_data['uuid']
        try:
            drug = drug_models.Drug.objects.get(pk=id, pharmacy__uuid=uuid)
        except drug_models.Drug.DoesNotExist:
            return HttpResponseBadRequest("Wrong drug")
        drug.delete()
        return HttpResponse("Deleted successfully")
    return HttpResponseBadRequest("Error trying to delete drug")

def recent_drugs(request, count):
    drugs = drug_models.Search.objects.values_list('name', flat=True)
    output = []
    for item in Counter(drugs).most_common(int(count)):
        output.append({
            'name': item[0],
            'count': item[1]})
    print output
    return HttpResponse(json.dumps(output))

def wishlist_drug(request):
    form = drug_forms.WishlistForm(request.GET)
    drugs = []
    if form.is_valid():
        pharmacy = form.cleaned_data['uuid']
        searches = drug_models.Search.objects.filter(
            pharmacy=pharmacy).values_list('name', flat=True)
        drugs = list(set(searches))
        print drugs
    return HttpResponse(json.dumps(drugs))

def request_drug(request, drug_id):
    try:
        drug = drug_models.Drug.objects.get(pk=drug_id)
    except drug_models.Drug.DoesNotExist:
        return HttpResponseBadRequest('Wrong drug id')
    form = drug_forms.UUIDForm(request.GET)
    if form.is_valid():
        pharmacy = form.cleaned_data['uuid']
        quantity = form.cleaned_data['quantity']
        drug_models.DrugRequest.objects.create(
            drug=drug, pharmacy=pharmacy, quantity=quantity)
        return HttpResponse('Successfully added request')
    return HttpResponseBadRequest('Error creating request')

def pending_requests(request):
    form = drug_forms.WishlistForm(request.GET)
    output = []
    if form.is_valid():
        pharmacy = form.cleaned_data['uuid']
        requests = drug_models.DrugRequest.objects.filter(
            drug__pharmacy=pharmacy, status=drug_models.DrugRequest.PENDING)
        for item in requests:
            output.append({
                'id': item.id,
                'name': item.drug.name,
                'cost': '{}'.format(item.drug.cost),
                'expiry': item.drug.expiry_date.strftime('%Y-%m-%d'),
                'quantity': item.quantity,
                'date': item.posted_on.strftime('%Y-%m-%d')
            })
    print output
    return HttpResponse(json.dumps(output))

def accept(request, request_id):
    form = drug_forms.WishlistForm(request.GET)
    if form.is_valid():
        pharmacy = form.cleaned_data['uuid']
        try:
            drug_request = drug_models.DrugRequest.objects.get(
                pk=request_id, drug__pharmacy=pharmacy)
        except drug_models.DrugRequest.DoesNotExist:
            return HttpResponseBadRequest('Error accepting request')
        drug_request.status = drug_models.DrugRequest.ACCEPTED
        drug_request.save()
        return HttpResponse("Accepted successfully")
    return HttpResponseBadRequest("Error trying to accept request")

def reject(request, request_id):
    form = drug_forms.WishlistForm(request.GET)
    if form.is_valid():
        pharmacy = form.cleaned_data['uuid']
        try:
            drug_request = drug_models.DrugRequest.objects.get(
                pk=request_id, drug__pharmacy=pharmacy)
        except drug_models.DrugRequest.DoesNotExist:
            return HttpResponseBadRequest('Error rejecting request')
        drug_request.status = drug_models.DrugRequest.CANCELLED
        drug_request.save()
        return HttpResponse("Rejected successfully")
    return HttpResponseBadRequest("Error trying to reject request")
<commit_msg>allow for re-registration of pharmacies<commit_after>#from django.shortcuts import render
from django.http import HttpResponse, HttpResponseBadRequest
from django.views.decorators.csrf import csrf_exempt
import json
import requests
from collections import Counter
from random import randrange

from depot.models import Station, Area, State
from depot.forms import EntryForm, APISearchForm, APIStationForm
from booking.forms import BookingForm
from insure.models import Device
from insure import forms as insure_forms
from drugshare import forms as drug_forms
from drugshare import models as drug_models

def add_station(request):
    form = APIStationForm(request.GET)
    if form.is_valid():
        brand_name = form.cleaned_data['brand'].upper()
        address = form.cleaned_data['address']
        state_tag = form.cleaned_data['state'].strip().lower()
        try:
            state = State.objects.get(tag__iexact=state_tag)
        except State.DoesNotExist:
            return HttpResponse('wrong state')

        #try:
        #    brand = Brand.objects.get(name=brand_name)
        #except Brand.DoesNotExist:
        #    brand = Brand.objects.create(name=brand_name)

        # Does the station already exist?
        try:
            station = Station.objects.get(
                brand=brand_name, address=address, state=state)
            return HttpResponse('station already exists')
        except Station.DoesNotExist:
            station = Station.objects.create(
                brand=brand_name, address=address, state=state)
            for name in form.cleaned_data['area']:
                area, _ = Area.objects.get_or_create(name=name)
                station.area.add(area)
            return HttpResponse('success')
    return HttpResponse('error')

def get_stations(request):
    stations = Station.objects.all()
    form = APISearchForm(request.GET)
    if form.is_valid():
        name = form.cleaned_data['name']
        state = form.cleaned_data['state']
        stations = stations.filter(
            area__name__icontains=name,
            state__tag__iexact=state)
    output = []
    for stn in stations:
        data = {
            'station_id': stn.id,
            'name': stn.brand,
            'address': stn.address,
            'num_cars': 'N/A',
            'fuel_price': 'N/A',
            'kegs': 'N/A',
            'time': 'N/A'
            }
        recent = stn.recent
        if recent:
            #kegs = 'Yes' if recent.kegs else 'No'
            data.update({
                'num_cars': recent.get_num_cars_display(),
                'fuel_price': str(recent.fuel_price) or 'N/A',
                'kegs': 'Yes' if recent.kegs else 'No',
                'time': recent.current_time.strftime('%Y-%m-%d %H:%M:%S')
            })
        output.append(data)
    return HttpResponse(json.dumps(output))

@csrf_exempt
def make_entry(request, station_id):
    station = Station.objects.get(pk=station_id)
    #import pdb;pdb.set_trace()
    if request.method == 'GET':
        form = EntryForm(request.GET)
        if form.is_valid():
            entry = form.save(commit=False)
            entry.station = station
            entry.save()
            return HttpResponse('Success')
    return HttpResponse('Error')

def booking(request):
    form = BookingForm(request.GET)
    if form.is_valid():
        obj = form.save(commit=False)
        code = randrange(10002321, 99221025)
        obj.code = code
        obj.save()
        payload = {
            'sender': 'VGCBOOK',
            'to': '234{}'.format(obj.phone[-10:]),
            'msg': "You have been booked into VGC with code: {}".format(code)
        }
        sms_url = 'http://shoutinsms.bayo.webfactional.com/api/sendmsg/'
        requests.get(sms_url, params=payload)
        return HttpResponse('A message has been sent to your visitor.')
    return HttpResponse('Error')

@csrf_exempt
def insure(request):
    form = insure_forms.EntryForm(request.POST, request.FILES)
    # import pdb;pdb.set_trace()
    if form.is_valid():
        obj = form.save(commit=False)
        uuid = request.POST.get('uuid', '')
        if uuid:
            device, _ = Device.objects.get_or_create(uuid=uuid)
            obj.device = device
        obj.save()
        return HttpResponse("Saved building information.")
    return HttpResponseBadRequest("Error")

def register_pharm(request):
    form = drug_forms.PharmacyForm(request.GET)
    #import pdb;pdb.set_trace()
    if form.is_valid():
        _state = request.GET.get('state')
        state = drug_models.State.objects.get(name__iexact=_state)
        uuid = form.cleaned_data['uuid']
        try:
            pharmacy = drug_models.Pharmacy.objects.get(uuid=uuid)
        except drug_models.Pharmacy.DoesNotExist:
            pharm = form.save(commit=False)
            pharm.state = state
            pharm.save()
        else:
            pharmacy.name = form.cleaned_data['name']
            pharmacy.phone = form.cleaned_data['phone']
            pharmacy.street = form.cleaned_data['street']
            pharmacy.area = form.cleaned_data['area']
            pharmacy.state = state
            pharmacy.save()
        return HttpResponse("Registered Pharmacy")
    return HttpResponseBadRequest('Unable to register pharmacy')

def add_drug(request):
    form = drug_forms.DrugForm(request.GET)
    #import pdb;pdb.set_trace()
    if form.is_valid():
        drug = form.save(commit=False)
        uuid = request.GET.get('uuid')
        try:
            pharm = drug_models.Pharmacy.objects.get(uuid=uuid)
        except drug_models.Pharmacy.DoesNotExist:
            return HttpResponseBadRequest("Please register first")
        else:
            drug.pharmacy = pharm
            drug.save()
            return HttpResponse("Drug added")
    return HttpResponseBadRequest('Unable to add the drug')

def search_drug(request):
    form = drug_forms.SearchForm(request.GET)
    drugs = []
    if form.is_valid():
        item = form.cleaned_data['name'].title()
        uuid = form.cleaned_data['uuid']
        try:
            pharmacy = drug_models.Pharmacy.objects.get(uuid=uuid)
        except drug_models.Pharmacy.DoesNotExist:
            return HttpResponseBadRequest('Please register')
        else:
            drug_models.Search.objects.create(pharmacy=pharmacy, name=item)

        for drug in drug_models.Drug.objects.filter(
                name__icontains=item).order_by('-expiry_date'):
            item = {
                'drug_id': drug.id,
                'name': drug.name,
                'area': drug.pharmacy.area,
                'cost': '{}'.format(drug.cost),
                'expiry': drug.expiry_date.strftime('%Y-%m-%d'),
                'quantity': drug.quantity
            }
            drugs.append(item)
    return HttpResponse(json.dumps(drugs))

def stock_drug(request):
    form = drug_forms.StockForm(request.GET)
    drugs = []
    if form.is_valid():
        uuid = form.cleaned_data['uuid']
        for drug in drug_models.Drug.objects.filter(
                pharmacy__uuid__iexact=uuid):
            item = {
                'drug_id': drug.id,
                'name': drug.name,
                'cost': '{}'.format(drug.cost),
                'expiry': drug.expiry_date.strftime('%Y-%m-%d'),
                'quantity': drug.quantity
            }
            drugs.append(item)
    return HttpResponse(json.dumps(drugs))

def remove_drug(request, id):
    form = drug_forms.StockForm(request.GET)
    if form.is_valid():
        uuid = form.cleaned_data['uuid']
        try:
            drug = drug_models.Drug.objects.get(pk=id, pharmacy__uuid=uuid)
        except drug_models.Drug.DoesNotExist:
            return HttpResponseBadRequest("Wrong drug")
        drug.delete()
        return HttpResponse("Deleted successfully")
    return HttpResponseBadRequest("Error trying to delete drug")

def recent_drugs(request, count):
    drugs = drug_models.Search.objects.values_list('name', flat=True)
    output = []
    for item in Counter(drugs).most_common(int(count)):
        output.append({
            'name': item[0],
            'count': item[1]})
    print output
    return HttpResponse(json.dumps(output))

def wishlist_drug(request):
    form = drug_forms.WishlistForm(request.GET)
    drugs = []
    if form.is_valid():
        pharmacy = form.cleaned_data['uuid']
        searches = drug_models.Search.objects.filter(
            pharmacy=pharmacy).values_list('name', flat=True)
        drugs = list(set(searches))
        print drugs
    return HttpResponse(json.dumps(drugs))

def request_drug(request, drug_id):
    try:
        drug = drug_models.Drug.objects.get(pk=drug_id)
    except drug_models.Drug.DoesNotExist:
        return HttpResponseBadRequest('Wrong drug id')
    form = drug_forms.UUIDForm(request.GET)
    if form.is_valid():
        pharmacy = form.cleaned_data['uuid']
        quantity = form.cleaned_data['quantity']
        drug_models.DrugRequest.objects.create(
            drug=drug, pharmacy=pharmacy, quantity=quantity)
        return HttpResponse('Successfully added request')
    return HttpResponseBadRequest('Error creating request')

def pending_requests(request):
    form = drug_forms.WishlistForm(request.GET)
    output = []
    if form.is_valid():
        pharmacy = form.cleaned_data['uuid']
        requests = drug_models.DrugRequest.objects.filter(
            drug__pharmacy=pharmacy, status=drug_models.DrugRequest.PENDING)
        for item in requests:
            output.append({
                'id': item.id,
                'name': item.drug.name,
                'cost': '{}'.format(item.drug.cost),
                'expiry': item.drug.expiry_date.strftime('%Y-%m-%d'),
                'quantity': item.quantity,
                'date': item.posted_on.strftime('%Y-%m-%d')
            })
    print output
    return HttpResponse(json.dumps(output))

def accept(request, request_id):
    form = drug_forms.WishlistForm(request.GET)
    if form.is_valid():
        pharmacy = form.cleaned_data['uuid']
        try:
            drug_request = drug_models.DrugRequest.objects.get(
                pk=request_id, drug__pharmacy=pharmacy)
        except drug_models.DrugRequest.DoesNotExist:
            return HttpResponseBadRequest('Error accepting request')
        drug_request.status = drug_models.DrugRequest.ACCEPTED
        drug_request.save()
        return HttpResponse("Accepted successfully")
    return HttpResponseBadRequest("Error trying to accept request")

def reject(request, request_id):
    form = drug_forms.WishlistForm(request.GET)
    if form.is_valid():
        pharmacy = form.cleaned_data['uuid']
        try:
            drug_request = drug_models.DrugRequest.objects.get(
                pk=request_id, drug__pharmacy=pharmacy)
        except drug_models.DrugRequest.DoesNotExist:
            return HttpResponseBadRequest('Error rejecting request')
        drug_request.status = drug_models.DrugRequest.CANCELLED
        drug_request.save()
        return HttpResponse("Rejected successfully")
    return HttpResponseBadRequest("Error trying to reject request")
<|endoftext|>