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

# Parse command line arguments
import argparse
import os
import pandas as pd
import sys

# Submit jobs to the cluster
from gscripts.qtools import Submitter

'''
Author: olga
Date created: 7/12/13 9:38 AM

The purpose of this program is to write submitter scripts to perform MISO
analysis on a large amount of files. This script assumes paired-end reads.

# **Note** for some reason,

Example runs:

submit_miso_pipeline.py --psi-only --paired-end --event-type SE \
--sample-info-file ~/projects/singlecell/singlecell/sample_info.txt \
--sh-scripts-dir ~/projects/singlecell/scripts/ \
--summary-output-dir-base ~/projects/singlecell/singlecell/analysis/ \
--psi-walltime '0:50:00' --annotation-index-strfmt \
'/home/yeo-lab/genomes/hg19/miso_annotations/%s_index' \
--sample-id-suffix min10reads \
--extra-miso-arguments ' --settings-filename \
~/MISO/misopy/settings/miso_settings_min_event_reads10.txt' \
--individual-jobs

submit_miso_pipeline.py --psi-only --paired-end --event-type SE --sample-info-file ~/projects/singlecell/singlecell/sample_info_round2and3.txt --sh-scripts-dir ~/projects/singlecell/scripts/ --summary-output-dir-base ~/projects/singlecell/singlecell/analysis/ --psi-walltime '1:50:00' --annotation-index-strfmt '/home/yeo-lab/genomes/hg19/miso_annotations/%s_index' --sample-id-suffix min10reads --extra-miso-arguments ' --settings-filename ~/MISO/misopy/settings/miso_settings_min_event_reads10.txt' --individual-jobs

submit_miso_pipeline.py --psi-only --single-end --event-type SE \
--sample-info-file ~/projects/singlecell/singlecell/sample_info.txt \
--sh-scripts-dir ~/projects/singlecell/scripts/ \
--summary-output-dir-base ~/projects/singlecell/singlecell/analysis/ \
--psi-walltime '0:50:00' \
--annotation-index-strfmt '/home/obotvinnik/genomes/hg19/miso_annotations/%s_index'

submit_miso_pipeline.py --run-all --single-bam $BAM $SAMPLE_ID\
--num-processes 16

TODO: deprecate the non-queue way of running
'''

# Class: CommandLine
class CommandLine(object):
    def __init__(self, inOpts=None):
        self.parser = argparse.ArgumentParser(
            description='''Write a script to perform MISO analysis
            on individual samples. By default, this is submitted to TSCC,
            unless "--do-not-submit" is specified.
            ''',
            add_help=True, prefix_chars='-')
        samples = self.parser.add_mutually_exclusive_group(required=True)
        samples.add_argument('--bam', type=str,
                             action='store', default='',
                             help='A single BAM file')
        samples.add_argument('--sample-info', type=str, action='store',
                             help='A tab-delimited file with Bam files as '
                                  'column 1 and the sample Ids as column 2 ('
                                  'no header). In conjunction with '
                                  '"--actually-submit", this will submit an '
                                  'array job to be a nice cluster user')

        self.parser.add_argument('--sample-id', type=str,
                                 action='store',
                                 help='sample ID. required if using --bam',
                                 required=False)
        self.parser.add_argument('--debug', action='store_true',
                                 default=False,
                                 help="Don't make any files, just print "
                                      "everything that would have been made")
        self.parser.add_argument('--genome', type=str, action='store',
                                 required=True, help='Which genome to use')
        self.parser.add_argument('--output-sh', type=str, required=True,
                                 action='store',
                                 help="The name of the .sh script created for one-touch action")
        self.parser.add_argument('--extra-miso-arguments', type=str,
                                 action='store',
                                 default='',
                                 help='Any additional MISO "compute psi" '
                                      'arguments you want'
                                      ' to supply to all the samples. The '
                                      'default is no additional arguments. '
                                      'Protect this argument with quotes so '
                                      'it does not get interpreted as an '
                                      'argument to the MISO pipeline script, '
                                      'e.g. --extra-miso-arguments " '
                                      '--no-filter-events'
                                      ' --settings-filename '
                                      'miso_settings_min_event_reads5.txt". '
                                      'If this is not working for you, '
                                      'try adding a space between the first '
                                      'quote and the first dash of the miso '
                                      'argument. For some reason this helps..'
                                      '..')
        self.parser.add_argument('--do-not-submit',
                                 action='store_true', default=False,
                                 help='Whether or not to actually submit the '
                                      'final file.')

        if inOpts is None:
            self.args = vars(self.parser.parse_args())
        else:
            self.args = vars(self.parser.parse_args(inOpts))

    def do_usage_and_die(self, str):
        '''
        If a critical error is encountered, where it is suspected that the
        program is not being called with consistent parameters or data, this
        method will write out an error string (str), then terminate execution
        of the program.
        '''
        import sys

        print >> sys.stderr, str
        self.parser.print_usage()
        return 2

# Class: Usage
class Usage(Exception):
    '''
    Used to signal a Usage error, evoking a usage statement and eventual
    exit when raised
    '''

    def __init__(self, msg):
        self.msg = msg

class MisoPipeline(object):
    def __init__(self, bam, sample_info_file,
                 sample_id, output_sh,
                 genome,

                 debug=False,
                 extra_miso_arguments='',
                 submit=False):
        """
        Parameters
        ----------

        Returns
        -------

        Raises
        ------
        """
        self.sample_info_file = sample_info_file

        if self.sample_info_file is not None:
            sample_info = pd.read_table(self.sample_info_file)
            self.bams = sample_info[0]
            self.sample_ids = sample_info[1]
            self.sh_files = ['{}.miso.sh'.format(bam) for bam in self.bams]
            self.multiple_samples = True
        else:
            self.sample_ids = [sample_id]
            self.bams = [bam]
            self.sh_files = [output_sh]
            self.multiple_samples = False

        self.genome = genome
        self.debug = debug
        self.extra_miso_arguments = extra_miso_arguments
        self.submit = submit

        all_samples_commands = []

        for bam, sample_id, sh_file in zip(self.bams, self.sample_ids,
                                           self.sh_files):
            self._write_single_sample(bam, sample_id, sh_file)

            sh_command = 'bash {}'.format(sh_file)
            if self.submit and not self.multiple_samples:
                commands = [sh_command]
                sub = Submitter(commands, job_name='miso',
                                sh_filename='{}.qsub.sh'.format(sh_file),
                                ppn=16, walltime='1:00:00')
                sub.job(submit=self.submit)

            if self.multiple_samples:
                all_samples_commands.append(sh_command)

        if self.multiple_samples:
            sub = Submitter(all_samples_commands, job_name='miso',
                            sh_filename=output_sh,
                            array=True, ppn=16, walltime='1:00:00')
            sub.job(submit=self.submit)

    def _write_single_sample(self, bam, sample_id, sh_file):
        commands = []
        commands.append('#!/bin/bash')
        commands.append('# Finding all MISO splicing scores for sample: {}. '
                        'Yay!\n'
                        .format(sample_id))

        event_types = ['SE', 'MXE', 'AFE', 'ALE', 'A3SS', 'A5SS',
                       'RI', 'TANDEMUTR']

        # Get the read length. Gonna keep this as bash because samtools
        # and head are very fast
        commands.append(
            "READ_LEN=$(samtools view %s | head -n 1 | cut -f 10 | awk '{ "
            "print length }')" % (bam))

        for event_type in event_types:
            out_dir = '{}/miso/{}/{}'.format(os.path.dirname(os.path
                                                             .abspath(bam)),
                                             sample_id, event_type)
            psi_out = '{}/psi.out'.format(out_dir)
            psi_err = '{}/psi.err'.format(out_dir)

            commands.append('\n\n# calculate Psi scores for'
                            ' all {} events'.format(event_type))
            commands.append('mkdir -p {}'.format(out_dir))
            commands.append("python /projects/ps-yeolab/software/bin/miso \
         --run /projects/ps-yeolab/genomes/{0}/miso/{1}_index \
         {2} --output-dir {3} \
         --read-len $READ_LEN \
         --settings-filename /projects/ps-yeolab/genomes/hg19/miso_annotations"
                            "/miso_settings_min_event_reads10.txt \
 -p 16 \
 > {4} \
 2> {5}".format(self.genome, event_type, bam, out_dir,
                psi_out, psi_err))

            commands.append("\n# Check that the psi calculation jobs didn't "
                            "fail.\n#'-z' "
                            "returns "
                            "true when a string is empty, so this is checking "
                            "that grepping these files for the words 'failed' "
                            "and 'shutdown' didn't find anything.")
            commands.append('iffailed=$(grep failed {})'.format(psi_out))
            commands.append('ifshutdown=$(grep shutdown {})'.format(psi_err))
            commands.append(
                "if [ ! -z \"$iffailed\" -o ! -z \"$ifshutdown\" ] ; "
                "then\n\
    #rm -rf {0}\n\
    echo \"MISO psi failed on event type: {1}\"\n\
    exit 1\n\
fi\n".format(out_dir, event_type))

            commands.append('# Summarize psi scores for all {} events'
                            .format(event_type))
            commands.append('python /home/yeo-lab/software/bin/run_miso.py '
                            '--summarize-samples {0} ' \
                            '{0} >{0}/summary.out 2>{0}/summary.err'.format(
                out_dir))
            commands.append("\n# Check that the summary jobs didn't fail")
            commands.append("# '-s' returns true if file size is nonzero, "
                            "and the error file should be empty.")
            commands.append("""if [ -s {0}/summary.err ] ; then
    #rm -rf {0}\n
    echo 'MISO psi failed on event type: {1}'
    exit 1
fi
""".format(out_dir, event_type))

        with open(sh_file, 'w') as f:
            f.write('\n'.join(commands))
        sys.stdout.write('Wrote miso script for sample "{}": {}\n'.format(
            sample_id, sh_file))

# Function: main
def main():
    '''
    This function is invoked when the program is run from the command line,
    i.e. as:
        python submit_miso_pipeline.py
    or as:
        ./submit_miso_pipeline.py
    If the user has executable permissions on the user (set by chmod ug+x
    program.py or by chmod 775 program py. Just need the 4th bit set to true)
    '''
    cl = CommandLine()
    try:
        submit = not cl.args['do_not_submit']

        MisoPipeline(cl.args['bam'],
                     cl.args['sample_info'],
                     cl.args['sample_id'],
                     cl.args['output_sh'],
                     cl.args['genome'],
                     debug=cl.args['debug'],
                     extra_miso_arguments=cl.args['extra_miso_arguments'],
                     submit=submit)

    # If not all the correct arguments are given, break the program and
    # show the usage information
    except Usage, err:
        cl.do_usage_and_die(err.msg)

if __name__ == '__main__':
    main()<commit_msg>Remove debug and extra_miso_arguments. Make '--sample-info' running more hands off<commit_after>#!/usr/bin/env python
# coding=utf-8

# Parse command line arguments
import argparse
import os
import pandas as pd
import sys

# Submit jobs to the cluster
from gscripts.qtools import Submitter

