<commit_before>from ..PulsePrimitives import *
from ..Compiler import compile_to_hardware
from ..PulseSequencePlotter import plot_pulse_files
from .helpers import create_cal_seqs
from itertools import product
import operator
from ..ControlFlow import *
from ..TdmInstructions import *
from functools import reduce

@qfunction
def qreset(qubits, signVec, measDelay, buf, reg_size=None, TDM_map=None):
    """
    For each qubit, build the set of feedback actions to perform when
    receiving a zero or one in the comparison register

    Parameters
    ----------
    qubits : Channels.LogicalChannel tupple
        A hashable (immutable) tupple of qubits to reset
    signVec : boolean tupple
        A hashable (immutable) tupple of binary values from the compairison
        register indicating the measured state of each qubit in the register
        before reset.
    measDelay : int/float
        Delay after measurement before performing the LOADCMP compairison with
        value in the register (seconds)
    buf : int/float
        Wait time between (seconds)
    reg_size : int, optional
        Size of the register in number of qubits, including those not reset.
        Default value is set to len(qubits).
    TDM_map : bit mask, optional
        Map each qubit to a TDM digital input.  If True, arguments reset a
        subset of the qubit register (see Reset).
        Default: np.array(qN, qN-1, ..., q1) from MSB to LSB.

    Returns
    -------
    seq : QGL.ControlFlow.Call
        QGL sequence with the qreset calls

    Examples
    --------
    >>> qreset((q1, q2), (0,1)], 2e-6, 2e-6);
    CALL(H:)
    """
    if not reg_size:
        reg_size = len(qubits)
        TDM_map = np.arange(reg_size,0,-1)

    FbGates = []
    for ct, q in enumerate(qubits):
        if signVec[ct] == 0:
            FbGates.append([gate(q) for gate in [Id, X]])
        else:  # inverted logic
            FbGates.append([gate(q) for gate in [X, Id]])
    FbSeq = [reduce(operator.mul, x) for x in product(*FbGates)]

    # load register
    seq = [Id(qubits[0], measDelay), qwait(kind='CMP'), Id(qubits[0], buf)]
    # create a branch for each possible comparison value
    for ct in range(2**reg_size):
        # duplicate branches for the irrelevant results
        # if reg_size > len(TDM_map)
        meas_result = [(ct & TDM_bit)>0 for TDM_bit in 2**(np.array(TDM_map)-1)]
        branch_idx = sum([t*2**(len(qubits)-ind-1)
                          for ind,t in enumerate((meas_result))])
        seq += qif(ct, [FbSeq[branch_idx]])

    return seq

def Reset(qubits,
          measDelay=1e-6,
          signVec=None,
          doubleRound=True,
          buf=20e-9,
          showPlot=False,
          measChans=None,
          docals=True,
          calRepeats=2,
          reg_size=None,
          TDM_map=None):
    """
    Preparation, simultanoeus reset, and measurement of an arbitrary number
    of qubits

    Parameters
    ----------
    qubits : Channels.LogicalChannel tupple
        A hashable (immutable) tupple of qubits to reset
    measDelay : int/float, optional
        Delay after measurement before performing the LOADCMP compairison with
        value in the register (seconds)
    signVec : boolean tupple, optional
        conditions for feedback. Tuple of 0 (flip if signal is above threshold) and 1 (flip if below) for each qubit. Default = 0 for all qubits
    doubleRound : boolean, optional
        If true, do two rounds of feedback
    showPlot : boolean, optional
        Whether to plot
    measChans : LogicalChannel tupple, optional
        A hashable (immutable) tupple of qubits to measured.
    docals : boolean, optional
        Whether to append calibration pulses to the end of the sequence
    calRepeats : int, optional
        How many times to repeat calibration scalings (default 2)
    reg_size : int, optional
        Size of the register in number of qubits, including those not reset.
        Default value is set to len(qubits).
    TDM_map : bit mask, optional
        Map each qubit to a TDM digital input.  If True, arguments reset a
        subset of the qubit register (see Reset).
        Default: np.array(qN, qN-1, ..., q1) from MSB to LSB.

    Returns
    -------
    metafile : string
        Path to a json metafile with details about the sequences and paths to
        compiled machine files

    Examples
    --------
    >>> Reset((q1, q2));
    Compiled 12 sequences.
    >>> mf
    '/path/to/exp/exp-meta.json'
    """
    if measChans is None:
        measChans = qubits

    if signVec == None:
        signVec = (0, ) * len(qubits)

    seqs = [prep + [qreset(qubits,
                           signVec,
                           measDelay,
                           buf,
                           reg_size=reg_size,
                           TDM_map=TDM_map)]
                           for prep in create_cal_seqs(qubits, 1)]
    measBlock = reduce(operator.mul, [MEAS(q) for q in qubits])
    if doubleRound:
        for seq in seqs:
            seq += [measBlock]
            seq.append(qreset(qubits,
                              signVec,
                              measDelay,
                              buf,
                              reg_size=reg_size,
                              TDM_map=TDM_map))

    # add final measurement
    for seq in seqs:
        seq += [measBlock, Id(qubits[0], measDelay), qwait(kind='CMP')]

    if docals:
        seqs += create_cal_seqs(qubits,
                                calRepeats,
                                measChans=measChans,
                                waitcmp=True)

    metafile = compile_to_hardware(seqs, 'Reset/Reset')

    if showPlot:
        plot_pulse_files(metafile)
    return metafile

# do not make it a subroutine for now
def BitFlip3(data_qs,
             ancilla_qs,
             theta=None,
             phi=None,
             nrounds=1,
             meas_delay=1e-6,
             docals=False,
             calRepeats=2):
    """
    Encoding on 3-qubit bit-flip code, followed by n rounds of syndrome
    detection, and final correction using the n results.

    Parameters
    ----------
    data_qs : Channels.LogicalChannel tupple
        A hashable (immutable) tupple of qubits of the 3 code qubits
    ancilla_qs : Channels.LogicalChannel tupple
        A hashable (immutable) tupple of qubits of the 2 syndrome qubits
    theta : int/float, optional
        Longitudinal rotation angle for the encoded state (radians).
        Default = None.
    phi : int/float, optional
        Azimuthal rotation angle for the encoded state (radians).
        Default = None.
    nrounds: int, optional
        Number of consecutive measurements
    measDelay : int/float, optional
        Delay between syndrome check rounds (seconds)
    docals : boolean, optional
        Whether to append calibration pulses to the end of the sequence
    calRepeats : int, optional
        How many times to repeat calibration scalings (default 2)

    Returns
    -------
    metafile : string
        Path to a json metafile with details about the sequences and paths to
        compiled machine files

    Examples
    --------
    >>> mf = BitFlip3((q1, q2, q3), (q4, q5));
    Compiled 12 sequences.
    >>> mf
    '/path/to/exp/exp-meta.json'
    """
    if len(data_qs) != 3 or len(ancilla_qs) != 2:
        raise Exception("Wrong number of qubits")
    seqs =  [
    DecodeSetRounds(1,0,nrounds),
    Invalidate(10, 2*nrounds),
    Invalidate(11, 0x1)]

    # encode single-qubit state into 3 qubits
    if theta and phi:
        seqs+=[Utheta(data_qs[1], theta, phi),
               CNOT(data_qs[1], data_qs[0]),
               CNOT(data_qs[1], data_qs[2])]

    # multiple rounds of syndrome measurements
    for n in range(nrounds):
        seqs+= [CNOT(data_qs[0],ancilla_qs[0])*CNOT(data_qs[1],ancilla_qs[1])],
        seqs+= [CNOT(data_qs[1], ancilla_qs[0])*CNOT(data_qs[2],ancilla_qs[1])],
        seqs+= [MEASA(ancilla_qs[0], maddr=(10, 2*n))*
                MEASA(ancilla_qs[1], maddr=(10, 2*n+1)),
                Id(ancilla_qs[0], meas_delay),
                    MEAS(data_qs[0], amp=0)*
                    MEAS(data_qs[1], amp=0)*
                    MEAS(data_qs[2], amp=0)]
                    # virtual msmt's just to keep the number of segments
                    # uniform across digitizer channels
    seqs+=Decode(10, 11, 2*nrounds)
    seqs+=qwait("RAM",11)
    seqs+=[MEAS(data_qs[0])*
           MEAS(data_qs[1])*
           MEAS(data_qs[2])*
           MEAS(ancilla_qs[0], amp=0)*
           MEAS(ancilla_qs[1], amp=0)]
           # virtual msmt's

    # apply corrective pulses depending on the decoder result
    FbGates = []
    for q in data_qs:
        FbGates.append([gate(q) for gate in [Id, X]])
    FbSeq = [reduce(operator.mul, x) for x in product(*FbGates)]
    for k in range(8):
        seqs += qif(k, [FbSeq[k]])
    if docals:
        seqs += create_cal_seqs(qubits,
        calRepeats)
    metafile = compile_to_hardware(seqs, 'BitFlip/BitFlip', tdm_seq=True)
    return metafile

