<commit_before>#!/usr/bin/python

"""
Copyright 2016 EMBL-European Bioinformatics Institute

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""

# -*- coding: utf-8 -*-
'''process whole genome bisulfate sequencing FastQ files'''
import argparse, time, urllib2, gzip, shutil
from pycompss.api.task import task
from pycompss.api.parameter import *
from pycompss.api.constraint import *

from common import common

from fastqreader import *
from FilterReads import *
from bs_index.wg_build import *

class process_wgbs:
    """
    Functions for downloading and processing whole genome bisulfate sequencings
    (WGBS) files. Files are downloaded from the European Nucleotide Archive
    (ENA), then filtered, aligned and analysed for points of methylation
    """

    def __init__ (self):
        """
        Initialise the module
        """
        self.ready=None

    @task(infile = FILE_IN, outfile = FILE_OUT, returns = int)
    def FilterFastQReads(self, infile, outfile):
        """
        This is optional, but removes reads that can be problematic for the
        alignment of whole genome datasets.

        If performing RRBS then this step can be skipped
        """
        FilterReads(infile, outfile, True)
        return 1

    @constraint(ProcessorCoreCount=8)
    @task(fasta_file = FILE_IN, aligner = IN, aligner_path = IN, ref_path = IN)
    def Builder(self, fasta_file, aligner, aligner_path, ref_path):
        """
        Function to submit the FASTA file for the reference sequence and build
        the required index file used by the aligner.

        This only needs to be done once, so there needs to be a check to ensure
        that if the index file have already been generated then they do no need
        to be analysed again
        """
        builder_exec = os.path.join(aligner_path,
                                    {BOWTIE   : 'bowtie-build',
                                     BOWTIE2  : 'bowtie2-build',
                                     SOAP     : '2bwt-builder',
                                     RMAP     : '' # do nothing
                                    }[aligner])

        build_command = builder_exec + { BOWTIE   : ' -f %(fname)s.fa %(fname)s',
                                         BOWTIE2  : ' -f %(fname)s.fa %(fname)s',
                                         SOAP     : ' %(fname)s.fa'
                                       }[aligner]

        wg_build(fasta_file, build_command, ref_path, aligner)

    def Splitter(self, in_file1, in_file2, tag):
        """
        Function to divide the FastQ files into separte sub files of 1000000
        sequences so that the aligner can get run in parallel.

        Returns: Returns a list of lists of the files that have been generated.
                 Each sub list containing the two paired end files for that
                 subset.
        """

        fqr = fastqreader()
        fqr.openPairedFastQ(file1, file2)
        fqr.createOutputFiles(tag)

        r1 = fqr.next(1)
        r2 = fqr.next(2)

        count_r1 = 0
        count_r2 = 0
        count_r3 = 0
        files_out = []

        while fqr.eof(1) == False and fqr.eof(2) == False:
            r1_id = r1["id"].split(" ")
            r2_id = r2["id"].split(" ")

            if r1_id[0] == r2_id[0]:
                fqr.writeOutput(r1, 1)
                fqr.writeOutput(r2, 2)

                r1 = fqr.next(1)
                r2 = fqr.next(2)

                count_r1 += 1
                count_r2 += 1
                count_r3 += 1
            elif r1_id[0] < r2_id[0]:
                r1 = fqr.next(1)
                count_r1 += 1
            else:
                r2 = fqr.next(2)
                count_r2 += 1

            if count_r3 % 1000000 == 0:
                fqr.incrementOutputFiles()
                f1 = self.fastq1.split("/")
                f1[-1] = f1[-1].replace(".fastq", "." + str(self.output_tag) + "_" + str(self.output_file_count) + ".fastq")
                f1.insert(-1, "tmp")

                f2 = self.fastq2.split("/")
                f2[-1] = f2[-1].replace(".fastq", "." + str(self.output_tag) + "_" + str(self.output_file_count) + ".fastq")
                f2.insert(-1, "tmp")

                files_out.append(["/".join(f1), "/".join(f2)])

        fqr.closePairedFastQ()
        fqr.closeOutputFiles()

        return files_out

    @constraint(ProcessorCoreCount=8)
    @task(input_fastq1 = FILE_IN, input_fastq2 = FILE_IN, aligner = IN, aligner_path = IN, genome_fasta = FILE_IN, returns = int)
    def Aligner(self, input_fastq1, input_fastq2, aligner, aligner_path, genome_fasta):
        """
        Alignment of the paired ends to the reference genome
        Generates bam files for the alignments
        This is performed by running the external program rather than reimplementing
        the code from the main function to make it easier when it comes to updating
        the changes in BS-Seeker2
        """
        import subprocess

        args = ["python", "bs_seeker2-align.py", "--input_1", input_fastq1, "--input_2", input_fastq2, "--aligner", aligner, "--path", aligner_path_path, "--genome", genome_fasta, "--bt2-p", "4"]
        p = subprocess.Popen(args)
        p.wait()

        return 1

    @constraint(ProcessorCoreCount=8)
    @task(bam_file = FILE_IN, output_prefix = IN, db_dir = IN, returns = int)
    def MethylationCaller(self, bam_file, output_prefix, db_dir):
        """
        Takes the merged and sorted bam file and calls the methylation sites.
        Generates a wig file of the potential sites.
        This is performed by running the external program rather than reimplementing
        the code from the main function to make it easier when it comes to updating
        the changes in BS-Seeker2
        """
        import subprocess

        args = ["python", "bs_seeker2-call_methylation.py", "--input", str(bam_file), "--output-prefix", str(output_prefix), "--db", db_dir]
        p = subprocess.Popen(args)
        p.wait()

        return 1

    def clean_up(self, data_dir):
        """
        Clears up the tmp folders
        """
        os.chdir(self.data_dir)

        try:
            shutil.rmtree("tmp")
        except:
            pass

if __name__ == "__main__":
    import sys
    import os
    from pycompss.api.api import compss_wait_on

    # Set up the command line parameters
    parser = argparse.ArgumentParser(description="Parse WGBS data")
    parser.add_argument("--genome", help="Genome name") #             default="GCA_000001405.22")
    parser.add_argument("--srr_id", help="SRR ID of the dataset") #   default="SRR1536575")
    parser.add_argument("--aligner", help="Aligner to use (eg bowtie2)") #   default="bowtie2")
    parser.add_argument("--tmp_dir", help="Temporary data dir")
    parser.add_argument("--data_dir", help="Data directory; location to download SRA FASTQ files and save results")
    parser.add_argument("--aligner_dir", help="Directory for the aligner program")
    parser.add_argument("--local", help="Directory and data files already available", default=0)

    # Get the matching parameters from the command line
    args = parser.parse_args()

    srr_id   = args.srr_id
    genome   = args.genome
    aligner  = args.aligner
    aligner_dir = args.aligner_dir
    data_dir = args.data_dir + '/' + srr_id
    tmp_dir  = args.tmp_dir
    local = args.local

    genome_dir = args.data_dir + genome + "/chroms/"

    start = time.time()

    db_dir = ""

    pwgbs = process_wgbs()

    if data_dir[-1] != "/":
        data_dir += "/"

    try:
        os.makedirs(data_dir)
    except:
        pass

    try:
        os.makedirs(data_dir + srr_id)
    except:
        pass

    cf = common()

    # Optain the paired FastQ files
    if (local == 1):
        in_files = cf.getFastqFiles(srr_id, data_dir)
    else:
        in_files = [f for f in os.listdir(data_dir + srr_id) if re.match(run_id, f)]

    in_file1 = in_files[0]
    in_file2 = in_files[1]
    out_file1 = in_file1.replace(".fastq", "_filtered.fastq")
    out_file2 = in_file2.replace(".fastq", "_filtered.fastq")

    # Run the FilterReads.py steps for the individual FastQ files
    x = []
    for l in [[in_file1, out_file1], [in_file2, out_file2]]:
        x.append(pwgbs.FilterFastQReads(l))
    x = compss_wait_on(x)

    # Run the bs_seeker2-builder.py steps
    pwgbs.Builder(genome_dir + genome + ".fa", "bowtie2", aligner_dir, genome_dir)

    # Split the paired fastq files
    tmp_fastq = pwgbs.Splitter(in_file1, in_file2, tag)

    bam_sort_files = []
    bam_merge_files = []
    fastq_for_alignment = []
    for bams in tmp_fastq:
        tmp = bams
        tmp.append(aligner, aligner_path, genome_fasta_files)
        fastq_for_alignment.append(tmp)
        bam_root = bams[0] + "_bspe.bam"
        bam_sort_files.append(bams[0] + "_bspe.bam")
        bam_merge_files.append(["-o", bam_root + ".sorted.bam", "-T", bam_root + ".bam_sort", bam_root])

    # Run the bs_seeker2-align.py steps on the split up fastq files
    x = []
    for ffa in fastq_for_alignment:
        x.append(pwgbs.Aligner(ffa))
    x = compss_wait_on(x)

    # Sort and merge the aligned bam files
    # Pre-sort the original input bam files
    x = map(pysam.sort, bam_sort_files)

    f_bam = in_file1.split("/")
    f_bam[-1] = f_bam[-1].replace(".fastq", ".sorted.bam")
    out_bam_file = "/".join(f_bam)

    pysam.merge(out_bam_file, bam_merge_files)

    pysam.sort("-o", out_bam_file + '.sorted.bam', "-T", out_bam_file + ".bam_sort", out_bam_file)

    pysam.index(out_bam_file)

    # Run the bs_seeker2-call_methylation.py steps
    x = pwgbs.MethylationCaller(out_bam_file, tag, db_dir)
    x = compss_wait_on(x)

    # Tidy up
    pwgbs.clean_up(data_dir + srr_id)

<commit_msg>Modified the logic due to flag error<commit_after>#!/usr/bin/python

"""
Copyright 2016 EMBL-European Bioinformatics Institute

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""

# -*- coding: utf-8 -*-
'''process whole genome bisulfate sequencing FastQ files'''
import argparse, time, urllib2, gzip, shutil
from pycompss.api.task import task
from pycompss.api.parameter import *
from pycompss.api.constraint import *

from common import common