'''
Author: olga
Date created: 7/12/13 9:38 AM

The purpose of this program is to write submitter scripts to perform MISO
analysis on a large amount of files. This script assumes paired-end reads.

# **Note** for some reason,

Example runs:

submit_miso_pipeline.py --psi-only --paired-end --event-type SE \
--sample-info-file ~/projects/singlecell/singlecell/sample_info.txt \
--sh-scripts-dir ~/projects/singlecell/scripts/ \
--summary-output-dir-base ~/projects/singlecell/singlecell/analysis/ \
--psi-walltime '0:50:00' --annotation-index-strfmt \
'/home/yeo-lab/genomes/hg19/miso_annotations/%s_index' \
--sample-id-suffix min10reads \
--extra-miso-arguments ' --settings-filename \
~/MISO/misopy/settings/miso_settings_min_event_reads10.txt' \
--individual-jobs

submit_miso_pipeline.py --psi-only --paired-end --event-type SE --sample-info-file ~/projects/singlecell/singlecell/sample_info_round2and3.txt --sh-scripts-dir ~/projects/singlecell/scripts/ --summary-output-dir-base ~/projects/singlecell/singlecell/analysis/ --psi-walltime '1:50:00' --annotation-index-strfmt '/home/yeo-lab/genomes/hg19/miso_annotations/%s_index' --sample-id-suffix min10reads --extra-miso-arguments ' --settings-filename ~/MISO/misopy/settings/miso_settings_min_event_reads10.txt' --individual-jobs

submit_miso_pipeline.py --psi-only --single-end --event-type SE \
--sample-info-file ~/projects/singlecell/singlecell/sample_info.txt \
--sh-scripts-dir ~/projects/singlecell/scripts/ \
--summary-output-dir-base ~/projects/singlecell/singlecell/analysis/ \
--psi-walltime '0:50:00' \
--annotation-index-strfmt '/home/obotvinnik/genomes/hg19/miso_annotations/%s_index'

submit_miso_pipeline.py --run-all --single-bam $BAM $SAMPLE_ID\
--num-processes 16

TODO: deprecate the non-queue way of running
'''

# Class: CommandLine
class CommandLine(object):
    def __init__(self, inOpts=None):
        self.parser = argparse.ArgumentParser(
            description='''Write a script to perform MISO analysis
            on individual samples. By default, this is submitted to TSCC,
            unless "--do-not-submit" is specified.
            ''',
            add_help=True, prefix_chars='-')
        samples = self.parser.add_mutually_exclusive_group(required=True)
        samples.add_argument('--bam', type=str,
                             action='store', default='',
                             help='A single BAM file')
        samples.add_argument('--sample-info', type=str, action='store',
                             help='A tab-delimited file with Bam files as '
                                  'column 1 and the sample Ids as column 2 ('
                                  'no header). If "--do-not-submit" is off, '
                                  'this will submit an '
                                  'array job to be a nice cluster user')

        self.parser.add_argument('--sample-id', type=str,
                                 action='store',
                                 help='sample ID. required if using --bam',
                                 required=False)
        self.parser.add_argument('--genome', type=str, action='store',
                                 required=True, help='Which genome to use')
        self.parser.add_argument('--output-sh', type=str, required=True,
                                 action='store',
                                 help="The name of the .sh script created for "
                                      "one-touch action. Not used with "
                                      "'--sample-info', where each sample "
                                      "gets its own sh file.")
        self.parser.add_argument('--extra-miso-arguments', type=str,
                                 action='store',
                                 default='',
                                 help='Any additional MISO "compute psi" '
                                      'arguments you want'
                                      ' to supply to all the samples. The '
                                      'default is no additional arguments. '
                                      'Protect this argument with quotes so '
                                      'it does not get interpreted as an '
                                      'argument to the MISO pipeline script, '
                                      'e.g. --extra-miso-arguments " '
                                      '--no-filter-events'
                                      ' --settings-filename '
                                      'miso_settings_min_event_reads5.txt". '
                                      'If this is not working for you, '
                                      'try adding a space between the first '
                                      'quote and the first dash of the miso '
                                      'argument. For some reason this helps..'
                                      '..')
        self.parser.add_argument('--do-not-submit',
                                 action='store_true', default=False,
                                 help='Whether or not to actually submit the '
                                      'final file.')

        if inOpts is None:
            self.args = vars(self.parser.parse_args())
        else:
            self.args = vars(self.parser.parse_args(inOpts))

    def do_usage_and_die(self, str):
        '''
        If a critical error is encountered, where it is suspected that the
        program is not being called with consistent parameters or data, this
        method will write out an error string (str), then terminate execution
        of the program.
        '''
        import sys

        print >> sys.stderr, str
        self.parser.print_usage()
        return 2

# Class: Usage
class Usage(Exception):
    '''
    Used to signal a Usage error, evoking a usage statement and eventual
    exit when raised
    '''

    def __init__(self, msg):
        self.msg = msg

class MisoPipeline(object):
    def __init__(self, bam, sample_info_file,
                 sample_id, output_sh,
                 genome,
                 extra_miso_arguments='',
                 submit=False):
        """
        Parameters
        ----------

        Returns
        -------

        Raises
        ------
        """
        self.sample_info_file = sample_info_file

        if self.sample_info_file is not None:
            sample_info = pd.read_table(self.sample_info_file, header=None)
            self.bams = sample_info[0]
            self.sample_ids = sample_info[1]
            self.sh_files = ['{}.miso.sh'.format(bam) for bam in self.bams]
            self.multiple_samples = True
        else:
            self.sample_ids = [sample_id]
            self.bams = [bam]
            self.sh_files = [output_sh]
            self.multiple_samples = False

        self.genome = genome
        self.submit = submit

        all_samples_commands = []

        for bam, sample_id, sh_file in zip(self.bams, self.sample_ids,
                                           self.sh_files):
            self._write_single_sample(bam, sample_id, sh_file)

            sh_command = 'bash {}'.format(sh_file)
            if self.submit and not self.multiple_samples:
                commands = [sh_command]
                sub = Submitter(commands, job_name='miso',
                                sh_filename='{}.qsub.sh'.format(sh_file),
                                ppn=16, walltime='1:00:00')
                sub.job(submit=self.submit)

            if self.multiple_samples:
                all_samples_commands.append(sh_command)

        if self.multiple_samples:
            sub = Submitter(all_samples_commands, job_name='miso',
                            sh_filename='miso.qsub.sh',
                            array=True, ppn=16, walltime='1:00:00')
            sub.job(submit=self.submit)

    def _write_single_sample(self, bam, sample_id, sh_file):
        commands = []
        commands.append('#!/bin/bash')
        commands.append('# Finding all MISO splicing scores for sample: {}. '
                        'Yay!\n'
                        .format(sample_id))

        event_types = ['SE', 'MXE', 'AFE', 'ALE', 'A3SS', 'A5SS',
                       'RI', 'TANDEMUTR']

        # Get the read length. Gonna keep this as bash because samtools
        # and head are very fast
        commands.append(
            "READ_LEN=$(samtools view %s | head -n 1 | cut -f 10 | awk '{ "
            "print length }')" % (bam))

        for event_type in event_types:
            out_dir = '{}/miso/{}/{}'.format(os.path.dirname(os.path
                                                             .abspath(bam)),
                                             sample_id, event_type)
            psi_out = '{}/psi.out'.format(out_dir)
            psi_err = '{}/psi.err'.format(out_dir)

            commands.append('\n\n# calculate Psi scores for'
                            ' all {} events'.format(event_type))
            commands.append('mkdir -p {}'.format(out_dir))
            commands.append("python /projects/ps-yeolab/software/bin/miso \
         --run /projects/ps-yeolab/genomes/{0}/miso/{1}_index \
         {2} --output-dir {3} \
         --read-len $READ_LEN \
         --settings-filename /projects/ps-yeolab/genomes/hg19/miso_annotations"
                            "/miso_settings_min_event_reads10.txt \
 -p 16 \
 > {4} \
 2> {5}".format(self.genome, event_type, bam, out_dir,
                psi_out, psi_err))

            commands.append("\n# Check that the psi calculation jobs didn't "
                            "fail.\n#'-z' "
                            "returns "
                            "true when a string is empty, so this is checking "
                            "that grepping these files for the words 'failed' "
                            "and 'shutdown' didn't find anything.")
            commands.append('iffailed=$(grep failed {})'.format(psi_out))
            commands.append('ifshutdown=$(grep shutdown {})'.format(psi_err))
            commands.append(
                "if [ ! -z \"$iffailed\" -o ! -z \"$ifshutdown\" ] ; "
                "then\n\
    #rm -rf {0}\n\
    echo \"MISO psi failed on event type: {1}\"\n\
    exit 1\n\
fi\n".format(out_dir, event_type))

            commands.append('# Summarize psi scores for all {} events'
                            .format(event_type))
            commands.append('python /home/yeo-lab/software/bin/run_miso.py '
                            '--summarize-samples {0} ' \
                            '{0} >{0}/summary.out 2>{0}/summary.err'.format(
                out_dir))
            commands.append("\n# Check that the summary jobs didn't fail")
            commands.append("# '-s' returns true if file size is nonzero, "
                            "and the error file should be empty.")
            commands.append("""if [ -s {0}/summary.err ] ; then
    #rm -rf {0}\n
    echo 'MISO psi failed on event type: {1}'
    exit 1
fi
""".format(out_dir, event_type))

        with open(sh_file, 'w') as f:
            f.write('\n'.join(commands))
        sys.stdout.write('Wrote miso script for sample "{}": {}\n'.format(
            sample_id, sh_file))

# Function: main
def main():
    '''
    This function is invoked when the program is run from the command line,
    i.e. as:
        python submit_miso_pipeline.py
    or as:
        ./submit_miso_pipeline.py
    If the user has executable permissions on the user (set by chmod ug+x
    program.py or by chmod 775 program py. Just need the 4th bit set to true)
    '''
    cl = CommandLine()
    try:
        submit = not cl.args['do_not_submit']

        MisoPipeline(cl.args['bam'],
                     cl.args['sample_info'],
                     cl.args['sample_id'],
                     cl.args['output_sh'],
                     cl.args['genome'],
                     extra_miso_arguments=cl.args['extra_miso_arguments'],
                     submit=submit)

    # If not all the correct arguments are given, break the program and
    # show the usage information
    except Usage, err:
        cl.do_usage_and_die(err.msg)

if __name__ == '__main__':
    main()<|endoftext|>


<commit_before>import os
import subprocess
from contextlib import contextmanager

import click
import jinja2
import logbook

import gossip

_logger = logbook.Logger(__name__)

_SKELETONS_ROOT = os.path.abspath(os.path.join(
    os.path.dirname(__file__), '..', '_skeletons'))

_ctx = {}

class UnknownSkeleton(Exception):
    pass

@click.group()
def generate():
    pass

def _get_grain_types():
    return sorted(filename.split('-', 1)[1]
                  for filename in os.listdir(_SKELETONS_ROOT)
                  if filename.startswith('grain-'))