def MajorityVoteN(qubits,
                  nrounds,
                  prep=[],
                  meas_delay=1e-6,
                  docals=False,
                  calRepeats=2):
    """
    Majority vote across multiple measurement results (same or different qubits)

    Parameters
    ----------
    qubits : Channels.LogicalChannel tupple
        A hashable (immutable) tupple of qubits for majority vote
    nrounds: int
        Number of consecutive measurements
    prep : boolean iterable, optional
        Array of binary values mapping X(q) pulses to the list of qubits
        proivided. Ex: (q1,q2), prep=(1,0) -> would apply a pi pulse to q1
        before the majority vote measurement. Default = []
    measDelay : int/float, optional
        Delay between syndrome check rounds (seconds)
    docals : boolean, optional
        Whether to append calibration pulses to the end of the sequence
    calRepeats : int, optional
        How many times to repeat calibration scalings (default 2)

    Returns
    -------
    metafile : string
        Path to a json metafile with details about the sequences and paths to
        compiled machine files

    Examples
    --------
    >>> mf = MajorityVoteN((q1, q2, q3), 10);
    Compiled 1 sequences.
    o INVALIDATE(channel=None, addr=0x1, mask=0x0)
    o WRITEADDR(channel=None, addr=0x1, value=0xfffff)
    MAJORITYMASK(in_addr=1, out_addr=0)
    o INVALIDATE(channel=None, addr=0xa, mask=0xfffff)
    o INVALIDATE(channel=None, addr=0xb, mask=0x1)
    MAJORITY(in_addr=a, out_addr=b)
    >>> mf
    '/path/to/exp/exp-meta.json'
    """
    nqubits = len(qubits)
    seqs = [MajorityMask(1, 0, nrounds*nqubits),
           Invalidate(10, nrounds*nqubits),
           Invalidate(11, 1)]
    if prep:
       seqs += [reduce(operator.mul,
                    [X(q) for n,q in enumerate(qubits) if prep[n]])]
    for n in range(nrounds):
       seqs += [reduce(operator.mul,
               [MEASA(q, (10, nqubits*n+m)) for m,q in enumerate(qubits)]),
               Id(qubits[0],meas_delay)]
    seqs+=MajorityVote(10,11, nrounds*nqubits)
    seqs+=qwait("RAM", 11)
    seqs+=[Id(qubits[0],100e-9)]
    seqs+=qif(1,[X(qubits[0])]) # placeholder for any conditional operation
    seqs=[seqs]
    if docals:
        seqs += create_cal_seqs(qubits,
        calRepeats)
    metafile = compile_to_hardware(seqs,
                                   'MajorityVote/MajorityVote',
                                   tdm_seq=True)
    return metafile
<commit_msg>A few typos<commit_after>from ..PulsePrimitives import *
from ..Compiler import compile_to_hardware
from ..PulseSequencePlotter import plot_pulse_files
from .helpers import create_cal_seqs
from itertools import product
import operator
from ..ControlFlow import *
from ..TdmInstructions import *
from functools import reduce

@qfunction
def qreset(qubits, signVec, measDelay, buf, reg_size=None, TDM_map=None):
    """
    For each qubit, build the set of feedback actions to perform when
    receiving a zero or one in the comparison register

    Parameters
    ----------
    qubits : Channels.LogicalChannel tuple
        A hashable (immutable) tuple of qubits to reset
    signVec : boolean tuple
        A hashable (immutable) tuple of binary values from the compairison
        register indicating the measured state of each qubit in the register
        before reset.
    measDelay : int/float
        Delay after measurement before performing the LOADCMP comparison with
        value in the register (seconds)
    buf : int/float
        Wait time between (seconds)
    reg_size : int, optional
        Size of the register in number of qubits, including those not reset.
        Default value is set to len(qubits).
    TDM_map : bit mask, optional
        Map each qubit to a TDM digital input.  If True, arguments reset a
        subset of the qubit register (see Reset).
        Default: np.array(qN, qN-1, ..., q1) from MSB to LSB.

    Returns
    -------
    seq : QGL.ControlFlow.Call
        QGL sequence with the qreset calls

    Examples
    --------
    >>> qreset((q1, q2), (0,1), 2e-6, 2e-6);
    CALL(H:)
    """
    if not reg_size:
        reg_size = len(qubits)
        TDM_map = np.arange(reg_size,0,-1)

    FbGates = []
    for ct, q in enumerate(qubits):
        if signVec[ct] == 0:
            FbGates.append([gate(q) for gate in [Id, X]])
        else:  # inverted logic
            FbGates.append([gate(q) for gate in [X, Id]])
    FbSeq = [reduce(operator.mul, x) for x in product(*FbGates)]

    # load register
    seq = [Id(qubits[0], measDelay), qwait(kind='CMP'), Id(qubits[0], buf)]
    # create a branch for each possible comparison value
    for ct in range(2**reg_size):
        # duplicate branches for the irrelevant results
        # if reg_size > len(TDM_map)
        meas_result = [(ct & TDM_bit)>0 for TDM_bit in 2**(np.array(TDM_map)-1)]
        branch_idx = sum([t*2**(len(qubits)-ind-1)
                          for ind,t in enumerate((meas_result))])
        seq += qif(ct, [FbSeq[branch_idx]])

    return seq

def Reset(qubits,
          measDelay=1e-6,
          signVec=None,
          doubleRound=True,
          buf=20e-9,
          showPlot=False,
          measChans=None,
          docals=True,
          calRepeats=2,
          reg_size=None,
          TDM_map=None):
    """
    Preparation, simultanoeus reset, and measurement of an arbitrary number
    of qubits

    Parameters
    ----------
    qubits : Channels.LogicalChannel tuple
        A hashable (immutable) tuple of qubits to reset
    measDelay : int/float, optional
        Delay after measurement before performing the LOADCMP compairison with
        value in the register (seconds)
    signVec : boolean tuple, optional
        conditions for feedback. Tuple of 0 (flip if signal is above threshold) and 1 (flip if below) for each qubit. Default = 0 for all qubits
    doubleRound : boolean, optional
        If true, do two rounds of feedback
    showPlot : boolean, optional
        Whether to plot
    measChans : LogicalChannel tuple, optional
        A hashable (immutable) tuple of qubits to measured.
    docals : boolean, optional
        Whether to append calibration pulses to the end of the sequence
    calRepeats : int, optional
        How many times to repeat calibration scalings (default 2)
    reg_size : int, optional
        Size of the register in number of qubits, including those not reset.
        Default value is set to len(qubits).
    TDM_map : bit mask, optional
        Map each qubit to a TDM digital input.  If True, arguments reset a
        subset of the qubit register (see Reset).
        Default: np.array(qN, qN-1, ..., q1) from MSB to LSB.

    Returns
    -------
    metafile : string
        Path to a json metafile with details about the sequences and paths to
        compiled machine files

    Examples
    --------
    >>> Reset((q1, q2));
    Compiled 12 sequences.
    >>> mf
    '/path/to/exp/exp-meta.json'
    """
    if measChans is None:
        measChans = qubits

    if signVec == None:
        signVec = (0, ) * len(qubits)

    seqs = [prep + [qreset(qubits,
                           signVec,
                           measDelay,
                           buf,
                           reg_size=reg_size,
                           TDM_map=TDM_map)]
                           for prep in create_cal_seqs(qubits, 1)]
    measBlock = reduce(operator.mul, [MEAS(q) for q in qubits])
    if doubleRound:
        for seq in seqs:
            seq += [measBlock]
            seq.append(qreset(qubits,
                              signVec,
                              measDelay,
                              buf,
                              reg_size=reg_size,
                              TDM_map=TDM_map))

    # add final measurement
    for seq in seqs:
        seq += [measBlock, Id(qubits[0], measDelay), qwait(kind='CMP')]

    if docals:
        seqs += create_cal_seqs(qubits,
                                calRepeats,
                                measChans=measChans,
                                waitcmp=True)

    metafile = compile_to_hardware(seqs, 'Reset/Reset')

    if showPlot:
        plot_pulse_files(metafile)
    return metafile

# do not make it a subroutine for now
def BitFlip3(data_qs,
             ancilla_qs,
             theta=None,
             phi=None,
             nrounds=1,
             meas_delay=1e-6,
             docals=False,
             calRepeats=2):
    """
    Encoding on 3-qubit bit-flip code, followed by n rounds of syndrome
    detection, and final correction using the n results.

    Parameters
    ----------
    data_qs : Channels.LogicalChannel tuple
        A hashable (immutable) tuple of qubits of the 3 code qubits
    ancilla_qs : Channels.LogicalChannel tuple
        A hashable (immutable) tuple of qubits of the 2 syndrome qubits
    theta : int/float, optional
        Longitudinal rotation angle for the encoded state (radians).
        Default = None.
    phi : int/float, optional
        Azimuthal rotation angle for the encoded state (radians).
        Default = None.
    nrounds: int, optional
        Number of consecutive measurements
    measDelay : int/float, optional
        Delay between syndrome check rounds (seconds)
    docals : boolean, optional
        Whether to append calibration pulses to the end of the sequence
    calRepeats : int, optional
        How many times to repeat calibration scalings (default 2)

    Returns
    -------
    metafile : string
        Path to a json metafile with details about the sequences and paths to
        compiled machine files

    Examples
    --------
    >>> mf = BitFlip3((q1, q2, q3), (q4, q5));
    Compiled 12 sequences.
    >>> mf
    '/path/to/exp/exp-meta.json'
    """
    if len(data_qs) != 3 or len(ancilla_qs) != 2:
        raise Exception("Wrong number of qubits")
    seqs =  [
    DecodeSetRounds(1,0,nrounds),
    Invalidate(10, 2*nrounds),
    Invalidate(11, 0x1)]

    # encode single-qubit state into 3 qubits
    if theta and phi:
        seqs+=[Utheta(data_qs[1], theta, phi),
               CNOT(data_qs[1], data_qs[0]),
               CNOT(data_qs[1], data_qs[2])]

    # multiple rounds of syndrome measurements
    for n in range(nrounds):
        seqs+= [CNOT(data_qs[0],ancilla_qs[0])*CNOT(data_qs[1],ancilla_qs[1])],
        seqs+= [CNOT(data_qs[1], ancilla_qs[0])*CNOT(data_qs[2],ancilla_qs[1])],
        seqs+= [MEASA(ancilla_qs[0], maddr=(10, 2*n))*
                MEASA(ancilla_qs[1], maddr=(10, 2*n+1)),
                Id(ancilla_qs[0], meas_delay),
                    MEAS(data_qs[0], amp=0)*
                    MEAS(data_qs[1], amp=0)*
                    MEAS(data_qs[2], amp=0)]
                    # virtual msmt's just to keep the number of segments
                    # uniform across digitizer channels
    seqs+=Decode(10, 11, 2*nrounds)
    seqs+=qwait("RAM",11)
    seqs+=[MEAS(data_qs[0])*
           MEAS(data_qs[1])*
           MEAS(data_qs[2])*
           MEAS(ancilla_qs[0], amp=0)*
           MEAS(ancilla_qs[1], amp=0)]
           # virtual msmt's

    # apply corrective pulses depending on the decoder result
    FbGates = []
    for q in data_qs:
        FbGates.append([gate(q) for gate in [Id, X]])
    FbSeq = [reduce(operator.mul, x) for x in product(*FbGates)]
    for k in range(8):
        seqs += qif(k, [FbSeq[k]])
    if docals:
        seqs += create_cal_seqs(qubits,
        calRepeats)
    metafile = compile_to_hardware(seqs, 'BitFlip/BitFlip', tdm_seq=True)
    return metafile