from fastqreader import *
from FilterReads import *
from bs_index.wg_build import *

class process_wgbs:
    """
    Functions for downloading and processing whole genome bisulfate sequencings
    (WGBS) files. Files are downloaded from the European Nucleotide Archive
    (ENA), then filtered, aligned and analysed for points of methylation
    """

    def __init__ (self):
        """
        Initialise the module
        """
        self.ready=None

    @task(infile = FILE_IN, outfile = FILE_OUT, returns = int)
    def FilterFastQReads(self, infile, outfile):
        """
        This is optional, but removes reads that can be problematic for the
        alignment of whole genome datasets.

        If performing RRBS then this step can be skipped
        """
        FilterReads(infile, outfile, True)
        return 1

    @constraint(ProcessorCoreCount=8)
    @task(fasta_file = FILE_IN, aligner = IN, aligner_path = IN, ref_path = IN)
    def Builder(self, fasta_file, aligner, aligner_path, ref_path):
        """
        Function to submit the FASTA file for the reference sequence and build
        the required index file used by the aligner.

        This only needs to be done once, so there needs to be a check to ensure
        that if the index file have already been generated then they do no need
        to be analysed again
        """
        builder_exec = os.path.join(aligner_path,
                                    {BOWTIE   : 'bowtie-build',
                                     BOWTIE2  : 'bowtie2-build',
                                     SOAP     : '2bwt-builder',
                                     RMAP     : '' # do nothing
                                    }[aligner])

        build_command = builder_exec + { BOWTIE   : ' -f %(fname)s.fa %(fname)s',
                                         BOWTIE2  : ' -f %(fname)s.fa %(fname)s',
                                         SOAP     : ' %(fname)s.fa'
                                       }[aligner]

        wg_build(fasta_file, build_command, ref_path, aligner)

    def Splitter(self, in_file1, in_file2, tag):
        """
        Function to divide the FastQ files into separte sub files of 1000000
        sequences so that the aligner can get run in parallel.

        Returns: Returns a list of lists of the files that have been generated.
                 Each sub list containing the two paired end files for that
                 subset.
        """

        fqr = fastqreader()
        fqr.openPairedFastQ(file1, file2)
        fqr.createOutputFiles(tag)

        r1 = fqr.next(1)
        r2 = fqr.next(2)

        count_r1 = 0
        count_r2 = 0
        count_r3 = 0
        files_out = []

        while fqr.eof(1) == False and fqr.eof(2) == False:
            r1_id = r1["id"].split(" ")
            r2_id = r2["id"].split(" ")

            if r1_id[0] == r2_id[0]:
                fqr.writeOutput(r1, 1)
                fqr.writeOutput(r2, 2)

                r1 = fqr.next(1)
                r2 = fqr.next(2)

                count_r1 += 1
                count_r2 += 1
                count_r3 += 1
            elif r1_id[0] < r2_id[0]:
                r1 = fqr.next(1)
                count_r1 += 1
            else:
                r2 = fqr.next(2)
                count_r2 += 1

            if count_r3 % 1000000 == 0:
                fqr.incrementOutputFiles()
                f1 = self.fastq1.split("/")
                f1[-1] = f1[-1].replace(".fastq", "." + str(self.output_tag) + "_" + str(self.output_file_count) + ".fastq")
                f1.insert(-1, "tmp")

                f2 = self.fastq2.split("/")
                f2[-1] = f2[-1].replace(".fastq", "." + str(self.output_tag) + "_" + str(self.output_file_count) + ".fastq")
                f2.insert(-1, "tmp")

                files_out.append(["/".join(f1), "/".join(f2)])

        fqr.closePairedFastQ()
        fqr.closeOutputFiles()

        return files_out

    @constraint(ProcessorCoreCount=8)
    @task(input_fastq1 = FILE_IN, input_fastq2 = FILE_IN, aligner = IN, aligner_path = IN, genome_fasta = FILE_IN, returns = int)
    def Aligner(self, input_fastq1, input_fastq2, aligner, aligner_path, genome_fasta):
        """
        Alignment of the paired ends to the reference genome
        Generates bam files for the alignments
        This is performed by running the external program rather than reimplementing
        the code from the main function to make it easier when it comes to updating
        the changes in BS-Seeker2
        """
        import subprocess

        args = ["python", "bs_seeker2-align.py", "--input_1", input_fastq1, "--input_2", input_fastq2, "--aligner", aligner, "--path", aligner_path_path, "--genome", genome_fasta, "--bt2-p", "4"]
        p = subprocess.Popen(args)
        p.wait()

        return 1

    @constraint(ProcessorCoreCount=8)
    @task(bam_file = FILE_IN, output_prefix = IN, db_dir = IN, returns = int)
    def MethylationCaller(self, bam_file, output_prefix, db_dir):
        """
        Takes the merged and sorted bam file and calls the methylation sites.
        Generates a wig file of the potential sites.
        This is performed by running the external program rather than reimplementing
        the code from the main function to make it easier when it comes to updating
        the changes in BS-Seeker2
        """
        import subprocess

        args = ["python", "bs_seeker2-call_methylation.py", "--input", str(bam_file), "--output-prefix", str(output_prefix), "--db", db_dir]
        p = subprocess.Popen(args)
        p.wait()

        return 1

    def clean_up(self, data_dir):
        """
        Clears up the tmp folders
        """
        os.chdir(self.data_dir)

        try:
            shutil.rmtree("tmp")
        except:
            pass

if __name__ == "__main__":
    import sys
    import os
    from pycompss.api.api import compss_wait_on

    # Set up the command line parameters
    parser = argparse.ArgumentParser(description="Parse WGBS data")
    parser.add_argument("--genome", help="Genome name") #             default="GCA_000001405.22")
    parser.add_argument("--srr_id", help="SRR ID of the dataset") #   default="SRR1536575")
    parser.add_argument("--aligner", help="Aligner to use (eg bowtie2)") #   default="bowtie2")
    parser.add_argument("--tmp_dir", help="Temporary data dir")
    parser.add_argument("--data_dir", help="Data directory; location to download SRA FASTQ files and save results")
    parser.add_argument("--aligner_dir", help="Directory for the aligner program")
    parser.add_argument("--local", help="Directory and data files already available", default=0)

    # Get the matching parameters from the command line
    args = parser.parse_args()

    srr_id   = args.srr_id
    genome   = args.genome
    aligner  = args.aligner
    aligner_dir = args.aligner_dir
    data_dir = args.data_dir + '/' + srr_id
    tmp_dir  = args.tmp_dir
    local = args.local

    genome_dir = args.data_dir + genome + "/chroms/"

    start = time.time()

    db_dir = ""

    pwgbs = process_wgbs()

    if data_dir[-1] != "/":
        data_dir += "/"

    try:
        os.makedirs(data_dir)
    except:
        pass

    try:
        os.makedirs(data_dir + srr_id)
    except:
        pass

    cf = common()

    # Optain the paired FastQ files
    if (local == 0):
        in_files = cf.getFastqFiles(srr_id, data_dir)
    else:
        in_files = [f for f in os.listdir(data_dir + srr_id) if re.match(run_id, f)]

    in_file1 = in_files[0]
    in_file2 = in_files[1]
    out_file1 = in_file1.replace(".fastq", "_filtered.fastq")
    out_file2 = in_file2.replace(".fastq", "_filtered.fastq")

    # Run the FilterReads.py steps for the individual FastQ files
    x = []
    for l in [[in_file1, out_file1], [in_file2, out_file2]]:
        x.append(pwgbs.FilterFastQReads(l))
    x = compss_wait_on(x)

    # Run the bs_seeker2-builder.py steps
    pwgbs.Builder(genome_dir + genome + ".fa", "bowtie2", aligner_dir, genome_dir)

    # Split the paired fastq files
    tmp_fastq = pwgbs.Splitter(in_file1, in_file2, tag)

    bam_sort_files = []
    bam_merge_files = []
    fastq_for_alignment = []
    for bams in tmp_fastq:
        tmp = bams
        tmp.append(aligner, aligner_path, genome_fasta_files)
        fastq_for_alignment.append(tmp)
        bam_root = bams[0] + "_bspe.bam"
        bam_sort_files.append(bams[0] + "_bspe.bam")
        bam_merge_files.append(["-o", bam_root + ".sorted.bam", "-T", bam_root + ".bam_sort", bam_root])

    # Run the bs_seeker2-align.py steps on the split up fastq files
    x = []
    for ffa in fastq_for_alignment:
        x.append(pwgbs.Aligner(ffa))
    x = compss_wait_on(x)

    # Sort and merge the aligned bam files
    # Pre-sort the original input bam files
    x = map(pysam.sort, bam_sort_files)

    f_bam = in_file1.split("/")
    f_bam[-1] = f_bam[-1].replace(".fastq", ".sorted.bam")
    out_bam_file = "/".join(f_bam)

    pysam.merge(out_bam_file, bam_merge_files)

    pysam.sort("-o", out_bam_file + '.sorted.bam', "-T", out_bam_file + ".bam_sort", out_bam_file)

    pysam.index(out_bam_file)

    # Run the bs_seeker2-call_methylation.py steps
    x = pwgbs.MethylationCaller(out_bam_file, tag, db_dir)
    x = compss_wait_on(x)

    # Tidy up
    pwgbs.clean_up(data_dir + srr_id)

<|endoftext|>


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

import sys, h5py
import numpy as np
import scipy.ndimage as ndimage
import matplotlib
import spimage
import argparse

parser = argparse.ArgumentParser(prog='processprtfs.py', description='Compute superimposed image and phase-retrieval transfer functions.')
parser.add_argument('-a', '--phase',  metavar='PHASE', type=str, default='vs72/phasing.h5', help='Phasing results for patterns')
parser.add_argument('-r', '--ref',  metavar='REF', type=str, default='reference.mat', help='File containing reference pattern')
args = parser.parse_args()

f = h5py.File(args.phase, 'r+')

recons  = f['real_space_final'][:]
fourier = f['fourier_space_final'][:]
support = f['support_final'][:]
rerror  = f['real_error'][:]
ferror  = f['fourier_error'][:]