@generate.command()
@click.option('-m', '--mountpoint', default="/")
@click.option('grain_type', '-t', '--type', default='views', type=click.Choice(_get_grain_types()))
@click.argument('name')
def grain(grain_type, name, mountpoint):
    _generate('grain-{}'.format(grain_type), name, {
        'name': name,
        'mountpoint': mountpoint,
    })
    gossip.trigger_with_tags('cob.after_generate.grain', tags=[grain_type], kwargs={'name': name})

@gossip.register('cob.after_generate.grain', tags=['frontend-ember'])
def after_generate_grain_frontend_ember(*, name):
    status, _ = subprocess.getstatusoutput('which ember')
    if status != 0:
        click.echo('You do not seem to have ember-cli installed. Skipping ember app creation...')
    else:
        click.echo('Generating new Ember project')
        subprocess.check_call('ember init', cwd=name, shell=True)

@generate.command()
@click.argument('path')
@click.argument('project_name', required=False)
def project(path, project_name=None):
    if project_name is None:
        project_name = os.path.basename(path)
    _generate('project', path, {
        'project_name': project_name
    })

@generate.command()
@click.argument('name')
@click.argument('mountpoint', default='/static')
def static_dir(name, mountpoint):
    _generate('static_dir', name, {
        'name': name,
        'mountpoint': mountpoint,
    })
    os.mkdir(os.path.join(name, 'root'))

@generate.command()
@click.argument('name', default='models')
def models(name):
    _generate('grain-models', name, {
        'name': name,
    })

def _generate(skeleton_name, dest_path, ctx):
    try:
        s = load_skeleton(skeleton_name)
    except UnknownSkeleton:
        raise click.ClickException('Unknown skeleton: {}'.format(skeleton_name))
    if s.is_single_file() and not dest_path.endswith('.py'):
        dest_path += '.py'
    with template_context(ctx):
        s.generate(dest_path)

@contextmanager
def template_context(ctx):
    _ctx.update(ctx)
    try:
        yield
    finally:
        _ctx.clear()

def load_skeleton(skeleton_name):
    skeleton_path = os.path.join(_SKELETONS_ROOT, skeleton_name)
    if not os.path.exists(skeleton_path):
        raise UnknownSkeleton()

    if os.path.isdir(skeleton_path):
        return SkeletonDir(skeleton_path)

    return SkeletonFile(skeleton_path)

class Skeleton(object):

    def generate(self, dest_path):
        raise NotImplementedError()  # pragma: no cover

    def is_single_file(self):
        return isinstance(self, SkeletonFile)

class SkeletonDir(Skeleton):

    def __init__(self, path):
        super(SkeletonDir, self).__init__()
        self._path = path

    def generate(self, dest_path):
        if not os.path.isdir(dest_path):
            os.mkdir(dest_path)
        for filename in os.listdir(self._path):
            if filename == '.cob.git.keep':
                continue
            skeleton = load_skeleton(os.path.join(self._path, filename))
            skeleton.generate(os.path.join(dest_path, filename))

class SkeletonFile(Skeleton):

    def __init__(self, path):
        super(SkeletonFile, self).__init__()
        self._path = path

    def generate(self, dest_path):
        env = jinja2.Environment(loader=jinja2.FileSystemLoader(os.path.dirname(self._path)),
                                 keep_trailing_newline=True)
        template = env.get_template(os.path.basename(self._path))
        normalized_path = os.path.relpath(dest_path) if not os.path.isabs(dest_path) else dest_path
        click.echo('Generating {}'.format(normalized_path))
        if os.path.exists(dest_path):
            raise click.ClickException("{} already exists".format(normalized_path))
        with open(normalized_path, 'w') as f:
            f.write(template.render(**_ctx))