def MajorityVoteN(qubits,
                  nrounds,
                  prep=[],
                  meas_delay=1e-6,
                  docals=False,
                  calRepeats=2):
    """
    Majority vote across multiple measurement results (same or different qubits)

    Parameters
    ----------
    qubits : Channels.LogicalChannel tuple
        A hashable (immutable) tuple of qubits for majority vote
    nrounds: int
        Number of consecutive measurements
    prep : boolean iterable, optional
        Array of binary values mapping X(q) pulses to the list of qubits
        proivided. Ex: (q1,q2), prep=(1,0) -> would apply a pi pulse to q1
        before the majority vote measurement. Default = []
    measDelay : int/float, optional
        Delay between syndrome check rounds (seconds)
    docals : boolean, optional
        Whether to append calibration pulses to the end of the sequence
    calRepeats : int, optional
        How many times to repeat calibration scalings (default 2)

    Returns
    -------
    metafile : string
        Path to a json metafile with details about the sequences and paths to
        compiled machine files

    Examples
    --------
    >>> mf = MajorityVoteN((q1, q2, q3), 10);
    Compiled 1 sequences.
    o INVALIDATE(channel=None, addr=0x1, mask=0x0)
    o WRITEADDR(channel=None, addr=0x1, value=0xfffff)
    MAJORITYMASK(in_addr=1, out_addr=0)
    o INVALIDATE(channel=None, addr=0xa, mask=0xfffff)
    o INVALIDATE(channel=None, addr=0xb, mask=0x1)
    MAJORITY(in_addr=a, out_addr=b)
    >>> mf
    '/path/to/exp/exp-meta.json'
    """
    nqubits = len(qubits)
    seqs = [MajorityMask(1, 0, nrounds*nqubits),
           Invalidate(10, nrounds*nqubits),
           Invalidate(11, 1)]
    if prep:
       seqs += [reduce(operator.mul,
                    [X(q) for n,q in enumerate(qubits) if prep[n]])]
    for n in range(nrounds):
       seqs += [reduce(operator.mul,
               [MEASA(q, (10, nqubits*n+m)) for m,q in enumerate(qubits)]),
               Id(qubits[0],meas_delay)]
    seqs+=MajorityVote(10,11, nrounds*nqubits)
    seqs+=qwait("RAM", 11)
    seqs+=[Id(qubits[0],100e-9)]
    seqs+=qif(1,[X(qubits[0])]) # placeholder for any conditional operation
    seqs=[seqs]
    if docals:
        seqs += create_cal_seqs(qubits,
        calRepeats)
    metafile = compile_to_hardware(seqs,
                                   'MajorityVote/MajorityVote',
                                   tdm_seq=True)
    return metafile
<|endoftext|>


<commit_before>from keywords import keyword, new, call, call_static, RemoteObject, RemoteClass

instrument_registry = 'android.support.test.InstrumentationRegistry'
solo_class_name = 'com.robotium.solo.Solo'

class Intent(RemoteObject):
    pass

class Context(RemoteObject):

    def get_package_manager(self):
        obj = call(self, 'getPackageManager')
        return PackageManager.from_object(obj)

class Activity(RemoteObject):
    pass

class PackageManager(RemoteObject):

    def get_launch_intent_for_package(self, package_name):
        obj = call(self, 'getLaunchIntentForPackage', package_name)
        return Intent.from_object(obj)

class Instrumentation(RemoteObject):

    def start_activity_sync(self, intent):
        obj = call(self, 'startActivitySync', intent)
        return Activity.from_object(obj)

    def get_context(self):
        obj = call(self, 'getContext')
        return Context.from_object(obj)

    def get_target_context(self):
        obj = call(self, 'getTargetContext')
        return Context.from_object(obj)

class InstrumentationRegistry(RemoteClass):

    @staticmethod
    def get_instrumentation():
        instrument_registry_class = RemoteClass.from_class_name(instrument_registry)
        remote_obj = call_static(instrument_registry_class, "getInstrumentation")
        return Instrumentation.from_object(remote_obj)

class Solo(RemoteObject):

    def __init__(self, instrumentation):
        solo_class = RemoteClass.from_class_name(solo_class_name)
        instrumentation.class_name = 'android.app.Instrumentation'
        remote_solo = new(solo_class, instrumentation)
        self.__dict__ = remote_solo.__dict__

    def get_view(self, res_id=None, class_name=None):
        if res_id:
            return call(self, "getView", res_id)
        if class_name:
            return call(self, "getView", RemoteClass.from_class_name(class_name))

    def wait_for_text(self, text):
        """
        Waits for the specified text to appear. Default timeout is 20 seconds.
        @param text the text to wait for, specified as a regular expression
        @return {@code true} if text is displayed and {@code false} if it is not displayed before the timeout
        """
        return call(self, "waitForText", text)

    def get_current_activity(self):
        """
        Returns the current Activity.
        :return: the current Activity.
        """
        obj = call(self, "getCurrentActivity")
        return Activity.from_object(obj)

    def assert_memory_not_low(self):
        """
        Asserts that the available memory is not considered low by the system.
        """
        return call(self, "assertMemoryNotLow")

    def wait_for_dialog_to_open(self):
        """
        Waits for a Dialog to open. Default timeout is 20 seconds.
        :return: {@code true} if the {@link android.app.Dialog} is opened before the timeout and {@code false} if it is not opened
        """
        return call(self, "waitForDialogToOpen")

    def wait_for_dialog_to_close(self):
        """
        Waits for a Dialog to close. Default timeout is 20 seconds.
        :return: @return {@code true} if the {@link android.app.Dialog} is closed before the timeout and {@code false} if it is not closed
        """
        return call(self, "waitForDialogToClose")

    def go_back(self):
        """
        Simulates pressing the hardware back key.
        """
        return call(self, "goBack")

    def click_on_screen(self, x, y):
        """
        Clicks the specified coordinates.
        :param x: the x coordinate
        :param y: the y coordinate
        """
        return call(self, "clickOnScreen", x, y)

    def click_long_on_screen(self, x, y):
        """
        Long clicks the specified coordinates.
        :param x: the x coordinate
        :param y: the y coordinate
        """
        return call(self, "clickLongOnScreen", x, y)

    def click_on_button(self, text):
        """
        Clicks a Button displaying the specified text. Will automatically scroll when needed.
        :param text: the text displayed by the {@link Button}. The parameter will be interpreted as a regular expression
        """
        return call(self, "clickOnButton", text)

    def click_on_image_button(self, index):
        """
        Clicks an ImageButton matching the specified index.
        :param index: the index of the {@link ImageButton} to click. 0 if only one is available
        """
        return call(self, "clickOnImageButton", index)

    def click_on_toggle_button(self, text):
        """
        Clicks a ToggleButton displaying the specified text.
        :param text: the text displayed by the {@link ToggleButton}. The parameter will be interpreted as a regular expression
        """
        return call(self, "clickOnToggleButton", text)

    def click_on_view(self, view):
        """
        Clicks the specified View.
        :param view: the {@link View} to click
        :return:
        """
        return call(self, "clickOnView", view)

    def click_long_on_view(self, view):
        """
        Long clicks the specified View.
        :param view: the {@link View} to long click
        :return:
        """
        return call(self, "clickLongOnView", view)

    def click_on_text(self, text):
        """
        Clicks a View or WebElement displaying the specified
        text. Will automatically scroll when needed.
        :param text: the text to click. The parameter will be interpreted as a regular expression
        """
        return call(self, "clickOnText", text)

    def click_long_on_text(self, text):
        """
        Long clicks a View or WebElement displaying the specified text. Will automatically scroll when needed.
        :param text: the text to click. The parameter will be interpreted as a regular expression
        """
        return call(self, "clickLongOnText", text)

    def drag(self, from_x, to_x, from_y, to_y, step_count):
        """
        Simulate touching the specified location and dragging it to a new location.

        :param from_x : x coordinate of the initial touch, in screen coordinates
        :param to_x : x coordinate of the drag destination, in screen coordinates
        :param from_y : y coordinate of the initial touch, in screen coordinates
        :param to_y : y coordinate of the drag destination, in screen coordinates
        :param step_count : how many move steps to include in the drag. Less steps results in a faster drag
        """
        return call(self, from_x, to_x, from_y, to_y, step_count)

    def enter_text(self, edit_text_view, text):
        """
        Enters text in the specified EditText.
        :param edit_text_view: the {@link EditText} to enter text in
        :param text: the text to enter in the {@link EditText} field
        """
        return call(self, "editText", edit_text_view, text)

    def clear_edit_text(self, edit_text_view):
        """
        Clears the value of an EditText.
        :param edit_text_view: the {@link EditText} to clear
        """
        return call(self, "clearEditText", edit_text_view)

    def get_text(self, text):
        """
        Returns a TextView displaying the specified text.
        :param text: the text that is displayed, specified as a regular expression
        :return: the {@link TextView} displaying the specified text
        """
        return call(self, "getText", text)

    def get_button(self, text):
        """
        Returns a Button displaying the specified text.
        :param text: the text that is displayed, specified as a regular expression
        :return: the {@link Button} displaying the specified text
        """
        return call(self, "getButton", text)

    def hide_soft_keyboard(self):
        """
        Hides the soft keyboard.
        """
        return call(self, "hideSoftKeyboard")

    def unlock_screen(self):
        """
        Unlocks the lock screen.
        """
        return call(self, "unlockScreen")

    def wait_for_activity(self, name):
        """
        Waits for an Activity matching the specified name. Default timeout is 20 seconds.
        :param name: the name of the {@code Activity} to wait for. Example is: {@code "MyActivity"}
        :return: {@code true} if {@code Activity} appears before the timeout and {@code false} if it does not
        """
        return call(self, "waitForActivity", name)

    def wait_for_fragment_by_tag(self, tag):
        """
        Waits for a Fragment matching the specified tag.
        :param tag: the name of the tag
        :return {@code true}: if fragment appears and {@code false} if it does not appear before the timeout
        """
        return call(self, " waitForFragmentByTag", tag)

    def wait_for_log_message(self, message):
        """
        Waits for the specified log message to appear. Default timeout is 20 seconds.
        Requires read logs permission (android.permission.READ_LOGS) in AndroidManifest.xml of the application under test.
        :param message: the log message to wait for
        :return: {@code true} if log message appears and {@code false} if it does not appear before the timeout
        """
        return call(self, "waitForLogMessage", message)

    def clear_log(self):
        """
        Clears the log.
        """
        return call(self, "clearLog")

    def sleep(self, time):
        """
        Robotium will sleep for the specified time.
        :param time: the time in milliseconds that Robotium should sleep
        """
        return call(self, "sleep", time)

    def finalize(self):
        """
        Finalizes the Solo object and removes the ActivityMonitor.
        :see finishOpenedActivities(): finishOpenedActivities() to close the activities that have been active
        """
        return call(self, "finalize")

    def finish_opened_activities(self):
        """
        The Activities that are alive are finished. Usually used in tearDown().
        """
        return call(self, "finishOpenedActivities")

    def take_screenshot(self, name):
        """
        Takes a screenshot and saves it with the specified name in the {@link Config} objects save path (default set to: /sdcard/Robotium-Screenshots/).
        Requires write permission (android.permission.WRITE_EXTERNAL_STORAGE) in AndroidManifest.xml of the application under test.
        :param name: the name to give the screenshot
        """
        call(self, "takeScreenshot", name)