with h5py.File(args.ref, 'r') as reff:
    f2 = np.reshape(reff['f2'][:],(256,256))
    reference = reff['reference'][:]
    reference = np.fft.ifftshift(np.fft.fft2(np.fft.fft2(np.fft.fftshift(reference['real'] + 1j * reference['imag'])) * np.sqrt(f2)))

# Loop over 50 original images
M = 50
N = 100
subsetcount = 10

allsupers = np.zeros((M, 256, 256), dtype=np.complex128)

for m in range(M):
    indices = np.argsort(rerror[(m*N):((m+1)*N)]) + m * N
    indices = indices[0:subsetcount]
    print indices
    output_prtf = spimage.prtf(recons[indices], support[indices], enantio=True, translate=True, clearsupport=True, reference=reference)
    allsupers[m,:,:] = output_prtf['super_image'] / subsetcount

try:
    del f['super_images']
except:
    pass

f['super_images'] = allsupers

<commit_msg>MSE computation compatible with OSS<commit_after>#!/usr/bin/env python

import sys, h5py
import numpy as np
import scipy.ndimage as ndimage
import matplotlib
import spimage
import argparse

parser = argparse.ArgumentParser(prog='processprtfs.py', description='Compute superimposed image and phase-retrieval transfer functions.')
parser.add_argument('-a', '--phase',  metavar='PHASE', type=str, default='vs72/phasing.h5', help='Phasing results for patterns')
parser.add_argument('-r', '--ref',  metavar='REF', type=str, default='reference.mat', help='File containing reference pattern')
args = parser.parse_args()

f = h5py.File(args.phase, 'r+')

recons  = f['real_space_final'][:]
#fourier = f['fourier_space_final'][:]
support = f['support_final'][:]
rerror  = f['real_error'][:]
#ferror  = f['fourier_error'][:]

with h5py.File(args.ref, 'r') as reff:
    f2 = np.reshape(reff['f2'][:],(256,256))
    reference = reff['reference'][:]
    reference = np.fft.ifftshift(np.fft.fft2(np.fft.fft2(np.fft.fftshift(reference['real'] + 1j * reference['imag'])) * np.sqrt(f2)))

# Loop over 50 original images
M = 50
N = 100
subsetcount = 10

allsupers = np.zeros((M, 256, 256), dtype=np.complex128)

for m in range(M):
    indices = np.argsort(rerror[(m*N):((m+1)*N)]) + m * N
    indices = indices[0:subsetcount]
    print indices
    output_prtf = spimage.prtf(recons[indices], support[indices], enantio=True, translate=True, clearsupport=True, reference=reference)
    allsupers[m,:,:] = output_prtf['super_image'] / subsetcount

try:
    del f['super_images']
except:
    pass

f['super_images'] = allsupers

<|endoftext|>


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

import parse
import sys

def produce(target, rules):
    for rule in rules:
        if rule.produce(target, rules):
            return

if __name__ == '__main__':
    _, target = sys.argv
    rules = parse.parse_producefile()
    produce(target, rules)
<commit_msg>error handling<commit_after>#!/usr/bin/env python3

import exceptions
import logging
import parse
import sys

logging.basicConfig(level=logging.INFO)

def produce(target, rules):
    for rule in rules:
        if rule.produce(target, rules):
            return

if __name__ == '__main__':
    _, target = sys.argv
    try:
        rules = parse.parse_producefile()
        produce(target, rules)
    except exceptions.UserError, e:
        logging.error(e)
        sys.exit(1)
<|endoftext|>


<commit_before>from tastypie.resources import ModelResource

from .models import TrackTrainsUser

class TrackTrainsUserResource(ModelResource):
    class Meta:
        queryset = TrackTrainsUser.objects.all()
        resource_name = 'user'
<commit_msg>TrackTrainsUserResource basic configuration and stubs for invite and signup.<commit_after>from django.conf.urls import url
from tastypie.resources import ModelResource
from tastypie.constants import ALL
from tastypie.utils import trailing_slash
from tastypie.authorization import ReadOnlyAuthorization
from tastypie.authentication import BasicAuthentication

from .models import TrackTrainsUser

class TrackTrainsUserResource(ModelResource):
    class Meta:
        queryset = TrackTrainsUser.objects.all()
        resource_name = 'user'
        authentication = BasicAuthentication()
        authorization = ReadOnlyAuthorization()
        filtering = {'email': ALL}
        fields = ['email', 'inviter', 'invites_counter', 'is_active', 'is_staff']

    def prepend_urls(self):
        return [
            url(r"(?P<resource_name>%s)/signup%s$" % (self._meta.resource_name, trailing_slash()),
                self.wrap_view("signup"),
                name="api_signup"),
            url(r"(?P<resource_name>%s)/invite%s$" % (self._meta.resource_name, trailing_slash()),
                self.wrap_view("invite"),
                name="api_invite")
        ]

    def signup(self, request, **kwargs):
        self.method_check(request, allowed=['post'])
        self.is_authenticated(request)
        self.throttle_check(request)

        # TODO sugnup implementation

        result = {'result': 'stub for signup'}

        self.log_throttled_access(request)
        return self.create_response(request, result)

    def invite(self, request, **kwargs):
        self.method_check(request, allowed=['post'])
        self.is_authenticated(request)
        self.throttle_check(request)

        # TODO invite implementation

        result = {'result': 'stub for invite'}

        self.log_throttled_access(request)
        return self.create_response(request, result)
<|endoftext|>


<commit_before>from __future__ import absolute_import

from django.contrib import admin
from django.conf import settings
from django.conf.urls import patterns, include, url
from django.conf.urls.static import static

from rapidsms.backends.kannel.views import KannelBackendView
from rapidsms.contrib.httptester import urls

admin.autodiscover()

urlpatterns = patterns('',
    url(r'^admin/', include(admin.site.urls)),
    # RapidSMS core URLs
    (r'^accounts/', include('rapidsms.urls.login_logout')),
    url(r'^$', 'rapidsms.views.dashboard', name='rapidsms-dashboard'),
    # RapidSMS contrib app URLs
    (r'^httptester/', include('rapidsms.contrib.httptester.urls')),
    #(r'^locations/', include('rapidsms.contrib.locations.urls')),
    (r'^messagelog/', include('rapidsms.contrib.messagelog.urls')),
    (r'^messaging/', include('rapidsms.contrib.messaging.urls')),
    (r'^registration/', include('rapidsms.contrib.registration.urls')),

    # Third party URLs
    (r'^selectable/', include('selectable.urls')),

    # kannel backend urls
    url(r"^backend/kannel-usb0-smsc/$",
        KannelBackendView.as_view(backend_name="kannel-usb0-smsc")),
    url(r'^kannel/', include('rapidsms.backends.kannel.urls')),

) + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
<commit_msg>Adding public_lights to urls<commit_after>from __future__ import absolute_import

from django.contrib import admin
from django.conf import settings
from django.conf.urls import patterns, include, url
from django.conf.urls.static import static

from rapidsms.backends.kannel.views import KannelBackendView
from rapidsms.contrib.httptester import urls

admin.autodiscover()

urlpatterns = patterns('',
    url(r'^admin/', include(admin.site.urls)),
    # RapidSMS core URLs
    (r'^accounts/', include('rapidsms.urls.login_logout')),
    url(r'^$', 'rapidsms.views.dashboard', name='rapidsms-dashboard'),
    # RapidSMS contrib app URLs
    (r'^httptester/', include('rapidsms.contrib.httptester.urls')),
    #(r'^locations/', include('rapidsms.contrib.locations.urls')),
    (r'^messagelog/', include('rapidsms.contrib.messagelog.urls')),
    (r'^messaging/', include('rapidsms.contrib.messaging.urls')),
    (r'^registration/', include('rapidsms.contrib.registration.urls')),

    # Third party URLs
    (r'^selectable/', include('selectable.urls')),

    # kannel backend urls
    url(r"^backend/kannel-usb0-smsc/$",
        KannelBackendView.as_view(backend_name="kannel-usb0-smsc")),
    url(r'^kannel/', include('rapidsms.backends.kannel.urls')),

    # public_lights
    url('^lights/', include('public_lights.urls')),

) + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
<|endoftext|>


<commit_before># General Utility Methods for Algorithms
import numpy as np

# James
def multiply_matrix(matrix_1, matrix_2):
    if matrix_1.shape[1] != matrix_2.shape[0]:
        return None

    result = np.empty((matrix_1.shape[0], matrix_2.shape[1]))
    # We can use transpose & dot product library function.
    # Dot product of first rows of matrix_1 and matrix_2^t gives us first resulting number.of first row.
    # Dot product of first row of matrix_1 and second row of matrix_2^t gives us second resulting number of first row.
    matrix_2_t = matrix_2.transpose()
    for i in range(matrix_1.shape[0]):
        for j in range(matrix_2_t.shape[0]):
            result[i, j] = matrix_1[i].dot(matrix_2_t[j])

    return result

def find_LU(matrix):
    size = matrix.shape[0]
    L = np.identity(size,float)
    U = np.ndarray.astype(matrix,float)
    for row in xrange(1, size):
        for col in xrange(0, row):
            L[row][col] = U[row][col] / U[col][col]
            U[row] -= L[row][col] * U[col]
    return L, U

def find_QR(matrix):
    return None

# Emeke
def find_determinant(matrix):
    return None

# Emeke
def find_eigenvalues(matrix):
    return None

# Emeke
def find_eigenvectors(matrix):
    return None
<commit_msg>Added matrix_trace function<commit_after># General Utility Methods for Algorithms
import numpy as np

# James
def multiply_matrix(matrix_1, matrix_2):
    if matrix_1.shape[1] != matrix_2.shape[0]:
        return None

    result = np.empty((matrix_1.shape[0], matrix_2.shape[1]))
    # We can use transpose & dot product library function.
    # Dot product of first rows of matrix_1 and matrix_2^t gives us first resulting number.of first row.
    # Dot product of first row of matrix_1 and second row of matrix_2^t gives us second resulting number of first row.
    matrix_2_t = matrix_2.transpose()
    for i in range(matrix_1.shape[0]):
        for j in range(matrix_2_t.shape[0]):
            result[i, j] = matrix_1[i].dot(matrix_2_t[j])

    return result