<commit_msg>Run `npm install` as a part of frontend grain generation (closes #60)<commit_after>import os
import subprocess
from contextlib import contextmanager

import click
import jinja2
import logbook

import gossip

_logger = logbook.Logger(__name__)

_SKELETONS_ROOT = os.path.abspath(os.path.join(
    os.path.dirname(__file__), '..', '_skeletons'))

_ctx = {}

class UnknownSkeleton(Exception):
    pass

@click.group()
def generate():
    pass

def _get_grain_types():
    return sorted(filename.split('-', 1)[1]
                  for filename in os.listdir(_SKELETONS_ROOT)
                  if filename.startswith('grain-'))

@generate.command()
@click.option('-m', '--mountpoint', default="/")
@click.option('grain_type', '-t', '--type', default='views', type=click.Choice(_get_grain_types()))
@click.argument('name')
def grain(grain_type, name, mountpoint):
    _generate('grain-{}'.format(grain_type), name, {
        'name': name,
        'mountpoint': mountpoint,
    })
    gossip.trigger_with_tags('cob.after_generate.grain', tags=[grain_type], kwargs={'name': name})

@gossip.register('cob.after_generate.grain', tags=['frontend-ember'])
def after_generate_grain_frontend_ember(*, name):
    status, _ = subprocess.getstatusoutput('which ember')
    if status != 0:
        click.echo('You do not seem to have ember-cli installed. Skipping ember app creation...')
    else:
        click.echo('Generating new Ember project')
        subprocess.check_call('ember init', cwd=name, shell=True)
        subprocess.check_call('npm install', cwd=name, shell=True)

@generate.command()
@click.argument('path')
@click.argument('project_name', required=False)
def project(path, project_name=None):
    if project_name is None:
        project_name = os.path.basename(path)
    _generate('project', path, {
        'project_name': project_name
    })

@generate.command()
@click.argument('name')
@click.argument('mountpoint', default='/static')
def static_dir(name, mountpoint):
    _generate('static_dir', name, {
        'name': name,
        'mountpoint': mountpoint,
    })
    os.mkdir(os.path.join(name, 'root'))

@generate.command()
@click.argument('name', default='models')
def models(name):
    _generate('grain-models', name, {
        'name': name,
    })

def _generate(skeleton_name, dest_path, ctx):
    try:
        s = load_skeleton(skeleton_name)
    except UnknownSkeleton:
        raise click.ClickException('Unknown skeleton: {}'.format(skeleton_name))
    if s.is_single_file() and not dest_path.endswith('.py'):
        dest_path += '.py'
    with template_context(ctx):
        s.generate(dest_path)

@contextmanager
def template_context(ctx):
    _ctx.update(ctx)
    try:
        yield
    finally:
        _ctx.clear()

def load_skeleton(skeleton_name):
    skeleton_path = os.path.join(_SKELETONS_ROOT, skeleton_name)
    if not os.path.exists(skeleton_path):
        raise UnknownSkeleton()

    if os.path.isdir(skeleton_path):
        return SkeletonDir(skeleton_path)

    return SkeletonFile(skeleton_path)

class Skeleton(object):

    def generate(self, dest_path):
        raise NotImplementedError()  # pragma: no cover

    def is_single_file(self):
        return isinstance(self, SkeletonFile)

class SkeletonDir(Skeleton):

    def __init__(self, path):
        super(SkeletonDir, self).__init__()
        self._path = path

    def generate(self, dest_path):
        if not os.path.isdir(dest_path):
            os.mkdir(dest_path)
        for filename in os.listdir(self._path):
            if filename == '.cob.git.keep':
                continue
            skeleton = load_skeleton(os.path.join(self._path, filename))
            skeleton.generate(os.path.join(dest_path, filename))

class SkeletonFile(Skeleton):

    def __init__(self, path):
        super(SkeletonFile, self).__init__()
        self._path = path

    def generate(self, dest_path):
        env = jinja2.Environment(loader=jinja2.FileSystemLoader(os.path.dirname(self._path)),
                                 keep_trailing_newline=True)
        template = env.get_template(os.path.basename(self._path))
        normalized_path = os.path.relpath(dest_path) if not os.path.isabs(dest_path) else dest_path
        click.echo('Generating {}'.format(normalized_path))
        if os.path.exists(dest_path):
            raise click.ClickException("{} already exists".format(normalized_path))
        with open(normalized_path, 'w') as f:
            f.write(template.render(**_ctx))
<|endoftext|>


<commit_before>from __future__ import absolute_import

import numpy as np
import os

from astropy.convolution import convolve, Gaussian1DKernel, Box1DKernel
from astropy.io import fits
from astropy.modeling import models
from ccdproc import CCDData
from unittest import TestCase, skip
from ..wavelength import (WavelengthCalibration,
                          WavelengthSolution)

from ..redspec import get_args
from ...core import add_wcs_keys

class WavelengthCalibrationTests(TestCase):

    def setUp(self):
        argument_list = ['--data-path', os.getcwd(),
                         '--proc-path', os.getcwd(),
                         '--search-pattern', 'cfzsto',
                         '--output-prefix', 'w',
                         '--extraction', 'fractional',
                         '--reference-files', 'data/ref_comp',
                         '--max-targets', '3',
                         ]
        arguments = get_args(argument_list)
        self.wc = WavelengthCalibration(args=arguments)

        self.ccd = CCDData(data=np.random.random_sample(200),
                           meta=fits.Header(),
                           unit='adu')
        self.ccd = add_wcs_keys(ccd=self.ccd)

    def test_add_wavelength_solution(self):
        self.wc.rms_error = 0.1
        self.wc.n_points = 100
        self.wc.n_rejections = 2

        self.wc.calibration_lamp = 'non-existent.fits'

        crval1 = 3977.948
        npix = 4060
        cdelt = 0.9910068

        x_axis = np.linspace(crval1,
                             crval1 + cdelt * npix,
                             npix)

        self.ccd = self.wc.add_wavelength_solution(ccd=self.ccd,
                                                   x_axis=x_axis)

        self.assertEqual(self.ccd.header['CTYPE1'], 'LINEAR')
        self.assertEqual(self.ccd.header['CRVAL1'], crval1)
        self.assertEqual(self.ccd.header['CRPIX1'], 1)
        self.assertAlmostEqual(self.ccd.header['CDELT1'], cdelt, places=3)
        self.assertEqual(self.ccd.header['DCLOG1'],
                         'REFSPEC1 = {:s}'.format(self.wc.calibration_lamp))
        self.assertEqual(self.ccd.header['GSP_WRMS'], self.wc.rms_error)
        self.assertEqual(self.ccd.header['GSP_WPOI'], self.wc.n_points)
        self.assertEqual(self.ccd.header['GSP_WREJ'], self.wc.n_rejections)

    def test_automatic_wavelength_solution(self):
        pass

    def test__bin_reference_data(self):
        wavelength = np.linspace(3000, 7000, 4000)
        intensity = np.random.random_sample(4000)

        for i in range(1, 4):
            self.wc.serial_binning = i

            new_wavelength, new_intensity = self.wc._bin_reference_data(
                wavelength=wavelength,
                intensity=intensity)

            self.assertEqual(len(wavelength), len(intensity))
            self.assertEqual(len(new_wavelength), len(new_intensity))
            self.assertEqual(len(new_wavelength), np.floor(len(wavelength) / i))

    def test__cross_correlation(self):
        self.wc.lamp = self.ccd.copy()

        x_axis = np.arange(0, 4060, 1)

        reference = np.zeros(4060)
        gaussian = models.Gaussian1D(stddev=2)

        for i in sorted(np.random.choice(x_axis, 30)):
            gaussian.mean.value = i
            reference += gaussian(x_axis)

        offset = np.random.choice(range(1, 15), 1)[0]

        for slit in [1, 2, 3, 4, 5]:

            new_array = np.append(reference[offset:], np.zeros(offset))

            if slit > 3:
                box_kernel = Box1DKernel(width=slit / 0.15)
                new_array = convolve(new_array, box_kernel)

            self.assertEqual(len(reference), len(new_array))

            self.wc.lamp.header['SLIT'] = '{:d}.0" long slit'.format(slit)

            correlation_value = self.wc._cross_correlation(reference=reference,
                                                           new_array=new_array)
            self.assertEqual(correlation_value, offset)

def test_process_spectroscopy_data():
    pass

def test_wavelength_calibration___init__():
    pass

def test_wavelength_calibration___call__():
    pass

def test_wavelength_calibration_get_wsolution():
    pass

def test_wavelength_calibration_get_calibration_lamp():
    pass

def test_wavelength_calibration_get_lines_in_lamp():
    pass

def test_wavelength_calibration_get_best_filling_value():
    pass

def test_wavelength_calibration_recenter_lines():
    pass

def test_wavelength_calibration_recenter_broad_lines():
    pass

def test_wavelength_calibration_get_spectral_characteristics():
    pass

def test_wavelength_calibration_interpolate():
    pass

def test_wavelength_calibration_recenter_line_by_data():
    pass

def test_wavelength_calibration_predicted_wavelength():
    pass

def test_wavelength_calibration_automatic_wavelength_solution():
    pass

def test_wavelength_calibration_interactive_wavelength_solution():
    pass

def test_wavelength_calibration_cross_correlation():
    pass

def test_wavelength_calibration_on_click():
    pass

def test_wavelength_calibration_key_pressed():
    pass

def test_wavelength_calibration_register_mark():
    pass

def test_wavelength_calibration_find_more_lines():
    pass

def test_wavelength_calibration_update_marks_plot():
    pass

def test_wavelength_calibration_plot_raw_over_reference():
    pass

def test_wavelength_calibration_evaluate_solution():
    pass

def test_wavelength_calibration_fit_pixel_to_wavelength():
    pass

def test_wavelength_calibration_linearize_spectrum():
    pass

def test_wavelength_calibration_add_wavelength_solution():
    pass

def test_wavelength_calibration_display_onscreen_message():
    pass

def test_wavelength_calibration_display_help_text():
    pass

def test_wavelength_solution___init__():
    pass

def test_wavelength_solution_set_spectral_features():
    pass

def test_wavelength_solution_check_compatibility():
    pass

def test_wavelength_solution_set_solution_name():
    pass

# old tests

def test_wavelength_calibration_instantiate():
    from ..wavelength import WavelengthCalibration
    from .test_redspec import test_get_args
    import os

    test_args = test_get_args()

    wavelength_calibration = WavelengthCalibration(args=test_args)

    assert isinstance(wavelength_calibration, WavelengthCalibration)
    assert os.path.exists(test_args.reference_dir)

def test_get_wsolution_none():
    pass

def test_lambda_pipeline_to_iraf():
    pass

def test_lamp_correlation():
    """Cross correlate lamp

    :return:
    """
    pass

def test_rms_pipeline_to_iraf():
    pass
<commit_msg>added test for _evaluate_solution<commit_after>from __future__ import absolute_import

import numpy as np
import os

from astropy.convolution import convolve, Gaussian1DKernel, Box1DKernel
from astropy.io import fits
from astropy.modeling import models
from ccdproc import CCDData
from unittest import TestCase, skip
from ..wavelength import (WavelengthCalibration,
                          WavelengthSolution)

from ..redspec import get_args
from ...core import add_wcs_keys

class WavelengthCalibrationTests(TestCase):

    def setUp(self):
        argument_list = ['--data-path', os.getcwd(),
                         '--proc-path', os.getcwd(),
                         '--search-pattern', 'cfzsto',
                         '--output-prefix', 'w',
                         '--extraction', 'fractional',
                         '--reference-files', 'data/ref_comp',
                         '--max-targets', '3',
                         ]
        arguments = get_args(argument_list)
        self.wc = WavelengthCalibration(args=arguments)

        self.ccd = CCDData(data=np.random.random_sample(200),
                           meta=fits.Header(),
                           unit='adu')
        self.ccd = add_wcs_keys(ccd=self.ccd)

    def test_add_wavelength_solution(self):
        self.wc.rms_error = 0.1
        self.wc.n_points = 100
        self.wc.n_rejections = 2

        self.wc.calibration_lamp = 'non-existent.fits'

        crval1 = 3977.948
        npix = 4060
        cdelt = 0.9910068

        x_axis = np.linspace(crval1,
                             crval1 + cdelt * npix,
                             npix)

        self.ccd = self.wc.add_wavelength_solution(ccd=self.ccd,
                                                   x_axis=x_axis)

        self.assertEqual(self.ccd.header['CTYPE1'], 'LINEAR')
        self.assertEqual(self.ccd.header['CRVAL1'], crval1)
        self.assertEqual(self.ccd.header['CRPIX1'], 1)
        self.assertAlmostEqual(self.ccd.header['CDELT1'], cdelt, places=3)
        self.assertEqual(self.ccd.header['DCLOG1'],
                         'REFSPEC1 = {:s}'.format(self.wc.calibration_lamp))
        self.assertEqual(self.ccd.header['GSP_WRMS'], self.wc.rms_error)
        self.assertEqual(self.ccd.header['GSP_WPOI'], self.wc.n_points)
        self.assertEqual(self.ccd.header['GSP_WREJ'], self.wc.n_rejections)

    def test_automatic_wavelength_solution(self):
        pass

    def test__bin_reference_data(self):
        wavelength = np.linspace(3000, 7000, 4000)
        intensity = np.random.random_sample(4000)

        for i in range(1, 4):
            self.wc.serial_binning = i

            new_wavelength, new_intensity = self.wc._bin_reference_data(
                wavelength=wavelength,
                intensity=intensity)

            self.assertEqual(len(wavelength), len(intensity))
            self.assertEqual(len(new_wavelength), len(new_intensity))
            self.assertEqual(len(new_wavelength), np.floor(len(wavelength) / i))

    def test__cross_correlation(self):
        self.wc.lamp = self.ccd.copy()

        x_axis = np.arange(0, 4060, 1)

        reference = np.zeros(4060)
        gaussian = models.Gaussian1D(stddev=2)

        for i in sorted(np.random.choice(x_axis, 30)):
            gaussian.mean.value = i
            reference += gaussian(x_axis)

        offset = np.random.choice(range(1, 15), 1)[0]

        for slit in [1, 2, 3, 4, 5]:

            new_array = np.append(reference[offset:], np.zeros(offset))

            if slit > 3:
                box_kernel = Box1DKernel(width=slit / 0.15)
                new_array = convolve(new_array, box_kernel)

            self.assertEqual(len(reference), len(new_array))

            self.wc.lamp.header['SLIT'] = '{:d}.0" long slit'.format(slit)

            correlation_value = self.wc._cross_correlation(reference=reference,
                                                           new_array=new_array)
            self.assertEqual(correlation_value, offset)

    def test__evaluate_solution(self):

        differences = np.array([0.5] * 10)

        clipped_differences = np.ma.masked_array(differences,
                                                 mask=[0,
                                                       0,
                                                       1,
                                                       0,
                                                       0,
                                                       1,
                                                       0,
                                                       0,
                                                       1,
                                                       0])

        rms_error, n_points, n_rej = self.wc._evaluate_solution(
            clipped_differences=clipped_differences)

        self.assertEqual(rms_error, 0.5)
        self.assertEqual(n_points, 10)
        self.assertEqual(n_rej, 3)

def test_process_spectroscopy_data():
    pass

def test_wavelength_calibration___init__():
    pass

def test_wavelength_calibration___call__():
    pass

def test_wavelength_calibration_get_wsolution():
    pass

def test_wavelength_calibration_get_calibration_lamp():
    pass

def test_wavelength_calibration_get_lines_in_lamp():
    pass

def test_wavelength_calibration_get_best_filling_value():
    pass

def test_wavelength_calibration_recenter_lines():
    pass

def test_wavelength_calibration_recenter_broad_lines():
    pass

def test_wavelength_calibration_get_spectral_characteristics():
    pass

def test_wavelength_calibration_interpolate():
    pass

def test_wavelength_calibration_recenter_line_by_data():
    pass

def test_wavelength_calibration_predicted_wavelength():
    pass

def test_wavelength_calibration_automatic_wavelength_solution():
    pass

def test_wavelength_calibration_interactive_wavelength_solution():
    pass

def test_wavelength_calibration_cross_correlation():
    pass

def test_wavelength_calibration_on_click():
    pass

def test_wavelength_calibration_key_pressed():
    pass

def test_wavelength_calibration_register_mark():
    pass

def test_wavelength_calibration_find_more_lines():
    pass

def test_wavelength_calibration_update_marks_plot():
    pass

def test_wavelength_calibration_plot_raw_over_reference():
    pass

def test_wavelength_calibration_evaluate_solution():
    pass

def test_wavelength_calibration_fit_pixel_to_wavelength():
    pass

def test_wavelength_calibration_linearize_spectrum():
    pass

def test_wavelength_calibration_add_wavelength_solution():
    pass

def test_wavelength_calibration_display_onscreen_message():
    pass

def test_wavelength_calibration_display_help_text():
    pass

def test_wavelength_solution___init__():
    pass

def test_wavelength_solution_set_spectral_features():
    pass

def test_wavelength_solution_check_compatibility():
    pass

def test_wavelength_solution_set_solution_name():
    pass

# old tests

def test_wavelength_calibration_instantiate():
    from ..wavelength import WavelengthCalibration
    from .test_redspec import test_get_args
    import os

    test_args = test_get_args()

    wavelength_calibration = WavelengthCalibration(args=test_args)

    assert isinstance(wavelength_calibration, WavelengthCalibration)
    assert os.path.exists(test_args.reference_dir)

def test_get_wsolution_none():
    pass

def test_lambda_pipeline_to_iraf():
    pass

def test_lamp_correlation():
    """Cross correlate lamp

    :return:
    """
    pass

def test_rms_pipeline_to_iraf():
    pass
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
__version__ = '0.1'
import sys, os.path
if os.path.exists('/var/www/pytmdb'):
	sys.path.append('var/www/pytmdb3/')
elif os.path.exists('../pytmdb3'):
	sys.path.append('../pytmdb3/')

sys.path.append('/usr/local/lib/python2.7/dist-packages/')
sys.path.append('/usr/lib/python2.7/dist-packages/')

from functools import wraps
from flask import Flask, session, redirect, url_for, request, render_template
from flask_debugtoolbar import DebugToolbarExtension
from flask.ext.mongoengine import MongoEngine

from tmdb3 import set_key

app = Flask('project')
app.config['SECRET_KEY'] = 'random'
app.config['MONGODB_SETTINGS'] = {'DB': 'my_movie_library'}
app.config['SMTP_USER'] = "my.movie.library.reminder@gmail.com"
app.config['SMTP_PASSWORD'] = "1 LikemoVies&p0pCO7n"
app.config['SMTP_SERVER'] = "smtp.gmail.com:587"
app.config['TMDB_API_KEY'] = "542606a6ccff81a0337dc370a0cbfc37"
set_key(app.config['TMDB_API_KEY'])

# app.config["MONGODB_SETTINGS"] = {'DB': "my_movie_library",
								   # 'host': '192.168.1.89'}
app.debug = True
# toolbar = DebugToolbarExtension(app)
db = MongoEngine(app)
# app.debug = True
# toolbar = DebugToolbarExtension(app)
def security(role=None):
	def wrapper(func):
		@wraps(func)
		def security_check(*args,**kwargs):
			import json
			user = None
			if 'user' in session:
				from project.model.User import User
				user = json.loads(session['user'])
				user = User.objects(email=user['email']).first()
				kwargs['user'] = user

			if role == None:
				return func(*args,**kwargs);
			if isinstance(role, list):
				if len(role) == 0:
					return func(*args,**kwargs);
				elif user == None:
					return redirect(url_for('start', next=request.url))

				for r in role:
					if r in user.roles:
						return func(*args,**kwargs);
				return redirect(url_for('start', next=request.url))

			if user == None or role not in user.roles:
				return redirect(url_for('start', next=request.url))

			return func(*args,**kwargs);
		return security_check
	return wrapper

from project.controllers import *
<commit_msg>Updated init<commit_after># -*- coding: utf-8 -*-
__version__ = '0.1'
import sys, os.path
if os.path.exists('/var/www/pytmdb'):
	sys.path.append('var/www/pytmdb3/')
elif os.path.exists('../pytmdb3'):
	sys.path.append('../pytmdb3/')

from functools import wraps
from flask import Flask, session, redirect, url_for, request, render_template
from flask_debugtoolbar import DebugToolbarExtension
from flask.ext.mongoengine import MongoEngine

from tmdb3 import set_key

app = Flask('project')
app.config['SECRET_KEY'] = 'random'
app.config['MONGODB_SETTINGS'] = {'DB': 'my_movie_library'}
app.config['SMTP_USER'] = ""
app.config['SMTP_PASSWORD'] = ""
app.config['SMTP_SERVER'] = "smtp.gmail.com:587"
app.config['TMDB_API_KEY'] = ""

set_key(app.config['TMDB_API_KEY'])

# app.config["MONGODB_SETTINGS"] = {'DB': "my_movie_library",
								   # 'host': '192.168.1.89'}
app.debug = True
# toolbar = DebugToolbarExtension(app)
db = MongoEngine(app)
# app.debug = True
# toolbar = DebugToolbarExtension(app)
def security(role=None):
	def wrapper(func):
		@wraps(func)
		def security_check(*args,**kwargs):
			import json
			user = None
			if 'user' in session:
				from project.model.User import User
				user = json.loads(session['user'])
				user = User.objects(email=user['email']).first()
				kwargs['user'] = user

			if role == None:
				return func(*args,**kwargs);
			if isinstance(role, list):
				if len(role) == 0:
					return func(*args,**kwargs);
				elif user == None:
					return redirect(url_for('start', next=request.url))

				for r in role:
					if r in user.roles:
						return func(*args,**kwargs);
				return redirect(url_for('start', next=request.url))

			if user == None or role not in user.roles:
				return redirect(url_for('start', next=request.url))

			return func(*args,**kwargs);
		return security_check
	return wrapper

from project.controllers import *
<|endoftext|>


<commit_before>from __future__ import with_statement

import datetime
import random
import hashlib
import base64
from decimal import Decimal

from django.db import models
from django.contrib.sites.models import Site
from django.conf import settings
from django.contrib.auth.models import User

from django_bitcoin.utils import *
from django_bitcoin.utils import bitcoind
from django_bitcoin import settings

from django.utils.translation import ugettext as _

PAYMENT_VALID_HOURS = getattr(
    settings,
    "BITCOIND_PAYMENT_VALID_HOURS",
    128)

PAYMENT_BUFFER_SIZE = getattr(
    settings,
    "PAYMENT_BUFFER_SIZE",
    5)

BITCOIN_MINIMUM_CONFIRMATIONS = getattr(
    settings,
    "BITCOIN_MINIMUM_CONFIRMATIONS",
    0)

REUSE_ADDRESSES = getattr(
    settings,
    "BITCOIND_REUSE_ADDRESSES",
    True)

ESCROW_PAYMENT_TIME_HOURS = getattr(
    settings,
    "BITCOIND_ESCROW_PAYMENT_TIME_HOURS",
    4)
ESCROW_RELEASE_TIME_DAYS = getattr(
    settings,
    "BITCOIND_ESCROW_RELEASE_TIME_DAYS",
    14)

currencies=(
    (1, "USD"),
    (2, "EUR"),
    (3, "BTC")
)

confirmation_choices=(
    (0, "0, (quick, recommended)"),
    (1, "1, (safer, slower for the buyer)"),
    (5, "5, (for the paranoid, not recommended)")
)

class Transaction(models.Model):
    created_at = models.DateTimeField(default=datetime.datetime.now)
    amount = models.DecimalField(
        max_digits=16,
        decimal_places=8,
        default=Decimal("0.0"))
    address = models.CharField(max_length=50)

class BitcoinAddress(models.Model):
    address = models.CharField(max_length=50, blank=True)
    created_at = models.DateTimeField(default=datetime.datetime.now)
    active = models.BooleanField(default=False)
    least_received = models.DecimalField(max_digits=16, decimal_places=8, default=Decimal(0))

    def received(self, minconf=BITCOIN_MINIMUM_CONFIRMATIONS):
        r=bitcoind.total_received(self.address, minconf=minconf)
        if r>self.least_received:
            self.least_received=r
            self.save()
        return r

    def __unicode__(self):
        return self.address

@transaction.commit_on_success
def new_bitcoin_address():
    bp=BitcoinAddress.objects.filter(active=False)
    if len(bp)<1:
        refill_payment_queue()
        bp=BitcoinAddress.objects.filter(active=False)
    bp=bp[0]
    bp.active=True
    bp.save()
    return bp

class Payment(models.Model):
    description = models.CharField(
        max_length=255,
        blank=True)
    address = models.CharField(
        max_length=50)
    amount = models.DecimalField(
        max_digits=16,
        decimal_places=8,
        default=Decimal("0.0"))
    amount_paid = models.DecimalField(
        max_digits=16,
        decimal_places=8,
        default=Decimal("0.0"))
    active = models.BooleanField(default=False)

    created_at = models.DateTimeField(default=datetime.datetime.now)
    updated_at = models.DateTimeField()

    paid_at = models.DateTimeField(null=True, default=None)

    withdrawn_total = models.DecimalField(
        max_digits=16,
        decimal_places=8,
        default=Decimal("0.0"))

    transactions = models.ManyToManyField(Transaction)

    def calculate_amount(self, proportion):
        return quantitize_bitcoin(
            Decimal((proportion/Decimal("100.0"))*self.amount))

    def add_transaction(self, amount, address):
        self.withdrawn_total += amount
        bctrans = self.transactions.create(
            amount=amount,
            address=address)
        self.save()

        return bctrans

    def withdraw_proportion(self, address, proportion):
        if proportion<=Decimal("0") or proportion>Decimal("100"):
            raise Exception("Illegal proportion.")

        amount = self.calculate_amount(proportion)

        if self.amount-self.withdrawn_total > amount:
            raise Exception("Trying to withdraw too much.")

        self.add_transaction(amount, address)
        bitcoind.send(address, amount)

    @classmethod
    def withdraw_proportion_all(cls, address, bitcoin_payments_proportions):
        """hash BitcoinPayment -> Proportion"""
        final_amount=Decimal("0.0")
        print bitcoin_payments_proportions
        for bp, proportion in bitcoin_payments_proportions.iteritems():
            am=bp.calculate_amount(proportion)
            final_amount+=am
            bp.add_transaction(am, address)
        bitcoind.send(address, final_amount)
        return True

    def withdraw_amounts(self, addresses_shares):
        """hash address -> percentage (string -> Decimal)"""
        if self.amount_paid<self.amount:
            raise Exception("Not paid.")
        if self.withdrawn_at:
            raise Exception("Trying to withdraw again.")
        if sum(addresses_shares.values())>100:
            raise Exception("Sum of proportions must be <=100.")
        #self.withdraw_addresses=",".join(addresses)
        #self.withdraw_proportions=",".join([str(x) for x in proportions])
        amounts=[]
        for p in addresses_shares.values():
            if p<=0:
                raise Exception()
            am=quantitize_bitcoin(Decimal((p/Decimal("100.0"))*self.amount))
            amounts.append(am)
        #self.withdraw_proportions=",".join([str(x) for x in ])
        if sum(amounts)>self.amount:
            raise Exception("Sum of calculated amounts exceeds funds.")
        return amounts

    @classmethod
    def calculate_amounts(cls, bitcoinpayments, addresses_shares):
        amounts_all=[Decimal("0.0") for _i in addresses_shares]
        for amount, payment in zip(amounts_all, bitcoinpayments):
            withdrawn=payment.withdraw_amounts(addresses_shares)
            amounts_all=[(w+total) for w, total in zip(withdrawn, amounts_all)]
        return amounts_all

    @classmethod
    def withdraw_all(cls, bitcoinpayments, addresses_shares):
        #if len(bitcoinpayments)!=len(addresses_shares):
        #    raise Exception("")
        amounts_all=Payment.calculate_amounts(bitcoinpayments, addresses_shares)
        for bp in bitcoinpayments:
            am=bp.withdraw_amounts(addresses_shares)
            bp.withdraw_addresses=",".join(addresses_shares.keys())
            bp.withdraw_proportions=",".join(
                [str(x) for x in addresses_shares.values()])
            bp.withdraw_amounts=",".join(
                [str(x) for x in am])
            bp.withdrawn_at=datetime.datetime.now()
            bp.withdrawn_total=sum(am)
            bp.save()
        for i, share in enumerate(addresses_shares.keys()):
            bitcoind.send(share, amounts_all[i])
        return True

    def is_paid(self, minconf=1):
        if self.paid_at:
            return True
        self.update_payment(minconf=minconf)
        return self.amount_paid>=self.amount

    def getbalance(self, minconf=1):
        return bitcoind.total_received(self.address, minconf=minconf)

    def update_payment(self, minconf=1):
        new_amount=Decimal(bitcoin_getbalance(self.address, minconf=minconf))
        print "blaa", new_amount, self.address
        if new_amount>=self.amount:
            self.amount_paid=new_amount
            self.paid_at=datetime.datetime.now()
            self.save()
        #elif (datetime.datetime.now()-self.updated_at)>datetime.timedelta(hours=PAYMENT_VALID_HOURS):
        #    self.deactivate()

    def deactivate(self):
        return False
        if self.amount_paid > Decimal("0"):
            return False
        self.active=False
        self.description=""
        self.save()
        return True

    def save(self, **kwargs):
        self.updated_at = datetime.datetime.now()
        return super(Payment, self).save(**kwargs)

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

    @models.permalink
    def get_absolute_url(self):
        return ('view_or_url_name',)

class WalletTransaction(models.Model):
    created_at = models.DateTimeField(default=datetime.datetime.now)
    from_wallet = models.ForeignKey(
        'Wallet',
        related_name="sent_transactions")
    to_wallet = models.ForeignKey(
        'Wallet',
        null=True,
        related_name="received_transactions")
    to_bitcoinaddress = models.CharField(
        max_length=50,
        blank=True)
    amount = models.DecimalField(
        max_digits=16,
        decimal_places=8,
        default=Decimal("0.0"))

    def __unicode__(self):
        if self.from_wallet and self.to_wallet:
            return u"Wallet transaction "+unicode(self.amount)
        elif self.from_wallet and self.to_bitcoinaddress:
            return u"Outgoing bitcoin transaction "+unicode(self.amount)
        return u"Fee "+unicode(self.amount)

class Wallet(models.Model):
    created_at = models.DateTimeField(default=datetime.datetime.now)
    updated_at = models.DateTimeField()

    addresses = models.ManyToManyField(BitcoinAddress)
    transactions_with = models.ManyToManyField(
        'self',
        through=WalletTransaction,
        symmetrical=False)

    def __unicode__(self):
        return u"%s: %s" % (self.id, unicode(self.created_at))

    def receiving_address(self, fresh_addr=True):
        usable_addresses = self.addresses.filter(active=True).order_by("-id")
        if fresh_addr:
            usable_addresses = usable_addresses.filter(least_received=Decimal(0))
        if usable_addresses.count():
            return usable_addresses[0].address
        addr=new_bitcoin_address()
        self.addresses.add(addr)
        return addr.address

    def static_receiving_address(self):
        '''
        Returns a static receiving address for this Wallet object.
        '''
        return self.receiving_address(fresh_addr=False)

    def send_to_wallet(self, otherWallet, amount):
        if amount>self.total_balance():
            raise Exception(_("Trying to send too much"))
        if self==otherWallet:
            raise Exception(_("Can't send to self-wallet"))
        if not otherWallet.id or not self.id:
            raise Exception(_("Some of the wallets not saved"))
        return WalletTransaction.objects.create(
            amount=amount,
            from_wallet=self,
            to_wallet=otherWallet)

    def send_to_address(self, address, amount):
        if Decimal(amount)<Decimal(0):
            raise Exception(_("Trying to send too much"))
        if Decimal(amount)>self.total_balance():
            raise Exception(_("Trying to send too much"))
        bwt = WalletTransaction.objects.create(
            amount=amount,
            from_wallet=self,
            to_bitcoinaddress=address)
        try:
            result=bitcoind.send(address, amount)
        except JSONRPCException:
            bwt.delete()
            raise
        #print result
        transaction=bitcoind.gettransaction(result)
        if Decimal(transaction['fee'])<Decimal(0):
            fee_transaction = WalletTransaction.objects.create(
                amount=Decimal(transaction['fee'])*Decimal(-1),
                from_wallet=self)
        return bwt

    def total_received(self):
        """docstring for getreceived"""
        s=sum([a.received() for a in self.addresses.all()])
        rt=self.received_transactions.aggregate(models.Sum("amount"))['amount__sum'] or Decimal(0)
        return (s+rt)

    def total_sent(self):
        return self.sent_transactions.aggregate(models.Sum("amount"))['amount__sum'] or Decimal(0)

    def total_balance(self):
        return self.total_received() - self.total_sent()

    def save(self, **kwargs):
        self.updated_at = datetime.datetime.now()
        super(Wallet, self).save(**kwargs)

### Maybe in the future

class FiatWalletTransaction(models.Model):
    """Transaction for storing fiat currencies"""
    pass

class FiatWallet(models.Model):
    """Wallet for storing fiat currencies"""
    pass

class BitcoinEscrow(models.Model):
    """Bitcoin escrow payment"""

    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    seller = models.ForeignKey(User)

    bitcoin_payment = models.ForeignKey(Payment)

    confirm_hash = models.CharField(max_length=50, blank=True)

    buyer_address = models.TextField()
    buyer_phone = models.CharField(max_length=20, blank=True)
    buyer_email = models.EmailField(max_length=75)

    def save(self, **kwargs):
        super(BitcoinEscrow, self).save(**kwargs)
        if not self.confirm_hash:
            self.confirm_hash=generateuniquehash(
                length=32,
                extradata=str(self.id))
            super(BitcoinEscrow, self).save(**kwargs)

    @models.permalink
    def get_absolute_url(self):
        return ('view_or_url_name',)

def refill_payment_queue():
    c=Payment.objects.filter(active=False).count()
    if PAYMENT_BUFFER_SIZE>c:
        for i in range(0,settings.PAYMENT_BUFFER_SIZE-c):
            bp=Payment()
            bp.address=bitcoind.create_address()
            bp.save()
    c=BitcoinAddress.objects.filter(active=False).count()
    if PAYMENT_BUFFER_SIZE>c:
        for i in range(0,settings.PAYMENT_BUFFER_SIZE-c):
            ba=BitcoinAddress()
            ba.address=bitcoind.create_address()
            ba.save()

def update_payments():
    if not cache.get('last_full_check'):
        cache.set('bitcoinprice', cache.get('bitcoinprice_old'))
    bps=BitcoinPayment.objects.filter(active=True)
    for bp in bps:
        bp.amount_paid=Decimal(bitcoin_getbalance(bp.address))
        bp.save()
        print bp.amount
        print bp.amount_paid

@transaction.commit_on_success
def new_bitcoin_payment(amount):
    bp=BitcoinPayment.objects.filter(active=False)
    if len(bp)<1:
        refill_payment_queue()
        bp=BitcoinPayment.objects.filter(active=False)
    bp=bp[0]
    bp.active=True
    bp.amount=amount
    bp.save()
    return bp

def getNewBitcoinPayment(amount):
    warnings.warn("Use new_bitcoin_payment(amount) instead",
                  DeprecationWarning)
    return new_bitcoin_payment(amount)

@transaction.commit_on_success
def new_bitcoin_payment_eur(amount):
    print bitcoinprice_eur()
    return new_bitcoin_payment(Decimal(amount)/Decimal(bitcoinprice_eur()['24h']))

def getNewBitcoinPayment_eur(amount):
    return new_bitcoin_payment_eur(amount)

# initialize the conversion module

from django_bitcoin import currency

from django.core import urlresolvers
from django.utils import importlib

for dottedpath in settings.BITCOIN_CURRENCIES:
    mod, func = urlresolvers.get_mod_func(dottedpath)
    klass = getattr(importlib.import_module(mod), func)
    currency.exchange.register_currency(klass())

# EOF

<commit_msg>fixed static_Receiving_address<commit_after>from __future__ import with_statement

import datetime
import random
import hashlib
import base64
from decimal import Decimal

from django.db import models
from django.contrib.sites.models import Site
from django.conf import settings
from django.contrib.auth.models import User

from django_bitcoin.utils import *
from django_bitcoin.utils import bitcoind
from django_bitcoin import settings

from django.utils.translation import ugettext as _

PAYMENT_VALID_HOURS = getattr(
    settings,
    "BITCOIND_PAYMENT_VALID_HOURS",
    128)

PAYMENT_BUFFER_SIZE = getattr(
    settings,
    "PAYMENT_BUFFER_SIZE",
    5)

BITCOIN_MINIMUM_CONFIRMATIONS = getattr(
    settings,
    "BITCOIN_MINIMUM_CONFIRMATIONS",
    0)

REUSE_ADDRESSES = getattr(
    settings,
    "BITCOIND_REUSE_ADDRESSES",
    True)

ESCROW_PAYMENT_TIME_HOURS = getattr(
    settings,
    "BITCOIND_ESCROW_PAYMENT_TIME_HOURS",
    4)
ESCROW_RELEASE_TIME_DAYS = getattr(
    settings,
    "BITCOIND_ESCROW_RELEASE_TIME_DAYS",
    14)

currencies=(
    (1, "USD"),
    (2, "EUR"),
    (3, "BTC")
)

confirmation_choices=(
    (0, "0, (quick, recommended)"),
    (1, "1, (safer, slower for the buyer)"),
    (5, "5, (for the paranoid, not recommended)")
)

class Transaction(models.Model):
    created_at = models.DateTimeField(default=datetime.datetime.now)
    amount = models.DecimalField(
        max_digits=16,
        decimal_places=8,
        default=Decimal("0.0"))
    address = models.CharField(max_length=50)

class BitcoinAddress(models.Model):
    address = models.CharField(max_length=50, blank=True)
    created_at = models.DateTimeField(default=datetime.datetime.now)
    active = models.BooleanField(default=False)
    least_received = models.DecimalField(max_digits=16, decimal_places=8, default=Decimal(0))

    def received(self, minconf=BITCOIN_MINIMUM_CONFIRMATIONS):
        r=bitcoind.total_received(self.address, minconf=minconf)
        if r>self.least_received:
            self.least_received=r
            self.save()
        return r

    def __unicode__(self):
        return self.address

@transaction.commit_on_success
def new_bitcoin_address():
    bp=BitcoinAddress.objects.filter(active=False)
    if len(bp)<1:
        refill_payment_queue()
        bp=BitcoinAddress.objects.filter(active=False)
    bp=bp[0]
    bp.active=True
    bp.save()
    return bp

class Payment(models.Model):
    description = models.CharField(
        max_length=255,
        blank=True)
    address = models.CharField(
        max_length=50)
    amount = models.DecimalField(
        max_digits=16,
        decimal_places=8,
        default=Decimal("0.0"))
    amount_paid = models.DecimalField(
        max_digits=16,
        decimal_places=8,
        default=Decimal("0.0"))
    active = models.BooleanField(default=False)

    created_at = models.DateTimeField(default=datetime.datetime.now)
    updated_at = models.DateTimeField()

    paid_at = models.DateTimeField(null=True, default=None)

    withdrawn_total = models.DecimalField(
        max_digits=16,
        decimal_places=8,
        default=Decimal("0.0"))

    transactions = models.ManyToManyField(Transaction)

    def calculate_amount(self, proportion):
        return quantitize_bitcoin(
            Decimal((proportion/Decimal("100.0"))*self.amount))

    def add_transaction(self, amount, address):
        self.withdrawn_total += amount
        bctrans = self.transactions.create(
            amount=amount,
            address=address)
        self.save()

        return bctrans

    def withdraw_proportion(self, address, proportion):
        if proportion<=Decimal("0") or proportion>Decimal("100"):
            raise Exception("Illegal proportion.")

        amount = self.calculate_amount(proportion)

        if self.amount-self.withdrawn_total > amount:
            raise Exception("Trying to withdraw too much.")

        self.add_transaction(amount, address)
        bitcoind.send(address, amount)

    @classmethod
    def withdraw_proportion_all(cls, address, bitcoin_payments_proportions):
        """hash BitcoinPayment -> Proportion"""
        final_amount=Decimal("0.0")
        print bitcoin_payments_proportions
        for bp, proportion in bitcoin_payments_proportions.iteritems():
            am=bp.calculate_amount(proportion)
            final_amount+=am
            bp.add_transaction(am, address)
        bitcoind.send(address, final_amount)
        return True

    def withdraw_amounts(self, addresses_shares):
        """hash address -> percentage (string -> Decimal)"""
        if self.amount_paid<self.amount:
            raise Exception("Not paid.")
        if self.withdrawn_at:
            raise Exception("Trying to withdraw again.")
        if sum(addresses_shares.values())>100:
            raise Exception("Sum of proportions must be <=100.")
        #self.withdraw_addresses=",".join(addresses)
        #self.withdraw_proportions=",".join([str(x) for x in proportions])
        amounts=[]
        for p in addresses_shares.values():
            if p<=0:
                raise Exception()
            am=quantitize_bitcoin(Decimal((p/Decimal("100.0"))*self.amount))
            amounts.append(am)
        #self.withdraw_proportions=",".join([str(x) for x in ])
        if sum(amounts)>self.amount:
            raise Exception("Sum of calculated amounts exceeds funds.")
        return amounts

    @classmethod
    def calculate_amounts(cls, bitcoinpayments, addresses_shares):
        amounts_all=[Decimal("0.0") for _i in addresses_shares]
        for amount, payment in zip(amounts_all, bitcoinpayments):
            withdrawn=payment.withdraw_amounts(addresses_shares)
            amounts_all=[(w+total) for w, total in zip(withdrawn, amounts_all)]
        return amounts_all

    @classmethod
    def withdraw_all(cls, bitcoinpayments, addresses_shares):
        #if len(bitcoinpayments)!=len(addresses_shares):
        #    raise Exception("")
        amounts_all=Payment.calculate_amounts(bitcoinpayments, addresses_shares)
        for bp in bitcoinpayments:
            am=bp.withdraw_amounts(addresses_shares)
            bp.withdraw_addresses=",".join(addresses_shares.keys())
            bp.withdraw_proportions=",".join(
                [str(x) for x in addresses_shares.values()])
            bp.withdraw_amounts=",".join(
                [str(x) for x in am])
            bp.withdrawn_at=datetime.datetime.now()
            bp.withdrawn_total=sum(am)
            bp.save()
        for i, share in enumerate(addresses_shares.keys()):
            bitcoind.send(share, amounts_all[i])
        return True

    def is_paid(self, minconf=1):
        if self.paid_at:
            return True
        self.update_payment(minconf=minconf)
        return self.amount_paid>=self.amount

    def getbalance(self, minconf=1):
        return bitcoind.total_received(self.address, minconf=minconf)

    def update_payment(self, minconf=1):
        new_amount=Decimal(bitcoin_getbalance(self.address, minconf=minconf))
        print "blaa", new_amount, self.address
        if new_amount>=self.amount:
            self.amount_paid=new_amount
            self.paid_at=datetime.datetime.now()
            self.save()
        #elif (datetime.datetime.now()-self.updated_at)>datetime.timedelta(hours=PAYMENT_VALID_HOURS):
        #    self.deactivate()

    def deactivate(self):
        return False
        if self.amount_paid > Decimal("0"):
            return False
        self.active=False
        self.description=""
        self.save()
        return True

    def save(self, **kwargs):
        self.updated_at = datetime.datetime.now()
        return super(Payment, self).save(**kwargs)

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

    @models.permalink
    def get_absolute_url(self):
        return ('view_or_url_name',)

class WalletTransaction(models.Model):
    created_at = models.DateTimeField(default=datetime.datetime.now)
    from_wallet = models.ForeignKey(
        'Wallet',
        related_name="sent_transactions")
    to_wallet = models.ForeignKey(
        'Wallet',
        null=True,
        related_name="received_transactions")
    to_bitcoinaddress = models.CharField(
        max_length=50,
        blank=True)
    amount = models.DecimalField(
        max_digits=16,
        decimal_places=8,
        default=Decimal("0.0"))

    def __unicode__(self):
        if self.from_wallet and self.to_wallet:
            return u"Wallet transaction "+unicode(self.amount)
        elif self.from_wallet and self.to_bitcoinaddress:
            return u"Outgoing bitcoin transaction "+unicode(self.amount)
        return u"Fee "+unicode(self.amount)

class Wallet(models.Model):
    created_at = models.DateTimeField(default=datetime.datetime.now)
    updated_at = models.DateTimeField()

    addresses = models.ManyToManyField(BitcoinAddress)
    transactions_with = models.ManyToManyField(
        'self',
        through=WalletTransaction,
        symmetrical=False)

    def __unicode__(self):
        return u"%s: %s" % (self.id, unicode(self.created_at))

    def receiving_address(self, fresh_addr=True):
        usable_addresses = self.addresses.filter(active=True).order_by("id")
        if fresh_addr:
            usable_addresses = usable_addresses.filter(least_received=Decimal(0))
        if usable_addresses.count():
            return usable_addresses[0].address
        addr=new_bitcoin_address()
        self.addresses.add(addr)
        return addr.address

    def static_receiving_address(self):
        '''
        Returns a static receiving address for this Wallet object.
        '''
        return self.receiving_address(fresh_addr=False)

    def send_to_wallet(self, otherWallet, amount):
        if amount>self.total_balance():
            raise Exception(_("Trying to send too much"))
        if self==otherWallet:
            raise Exception(_("Can't send to self-wallet"))
        if not otherWallet.id or not self.id:
            raise Exception(_("Some of the wallets not saved"))
        return WalletTransaction.objects.create(
            amount=amount,
            from_wallet=self,
            to_wallet=otherWallet)

    def send_to_address(self, address, amount):
        if Decimal(amount)<Decimal(0):
            raise Exception(_("Trying to send too much"))
        if Decimal(amount)>self.total_balance():
            raise Exception(_("Trying to send too much"))
        bwt = WalletTransaction.objects.create(
            amount=amount,
            from_wallet=self,
            to_bitcoinaddress=address)
        try:
            result=bitcoind.send(address, amount)
        except JSONRPCException:
            bwt.delete()
            raise
        #print result
        transaction=bitcoind.gettransaction(result)
        if Decimal(transaction['fee'])<Decimal(0):
            fee_transaction = WalletTransaction.objects.create(
                amount=Decimal(transaction['fee'])*Decimal(-1),
                from_wallet=self)
        return bwt

    def total_received(self):
        """docstring for getreceived"""
        s=sum([a.received() for a in self.addresses.all()])
        rt=self.received_transactions.aggregate(models.Sum("amount"))['amount__sum'] or Decimal(0)
        return (s+rt)

    def total_sent(self):
        return self.sent_transactions.aggregate(models.Sum("amount"))['amount__sum'] or Decimal(0)

    def total_balance(self):
        return self.total_received() - self.total_sent()

    def save(self, **kwargs):
        self.updated_at = datetime.datetime.now()
        super(Wallet, self).save(**kwargs)

### Maybe in the future

class FiatWalletTransaction(models.Model):
    """Transaction for storing fiat currencies"""
    pass

class FiatWallet(models.Model):
    """Wallet for storing fiat currencies"""
    pass

class BitcoinEscrow(models.Model):
    """Bitcoin escrow payment"""

    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    seller = models.ForeignKey(User)

    bitcoin_payment = models.ForeignKey(Payment)

    confirm_hash = models.CharField(max_length=50, blank=True)

    buyer_address = models.TextField()
    buyer_phone = models.CharField(max_length=20, blank=True)
    buyer_email = models.EmailField(max_length=75)

    def save(self, **kwargs):
        super(BitcoinEscrow, self).save(**kwargs)
        if not self.confirm_hash:
            self.confirm_hash=generateuniquehash(
                length=32,
                extradata=str(self.id))
            super(BitcoinEscrow, self).save(**kwargs)

    @models.permalink
    def get_absolute_url(self):
        return ('view_or_url_name',)

def refill_payment_queue():
    c=Payment.objects.filter(active=False).count()
    if PAYMENT_BUFFER_SIZE>c:
        for i in range(0,settings.PAYMENT_BUFFER_SIZE-c):
            bp=Payment()
            bp.address=bitcoind.create_address()
            bp.save()
    c=BitcoinAddress.objects.filter(active=False).count()
    if PAYMENT_BUFFER_SIZE>c:
        for i in range(0,settings.PAYMENT_BUFFER_SIZE-c):
            ba=BitcoinAddress()
            ba.address=bitcoind.create_address()
            ba.save()

def update_payments():
    if not cache.get('last_full_check'):
        cache.set('bitcoinprice', cache.get('bitcoinprice_old'))
    bps=BitcoinPayment.objects.filter(active=True)
    for bp in bps:
        bp.amount_paid=Decimal(bitcoin_getbalance(bp.address))
        bp.save()
        print bp.amount
        print bp.amount_paid

@transaction.commit_on_success
def new_bitcoin_payment(amount):
    bp=BitcoinPayment.objects.filter(active=False)
    if len(bp)<1:
        refill_payment_queue()
        bp=BitcoinPayment.objects.filter(active=False)
    bp=bp[0]
    bp.active=True
    bp.amount=amount
    bp.save()
    return bp

def getNewBitcoinPayment(amount):
    warnings.warn("Use new_bitcoin_payment(amount) instead",
                  DeprecationWarning)
    return new_bitcoin_payment(amount)

@transaction.commit_on_success
def new_bitcoin_payment_eur(amount):
    print bitcoinprice_eur()
    return new_bitcoin_payment(Decimal(amount)/Decimal(bitcoinprice_eur()['24h']))

def getNewBitcoinPayment_eur(amount):
    return new_bitcoin_payment_eur(amount)

# initialize the conversion module

from django_bitcoin import currency

from django.core import urlresolvers
from django.utils import importlib

for dottedpath in settings.BITCOIN_CURRENCIES:
    mod, func = urlresolvers.get_mod_func(dottedpath)
    klass = getattr(importlib.import_module(mod), func)
    currency.exchange.register_currency(klass())

# EOF

<|endoftext|>


<commit_before>from django.conf import settings
from gears.environment import Environment, DEFAULT_PUBLIC_ASSETS
from .utils import get_cache, get_finder, get_asset_handler

DEFAULT_CACHE = 'gears.cache.SimpleCache'

DEFAULT_FINDERS = (
    ('gears.finders.FileSystemFinder', {
        'directories': getattr(settings, 'GEARS_DIRS', ()),
    }),
)

DEFAULT_MIMETYPES = {
    '.css': 'text/css',
    '.js': 'application/javascript',
}

DEFAULT_PREPROCESSORS = {
    'text/css': 'gears.processors.DirectivesProcessor',
    'application/javascript': 'gears.processors.DirectivesProcessor',
}

DEFAULT_POSTPROCESSORS = {
    'text/css': 'gears.processors.HexdigestPathsProcessor',
}

GEARS_DEBUG = getattr(settings, 'GEARS_DEBUG', settings.DEBUG)

GEARS_URL = getattr(settings, 'GEARS_URL', settings.STATIC_URL)

path = getattr(settings, 'GEARS_CACHE', DEFAULT_CACHE)
if isinstance(path, (list, tuple)):
    path, options = path
else:
    options = None
cache = get_cache(path, options)

environment = Environment(
    root=getattr(settings, 'GEARS_ROOT'),
    public_assets=getattr(settings, 'GEARS_PUBLIC_ASSETS', DEFAULT_PUBLIC_ASSETS),
    cache=cache,
)

for path in getattr(settings, 'GEARS_FINDERS', DEFAULT_FINDERS):
    if isinstance(path, (list, tuple)):
        path, options = path
    else:
        options = None
    environment.finders.register(get_finder(path, options))

mimetypes = getattr(settings, 'GEARS_MIMETYPES', DEFAULT_MIMETYPES)
for extension, mimetype in mimetypes.items():
    environment.mimetypes.register(extension, mimetype)

for extension, path in getattr(settings, 'GEARS_COMPILERS', {}).items():
    if isinstance(path, (list, tuple)):
        path, options = path
    else:
        options = {}
    environment.compilers.register(extension, get_asset_handler(path, options))

preprocessors = getattr(settings, 'GEARS_PREPROCESSORS', DEFAULT_PREPROCESSORS)
for mimetype, paths in preprocessors.items():
    if not isinstance(paths, (list, tuple)):
        paths = [paths]
    for path in paths:
        environment.preprocessors.register(mimetype, get_asset_handler(path))

postprocessors = getattr(settings, 'GEARS_POSTPROCESSORS', DEFAULT_POSTPROCESSORS)
for mimetype, paths in postprocessors.items():
    if not isinstance(paths, (list, tuple)):
        paths = [paths]
    for path in paths:
        environment.postprocessors.register(mimetype, get_asset_handler(path))

compressors = getattr(settings, 'GEARS_COMPRESSORS', {})
for mimetype, path in compressors.items():
    environment.compressors.register(mimetype, get_asset_handler(path))
<commit_msg>Add gzip support<commit_after>from django.conf import settings
from gears.environment import Environment, DEFAULT_PUBLIC_ASSETS
from .utils import get_cache, get_finder, get_asset_handler

DEFAULT_CACHE = 'gears.cache.SimpleCache'

DEFAULT_FINDERS = (
    ('gears.finders.FileSystemFinder', {
        'directories': getattr(settings, 'GEARS_DIRS', ()),
    }),
)

DEFAULT_MIMETYPES = {
    '.css': 'text/css',
    '.js': 'application/javascript',
}

DEFAULT_PREPROCESSORS = {
    'text/css': 'gears.processors.DirectivesProcessor',
    'application/javascript': 'gears.processors.DirectivesProcessor',
}

DEFAULT_POSTPROCESSORS = {
    'text/css': 'gears.processors.HexdigestPathsProcessor',
}

GEARS_DEBUG = getattr(settings, 'GEARS_DEBUG', settings.DEBUG)

GEARS_URL = getattr(settings, 'GEARS_URL', settings.STATIC_URL)

path = getattr(settings, 'GEARS_CACHE', DEFAULT_CACHE)
if isinstance(path, (list, tuple)):
    path, options = path
else:
    options = None
cache = get_cache(path, options)

environment = Environment(
    root=getattr(settings, 'GEARS_ROOT'),
    public_assets=getattr(settings, 'GEARS_PUBLIC_ASSETS', DEFAULT_PUBLIC_ASSETS),
    cache=cache,
    gzip=getattr(settings, 'GEARS_GZIP', False),
)

for path in getattr(settings, 'GEARS_FINDERS', DEFAULT_FINDERS):
    if isinstance(path, (list, tuple)):
        path, options = path
    else:
        options = None
    environment.finders.register(get_finder(path, options))

mimetypes = getattr(settings, 'GEARS_MIMETYPES', DEFAULT_MIMETYPES)
for extension, mimetype in mimetypes.items():
    environment.mimetypes.register(extension, mimetype)

for extension, path in getattr(settings, 'GEARS_COMPILERS', {}).items():
    if isinstance(path, (list, tuple)):
        path, options = path
    else:
        options = {}
    environment.compilers.register(extension, get_asset_handler(path, options))

preprocessors = getattr(settings, 'GEARS_PREPROCESSORS', DEFAULT_PREPROCESSORS)
for mimetype, paths in preprocessors.items():
    if not isinstance(paths, (list, tuple)):
        paths = [paths]
    for path in paths:
        environment.preprocessors.register(mimetype, get_asset_handler(path))

postprocessors = getattr(settings, 'GEARS_POSTPROCESSORS', DEFAULT_POSTPROCESSORS)
for mimetype, paths in postprocessors.items():
    if not isinstance(paths, (list, tuple)):
        paths = [paths]
    for path in paths:
        environment.postprocessors.register(mimetype, get_asset_handler(path))

compressors = getattr(settings, 'GEARS_COMPRESSORS', {})
for mimetype, path in compressors.items():
    environment.compressors.register(mimetype, get_asset_handler(path))
<|endoftext|>


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

import re
from django.shortcuts import redirect
from django.utils.deprecation import MiddlewareMixin

from .configs.settings import LOGIN_NOT_REQUIRED

class LoginRequiredMiddleware(MiddlewareMixin):

    def __init__(self, get_response=None, *args, **kwargs):
        self.exceptions = tuple(re.compile(url) for url in LOGIN_NOT_REQUIRED)
        self.get_response = get_response

        return super(LoginRequiredMiddleware, self).__init__(get_response, *args, **kwargs)

    def process_view(self, request, view_func, view_args, view_kwargs):
        # Caso o user ja esteja logado:
        if request.user.is_authenticated():
            for url in self.exceptions:
                if url.match(request.path):
                    return redirect('base:index')
            return None

        for url in self.exceptions:
            if url.match(request.path):
                return None

        return redirect('login:loginview')
<commit_msg>Fixed #20<commit_after># -*- coding: utf-8 -*-

import re
from django.shortcuts import redirect
from django.utils.deprecation import MiddlewareMixin

from .configs.settings import LOGIN_NOT_REQUIRED

class LoginRequiredMiddleware(MiddlewareMixin):

    def __init__(self, get_response=None, *args, **kwargs):
        self.exceptions = tuple(re.compile(url) for url in LOGIN_NOT_REQUIRED)
        self.get_response = get_response

        return super(LoginRequiredMiddleware, self).__init__(get_response, *args, **kwargs)

    def process_view(self, request, view_func, view_args, view_kwargs):
        # Caso o user ja esteja logado:
        if request.user.is_authenticated:
            for url in self.exceptions:
                if url.match(request.path):
                    return redirect('base:index')
            return None

        for url in self.exceptions:
            if url.match(request.path):
                return None

        return redirect('login:loginview')
<|endoftext|>


<commit_before>"""
This module is being execfile'd from `setup.py`, `djangosite/__init__.py`
and possibly some external tools, too.

:copyright: Copyright 2013 by Luc Saffre.
:license: BSD, see LICENSE for more details.
"""
SETUP_INFO = dict(
  name = 'djangosite',
  version = '0.1.1',
  install_requires = ['Django','Sphinx','unipath','python_dateutil'],
  description = "A server startup signal for Django",
  license = 'Free BSD',
  test_suite = 'tests',
  author = 'Luc Saffre',
  author_email = 'luc.saffre@gmail.com',
  url = "http://site.lino-framework.org",
  long_description="""\
`djangosite` adds to a Django project the concept of
"the application running on this site".
It defines a `Site` class
and expects an instance of it in ``settings.SITE``.

This brings an additional level of encapsulation to Django.
A `Site` is "something between an app and a project",
it is a kind of "master app" or "project template".
Note that it has nothing to do with Django's `SITE_ID
<https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-SITE_ID>`__
setting.
More about this vocabulary problem in
`What is a software application?
<http://site.lino-framework.org/application.html>`__.

An immediate benefit of `djangosite` is to implement a
`server startup signal for Django
<http://site.lino-framework.org/startup_signal.html>`__

`djangosite` is also the foundation for projects like
`North <http://north.lino-framework.org>`__
and the `Lino framework <http://www.lino-framework.org>`__.""",
  #~ test_suite = 'tests.suite',
  #~ test_suite = 'fabfile.suite',
  classifiers="""\
  Programming Language :: Python
  Programming Language :: Python :: 2.6
  Programming Language :: Python :: 2.7
  Development Status :: 4 - Beta
  Environment :: Web Environment
  Framework :: Django
  Intended Audience :: Developers
  Intended Audience :: System Administrators
  License :: OSI Approved :: BSD License
  Natural Language :: English
  Operating System :: OS Independent
  Topic :: Database :: Front-Ends
  Topic :: Software Development :: Libraries :: Application Frameworks""".splitlines())

SETUP_INFO.update(packages = [str(n) for n in """
djangosite
djangosite.management
djangosite.management.commands
djangosite.utils
djangosite.utils.sphinxconf
""".splitlines() if n])

<commit_msg>http://code.google.com/p/lino/source/browse/docs/blog/2013/0410.rst<commit_after>"""
This module is being execfile'd from `setup.py`, `djangosite/__init__.py`
and possibly some external tools, too.

:copyright: Copyright 2013 by Luc Saffre.
:license: BSD, see LICENSE for more details.
"""
SETUP_INFO = dict(
  name = 'djangosite',
  version = '0.1.1',
  install_requires = ['atelier','Django','Sphinx','unipath','python_dateutil'],
  description = "A server startup signal for Django",
  license = 'Free BSD',
  test_suite = 'tests',
  author = 'Luc Saffre',
  author_email = 'luc.saffre@gmail.com',
  url = "http://site.lino-framework.org",
  long_description="""\
`djangosite` adds to a Django project the concept of
"the application running on this site".
It defines a `Site` class
and expects an instance of it in ``settings.SITE``.

This brings an additional level of encapsulation to Django.
A `Site` is "something between an app and a project",
it is a kind of "master app" or "project template".
Note that it has nothing to do with Django's `SITE_ID
<https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-SITE_ID>`__
setting.
More about this vocabulary problem in
`What is a software application?
<http://site.lino-framework.org/application.html>`__.

An immediate benefit of `djangosite` is to implement a
`server startup signal for Django
<http://site.lino-framework.org/startup_signal.html>`__

`djangosite` is also the foundation for projects like
`North <http://north.lino-framework.org>`__
and the `Lino framework <http://www.lino-framework.org>`__.""",
  #~ test_suite = 'tests.suite',
  #~ test_suite = 'fabfile.suite',
  classifiers="""\
  Programming Language :: Python
  Programming Language :: Python :: 2.6
  Programming Language :: Python :: 2.7
  Development Status :: 4 - Beta
  Environment :: Web Environment
  Framework :: Django
  Intended Audience :: Developers
  Intended Audience :: System Administrators
  License :: OSI Approved :: BSD License
  Natural Language :: English
  Operating System :: OS Independent
  Topic :: Database :: Front-Ends
  Topic :: Software Development :: Libraries :: Application Frameworks""".splitlines())

SETUP_INFO.update(packages = [str(n) for n in """
djangosite
djangosite.management
djangosite.management.commands
djangosite.utils
djangosite.utils.sphinxconf
""".splitlines() if n])

<|endoftext|>