@keyword("runReflection")
def run_reflection_test():
    instrumentation = InstrumentationRegistry.get_instrumentation()
    intent = instrumentation\
        .get_context()\
        .get_package_manager()\
        .get_launch_intent_for_package("com.ifeng.at.testagent")
    activity = instrumentation.start_activity_sync(intent)
    print(activity.class_name)
    solo = Solo(InstrumentationRegistry.get_instrumentation())
    v = solo.get_view(res_id="com.ifeng.at.testagent:id/email_sign_in_button")
    print(v.class_name)

<commit_msg>Fix bug: remote object class error<commit_after>from keywords import keyword, new, call, call_static, RemoteObject, RemoteClass

instrument_registry = 'android.support.test.InstrumentationRegistry'
solo_class_name = 'com.robotium.solo.Solo'
android_view = 'android.view.View'
android_edit_text = 'android.widget.EditText'
java_float = 'java.lang.Float'
java_object = 'java.lang.Object'

class Intent(RemoteObject):
    pass

class Context(RemoteObject):

    def get_package_manager(self):
        obj = call(self, 'getPackageManager')
        return PackageManager.from_object(obj)

class Activity(RemoteObject):
    pass

class PackageManager(RemoteObject):

    def get_launch_intent_for_package(self, package_name):
        obj = call(self, 'getLaunchIntentForPackage', package_name)
        return Intent.from_object(obj)

class Instrumentation(RemoteObject):

    def start_activity_sync(self, intent):
        obj = call(self, 'startActivitySync', intent)
        return Activity.from_object(obj)

    def get_context(self):
        obj = call(self, 'getContext')
        return Context.from_object(obj)

    def get_target_context(self):
        obj = call(self, 'getTargetContext')
        return Context.from_object(obj)

class InstrumentationRegistry(RemoteClass):

    @staticmethod
    def get_instrumentation():
        instrument_registry_class = RemoteClass.from_class_name(instrument_registry)
        remote_obj = call_static(instrument_registry_class, "getInstrumentation")
        return Instrumentation.from_object(remote_obj)

class Solo(RemoteObject):

    def __init__(self, instrumentation):
        solo_class = RemoteClass.from_class_name(solo_class_name)
        instrumentation.class_name = 'android.app.Instrumentation'
        remote_solo = new(solo_class, instrumentation)
        self.__dict__ = remote_solo.__dict__

    def get_view(self, res_id=None, class_name=None):
        if res_id:
            return call(self, "getView", res_id)
        if class_name:
            return call(self, "getView", RemoteClass.from_class_name(class_name))

    def wait_for_text(self, text):
        """
        Waits for the specified text to appear. Default timeout is 20 seconds.
        @param text the text to wait for, specified as a regular expression
        @return {@code true} if text is displayed and {@code false} if it is not displayed before the timeout
        """
        return call(self, "waitForText", text)

    def get_current_activity(self):
        """
        Returns the current Activity.
        :return: the current Activity.
        """
        obj = call(self, "getCurrentActivity")
        return Activity.from_object(obj)

    def assert_memory_not_low(self):
        """
        Asserts that the available memory is not considered low by the system.
        """
        return call(self, "assertMemoryNotLow")

    def wait_for_dialog_to_open(self):
        """
        Waits for a Dialog to open. Default timeout is 20 seconds.
        :return: {@code true} if the {@link android.app.Dialog} is opened before the timeout and {@code false} if it is not opened
        """
        return call(self, "waitForDialogToOpen")

    def wait_for_dialog_to_close(self):
        """
        Waits for a Dialog to close. Default timeout is 20 seconds.
        :return: @return {@code true} if the {@link android.app.Dialog} is closed before the timeout and {@code false} if it is not closed
        """
        return call(self, "waitForDialogToClose")

    def go_back(self):
        """
        Simulates pressing the hardware back key.
        """
        return call(self, "goBack")

    def click_on_screen(self, x, y):
        """
        Clicks the specified coordinates.
        :param x: the x coordinate
        :param y: the y coordinate
        """
        return call(self, "clickOnScreen", x, y)

    def click_long_on_screen(self, x, y):
        """
        Long clicks the specified coordinates.
        :param x: the x coordinate
        :param y: the y coordinate
        """
        return call(self, "clickLongOnScreen", x, y)

    def click_on_button(self, text):
        """
        Clicks a Button displaying the specified text. Will automatically scroll when needed.
        :param text: the text displayed by the {@link Button}. The parameter will be interpreted as a regular expression
        """
        return call(self, "clickOnButton", text)

    def click_on_image_button(self, index):
        """
        Clicks an ImageButton matching the specified index.
        :param index: the index of the {@link ImageButton} to click. 0 if only one is available
        """
        return call(self, "clickOnImageButton", index)

    def click_on_toggle_button(self, text):
        """
        Clicks a ToggleButton displaying the specified text.
        :param text: the text displayed by the {@link ToggleButton}. The parameter will be interpreted as a regular expression
        """
        return call(self, "clickOnToggleButton", text)

    def click_on_view(self, view):
        """
        Clicks the specified View.
        :param view: the {@link View} to click
        :return:
        """
        view.class_name = android_view
        return call(self, "clickOnView", view)

    def click_long_on_view(self, view):
        """
        Long clicks the specified View.
        :param view: the {@link View} to long click
        :return:
        """
        view.class_name = android_view
        return call(self, "clickLongOnView", view)

    def click_on_text(self, text):
        """
        Clicks a View or WebElement displaying the specified
        text. Will automatically scroll when needed.
        :param text: the text to click. The parameter will be interpreted as a regular expression
        """
        return call(self, "clickOnText", text)

    def click_long_on_text(self, text):
        """
        Long clicks a View or WebElement displaying the specified text. Will automatically scroll when needed.
        :param text: the text to click. The parameter will be interpreted as a regular expression
        """
        return call(self, "clickLongOnText", text)

    def drag(self, from_x, to_x, from_y, to_y, step_count):
        """
        Simulate touching the specified location and dragging it to a new location.

        :param from_x : x coordinate of the initial touch, in screen coordinates
        :param to_x : x coordinate of the drag destination, in screen coordinates
        :param from_y : y coordinate of the initial touch, in screen coordinates
        :param to_y : y coordinate of the drag destination, in screen coordinates
        :param step_count : how many move steps to include in the drag. Less steps results in a faster drag
        """
        return call(self, from_x, to_x, from_y, to_y, step_count)

    def enter_text(self, edit_text_view, text):
        """
        Enters text in the specified EditText.
        :param edit_text_view: the {@link EditText} to enter text in
        :param text: the text to enter in the {@link EditText} field
        """
        edit_text_view.class_name = android_edit_text
        return call(self, "editText", edit_text_view, text)

    def clear_edit_text(self, edit_text_view):
        """
        Clears the value of an EditText.
        :param edit_text_view: the {@link EditText} to clear
        """
        edit_text_view.class_name = android_edit_text
        return call(self, "clearEditText", edit_text_view)

    def get_text(self, text):
        """
        Returns a TextView displaying the specified text.
        :param text: the text that is displayed, specified as a regular expression
        :return: the {@link TextView} displaying the specified text
        """
        return call(self, "getText", text)

    def get_button(self, text):
        """
        Returns a Button displaying the specified text.
        :param text: the text that is displayed, specified as a regular expression
        :return: the {@link Button} displaying the specified text
        """
        return call(self, "getButton", text)

    def hide_soft_keyboard(self):
        """
        Hides the soft keyboard.
        """
        return call(self, "hideSoftKeyboard")

    def unlock_screen(self):
        """
        Unlocks the lock screen.
        """
        return call(self, "unlockScreen")

    def wait_for_activity(self, name):
        """
        Waits for an Activity matching the specified name. Default timeout is 20 seconds.
        :param name: the name of the {@code Activity} to wait for. Example is: {@code "MyActivity"}
        :return: {@code true} if {@code Activity} appears before the timeout and {@code false} if it does not
        """
        return call(self, "waitForActivity", name)

    def wait_for_fragment_by_tag(self, tag):
        """
        Waits for a Fragment matching the specified tag.
        :param tag: the name of the tag
        :return {@code true}: if fragment appears and {@code false} if it does not appear before the timeout
        """
        return call(self, " waitForFragmentByTag", tag)

    def wait_for_log_message(self, message):
        """
        Waits for the specified log message to appear. Default timeout is 20 seconds.
        Requires read logs permission (android.permission.READ_LOGS) in AndroidManifest.xml of the application under test.
        :param message: the log message to wait for
        :return: {@code true} if log message appears and {@code false} if it does not appear before the timeout
        """
        return call(self, "waitForLogMessage", message)

    def clear_log(self):
        """
        Clears the log.
        """
        return call(self, "clearLog")

    def sleep(self, time):
        """
        Robotium will sleep for the specified time.
        :param time: the time in milliseconds that Robotium should sleep
        """
        return call(self, "sleep", time)

    def finalize(self):
        """
        Finalizes the Solo object and removes the ActivityMonitor.
        :see finishOpenedActivities(): finishOpenedActivities() to close the activities that have been active
        """
        return call(self, "finalize")

    def finish_opened_activities(self):
        """
        The Activities that are alive are finished. Usually used in tearDown().
        """
        return call(self, "finishOpenedActivities")

    def take_screenshot(self, name):
        """
        Takes a screenshot and saves it with the specified name in the {@link Config} objects save path (default set to: /sdcard/Robotium-Screenshots/).
        Requires write permission (android.permission.WRITE_EXTERNAL_STORAGE) in AndroidManifest.xml of the application under test.
        :param name: the name to give the screenshot
        """
        call(self, "takeScreenshot", name)