# Seth
def find_LU(matrix):
    size = matrix.shape[0]
    L = np.identity(size, float)
    U = np.ndarray.astype(matrix, float)  # @TODO this is giving me warning (maybe try without float .. it auto casts?)
    for row in xrange(1, size):
        for col in xrange(0, row):
            L[row][col] = U[row][col] / U[col][col]
            U[row] -= L[row][col] * U[col]
    return L, U

def find_QR(matrix):
    return None

# Emeke
def find_determinant(matrix):
    return None

# Emeke
def find_eigenvalues(matrix):
    return None

# Emeke
def find_eigenvectors(matrix):
    return None

# James
def matrix_trace(matrix):
    loop = min(matrix.shape[1], matrix.shape[0])
    sum = 0
    for i in range(loop):
        sum += matrix[i, i]
    return sum
<|endoftext|>


<commit_before>"""
Name-Suhan
Credit-Stack Overflow, Alexandru Munteanu

Jane spent $42 for shoes.  This was $14 less than twice what she spent for a blouse.  How much was the blouse?
"""
import math
import re
#import enchant

problem=input("What is your mathematical word problem? (Spelling, grammar, and punctuation count!!)\n\nYour problem: ")

while problem=="":
    print("You forgot to put in the problem")
    break

donfail=problem.count('?')
while donfail==0:
    print("You forgot a question mark")
    break

problem_=''.join( c for c in problem if  c not in '$')
problem.replace('a','1')

deci=re.findall("\d+.\d+", problem_) #find decimals
len_dec=len(deci)
dec_range=list(range(0,len_dec))
dci=str(deci)
word_=problem_.split()
list0 = [item for item in word_ if item not in deci] #DESTROY THE DECIMALS!

inte=[int(s) for s in problem_.split() if s.isdigit()]
inte_=str(inte)
list1 = [item for item in list0 if item not in inte_] #DESTROY THE INTEGERS!
print(list1)

problem__=" ".join(list1)

sentences = re.split(' *[\.\?!][\'"\)\]]* *', problem__) #split the sentences!

um=len(sentences)
num=um-1

while num > 10:
    print("\nWord problem too long!")
    break

while um==0:
    print("You forgot a period somewhere pal")
    break

if num>=1:
    words1=sentences[0].split()
if num>=2:
    words2=sentences[1].split()
if num>=3:
    words3=sentences[0].split()
if num>=4:
    words4=sentences[1].split()
if num>=5:
    words5=sentences[0].split()
if num>=6:
    words6=sentences[1].split()
if num>=7:
    words7=sentences[0].split()
if num>=8:
    words8=sentences[1].split()
if num>=9:
    words9=sentences[0].split()
if num==10:
    words10=sentences[1].split()

"""
#Finale!
print("Ok. Lets split your problem into statements

if num_>=1:
    print("For the first sentence,
if num_>=2:
    print("For the second sentence,
if num_>=3:
    print("For the third sentence,
if num_>=4:
    print("For the fourth sentence,
if num_>=5:
    print("For the fifth sentence,
if num_>=6:
    print("For the sixth sentence,
if num_>=7:
    print("For the seventh sentence,
if num_>=8:
    print("For the eighth sentence,
if num==9:
    print("For the ninth sentence,
"""<commit_msg>Updated from Brython Server: 11/20/2015 2:31:37 PM<commit_after>"""
Name-Suhan
Credit-Stack Overflow, Alexandru Munteanu

Jane spent $42 for shoes.  This was $14 less than twice what she spent for a blouse.  How much was the blouse?
"""
import math
import re
#import enchant

problem=input("What is your mathematical word problem? (Spelling, grammar, and punctuation count!!)\n\nYour problem: ")

donfail=problem.count('?')
while donfail==0:
    print("You forgot a question mark")
    break

problem_=''.join( c for c in problem if  c not in '$')

deci=re.findall("\d+.\d+", problem_) #find decimals
len_dec=len(deci)
dec_range=list(range(0,len_dec))
dci=str(deci)
word_=problem_.split()
list0 = [item for item in word_ if item not in deci] #DESTROY THE DECIMALS!
list1=['1' if x=='a' else x for x in list0]#REPLACE TEH 'A's

inte=[int(s) for s in problem_.split() if s.isdigit()]
inte_=str(inte)
list2 = [item for item in list1 if item not in inte_] #DESTROY THE INTEGERS!

problem__=" ".join(list2)

sentences = re.split(' *[\.\?!][\'"\)\]]* *', problem__) #split the sentences!

um=len(sentences)
num=um-1

while num > 10:
    print("\nWord problem too long!")
    break

while um==0:
    print("You forgot a period somewhere pal")
    break

print("Ok. Lets split your problem into statements")
if num>=1:
    words1=sentences[0].split()
if num>=2:
    words2=sentences[1].split()
if num>=3:
    words3=sentences[2].split()
if num>=4:
    words4=sentences[3].split()
if num>=5:
    words5=sentences[4].split()
if num>=6:
    words6=sentences[5].split()
if num>=7:
    words7=sentences[6].split()
if num>=8:
    words8=sentences[7].split()
if num>=9:
    words9=sentences[8].split()
if num==10:
    words10=sentences[9].split()<|endoftext|>


<commit_before># This script is used to import Northern Ireland postcode information from the
# National Statistics Postcode Database.
# http://www.ons.gov.uk/about-statistics/geography/products/geog-products-postcode/nspd/
#
# The fields of NSPD Open CSV file are:
#   Postcode (7), Postcode (8), Postcode (sp), Start date, End date, County,
#   council, ward, usertype, Easting, Northing, quality, SHA, IT cluster,
#   country, GOR, Stats region, Parliamentary constituency, Euro region,
#   TEC/LEC, Travel to Work area, Primary Care Org, NUTS, 1991 census ED,
#   1991 census ED, ED indicator, Pre-July 2006 SHA, LEA, Pre 2002 Health
#   Authority, 1991 ward code, 1991 ward code, 1998 ward code, 2005 stats ward,
#   OA code, OA indicator, CAS ward, National Park, SOA (Lower), Datazone, SOA
#   (Middle), Urban/rural, Urban/rural, Urban/rural, Intermediate, SOA (NI), OA
#   classification, Pre October 2006 PCO

import sys
import csv
from django.contrib.gis.geos import Point
from django.core.management.base import BaseCommand
from mapit.postcodes.models import Postcode
from mapit.areas.models import Area, Generation

class Command(BaseCommand):
    help = 'Imports Northern Ireland postcodes from the NSPD, creates the areas if need be'

    def handle(self, *args, **options):
        current_generation = Generation.objects.current()
        new_generation = Generation.objects.new()
        if not new_generation:
            raise Exception, "No new generation to be used for import!"

        euro_area, created = Area.objects.get_or_create(country='N', type='EUR',
            generation_low__lte=current_generation, generation_high__gte=current_generation,
            defaults = { 'generation_low': new_generation, 'generation_high': new_generation }
        )
        euro_area.generation_high = new_generation
        euro_area.save()
        euro_area.names.get_or_create(type='S', name='Northern Ireland')

        # Read in ward name -> electoral area name/area
        ni_eas = csv.reader(open('../../data/ni-electoral-areas.csv'))
        ward_to_electoral_area = {}
        e = {}
        for district, electoral_area, ward, dummy in ni_eas:
            if not district:
                district = last_district
            if not electoral_area:
                electoral_area = last_electoral_area
            last_district = district
            last_electoral_area = electoral_area
            if electoral_area not in e:
                ea = Area.objects.get_or_create_with_name(
                    country='N', type='LGE', name_type='M', name=electoral_area,
                )
                e[electoral_area] = ea
            ward_to_electoral_area.setdefault(district, {})[ward] = e[electoral_area]

        # Read in new ONS code to names
        snac = csv.reader(open('../../data/snac-2009-ni-cons2ward.csv'))
        code_to_area = {}
        ward_to_parl = {}
        for parl_code, parl_name, ward_code, ward_name, district_code, district_name in snac:
            if district_name not in ward_to_electoral_area:
                raise Exception, "District %s is missing" % district_name
            if ward_name not in ward_to_electoral_area[district_name]:
                raise Exception, "Ward %s, district %s is missing" % (ward_name, district_name)

            ward_code = ward_code.replace(' ', '')

            if district_code not in code_to_area:
                district_area = Area.objects.get_or_create_with_code(
                    country='N', type='LGD', code_type='ons', code=district_code,
                )
                district_area.names.get_or_create(type='S', name=district_name)
                code_to_area[district_code] = district_area

            if ward_code not in code_to_area:
                ward_area = Area.objects.get_or_create_with_code(
                    country='N', type='LGW', code_type='ons', code=ward_code
                )
                ward.names.get_or_create(type='S', name=ward_name)
                ward_area.parent_area = ward_to_electoral_area[district_name][ward_name]
                ward_area.parent_area.parent_area = code_to_area[district_code]
                code_to_area[ward_code] = ward_area

            if parl_code not in code_to_area:
                parl_area = Area.objects.get_or_create_with_code(
                    country='N', type='WMC', code_type='ons', code=parl_code,
                )
                parl_area.names.get_or_create(type='S', name=parl_name)
                code_to_area[parl_code] = parl_area
                name_to_area[parl_name] = parl_area

            ward_to_parl[ward_code] = code_to_area[parl_code]

        # Read in old SNAC for NI Assembly boundaries, still the same until 2011
        snac = csv.reader(open('../../data/snac-2003-ni-cons2ward.csv'))
        ward_to_assembly = {}
        for parl_code, parl_name, ward_code, ward_name, district_code, district_name in snac:
            if 'NIE' + parl_code not in code_to_area:
                nia_area = Area.objects.get_or_create_with_name(
                    country='N', type='NIE', name_type='S', name=parl_name,
                )
                code_to_area['NIE' + parl_code] = nia_area
            ward_to_assembly[ward_code] = code_to_area['NIE' + parl_code]

        # The manual fix for the split ward in the 2010 boundaries
        derryaghy = csv.reader(open('../../data/Derryaghy-postcodes.csv'))
        derryaghy_fix = {}
        for postcode, parl_name in derryaghy:
            derryaghy_fix[postcode] = name_to_area[parl_name]

        count = 0
        for row in csv.reader(sys.stdin):
            if row[4]: continue # Terminated postcode
            if row[11] == '9': continue # PO Box etc.

            postcode = row[0].strip().replace(' ', '')
            if postcode[0:2] != 'BT': continue # Only importing NI from NSPD

            # Create/update the postcode
            location = Point(map(float, row[9:11]), srid=27700)
            try:
                pc = Postcode.objects.get(postcode=postcode)
                if pc.location != location:
                    pc.location = location
                    pc.save()
            except Postcode.DoesNotExist:
                pc = Postcode.objects.create(postcode=postcode, location=location)

            # Create/update the areas
            ons_code = ''.join(row[5:8])
            ward = Area.objects.get(codes__type='ons', codes__code=ons_code)
            electoral_area = ward.parent_area
            council = electoral_area.parent_area
            nia_area = ward_to_assembly[ons_code]
            parl_area = ward_to_parl[ons_code]
            if postcode in derryaghy_fix:
                parl_area = derryaghy_fix[postcode]
            pc.areas.add(ward, electoral_area, council, nia_area, parl_area, euro_area)

            count += 1
            if count % 10000 == 0:
                print "Imported %d" % count
<commit_msg>Skip header rows.<commit_after># This script is used to import Northern Ireland postcode information from the
# National Statistics Postcode Database.
# http://www.ons.gov.uk/about-statistics/geography/products/geog-products-postcode/nspd/
#
# The fields of NSPD Open CSV file are:
#   Postcode (7), Postcode (8), Postcode (sp), Start date, End date, County,
#   council, ward, usertype, Easting, Northing, quality, SHA, IT cluster,
#   country, GOR, Stats region, Parliamentary constituency, Euro region,
#   TEC/LEC, Travel to Work area, Primary Care Org, NUTS, 1991 census ED,
#   1991 census ED, ED indicator, Pre-July 2006 SHA, LEA, Pre 2002 Health
#   Authority, 1991 ward code, 1991 ward code, 1998 ward code, 2005 stats ward,
#   OA code, OA indicator, CAS ward, National Park, SOA (Lower), Datazone, SOA
#   (Middle), Urban/rural, Urban/rural, Urban/rural, Intermediate, SOA (NI), OA
#   classification, Pre October 2006 PCO

import sys
import csv
from django.contrib.gis.geos import Point
from django.core.management.base import BaseCommand
from mapit.postcodes.models import Postcode
from mapit.areas.models import Area, Generation

class Command(BaseCommand):
    help = 'Imports Northern Ireland postcodes from the NSPD, creates the areas if need be'

    def handle(self, *args, **options):
        current_generation = Generation.objects.current()
        new_generation = Generation.objects.new()
        if not new_generation:
            raise Exception, "No new generation to be used for import!"

        euro_area, created = Area.objects.get_or_create(country='N', type='EUR',
            generation_low__lte=current_generation, generation_high__gte=current_generation,
            defaults = { 'generation_low': new_generation, 'generation_high': new_generation }
        )
        euro_area.generation_high = new_generation
        euro_area.save()
        euro_area.names.get_or_create(type='S', name='Northern Ireland')

        # Read in ward name -> electoral area name/area
        ni_eas = csv.reader(open('../../data/ni-electoral-areas.csv'))
        ward_to_electoral_area = {}
        e = {}
        for district, electoral_area, ward, dummy in ni_eas:
            if not district:
                district = last_district
            if not electoral_area:
                electoral_area = last_electoral_area
            last_district = district
            last_electoral_area = electoral_area
            if electoral_area not in e:
                ea = Area.objects.get_or_create_with_name(
                    country='N', type='LGE', name_type='M', name=electoral_area,
                )
                e[electoral_area] = ea
            ward_to_electoral_area.setdefault(district, {})[ward] = e[electoral_area]

        # Read in new ONS code to names
        snac = csv.reader(open('../../data/snac-2009-ni-cons2ward.csv'))
        snac.next()
        code_to_area = {}
        ward_to_parl = {}
        for parl_code, parl_name, ward_code, ward_name, district_code, district_name in snac:
            if district_name not in ward_to_electoral_area:
                raise Exception, "District %s is missing" % district_name
            if ward_name not in ward_to_electoral_area[district_name]:
                raise Exception, "Ward %s, district %s is missing" % (ward_name, district_name)

            ward_code = ward_code.replace(' ', '')

            if district_code not in code_to_area:
                district_area = Area.objects.get_or_create_with_code(
                    country='N', type='LGD', code_type='ons', code=district_code,
                )
                district_area.names.get_or_create(type='S', name=district_name)
                code_to_area[district_code] = district_area

            if ward_code not in code_to_area:
                ward_area = Area.objects.get_or_create_with_code(
                    country='N', type='LGW', code_type='ons', code=ward_code
                )
                ward.names.get_or_create(type='S', name=ward_name)
                ward_area.parent_area = ward_to_electoral_area[district_name][ward_name]
                ward_area.parent_area.parent_area = code_to_area[district_code]
                code_to_area[ward_code] = ward_area

            if parl_code not in code_to_area:
                parl_area = Area.objects.get_or_create_with_code(
                    country='N', type='WMC', code_type='ons', code=parl_code,
                )
                parl_area.names.get_or_create(type='S', name=parl_name)
                code_to_area[parl_code] = parl_area
                name_to_area[parl_name] = parl_area

            ward_to_parl[ward_code] = code_to_area[parl_code]

        # Read in old SNAC for NI Assembly boundaries, still the same until 2011
        snac = csv.reader(open('../../data/snac-2003-ni-cons2ward.csv'))
        snac.next()
        ward_to_assembly = {}
        for parl_code, parl_name, ward_code, ward_name, district_code, district_name in snac:
            if 'NIE' + parl_code not in code_to_area:
                nia_area = Area.objects.get_or_create_with_name(
                    country='N', type='NIE', name_type='S', name=parl_name,
                )
                code_to_area['NIE' + parl_code] = nia_area
            ward_to_assembly[ward_code] = code_to_area['NIE' + parl_code]

        # The manual fix for the split ward in the 2010 boundaries
        derryaghy = csv.reader(open('../../data/Derryaghy-postcodes.csv'))
        derryaghy_fix = {}
        for postcode, parl_name in derryaghy:
            derryaghy_fix[postcode] = name_to_area[parl_name]

        count = 0
        for row in csv.reader(sys.stdin):
            if row[4]: continue # Terminated postcode
            if row[11] == '9': continue # PO Box etc.

            postcode = row[0].strip().replace(' ', '')
            if postcode[0:2] != 'BT': continue # Only importing NI from NSPD

            # Create/update the postcode
            location = Point(map(float, row[9:11]), srid=27700)
            try:
                pc = Postcode.objects.get(postcode=postcode)
                if pc.location != location:
                    pc.location = location
                    pc.save()
            except Postcode.DoesNotExist:
                pc = Postcode.objects.create(postcode=postcode, location=location)

            # Create/update the areas
            ons_code = ''.join(row[5:8])
            ward = Area.objects.get(codes__type='ons', codes__code=ons_code)
            electoral_area = ward.parent_area
            council = electoral_area.parent_area
            nia_area = ward_to_assembly[ons_code]
            parl_area = ward_to_parl[ons_code]
            if postcode in derryaghy_fix:
                parl_area = derryaghy_fix[postcode]
            pc.areas.add(ward, electoral_area, council, nia_area, parl_area, euro_area)

            count += 1
            if count % 10000 == 0:
                print "Imported %d" % count
<|endoftext|>


<commit_before>import datetime
from app.core.db import db
from app.user.models import User

class Reservation(db.Model):
    __tablename__ = 'Reservation'
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('User.id'))
    user = db.relationship('User',
        backref=db.backref('reservation', lazy='dynamic'))
    reservation_code = db.Column(db.String(10))
    checkin_date = db.Column(db.DateTime)
    checkout_date = db.Column(db.DateTime)
    room_number = db.Column(db.Integer)
    room = db.Column(db.Integer)
    adult = db.Column(db.Integer)
    amount = db.Column(db.Float)
    night = db.Column(db.Integer)
    status = db.Column(db.Boolean)
    chekin_status = db.Column(db.Boolean)
    checkout_status = db.Column(db.Boolean)
<commit_msg>update modeling in reservation model<commit_after>import datetime
from app.core.db import db
from app.user.models import User
from app.hotel.models import Hotels

class Reservation(db.Model):
    __tablename__ = 'Reservation'
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('User.id'))
    user = db.relationship('User',
        backref=db.backref('reservation', lazy='dynamic'))
    hotel_id = db.Column(db.Integer, db.ForeignKey('Hotels.id'))
    hotel = db.relationship('Hotels',
        backref=db.backref('reservation', lazy='dynamic'))
    reservation_code = db.Column(db.String(10))
    checkin_date = db.Column(db.DateTime)
    checkout_date = db.Column(db.DateTime)
    room_number = db.Column(db.Integer)
    room = db.Column(db.Integer)
    adult = db.Column(db.Integer)
    amount = db.Column(db.Float)
    night = db.Column(db.Integer)
    status = db.Column(db.Boolean)
    chekin_status = db.Column(db.Boolean)
    checkout_status = db.Column(db.Boolean)
<|endoftext|>


<commit_before>import re
import ephem

from astropy import units as u
from astropy.coordinates import SkyCoord

from panoptes.mount.mount import AbstractMount
from panoptes.utils import logger, config, param_server, error