@keyword("runReflection")
def run_reflection_test():
    instrumentation = InstrumentationRegistry.get_instrumentation()
    intent = instrumentation\
        .get_context()\
        .get_package_manager()\
        .get_launch_intent_for_package("com.ifeng.at.testagent")
    activity = instrumentation.start_activity_sync(intent)
    print(activity.class_name)
    solo = Solo(InstrumentationRegistry.get_instrumentation())
    v = solo.get_view(res_id="com.ifeng.at.testagent:id/email_sign_in_button")
    print(v.class_name)
    solo.click_long_on_view(v)
    solo.sleep(5)

<|endoftext|>


<commit_before>from typing import Set
import os
from aiohttp import web
import jinja2
import logging
import aiohttp_session
import glob

from hailtop.config import get_deploy_config
from hailtop.tls import internal_server_ssl_context
from hailtop.hail_logging import AccessLogger
from gear import setup_aiohttp_session, web_maybe_authenticated_user
from web_common import (setup_aiohttp_jinja2, setup_common_static_routes, render_template,
                        sass_compile)

MODULE_PATH = os.path.dirname(__file__)
log = logging.getLogger('scorecard')
deploy_config = get_deploy_config()
routes = web.RouteTableDef()

def redirect(from_url, to_url):
    async def serve(request):  # pylint: disable=unused-argument
        raise web.HTTPFound(to_url)
    routes.get(from_url)(serve)

@routes.get('/healthcheck')
async def get_healthcheck(request):  # pylint: disable=unused-argument
    return web.Response()

@routes.get('/robots.txt')
async def get_robots(request):  # pylint: disable=unused-argument
    return web.Response(text='user-agent: *\nAllow: /')

routes.static('/static', f'{MODULE_PATH}/static')
redirect('/favicon.ico', 'common_static/hail_logo_sq.ico')
redirect('/docs/batch', 'batch/index.html')
redirect('/docs/batch/', 'index.html')
redirect('/docs/0.2', '0.2/index.html')
redirect('/docs/0.2/', 'index.html')

DOCS_PATH = f'{MODULE_PATH}/docs/'
STATIC_DOCS_PATHS = ['0.2/_static',
                     '0.2/_sources',
                     'batch/_static',
                     'batch/_images',
                     'batch/_sources']
FQ_STATIC_DOCS_PATHS: Set[str] = set()

for path in STATIC_DOCS_PATHS:
    routes.static('/docs/' + path, DOCS_PATH + path)
    FQ_STATIC_DOCS_PATHS.add(DOCS_PATH + path)

docs_pages = set(
    x[0][len(DOCS_PATH):] + '/' + y
    for x in os.walk(DOCS_PATH)
    if x[0] not in FQ_STATIC_DOCS_PATHS
    for y in x[2])

@routes.get('/docs/{tail:.*}')
@web_maybe_authenticated_user
async def serve_docs(request, userdata):
    tail = request.match_info['tail']
    if tail in docs_pages:
        if tail.endswith('.html'):
            return await render_template('website', request, userdata, tail, dict())
        return web.FileResponse(tail)
    raise web.HTTPNotFound()

def make_template_handler(template_fname):
    @web_maybe_authenticated_user
    async def serve(request, userdata):
        return await render_template(
            'website', request, userdata, template_fname, dict())
    return serve

for fname in os.listdir(f'{MODULE_PATH}/pages'):
    routes.get(f'/{fname}')(make_template_handler(fname))
    if fname == 'index.html':
        routes.get('/')(make_template_handler(fname))

def run(local_mode):
    app = web.Application()

    if local_mode:
        log.error('running in local mode with bogus cookie storage key')
        aiohttp_session.setup(app, aiohttp_session.cookie_storage.EncryptedCookieStorage(
            b'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
            cookie_name=deploy_config.auth_session_cookie_name(),
            secure=True,
            httponly=True,
            domain=os.environ['HAIL_DOMAIN'],
            # 2592000s = 30d
            max_age=2592000))
    else:
        setup_aiohttp_session(app)

    setup_aiohttp_jinja2(app, 'website',
                         jinja2.PackageLoader('website', 'pages'),
                         jinja2.PackageLoader('website', 'docs'))
    setup_common_static_routes(routes)
    app.add_routes(routes)
    sass_compile('website')
    web.run_app(deploy_config.prefix_application(app, 'website'),
                host='0.0.0.0',
                port=5000,
                access_log_class=AccessLogger,
                ssl_context=None if local_mode else internal_server_ssl_context())