@logger.set_log_level('debug')
@logger.has_logger
class Mount(AbstractMount):

    """
        Mount class for iOptron mounts. Overrides the base `initialize` method
        and providers some helper methods to convert coordinates.
    """

    def __init__(self, *args, **kwargs):
        self.logger.info('Creating mount')
        super().__init__(*args, **kwargs)

        # Regexp to match the iOptron RA/Dec format
        self._ra_format = re.compile('(?P<ra_hour>\d{2})(?P<ra_minute>\d{2})(?P<ra_second>\d{2})')
        self._dec_format = re.compile('(?P<dec_sign>[\+\-])(?P<dec_degree>\d{2})(?P<dec_minute>\d{2})(?P<dec_second>\d{2})')
        self._coords_format = re.compile(self._dec_format + self._ra_format)

        self.logger.info('Mount created')

    def initialize(self):
        """
        iOptron mounts are initialized by sending the following two commands
        to the mount:
        * Version
        * MountInfo

        If the mount is successfully initialized, the `calibrate_mount` command
        is also issued to the mount.

        Returns:
            bool:   Returns the value from `self.is_initialized`.
        """
        self.logger.info('Initializing {} mount'.format(__name__))
        if not self.is_connected():
            self.connect()

        if not self.is_initialized:

            # We trick the mount into thinking it's initialized while we
            # initialize otherwise the `serial_query` method will test
            # to see if initialized and be put into loop.
            self.is_initialized = True

            actual_version = self.serial_query('version')
            actual_mount_info = self.serial_query('mount_info')

            expected_version = self.commands.get('version').get('response')
            expected_mount_info = self.commands.get(
                'mount_info').get('response')
            self.is_initialized = False

            # Test our init procedure for iOptron
            if actual_version != expected_version or actual_mount_info != expected_mount_info:
                self.logger.debug(
                    '{} != {}'.format(actual_version, expected_version))
                self.logger.debug(
                    '{} != {}'.format(actual_mount_info, expected_mount_info))
                raise error.MountNotFound('Problem initializing mount')
            else:
                self.is_initialized = True
                self.setup_site()

        self.logger.info('Mount initialized: {}'.format(self.is_initialized))

        return self.is_initialized

    def setup_site(self, site=None):
        """
        Sets the mount up to the current site. Includes:
        * Latitude set_long
        * Longitude set_lat
        * Universal Time Offset set_gmt_offset
        * Daylight Savings disable_daylight_savings
        * Current Date set_local_date
        * Current Time set_local_time

        Args:
            site (ephem.Observer): A defined location for the observatory.
        """
        site = self.site
        assert site is not None, self.logger.warning('setup_site requires a site in the config')
        self.logger.info('Setting up mount for site')

        # Location
            # Adjust the lat/long for format expected by iOptron
        lat = '{}'.format(site.lat).replace(':', '').split('.')[0]
        lon = '{}'.format(site.long).replace(':', '').split('.')[0]

        if site.lat > 0:
            lat = '+{}'.format(lat)
        else:
            lat = '-{}'.format(lat)

        if site.lon > 0:
            lon = '+{}'.format(lon)
        else:
            lon = '-{}'.format(lon)

        self.serial_query('set_long', lon)
        self.serial_query('set_lat', lat)

        # Time
        self.serial_query('disable_daylight_savings')
        self.serial_query('set_gmt_offset', self.config.get('site').get('gmt_offset', 0))

        dt = ephem.localtime(site.date)

        t = "{:02d}{:02d}{:02d}".format(dt.hour, dt.minute, dt.second)
        d = "{:02d}{:02d}{:02d}".format(dt.year - 2000, dt.month, dt.day)

        self.serial_query('set_local_time', t)
        self.serial_query('set_local_date', d)

    def _mount_coord_to_skycoord(self, mount_coords):
        """
        Converts between iOptron RA/Dec format and a SkyCoord

        @param  mount_ra    RA in mount specific format
        @param  mount_dec   Dec in mount specific format

        @retval     astropy.coordinates.SkyCoord
        """
        coords_match = self._coords_format.fullmatch(mount_coords)

        coords = None

        if coords_match is not None:
            ra = "{}h{}m{}s".format(
                coords_match.group('ra_hour'),
                coords_match.group('ra_minute'),
                coords_match.group('ra_second')
            )
            dec = "{}{}d{}m{}s".format(
                coords_match.group('dec_sign'),
                coords_match.group('dec_degree'),
                coords_match.group('dec_minute'),
                coords_match.group('dec_second')
            )
            coords = SkyCoord(ra, dec, frame='icrs')
        else:
            self.logger.warning(
                "Cannot create SkyCoord from mount coordinates")

        return coords

    def _skycoord_to_mount_coord(self, coords):
        """
        Converts between SkyCoord and a iOptron RA/Dec format

        @param  coords  astropy.coordinates.SkyCoord

        @retval         A tuple of RA/Dec coordinates
        """

        ra_hms = coords.ra.hms
        mount_ra = "{:=02.0f}1{:=02.0f}{:=02.0f}".format(ra_hms.h, ra_hms.m, ra_hms.s)

        dec_dms = coords.dec.dms
        mount_dec = "{:=+03.0f}{:02.0f}{:02.0f}".format(dec_dms.d, abs(dec_dms.m), abs(dec_dms.s))

        mount_coords = (mount_ra, mount_dec)

        return mount_coords
<commit_msg>Adding status command basics<commit_after>import re
import ephem

from astropy import units as u
from astropy.coordinates import SkyCoord

from panoptes.mount.mount import AbstractMount
from panoptes.utils import logger, config, param_server, error

@logger.set_log_level('debug')
@logger.has_logger
class Mount(AbstractMount):

    """
        Mount class for iOptron mounts. Overrides the base `initialize` method
        and providers some helper methods to convert coordinates.
    """

    def __init__(self, *args, **kwargs):
        self.logger.info('Creating mount')
        super().__init__(*args, **kwargs)

        # Regexp to match the iOptron RA/Dec format
        self._ra_format = re.compile('(?P<ra_hour>\d{2})(?P<ra_minute>\d{2})(?P<ra_second>\d{2})')
        self._dec_format = re.compile(
            '(?P<dec_sign>[\+\-])(?P<dec_degree>\d{2})(?P<dec_minute>\d{2})(?P<dec_second>\d{2})')
        self._coords_format = re.compile(self._dec_format + self._ra_format)

        self.logger.info('Mount created')

    def initialize(self):
        """
        iOptron mounts are initialized by sending the following two commands
        to the mount:
        * Version
        * MountInfo

        If the mount is successfully initialized, the `calibrate_mount` command
        is also issued to the mount.

        Returns:
            bool:   Returns the value from `self.is_initialized`.
        """
        self.logger.info('Initializing {} mount'.format(__name__))
        if not self.is_connected():
            self.connect()

        if not self.is_initialized:

            # We trick the mount into thinking it's initialized while we
            # initialize otherwise the `serial_query` method will test
            # to see if initialized and be put into loop.
            self.is_initialized = True

            actual_version = self.serial_query('version')
            actual_mount_info = self.serial_query('mount_info')

            expected_version = self.commands.get('version').get('response')
            expected_mount_info = self.commands.get(
                'mount_info').get('response')
            self.is_initialized = False

            # Test our init procedure for iOptron
            if actual_version != expected_version or actual_mount_info != expected_mount_info:
                self.logger.debug(
                    '{} != {}'.format(actual_version, expected_version))
                self.logger.debug(
                    '{} != {}'.format(actual_mount_info, expected_mount_info))
                raise error.MountNotFound('Problem initializing mount')
            else:
                self.is_initialized = True
                self.setup_site()

        self.logger.info('Mount initialized: {}'.format(self.is_initialized))

        return self.is_initialized

    def setup_site(self, site=None):
        """
        Sets the mount up to the current site. Includes:
        * Latitude set_long
        * Longitude set_lat
        * Universal Time Offset set_gmt_offset
        * Daylight Savings disable_daylight_savings
        * Current Date set_local_date
        * Current Time set_local_time

        Args:
            site (ephem.Observer): A defined location for the observatory.
        """
        site = self.site
        assert site is not None, self.logger.warning('setup_site requires a site in the config')
        self.logger.info('Setting up mount for site')

        # Location
        # Adjust the lat/long for format expected by iOptron
        lat = '{}'.format(site.lat).replace(':', '').split('.')[0]
        lon = '{}'.format(site.long).replace(':', '').split('.')[0]

        if site.lat > 0:
            lat = '+{}'.format(lat)
        else:
            lat = '-{}'.format(lat)

        if site.lon > 0:
            lon = '+{}'.format(lon)
        else:
            lon = '-{}'.format(lon)

        self.serial_query('set_long', lon)
        self.serial_query('set_lat', lat)

        # Time
        self.serial_query('disable_daylight_savings')
        self.serial_query('set_gmt_offset', self.config.get('site').get('gmt_offset', 0))

        dt = ephem.localtime(site.date)

        t = "{:02d}{:02d}{:02d}".format(dt.hour, dt.minute, dt.second)
        d = "{:02d}{:02d}{:02d}".format(dt.year - 2000, dt.month, dt.day)

        self.serial_query('set_local_time', t)
        self.serial_query('set_local_date', d)

    def status(self):
        """
        Gets the system status

        From the documentation (iOptron ® Mount RS-232 Command Language 2014 Version 2.0 August 8th, 2014)

        Command: “:GAS#”
        Response: “nnnnnn#”
        The 1st digit stands for GPS status: 0 means GPS off, 1 means GPS on, 2 means GPS data extracted
        correctly.
        The 2nd digit stands for system status: 0 means stopped (not at zero position), 1 means tracking
        with PEC disabled, 2 means slewing, 3 means guiding, 4 means meridian flipping, 5 means tracking
        with PEC enabled (only for non-encoder edition), 6 means parked, 7 means stopped at zero position
        (home position).
        The 3rd digit stands for tracking rates: 0 means sidereal rate, 1 means lunar rate, 2 means solar rate,
        3 means King rate, 4 means custom rate.
        The 4th digit stands for moving speed by arrow button or moving command: 1 means 1x sidereal
        tracking rate, 2 means 2x, 3 means 8x, 4 means 16x, 5 means 64x, 6 means 128x, 7 means 256x, 8
        means 512x, 9 means maximum speed. Currently, the maximum speed of CEM60 (-EC) is 900x,
        the maximum speed of iEQ45 Pro (/AA) is 1400x.
        The 5th digit stands for time source: 1 means RS-232 port, 2 means hand controller, 3 means GPS.
        The 6th digit stands for hemisphere: 0 means Southern Hemisphere, 1 means Northern Hemisphere.
        """
        # Get the status
        status = self.serial_query('get_status')

        status_lookup = {
            'gps':    {
                0: 'Off',
                1: 'On',
                2: 'Data Extracted'
            },
            'system':   {
                0: 'Stopped - Not at Zero Position',
                1: 'Tracking (PEC disabled)',
                2: 'Slewing',
                3: 'Guiding',
                4: 'Meridian Flipping',
                5: 'Tracking (PEC enabled)',
                6: 'Parked',
                7: 'Stopped - Zero Position'
            },
            'tracking': {
                0: 'Sidereal',
                1: 'Lunar',
                2: 'Solar',
                3: 'King',
                4: 'Custom'
            },
            'movement_speed': {
                1: '1x sidereal',
                2: '2x sidereal',
                3: '8x sidereal',
                4: '16x sidereal',
                5: '64x sidereal',
                6: '128x sidereal',
                7: '256x sidereal',
                8: '512x sidereal',
                9: 'Max sidereal',
            },
            'time_source': {
                1: 'RS-232',
                2: 'Hand Controller',
                3: 'GPS'
            },
            'hemisphere': {
                0: 'Southern',
                1: 'Northern'
            }
        }

    def _mount_coord_to_skycoord(self, mount_coords):
        """
        Converts between iOptron RA/Dec format and a SkyCoord

        @param  mount_ra    RA in mount specific format
        @param  mount_dec   Dec in mount specific format

        @retval     astropy.coordinates.SkyCoord
        """
        coords_match = self._coords_format.fullmatch(mount_coords)

        coords = None

        if coords_match is not None:
            ra = "{}h{}m{}s".format(
                coords_match.group('ra_hour'),
                coords_match.group('ra_minute'),
                coords_match.group('ra_second')
            )
            dec = "{}{}d{}m{}s".format(
                coords_match.group('dec_sign'),
                coords_match.group('dec_degree'),
                coords_match.group('dec_minute'),
                coords_match.group('dec_second')
            )
            coords = SkyCoord(ra, dec, frame='icrs')
        else:
            self.logger.warning(
                "Cannot create SkyCoord from mount coordinates")

        return coords

    def _skycoord_to_mount_coord(self, coords):
        """
        Converts between SkyCoord and a iOptron RA/Dec format

        @param  coords  astropy.coordinates.SkyCoord

        @retval         A tuple of RA/Dec coordinates
        """

        ra_hms = coords.ra.hms
        mount_ra = "{:=02.0f}1{:=02.0f}{:=02.0f}".format(ra_hms.h, ra_hms.m, ra_hms.s)

        dec_dms = coords.dec.dms
        mount_dec = "{:=+03.0f}{:02.0f}{:02.0f}".format(dec_dms.d, abs(dec_dms.m), abs(dec_dms.s))

        mount_coords = (mount_ra, mount_dec)

        return mount_coords
<|endoftext|>


<commit_before>import re

from astropy import units as u
from astropy.coordinates import SkyCoord

from panoptes.mount.mount import AbstractMount
from panoptes.utils import logger, config, param_server

@logger.has_logger
class Mount(AbstractMount):

    """
        Mount class for iOptron mounts. Overrides the base `initialize_mount` method
        and providers some helper methods to convert coordinates.
    """

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # Regexp to match the iOptron RA/Dec format
        self._ra_format = re.compile(
            '(?P<hour>\d{2}):(?P<minute>\d{2}):(?P<second>\d{2})')
        self._dec_format = re.compile(
            '(?P<sign>[\+\-])(?P<degree>\d{2})\*(?P<minute>\d{2}):(?P<second>\d{2})')

    def initialize_mount(self):
        """
            iOptron init procedure:
                    - Version
                    - MountInfo
        """
        self.logger.info('Initializing {} mount'.format(__name__))
        if not self.is_connected():
            self.connect()

        if not self.is_initialized:

            # We trick the mount into thinking it's initialized while we
            # initialize
            self.is_initialized = True

            actual_version = self.serial_query('version')
            actual_mount_info = self.serial_query('mount_info')

            expected_version = self.commands.get('version').get('response')
            expected_mount_info = self.commands.get(
                'mount_info').get('response')
            self.is_initialized = False

            # Test our init procedure for iOptron
            if actual_version != expected_version or actual_mount_info != expected_mount_info:
                self.logger.debug(
                    '{} != {}'.format(actual_version, expected_version))
                self.logger.debug(
                    '{} != {}'.format(actual_mount_info, expected_mount_info))
                raise error.MountNotFound('Problem initializing mount')
            else:
                self.is_initialized = True
                self.serial_query('calibrate_mount')

        self.logger.debug('Mount initialized: {}'.format(self.is_initialized))
        return self.is_initialized

    def _mount_coord_to_skycoord(self, mount_ra, mount_dec):
        """
        Converts between iOptron RA/Dec format and a SkyCoord

        @param  mount_ra    RA in mount specific format
        @param  mount_dec   Dec in mount specific format

        @retval     astropy.coordinates.SkyCoord
        """
        ra_match = self._ra_format.fullmatch(mount_ra)
        dec_match = self._dec_format.fullmatch(mount_dec)

        coords = None

        if ra_match is not None and dec_match is not None:
            ra = "{}h{}m{}s".format(
                ra_match.group('hour'),
                ra_match.group('minute'),
                ra_match.group('second')
            )
            dec = "{}{}d{}m{}s".format(
                dec_match.group('sign'),
                dec_match.group('degree'),
                dec_match.group('minute'),
                dec_match.group('second')
            )
            coords = SkyCoord(ra, dec, frame='icrs')
        else:
            self.logger.warning(
                "Cannot create SkyCoord from mount coordinates")

        return coords

    def _skycoord_to_mount_coord(self, coords):
        """
        Converts between SkyCoord and a iOptron RA/Dec format

        @param  coords  astropy.coordinates.SkyCoord

        @retval         A tuple of RA/Dec coordinates
        """

        ra_hms = coords.ra.hms
        mount_ra = "{:=02.0f}:{:=02.0f}:{:=02.0f}".format(ra_hms.h, ra_hms.m, ra_hms.s)

        dec_dms = coords.dec.dms
        mount_dec = "{:=+03.0f}*{:02.0f}:{:02.0f}".format(dec_dms.d, abs(dec_dms.m), abs(dec_dms.s))

        mount_coords = (mount_ra, mount_dec)

        return mount_coords
<commit_msg>initialize instead of initialize_mount<commit_after>import re

from astropy import units as u
from astropy.coordinates import SkyCoord

from panoptes.mount.mount import AbstractMount
from panoptes.utils import logger, config, param_server

@logger.has_logger
class Mount(AbstractMount):

    """
        Mount class for iOptron mounts. Overrides the base `initialize` method
        and providers some helper methods to convert coordinates.
    """

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # Regexp to match the iOptron RA/Dec format
        self._ra_format = re.compile(
            '(?P<hour>\d{2}):(?P<minute>\d{2}):(?P<second>\d{2})')
        self._dec_format = re.compile(
            '(?P<sign>[\+\-])(?P<degree>\d{2})\*(?P<minute>\d{2}):(?P<second>\d{2})')

    def initialize(self):
        """
            iOptron init procedure:
                    - Version
                    - MountInfo
        """
        self.logger.info('Initializing {} mount'.format(__name__))
        if not self.is_connected():
            self.connect()

        if not self.is_initialized:

            # We trick the mount into thinking it's initialized while we
            # initialize
            self.is_initialized = True

            actual_version = self.serial_query('version')
            actual_mount_info = self.serial_query('mount_info')

            expected_version = self.commands.get('version').get('response')
            expected_mount_info = self.commands.get(
                'mount_info').get('response')
            self.is_initialized = False

            # Test our init procedure for iOptron
            if actual_version != expected_version or actual_mount_info != expected_mount_info:
                self.logger.debug(
                    '{} != {}'.format(actual_version, expected_version))
                self.logger.debug(
                    '{} != {}'.format(actual_mount_info, expected_mount_info))
                raise error.MountNotFound('Problem initializing mount')
            else:
                self.is_initialized = True
                self.serial_query('calibrate_mount')

        self.logger.debug('Mount initialized: {}'.format(self.is_initialized))
        return self.is_initialized

    def _mount_coord_to_skycoord(self, mount_ra, mount_dec):
        """
        Converts between iOptron RA/Dec format and a SkyCoord

        @param  mount_ra    RA in mount specific format
        @param  mount_dec   Dec in mount specific format

        @retval     astropy.coordinates.SkyCoord
        """
        ra_match = self._ra_format.fullmatch(mount_ra)
        dec_match = self._dec_format.fullmatch(mount_dec)

        coords = None

        if ra_match is not None and dec_match is not None:
            ra = "{}h{}m{}s".format(
                ra_match.group('hour'),
                ra_match.group('minute'),
                ra_match.group('second')
            )
            dec = "{}{}d{}m{}s".format(
                dec_match.group('sign'),
                dec_match.group('degree'),
                dec_match.group('minute'),
                dec_match.group('second')
            )
            coords = SkyCoord(ra, dec, frame='icrs')
        else:
            self.logger.warning(
                "Cannot create SkyCoord from mount coordinates")

        return coords

    def _skycoord_to_mount_coord(self, coords):
        """
        Converts between SkyCoord and a iOptron RA/Dec format

        @param  coords  astropy.coordinates.SkyCoord

        @retval         A tuple of RA/Dec coordinates
        """

        ra_hms = coords.ra.hms
        mount_ra = "{:=02.0f}:{:=02.0f}:{:=02.0f}".format(ra_hms.h, ra_hms.m, ra_hms.s)

        dec_dms = coords.dec.dms
        mount_dec = "{:=+03.0f}*{:02.0f}:{:02.0f}".format(dec_dms.d, abs(dec_dms.m), abs(dec_dms.s))

        mount_coords = (mount_ra, mount_dec)

        return mount_coords
<|endoftext|>


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

###############################################################################
# Imports
###############################################################################

from pants.shared import log

###############################################################################
# Publisher Class
###############################################################################