<commit_msg>[website] dont jinja render any of the batch docs (#10190)<commit_after>from typing import Set
import os
from aiohttp import web
import jinja2
import logging
import aiohttp_session
import glob

from hailtop.config import get_deploy_config
from hailtop.tls import internal_server_ssl_context
from hailtop.hail_logging import AccessLogger
from gear import setup_aiohttp_session, web_maybe_authenticated_user
from web_common import (setup_aiohttp_jinja2, setup_common_static_routes, render_template,
                        sass_compile)

MODULE_PATH = os.path.dirname(__file__)
log = logging.getLogger('scorecard')
deploy_config = get_deploy_config()
routes = web.RouteTableDef()

def redirect(from_url, to_url):
    async def serve(request):  # pylint: disable=unused-argument
        raise web.HTTPFound(to_url)
    routes.get(from_url)(serve)

@routes.get('/healthcheck')
async def get_healthcheck(request):  # pylint: disable=unused-argument
    return web.Response()

@routes.get('/robots.txt')
async def get_robots(request):  # pylint: disable=unused-argument
    return web.Response(text='user-agent: *\nAllow: /')

routes.static('/static', f'{MODULE_PATH}/static')
redirect('/favicon.ico', 'common_static/hail_logo_sq.ico')
redirect('/docs/batch', 'batch/index.html')
redirect('/docs/batch/', 'index.html')
redirect('/docs/0.2', '0.2/index.html')
redirect('/docs/0.2/', 'index.html')

DOCS_PATH = f'{MODULE_PATH}/docs/'
STATIC_DOCS_PATHS = ['0.2/_static',
                     '0.2/_sources',
                     'batch']
FQ_STATIC_DOCS_PATHS: Set[str] = set()

for path in STATIC_DOCS_PATHS:
    routes.static('/docs/' + path, DOCS_PATH + path)
    FQ_STATIC_DOCS_PATHS.add(DOCS_PATH + path)

docs_pages = set(
    x[0][len(DOCS_PATH):] + '/' + y
    for x in os.walk(DOCS_PATH)
    if x[0] not in FQ_STATIC_DOCS_PATHS
    for y in x[2])

@routes.get('/docs/{tail:.*}')
@web_maybe_authenticated_user
async def serve_docs(request, userdata):
    tail = request.match_info['tail']
    if tail in docs_pages:
        if tail.endswith('.html'):
            return await render_template('website', request, userdata, tail, dict())
        return web.FileResponse(tail)
    raise web.HTTPNotFound()

def make_template_handler(template_fname):
    @web_maybe_authenticated_user
    async def serve(request, userdata):
        return await render_template(
            'website', request, userdata, template_fname, dict())
    return serve

for fname in os.listdir(f'{MODULE_PATH}/pages'):
    routes.get(f'/{fname}')(make_template_handler(fname))
    if fname == 'index.html':
        routes.get('/')(make_template_handler(fname))

def run(local_mode):
    app = web.Application()

    if local_mode:
        log.error('running in local mode with bogus cookie storage key')
        aiohttp_session.setup(app, aiohttp_session.cookie_storage.EncryptedCookieStorage(
            b'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
            cookie_name=deploy_config.auth_session_cookie_name(),
            secure=True,
            httponly=True,
            domain=os.environ['HAIL_DOMAIN'],
            # 2592000s = 30d
            max_age=2592000))
    else:
        setup_aiohttp_session(app)

    setup_aiohttp_jinja2(app, 'website',
                         jinja2.PackageLoader('website', 'pages'),
                         jinja2.PackageLoader('website', 'docs'))
    setup_common_static_routes(routes)
    app.add_routes(routes)
    sass_compile('website')
    web.run_app(deploy_config.prefix_application(app, 'website'),
                host='0.0.0.0',
                port=5000,
                access_log_class=AccessLogger,
                ssl_context=None if local_mode else internal_server_ssl_context())
<|endoftext|>


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

"""
cli.py
=========

Description: A command line tool for adding boilerplate licensing to your open
source projects.

Author: Jennifer Hamon (jhamon@gmail.com)

License: MIT (see LICENSE)
"""

import argparse
import sys
import datetime
import os
import re
import licme.headers
import licme.utils

# This dictionary keys license argument to ["longform license name", "license filename",
# boolean: recommend in-file notice?]
LIC_DETAILS = {
#        'artistic': ['Perl Foudation Artistic License, Version 2.0', 'LICENSE',
#        True],
             'agpl3': ['GNU Affero General Public License, Version 3.0',
                 'LICENSE', True],
#             'apache2': ['Apache License 2.0', 'LICENSE', True],
#             'bsd3': ['BSD 3-Clause License', 'LICENSE', False],
#             'bsd2': ['BSD 2-Clause License', 'LICENSE', False],
             'gpl2': ['GNU General Public License, Version 2.0', 'COPYING', True],
             'gpl3': ['GNU General Public License, Version 3.0', 'COPYING', True],
#             'lgpl3': ['GNU Lesser General Public License, Version 3.0'
#                 ,'COPYING.LESSER', True],
             'mit': ['MIT License' ,'LICENSE', False],
#             'mpl2': ['Mozilla Public License, Version 2.0', 'LICENSE', True],
             'gpl1': ['GNU General Public License, Version 1.0', 'COPYING', True],
#            'lgpl2': ['GNU Lesser General Public License, Version 2.0',
#            'COPYING.LESSER', True],
#             'lgpl2.1': ['GNU Lesser General Public License, Version 2.1',
#             'COPYING.LESSER', True],
#             'mpl1.1': ['Mozilla Public License, Version 1.1', 'LICENSE', True],
             'crapl': ['Community Research and Academic Programming License',
                 'LICENSE', False],
#             'unlicense': ['Unlicense', 'UNLICENSE', False],
             'wtfpl': ['Do What the Fuck You Want To Public License, Version 2',
             'LICENSE', False]}

class Licme(object):
    """ main class for cli licensing tool """

    def __init__(self):
        self.parser = self.setup_parser()
        self.cwd = os.getcwd()

    def run(self):
        self.args = self.parser.parse_args()
        self.check_if_already_has_license()
        self.validate_cli_arguments()

    def setup_parser(self):
        """ returns argparse instance """

        parser = argparse.ArgumentParser(prog="LICME",
                description="""
            LICME is designed to help take the pain out of boilerplate licensing.
            You specify the copyright holder and the name of a popular open
            source license, and licme will create the appropriate LICENSE file
            in your project directory.  Copyright and license information will be
            appended to your existing README file, or one will be created for you
            if it does not already exist.

        BASIC EXAMPLE

            $ licme gpl3 "Free Software Foundation, Inc." "Emacs 24"
            $ licme mit "Jennifer Hamon" "Licme"

                """,
                formatter_class=argparse.RawDescriptionHelpFormatter,
                epilog="""
        SUPPORTED LICENSES
            Licme supports many popular and interesting software licenses.

            Popular:
                    artistic  Perl Foudation Artistic License, Version 2.0
                    agpl3     GNU Affero General Public License, Version 3.0
                    apache2   Apache License, Version 2.0
                    bsd3      BSD 3-Clause License
                    bsd2      BSD 2-Clause License
                    gpl2      GNU General Public License, Version 2.0
                    gpl3      GNU General Public License, Version 3.0
                    lgpl3     GNU Lesser General Public License,Version 3.0
                    mit       MIT License
                    mpl2      Mozilla Public License, Version 2.0

            Old and Deprecated:
                    gpl1      GNU General Public License, Version 1.0
                    lgpl2     GNU Lesser General Public License, Version 2.0
                    lgpl2.1   GNU Lesser General Public License, Version 2.1
                    mpl1.1    Mozilla Public License, Version 1.1

            Other:
                    crapl       Community Research and Academic Programming License
                    unlicense   Release code to public domain.  See unlicense.org.
                    wtfpl       Do What the Fuck You Want To Public License, Version 2

        CONTRIBUTING
            If there is another license you would like to see included in licme,
            please submit a pull request at http://www.github.com/jhamon/licme
                """)

        parser.add_argument('license',
            help="specify the license you would like to use.")
        parser.add_argument('copyright_holder',
            help="specify the author or copyright holder.",
            type=str)
        parser.add_argument('program_name', help="specify the name of your software")
        parser.add_argument('-y', '--year',
            help="specify copyright year other than the present year",
            dest="year",
            default=str(datetime.date.today().year))
        parser.add_argument('-n', '--no-readme',
            help="use this option to prevent changes to the README file.",
            action="store_false",
            default=True,
            dest="r")
        parser.add_argument('-a', '--add-sourcefile-headers',
            help='add short copyright and license notice to individual source files',
            action='store_true',
            default=False,
            dest='add_headers')
        parser.add_argument('-r', '--remove-sourcefile-headers',
            help='remove in-file license notices previously applied by licme',
            action='store_true',
            default=False,
            dest='remove_headers')
        parser.add_argument('-q', '--quiet',
            help='supress some informational output',
            action='store_true',
            default=False,
            dest='q')

        return parser

    def validate_cli_arguments(self):
        """
        Checks for obvious conflicts in options given by the user.  If any are
        found, stops execution.
        """
        help = 'Try -h for help information.'
        if args.license not in LIC_DETAILS.keys():
            print 'You have entered an invalid license name.'
            print help
            sys.exit(1)
        if args.remove_headers and args.add_headers:
            print 'You have used conflicting header options.'
            print help
            sys.exit(1)

    def check_if_already_has_license(self):
        """ returns boolean value indicating whether there is
        already a file in the current working directory that has
        'license' or similar in the filename
        """
        common_license_filenames = ['license',
                                    'copying',
                                    'unlicense',
                                    'copying.lesser',
                                    'license.txt',
                                    'unlicense.txt',
                                    'copying.txt']
        cwd_files = os.listdir(self.cwd)
        possible_licenses = [x for x in cwd_files if x.lower() in
                common_license_filenames]
        if len(possible_licenses) != 0:
            print 'This repository appears to contain license information already.'
            print 'If you would like to apply a new license using licme, first'
            print 'remove any license files such as LICENSE, COPYING, or UNLICENSE.'
            if not args.q:
                print '\n  Conflicting files: \n    {0}'.format('\n    '.join(possible_licenses))
            print '\nNo changes have been made.'
            sys.exit(1)
        else:
            return False

if __name__ == '__main__':
    my_licme = Licme()
    my_listme.run()
<commit_msg>Refactor LIC_DETAILS into more readable dictionaries with more descriptive names.<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
cli.py
=========

Description: A command line tool for adding boilerplate licensing to your open
source projects.

Author: Jennifer Hamon (jhamon@gmail.com)

License: MIT (see LICENSE)
"""

import argparse
import sys
import datetime
import os
import re
import licme.headers
import licme.utils

# Do usage guidelines for this license recommend an in-file copyright and
# licensing notice in every source file?  If yes, store that license name into
# this list.
recommend_infile = 'mpl1.1 lgpl2.1 gpl1 gpl2 gpl3 mpl2 agpl3 apache2 artistic'.split(' ')

# Some licenses have special recommendations for the name of the file in which
# the full license text is stored.  In practice it shouldn't matter, but it is
# good to follow tradition. The name of the license file is stored in a
# dictionary, keyed by license name.
filename_LICENSE = 'mit agpl3 apache2 bsd3 bsd2 mpl2 crapl wtfpl'.split(' ')
filename_COPYING = 'gpl1 gpl2 gpl3'.split(' ')
filename_COPYINGLESSER = 'lgpl2.1 lgpl2'.split(' ')
filename_UNLICENSE = ['unlicense']
license_filenames = {key:'LICENSE' for key in filename_LICENSE}
license_filenames.update({key:'COPYING' for key in filename_COPYING})
license_filenames.update({key:'COPYING.LESSER' for key in filename_COPYINGLESSER})
license_filenames.update({key:'UNLICENSE' for key in filename_UNLICENSE})

# To fill some templates, we need to know the "long" version of each filename.
# Those are also stored in a dictionary.
longnames = {}
longnames['wtfpl'] = 'Do What the Fuck You Want To Public License, Version 2'
longnames['unlicense'] = 'Unlicense'
longnames['artistic'] = 'Perl Foundation Artistic License, Version 2.0'
longnames['agpl3'] = 'GNU Affero General Public License, Version 3.0'
longnames['apache2'] = 'Apache License 2.0'
longnames['bsd3'] = 'BSD 3-Clause License'
longnames['bsd2'] = 'BSD 2-Clause License'
longnames['gpl2'] = 'GNU General Public License, Version 2.0'
longnames['gpl3'] = 'GNU General Public License, Version 3.0'
longnames['lgpl3'] = 'GNU Lesser General Public License, Version 3.0'
longnames['lgpl2'] = 'GNU Lesser General Public License, Version 2.0'
longnames['lgpl2.1'] = 'GNU Lesser General Public License, Version 2.1'
longnames['mit'] = 'MIT License'
longnames['mpl2'] = 'Mozilla Public License, Version 2.0'
longnames['mpl1.1'] = 'Mozilla Public License, Version 1.1'
longnames['gpl1'] = 'GNU General Public License, Version 1.0'
longnames['crapl'] = 'Community Research and Academic Programming License'

class Licme(object):
    """ main class for cli licensing tool """

    def __init__(self):
        self.parser = self.setup_parser()
        self.cwd = os.getcwd()

    def run(self):
        self.args = self.parser.parse_args()
        self.check_if_already_has_license()
        self.validate_cli_arguments()

    def setup_parser(self):
        """ returns argparse instance """

        parser = argparse.ArgumentParser(prog="LICME",
                description="""
            LICME is designed to help take the pain out of boilerplate licensing.
            You specify the copyright holder and the name of a popular open
            source license, and licme will create the appropriate LICENSE file
            in your project directory.  Copyright and license information will be
            appended to your existing README file, or one will be created for you
            if it does not already exist.

        BASIC EXAMPLE

            $ licme gpl3 "Free Software Foundation, Inc." "Emacs 24"
            $ licme mit "Jennifer Hamon" "Licme"

                """,
                formatter_class=argparse.RawDescriptionHelpFormatter,
                epilog="""
        SUPPORTED LICENSES
            Licme supports many popular and interesting software licenses.

            Popular:
                    artistic  Perl Foudation Artistic License, Version 2.0
                    agpl3     GNU Affero General Public License, Version 3.0
                    apache2   Apache License, Version 2.0
                    bsd3      BSD 3-Clause License
                    bsd2      BSD 2-Clause License
                    gpl2      GNU General Public License, Version 2.0
                    gpl3      GNU General Public License, Version 3.0
                    lgpl3     GNU Lesser General Public License,Version 3.0
                    mit       MIT License
                    mpl2      Mozilla Public License, Version 2.0

            Old and Deprecated:
                    gpl1      GNU General Public License, Version 1.0
                    lgpl2     GNU Lesser General Public License, Version 2.0
                    lgpl2.1   GNU Lesser General Public License, Version 2.1
                    mpl1.1    Mozilla Public License, Version 1.1

            Other:
                    crapl       Community Research and Academic Programming License
                    unlicense   Release code to public domain.  See unlicense.org.
                    wtfpl       Do What the Fuck You Want To Public License, Version 2

        CONTRIBUTING
            If there is another license you would like to see included in licme,
            please submit a pull request at http://www.github.com/jhamon/licme
                """)

        parser.add_argument('license',
            help="specify the license you would like to use.")
        parser.add_argument('copyright_holder',
            help="specify the author or copyright holder.",
            type=str)
        parser.add_argument('program_name', help="specify the name of your software")
        parser.add_argument('-y', '--year',
            help="specify copyright year other than the present year",
            dest="year",
            default=str(datetime.date.today().year))
        parser.add_argument('-n', '--no-readme',
            help="use this option to prevent changes to the README file.",
            action="store_false",
            default=True,
            dest="r")
        parser.add_argument('-a', '--add-sourcefile-headers',
            help='add short copyright and license notice to individual source files',
            action='store_true',
            default=False,
            dest='add_headers')
        parser.add_argument('-r', '--remove-sourcefile-headers',
            help='remove in-file license notices previously applied by licme',
            action='store_true',
            default=False,
            dest='remove_headers')
        parser.add_argument('-q', '--quiet',
            help='supress some informational output',
            action='store_true',
            default=False,
            dest='q')

        return parser

    def validate_cli_arguments(self):
        """
        Checks for obvious conflicts in options given by the user.  If any are
        found, stops execution.
        """
        help = 'Try -h for help information.'
        if args.license not in LIC_DETAILS.keys():
            print 'You have entered an invalid license name.'
            print help
            sys.exit(1)
        if args.remove_headers and args.add_headers:
            print 'You have used conflicting header options.'
            print help
            sys.exit(1)

    def check_if_already_has_license(self):
        """ returns boolean value indicating whether there is
        already a file in the current working directory that has
        'license' or similar in the filename
        """
        common_license_filenames = ['license',
                                    'copying',
                                    'unlicense',
                                    'copying.lesser',
                                    'license.txt',
                                    'unlicense.txt',
                                    'copying.txt']
        cwd_files = os.listdir(self.cwd)
        possible_licenses = [x for x in cwd_files if x.lower() in
                common_license_filenames]
        if len(possible_licenses) != 0:
            print 'This repository appears to contain license information already.'
            print 'If you would like to apply a new license using licme, first'
            print 'remove any license files such as LICENSE, COPYING, or UNLICENSE.'
            if not args.q:
                print '\n  Conflicting files: \n    {0}'.format('\n    '.join(possible_licenses))
            print '\nNo changes have been made.'
            sys.exit(1)
        else:
            return False

if __name__ == '__main__':
    my_licme = Licme()
    my_listme.run()
<|endoftext|>


<commit_before>#Copyright (c) 2009-10, Walter Bender

#Permission is hereby granted, free of charge, to any person obtaining a copy
#of this software and associated documentation files (the "Software"), to deal
#in the Software without restriction, including without limitation the rights
#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
#copies of the Software, and to permit persons to whom the Software is
#furnished to do so, subject to the following conditions:

#The above copyright notice and this permission notice shall be included in
#all copies or substantial portions of the Software.

#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
#THE SOFTWARE.

#
# This procedure is invoked when the user-definable block on the "extras"
# palette is selected. Some examples of how to use this block are included
# below. Try uncommenting an example or write your own Python code.
#
# To uncomment code, remove the '# ' in the Python code. Take care to preserve
# the proper indentations.
#

def myblock(lc,x):

    ###########################################################################
    #
    # Draw a dotted line of length x.
    #
    ###########################################################################

    try:  # make sure x is a number
       x = float(x)
    except ValueError:
        return

    pen = lc.tw.canvas.pendown              # save current turtle pen state

    dist = 0
    while dist+lc.tw.canvas.pensize < x:    # repeat drawing dots
        lc.tw.canvas.setpen(True)
        lc.tw.canvas.forward(1)
        lc.tw.canvas.setpen(False)
        lc.tw.canvas.forward((lc.tw.canvas.pensize*2)-1)
        dist += (lc.tw.canvas.pensize*2)
    lc.tw.canvas.forward(x-dist)           # make sure we have moved x

    lc.tw.canvas.setpen(pen)               # restore pen state

    ###########################################################################
    #
    # Push an uppercase version of a string onto the heap.
    # Use a 'pop' block to use the new string.
    #
    ###########################################################################

    # if type(x) != str:
    #     X = str(x).upper()
    # else:
    #     X = x.upper()
    # lc.heap.append(X)

    ###########################################################################
    #
    # Push hours, minutes, seconds onto the FILO.
    # Use three 'pop' blocks to retrieve these values.
    # Note: because we use a FILO (first in, last out heap),
    # the first value you will pop will be seconds.
    #
    ###########################################################################

    # lc.heap.append(localtime().tm_hour)
    # lc.heap.append(localtime().tm_min)
    # lc.heap.append(localtime().tm_sec)

    ###########################################################################
    #
    # Add a third dimension (gray) to the color model.
    #
    ###########################################################################

    # val = 0.3 * lc.tw.rgb[0] + 0.6 * lc.tw.rgb[1] + 0.1 * lc.tw.rgb[2]
    # if x != 100:
    #     x = int(x)%100
    # r = int((val*(100-x) + lc.tw.rgb[0]*x)/100)
    # g = int((val*(100-x) + lc.tw.rgb[1]*x)/100)
    # b = int((val*(100-x) + lc.tw.rgb[2]*x)/100)
    # reallocate current color
    # lc.tw.fgcolor = lc.tw.cm.alloc_color(r<<8,g<<8,b<<8)

    ###########################################################################
    #
    # Save an image named x to the Sugar Journal.
    #
    ###########################################################################

    # lc.tw.save_as_image(str(x))

    return

<commit_msg>new python example<commit_after>#Copyright (c) 2009-10, Walter Bender

#Permission is hereby granted, free of charge, to any person obtaining a copy
#of this software and associated documentation files (the "Software"), to deal
#in the Software without restriction, including without limitation the rights
#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
#copies of the Software, and to permit persons to whom the Software is
#furnished to do so, subject to the following conditions:

#The above copyright notice and this permission notice shall be included in
#all copies or substantial portions of the Software.

#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
#THE SOFTWARE.

#
# This procedure is invoked when the user-definable block on the "extras"
# palette is selected. Some examples of how to use this block are included
# below. Try uncommenting an example or write your own Python code.
#
# To uncomment code, remove the '# ' in the Python code. Take care to preserve
# the proper indentations.
#

def myblock(lc, x):

    ###########################################################################
    #
    # Set rgb color
    #
    ###########################################################################

    # lc.tw.fgcolor = lc.tw.cm.alloc_color(x[0],x[1],x[2])
    # return

    ###########################################################################
    #
    # Draw a dotted line of length x.
    #
    ###########################################################################

    try:  # make sure x is a number
       x = float(x)
    except ValueError:
        return

    pen = lc.tw.canvas.pendown              # save current turtle pen state

    dist = 0
    while dist+lc.tw.canvas.pensize < x:    # repeat drawing dots
        lc.tw.canvas.setpen(True)
        lc.tw.canvas.forward(1)
        lc.tw.canvas.setpen(False)
        lc.tw.canvas.forward((lc.tw.canvas.pensize*2)-1)
        dist += (lc.tw.canvas.pensize*2)
    lc.tw.canvas.forward(x-dist)           # make sure we have moved x

    lc.tw.canvas.setpen(pen)               # restore pen state

    ###########################################################################
    #
    # Push an uppercase version of a string onto the heap.
    # Use a 'pop' block to use the new string.
    #
    ###########################################################################

    # if type(x) != str:
    #     X = str(x).upper()
    # else:
    #     X = x.upper()
    # lc.heap.append(X)

    ###########################################################################
    #
    # Push hours, minutes, seconds onto the FILO.
    # Use three 'pop' blocks to retrieve these values.
    # Note: because we use a FILO (first in, last out heap),
    # the first value you will pop will be seconds.
    #
    ###########################################################################

    # lc.heap.append(localtime().tm_hour)
    # lc.heap.append(localtime().tm_min)
    # lc.heap.append(localtime().tm_sec)

    ###########################################################################
    #
    # Add a third dimension (gray) to the color model.
    #
    ###########################################################################

    # val = 0.3 * lc.tw.rgb[0] + 0.6 * lc.tw.rgb[1] + 0.1 * lc.tw.rgb[2]
    # if x != 100:
    #     x = int(x)%100
    # r = int((val*(100-x) + lc.tw.rgb[0]*x)/100)
    # g = int((val*(100-x) + lc.tw.rgb[1]*x)/100)
    # b = int((val*(100-x) + lc.tw.rgb[2]*x)/100)
    # reallocate current color
    # lc.tw.fgcolor = lc.tw.cm.alloc_color(r<<8,g<<8,b<<8)

    ###########################################################################
    #
    # Save an image named x to the Sugar Journal.
    #
    ###########################################################################

    # lc.tw.save_as_image(str(x))

    return

<|endoftext|>


<commit_before># Copyright 2011 the Melange authors.
#
# 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.

"""This module contains the GSoCProject Model.
"""

from google.appengine.ext import db

from django.utils.translation import ugettext

from soc.modules.gsoc.models.code_sample import GSoCCodeSample
from soc.modules.gsoc.models.profile import GSoCProfile

import soc.modules.gsoc.models.proposal
import soc.models.program
import soc.models.organization

class GSoCProject(db.Model):
  """Model for a GSoC project used in the GSoC workflow.

  Parent:
    soc.modules.gsoc.models.profile.Profile
  """

  #: Required field indicating the "title" of the project
  title = db.StringProperty(required=True,
      verbose_name=ugettext('Title'))
  title.help_text = ugettext('Title of the project')

  #: Required, text field describing the project
  abstract = db.TextProperty(
      required=True, verbose_name=ugettext('Project abstract'))
  abstract.help_text = ugettext(
      'Short abstract, summary, or snippet;'
      ' 500 characters or less, plain text displayed publicly')

  #: Optional, text field containing all kinds of information about this project
  public_info = db.TextProperty(
      required=False, default ='',
      verbose_name=ugettext('Additional information'))
  public_info.help_text = ugettext(
      'Additional information about this project to be shown publicly')

  #: Optional, URL which can give more information about this project
  additional_info = db.URLProperty(
      required=False, verbose_name=ugettext('External resource URL'))
  additional_info.help_text = ugettext(
      'Link to a resource containing more information about this project.')

  #: Optional field storing a feed URL; displayed publicly
  feed_url = db.LinkProperty(
      verbose_name=ugettext('Project Feed URL'))
  feed_url.help_text = ugettext(
      'The URL should be a valid ATOM or RSS feed. '
      'Feed entries are shown on the public page.')

  #: The project can be marked to be featured on program home page.
  is_featured = db.BooleanProperty(default=False, required=True,
                                   verbose_name=ugettext('Featured'))
  is_featured.help_text = ugettext(
      'Should this project be featured on the program homepage.')

  #: A property containing a list of Mentors assigned for this project
  mentors = db.ListProperty(item_type=db.Key, default=[], required=True)

  def getMentors(self):
    """Returns a list of GSoCProfile entities which
    are mentors for this project.
    """
    return [m for m in GSoCProfile.get(self.mentors) if m]

  #: The status of this project
  #: accepted: This project has been accepted into the program
  #: failed: This project has failed an evaluation.
  #: withdrawn: This project has been withdrawn from the program by a Program
  #:            Administrator or higher.
  #: invalid: This project has been marked as invalid because it was deleted
  status = db.StringProperty(
      required=True, default='accepted',
      choices=['accepted', 'failed', 'withdrawn', 'invalid'])

  #: List of all processed GradingRecords which state a pass for this project.
  #: This property can be used to determine how many evaluations someone has
  #: passed. And is also used to ensure that a GradingRecord has been
  #: processed.
  passed_evaluations = db.ListProperty(item_type=db.Key, default=[])

  #: List of all processed GradingRecords which state a fail for this project.
  #: This is a ListProperty to ensure that the system keeps functioning when
  #: manual changes in GradingRecords occur.
  failed_evaluations = db.ListProperty(item_type=db.Key, default=[])

  #: Organization which this project is in
  org = db.ReferenceProperty(
      reference_class=soc.models.organization.Organization,
      required=True, collection_name='student_projects')

  #: Program in which this project has been created
  program = db.ReferenceProperty(reference_class=soc.models.program.Program,
                                 required=True,
                                 collection_name='projects')

  #: Proposal to which this project corresponds to
  proposal = db.ReferenceProperty(
      reference_class=soc.modules.gsoc.models.proposal.GSoCProposal,
      required=False,
      collection_name='projects')

  #: Whether the student has submitted their code samples or not
  code_samples_submitted = db.BooleanProperty(default=False)

  def codeSamples(self):
    """Returns GSoCCodeSample entities uploaded for this project.
    """
    query = GSoCCodeSample.all()
    query.ancestor(self)
    return query.fetch(1000)

  def countCodeSamples(self):
    """Returns number of GSoCCodeSample entities uploaded for this project.
    """
    query = GSoCCodeSample.all(keys_only=True)
    query.ancestor(self)
    return query.count()
<commit_msg>Project status choices moved to constants.<commit_after># Copyright 2011 the Melange authors.
#
# 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.

"""This module contains the GSoCProject Model."""

from google.appengine.ext import db

from django.utils.translation import ugettext

from soc.modules.gsoc.models import code_sample as code_sample_model
from soc.modules.gsoc.models import profile as profile_model

import soc.modules.gsoc.models.proposal
import soc.models.program
import soc.models.organization

# constants with possible statuses of projects

# the project has been accepted into the program
STATUS_ACCEPTED = 'accepted'

# the project has failed one of evaluations
STATUS_FAILED = 'failed'

# the project has been withdrawn
STATUS_WITHDRAWN = 'withdrawn'

# the project has been marked as invalid
STATUS_INVALID = 'invalid'

class GSoCProject(db.Model):
  """Model for a GSoC project used in the GSoC workflow.

  Parent:
    soc.modules.gsoc.models.profile.Profile
  """

  #: Required field indicating the "title" of the project
  title = db.StringProperty(required=True,
      verbose_name=ugettext('Title'))
  title.help_text = ugettext('Title of the project')

  #: Required, text field describing the project
  abstract = db.TextProperty(
      required=True, verbose_name=ugettext('Project abstract'))
  abstract.help_text = ugettext(
      'Short abstract, summary, or snippet;'
      ' 500 characters or less, plain text displayed publicly')

  #: Text field containing all kinds of information about this project
  public_info = db.TextProperty(
      required=False, default ='',
      verbose_name=ugettext('Additional information'))
  public_info.help_text = ugettext(
      'Additional information about this project to be shown publicly')

  #: Optional, URL which can give more information about this project
  additional_info = db.URLProperty(
      required=False, verbose_name=ugettext('External resource URL'))
  additional_info.help_text = ugettext(
      'Link to a resource containing more information about this project.')

  #: Optional field storing a feed URL; displayed publicly
  feed_url = db.LinkProperty(
      verbose_name=ugettext('Project Feed URL'))
  feed_url.help_text = ugettext(
      'The URL should be a valid ATOM or RSS feed. '
      'Feed entries are shown on the public page.')

  #: The project can be marked to be featured on program home page.
  is_featured = db.BooleanProperty(default=False, required=True,
                                   verbose_name=ugettext('Featured'))
  is_featured.help_text = ugettext(
      'Should this project be featured on the program homepage.')

  #: A property containing a list of Mentors assigned for this project
  mentors = db.ListProperty(item_type=db.Key, default=[], required=True)

  def getMentors(self):
    """Returns a list of profile_model.GSoCProfile entities which
    are mentors for this project.

    Returns:
      list of mentors for this project
    """
    return [m for m in profile_model.GSoCProfile.get(self.mentors) if m]

  #: The status of this project
  status = db.StringProperty(required=True, default=STATUS_ACCEPTED,
      choices=[STATUS_ACCEPTED, STATUS_FAILED,
          STATUS_WITHDRAWN, STATUS_INVALID])

  #: List of all processed GradingRecords which state a pass for this project.
  #: This property can be used to determine how many evaluations someone has
  #: passed. And is also used to ensure that a GradingRecord has been
  #: processed.
  passed_evaluations = db.ListProperty(item_type=db.Key, default=[])

  #: List of all processed GradingRecords which state a fail for this project.
  #: This is a ListProperty to ensure that the system keeps functioning when
  #: manual changes in GradingRecords occur.
  failed_evaluations = db.ListProperty(item_type=db.Key, default=[])

  #: Organization which this project is in
  org = db.ReferenceProperty(
      reference_class=soc.models.organization.Organization,
      required=True, collection_name='student_projects')

  #: Program in which this project has been created
  program = db.ReferenceProperty(
      reference_class=soc.models.program.Program, required=True,
      collection_name='projects')

  #: Proposal to which this project corresponds to
  proposal = db.ReferenceProperty(
      reference_class=soc.modules.gsoc.models.proposal.GSoCProposal,
      required=False,
      collection_name='projects')

  #: Whether the student has submitted their code samples or not
  code_samples_submitted = db.BooleanProperty(default=False)

  def codeSamples(self):
    """Returns code_sample.GSoCCodeSample entities uploaded for this project.

    Returns:
      code sample entities for this project
    """
    query = code_sample_model.GSoCCodeSample.all()
    query.ancestor(self)
    return query.fetch(1000)

  def countCodeSamples(self):
    """Returns number of code_sample.GSoCCodeSample entities uploaded
    for this project.

    Returns:
      number of code samples uploaded for this project
    """
    query = code_sample_model.GSoCCodeSample.all(keys_only=True)
    query.ancestor(self)
    return query.count()
<|endoftext|>