class Publisher(object):
    """
    A class that implements the publish/subscribe event pattern.

    This class may be directly instantiated to create a standalone
    publisher object, or it may be inherited by another class to provide
    pub/sub capabilities to instances of that class.
    """
    def __init__(self):
        """
        Initialises the publisher object.
        """
        self._events = {}

    def event(self, event):
        """
        Decorator. Subscribe a function to an event.

        Parameters:
            event - The event identifier, typically a string.
        """
        def decorator(func):
            self.subscribe(event, func)
            return func

        return decorator

    def publish(self, event, *args, **kwargs):
        """
        Publish an event.

        Parameters:
            event - The event identifier, typically a string.
            *args - Positional arguments to be passed to subscribers.
            **kwargs - Keyword arguments to be passed to subscribers.
        """
        if not event in self._events:
            return

        for func in self._events[event]:
            try:
                func(*args, **kwargs)
            except Exception:
                log.exception("Exception raised while executing event.")

    def subscribe(self, event, func):
        """
        Subscribe a callable to an event.

        Parameters:
            event - The event identifier, typically a string.
            func - A callable that will be executed whenever the event
                is published.
        """
        if not event in self._events:
            self._events[event] = []

        self._events[event].append(func)

    def unsubscribe(self, event=None, func=None):
        """
        Unsubscribe a callable from an event.

        An event and a callable can be passed to this method. If no
        event is passed, all callables will be unsubscribed from all
        events. If an event is passed without a callable, all callables
        will be unsubscribed from that event. If both an event and a
        callable are passed then the callable will be unsubscribed from
        the event.

        Note that if a callable is passed without an event, all
        callables will be unsubscribed from all events.

        Parameters:
            event - The event identifier, typically a string.
            func - A callable subscribed to some number of events.
        """
        if event is None:
            self._events = {}
        elif func is None:
            self._events[event] = []
        else:
            self._events[event].remove(func)

###############################################################################
# Initialisation
###############################################################################

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

###############################################################################
# Imports
###############################################################################

from pants.shared import log

###############################################################################
# Publisher Class
###############################################################################

class Publisher(object):
    """
    A class that implements the publish/subscribe event pattern.

    This class may be directly instantiated to create a standalone
    publisher object, or it may be inherited by another class to provide
    pub/sub capabilities to instances of that class.
    """
    def __init__(self):
        """
        Initialises the publisher object.
        """
        self._events = {}

    def event(self, event):
        """
        Decorator. Subscribe a function to an event.

        Parameters:
            event - The event identifier, typically a string.
        """
        def decorator(handler):
            self.subscribe(event, handler)
            return handler

        return decorator

    def publish(self, event, *args, **kwargs):
        """
        Publish an event.

        Parameters:
            event - The event identifier, typically a string.
            *args - Positional arguments to be passed to subscribers.
            **kwargs - Keyword arguments to be passed to subscribers.
        """
        if not event in self._events:
            return

        for handler in self._events[event]:
            try:
                handler(*args, **kwargs)
            except Exception:
                log.exception("Exception raised while executing event.")

    def subscribe(self, event, handler):
        """
        Subscribe a callable to an event.

        Parameters:
            event - The event identifier, typically a string.
            handler - A callable that will be executed whenever the
                event is published.
        """
        if not event in self._events:
            self._events[event] = []

        self._events[event].append(handler)

    def unsubscribe(self, event=None, handler=None):
        """
        Unsubscribe a callable from an event.

        An event and a callable can be passed to this method. If no
        event is passed, all callables will be unsubscribed from all
        events. If an event is passed without a callable, all callables
        will be unsubscribed from that event. If both an event and a
        callable are passed then the callable will be unsubscribed from
        the event.

        Note that if a callable is passed without an event, all
        callables will be unsubscribed from all events.

        Parameters:
            event - The event identifier, typically a string.
            handler - A callable subscribed to some number of events.
        """
        if event is None:
            self._events = {}
        elif handler is None:
            self._events[event] = []
        else:
            self._events[event].remove(handler)

###############################################################################
# Initialisation
###############################################################################

#: The global publisher object.
publisher = Publisher()
<|endoftext|>


<commit_before>#
# Author    : Manuel Bernal Llinares
# Project   : trackhub-creator
# Timestamp : 12-09-2017 16:10
# ---
# © 2017 Manuel Bernal Llinares <mbdebian@gmail.com>
# All rights reserved.
#

"""
This file contains different models for the execution of subprocesses / external processes, e.g. via the command line
"""

import abc
import threading
import subprocess
# App imports
import config_manager
from .exceptions import ParallelRunnerException

# Execution of commands
class CommandLineRunnerFactory:
    @staticmethod
    def get_command_line_runner():
        # TODO - This Factory is creating only local runners in the first iteration
        return CommandLineRunnerAsThread()

class ParallelManager:
    pass

class ParallelRunner(metaclass=abc.ABCMeta, threading.Thread):
    def __init__(self):
        super().__init__()
        self._logger = config_manager \
            .get_app_config_manager() \
            .get_logger_for("{}.{}".format(__name__, type(self).__name__))
        self._stdout = b' '
        self._stderr = b' '
        self._done = False
        self._shutdown = False

    @abc.abstractmethod
    def _run(self):
        ...

    def run(self):
        self._logger.debug("Runner Thread ID '{}' --- START ---".format(threading.current_thread().getName()))
        try:
            self._run()
        finally:
            self._done = True

    def cancel(self):
        self._logger.debug("Runner Thread ID '{}' --- CANCEL ---".format(threading.current_thread().getName()))
        self._shutdown = True
        self._stop()

    def wait(self):
        self._logger.debug("Runner Thread ID '{}' --- WAIT ---".format(threading.current_thread().getName()))
        self.join()

    def get_stdout(self):
        # Never give it back until the runner is done with whatever it is doing
        if not self._done:
            raise ParallelRunnerException("Runner Thread ID '{}' is NOT DONE doing its job, "
                                          "thus 'stdout' is NOT AVAILABLE".format(threading.current_thread().getName()))
        return self._stdout

    def get_stderr(self):
        # Never give it back until the runner is done with whatever it is doing
        if not self._done:
            raise ParallelRunnerException("Runner Thread ID '{}' is NOT DONE doing its job, "
                                          "thus 'stderr' is NOT AVAILABLE".format(threading.current_thread().getName()))
        return self._stderr

class CommandLineRunner(ParallelRunner):
    def __init__(self):
        super().__init__()
        self._logger = config_manager \
            .get_app_config_manager() \
            .get_logger_for("{}.{}".format(__name__, type(self).__name__))
        self.command = None
        self.timeout = None

class CommandLineRunnerAsThread(CommandLineRunner):
    def __init__(self):
        super().__init__()
        self._logger = config_manager \
            .get_app_config_manager() \
            .get_logger_for("{}.{}-{}".format(__name__, type(self).__name__, threading.current_thread().getName()))

    def _run(self):
        pass

class CommandLineRunnerOnHpc(CommandLineRunner):
    def __init__(self):
        super().__init__()
        self._logger = config_manager \
            .get_app_config_manager() \
            .get_logger_for("{}.{}".format(__name__, type(self).__name__))

    def _run(self):
        pass
<commit_msg>refactor logger<commit_after>#
# Author    : Manuel Bernal Llinares
# Project   : trackhub-creator
# Timestamp : 12-09-2017 16:10
# ---
# © 2017 Manuel Bernal Llinares <mbdebian@gmail.com>
# All rights reserved.
#

"""
This file contains different models for the execution of subprocesses / external processes, e.g. via the command line
"""

import abc
import threading
import subprocess
# App imports
import config_manager
from .exceptions import ParallelRunnerException

# Execution of commands
class CommandLineRunnerFactory:
    @staticmethod
    def get_command_line_runner():
        # TODO - This Factory is creating only local runners in the first iteration
        return CommandLineRunnerAsThread()

class ParallelManager:
    pass

class ParallelRunner(metaclass=abc.ABCMeta, threading.Thread):
    def __init__(self):
        super().__init__()
        self._logger = config_manager \
            .get_app_config_manager() \
            .get_logger_for("{}.{}".format(__name__, type(self).__name__))
        self._stdout = b' '
        self._stderr = b' '
        self._done = False
        self._shutdown = False

    @abc.abstractmethod
    def _run(self):
        ...

    def run(self):
        self._logger.debug("Runner Thread ID '{}' --- START ---".format(threading.current_thread().getName()))
        try:
            self._run()
        finally:
            self._done = True

    def cancel(self):
        self._logger.debug("Runner Thread ID '{}' --- CANCEL ---".format(threading.current_thread().getName()))
        self._shutdown = True
        self._stop()

    def wait(self):
        self._logger.debug("Runner Thread ID '{}' --- WAIT ---".format(threading.current_thread().getName()))
        self.join()

    def get_stdout(self):
        # Never give it back until the runner is done with whatever it is doing
        if not self._done:
            raise ParallelRunnerException("Runner Thread ID '{}' is NOT DONE doing its job, "
                                          "thus 'stdout' is NOT AVAILABLE".format(threading.current_thread().getName()))
        return self._stdout

    def get_stderr(self):
        # Never give it back until the runner is done with whatever it is doing
        if not self._done:
            raise ParallelRunnerException("Runner Thread ID '{}' is NOT DONE doing its job, "
                                          "thus 'stderr' is NOT AVAILABLE".format(threading.current_thread().getName()))
        return self._stderr

class CommandLineRunner(ParallelRunner):
    def __init__(self):
        super().__init__()
        self._logger = config_manager \
            .get_app_config_manager() \
            .get_logger_for("{}.{}".format(__name__, type(self).__name__))
        self.command = None
        self.timeout = None

class CommandLineRunnerAsThread(CommandLineRunner):
    def __init__(self):
        super().__init__()
        self._logger = config_manager \
            .get_app_config_manager() \
            .get_logger_for("{}.{}-{}".format(__name__, type(self).__name__, threading.current_thread().getName()))

    def _run(self):
        pass

class CommandLineRunnerOnHpc(CommandLineRunner):
    def __init__(self):
        super().__init__()
        self._logger = config_manager \
            .get_app_config_manager() \
            .get_logger_for("{}.{}-{}".format(__name__, type(self).__name__, threading.current_thread().getName()))

    def _run(self):
        pass
<|endoftext|>