<commit_before>#!/usr/bin/env python2.5
#
# 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.

"""Module containing the views for GSoC Homepage Application.
"""

__authors__ = [
  '"Madhusudan.C.S" <madhusudancs@gmail.com>',
  ]

from django.conf.urls.defaults import url

from soc.logic.exceptions import AccessViolation
from soc.views.template import Template

from soc.modules.gsoc.logic.models.student_project import logic as sp_logic
from soc.modules.gsoc.views.base import RequestHandler
from soc.modules.gsoc.views.helper import lists
from soc.modules.gsoc.views.helper import url_patterns

class Contact(Template):
  """Organization Contact template.
  """

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

  def context(self):
    return {
      'organization': self.data.organization,
    }

  def templatePath(self):
    return "v2/modules/gsoc/org_home/_contact.html"

class ProjectList(Template):
  """Template for list of student projects accepted under the organization.
  """

  def __init__(self, request, data):
    self.request = request
    self.data = data

    list_config = lists.ListConfiguration()
    list_config.addColumn('student', 'Student',
                          lambda entity, *args: entity.student.user.name)
    list_config.addSimpleColumn('title', 'Title')
    list_config.addColumn('mentor', 'Mentor',
                          lambda entity, *args: entity.mentor.user.name)
    self._list_config = list_config

  def context(self):
    list = lists.ListConfigurationResponse(
        self._list_config, idx=0,
        description='List of projects accepted into %s' % (
            self.data.organization.name))

    return {
        'lists': [list],
        }

  def getListData(self):
    """Returns the list data as requested by the current request.

    If the lists as requested is not supported by this component None is
    returned.
    """
    idx = lists.getListIndex(self.request)
    if idx == 0:
      fields = {'scope': self.data.organization,
                'status': 'accepted'}
      response_builder = lists.QueryContentResponseBuilder(
          self.request, self._list_config, sp_logic,
          fields)
      return response_builder.build()
    else:
      return None

  def templatePath(self):
    return "v2/modules/gsoc/org_home/_project_list.html"

class OrgHome(RequestHandler):
  """View methods for Organization Home page.
  """

  def templatePath(self):
    return 'v2/modules/gsoc/org_home/base.html'

  def djangoURLPatterns(self):
    """Returns the list of tuples for containing URL to view method mapping.
    """

    return [
        url(r'^gsoc/org/%s$' % url_patterns.ORG, self,
            name='gsoc_org_home')
    ]

  def checkAccess(self):
    """Access checks for GSoC Organization Application.
    """
    pass

  def jsonContext(self):
    """Handler for JSON requests.
    """
    list_content = ProjectList(self.request, self.data).getListData()

    if not list_content:
      raise AccessViolation(
          'You do not have access to this data')
    return list_content.content()

  def context(self):
    """Handler to for GSoC Organization Home page HTTP get request.
    """
    organization = self.data.organization

    return {
        'page_name': '%s - Homepage' % organization.short_name,
        'organization': organization,
        'contact': Contact(self.data),
        'tags': organization.tags_string(organization.org_tag),
        'project_list': ProjectList(self.request, self.data),
    }
<commit_msg>Display the list of accepted projects on Org Home only after they are announced.<commit_after>#!/usr/bin/env python2.5
#
# 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.

"""Module containing the views for GSoC Homepage Application.
"""

__authors__ = [
  '"Madhusudan.C.S" <madhusudancs@gmail.com>',
  ]

from django.conf.urls.defaults import url

from soc.logic.exceptions import AccessViolation
from soc.logic.helper import timeline as timeline_helper
from soc.views.template import Template

from soc.modules.gsoc.logic.models.student_project import logic as sp_logic
from soc.modules.gsoc.views.base import RequestHandler
from soc.modules.gsoc.views.helper import lists
from soc.modules.gsoc.views.helper import url_patterns

class Contact(Template):
  """Organization Contact template.
  """

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

  def context(self):
    return {
      'organization': self.data.organization,
    }

  def templatePath(self):
    return "v2/modules/gsoc/org_home/_contact.html"

class ProjectList(Template):
  """Template for list of student projects accepted under the organization.
  """

  def __init__(self, request, data):
    self.request = request
    self.data = data

    list_config = lists.ListConfiguration()
    list_config.addColumn('student', 'Student',
                          lambda entity, *args: entity.student.user.name)
    list_config.addSimpleColumn('title', 'Title')
    list_config.addColumn('mentor', 'Mentor',
                          lambda entity, *args: entity.mentor.user.name)
    self._list_config = list_config

  def context(self):
    list = lists.ListConfigurationResponse(
        self._list_config, idx=0,
        description='List of projects accepted into %s' % (
            self.data.organization.name))

    return {
        'lists': [list],
        }

  def getListData(self):
    """Returns the list data as requested by the current request.

    If the lists as requested is not supported by this component None is
    returned.
    """
    idx = lists.getListIndex(self.request)
    if idx == 0:
      fields = {'scope': self.data.organization,
                'status': 'accepted'}
      response_builder = lists.QueryContentResponseBuilder(
          self.request, self._list_config, sp_logic,
          fields)
      return response_builder.build()
    else:
      return None

  def templatePath(self):
    return "v2/modules/gsoc/org_home/_project_list.html"

class OrgHome(RequestHandler):
  """View methods for Organization Home page.
  """

  def templatePath(self):
    return 'v2/modules/gsoc/org_home/base.html'

  def djangoURLPatterns(self):
    """Returns the list of tuples for containing URL to view method mapping.
    """

    return [
        url(r'^gsoc/org/%s$' % url_patterns.ORG, self,
            name='gsoc_org_home')
    ]

  def checkAccess(self):
    """Access checks for GSoC Organization Application.
    """
    pass

  def jsonContext(self):
    """Handler for JSON requests.
    """
    list_content = ProjectList(self.request, self.data).getListData()

    if not list_content:
      raise AccessViolation(
          'You do not have access to this data')
    return list_content.content()

  def context(self):
    """Handler to for GSoC Organization Home page HTTP get request.
    """
    organization = self.data.organization

    context = {
        'page_name': '%s - Homepage' % organization.short_name,
        'organization': organization,
        'contact': Contact(self.data),
        'tags': organization.tags_string(organization.org_tag),
    }

    if timeline_helper.isAfterEvent(
        self.data.program_timeline, 'accepted_students_announced_deadline'):
      context['project_list'] = ProjectList(self.request, self.data)

    return context
<|endoftext|>


<commit_before>from textwrap import fill
from clint.textui import colored, cols
# from clint.textui import puts

ANSWERS_YES = "y yes true sure ok 1 tada".split()
ANSWERS_NO = "n no not false 0 nah".split()

MAX_LENGTH = 79

QUESTION_PREFIX = colored.blue("> ")

def confirm(question, default=False, prompt=None):
    prompt_addon = prompt or "[Y/n]" if default else "[N/y]"
    prompt = "{}{} {}: ".format(QUESTION_PREFIX, question.strip(), colored.green(prompt_addon))
    while True:
        val = raw_input(prompt)
        if val.strip() == "":
            return default
        if val in ANSWERS_YES:
            return True
        if val in ANSWERS_NO:
            return False

def ask(question, default=None):
    # TODO: check if question + prompt < MAX_LENGTH
    if default:
        prompt = "{}{} [{}]: ".format(QUESTION_PREFIX, question, colored.green(default))
    else:
        prompt = "{}{}: ".format(QUESTION_PREFIX, question)
    while True:
        val = raw_input(prompt)
        if val.strip():
            return val
        if val.strip() and default:
            return default

def __prepare_choices(choices):
    choices_list = []
    for i, choice in enumerate(choices):
        choices_list.append({
            'title': choice[1],
            'value': choice[0],
            'selected': False,
            'id': i + 1
            })
    return choices_list

def __choice_line(choice):
    # TODO: multiline title
    mark = (" ", "*")[int(choice['selected'])]
    print("{}{}{})\t{}".format(QUESTION_PREFIX, mark, choice['id'], choice['title']))

def select(choices, title=None, default=None, multiple=None):
    if title:
        print(title)

    choices = __prepare_choices(choices)

    while True:
        for choice in choices:
            __choice_line(choice)
        val = raw_input("[?]: ").strip()
        print val
        if val == "?":
            print "Help message. Clear?"
            raw_input()
        # TODO: 1,2,3 1 2 3, 12-14,15
        if val == "":
            # TODO: return valueS!
            return True

def success(message):
    message = fill(message, MAX_LENGTH)
    message = colored.green(message)
    print(message)

def warning(message):
    message = fill(message, MAX_LENGTH)
    message = colored.yellow(message)
    print(message)

def error(message):
    message = fill(message, MAX_LENGTH)
    message = colored.red(message)
    print(message)
<commit_msg>guitar-package: fix inquirer confirm<commit_after>from textwrap import fill
from clint.textui import colored, cols
# from clint.textui import puts

ANSWERS_YES = "y yes true sure ok 1 tada".split()
ANSWERS_NO = "n no not false 0 nah".split()

MAX_LENGTH = 79

QUESTION_PREFIX = colored.blue("> ")

def confirm(question, default=False, prompt=None):
    prompt_addon = prompt or "[Y/n]" if default else "[N/y]"
    prompt = "{}{} {}: ".format(QUESTION_PREFIX, question.strip(), colored.green(prompt_addon))
    while True:
        val = raw_input(prompt).lower()
        if val.strip() == "":
            return default
        if val in ANSWERS_YES:
            return True
        if val in ANSWERS_NO:
            return False

def ask(question, default=None):
    # TODO: check if question + prompt < MAX_LENGTH
    if default:
        prompt = "{}{} [{}]: ".format(QUESTION_PREFIX, question, colored.green(default))
    else:
        prompt = "{}{}: ".format(QUESTION_PREFIX, question)
    while True:
        val = raw_input(prompt)
        if val.strip():
            return val
        if val.strip() and default:
            return default

def __prepare_choices(choices):
    choices_list = []
    for i, choice in enumerate(choices):
        choices_list.append({
            'title': choice[1],
            'value': choice[0],
            'selected': False,
            'id': i + 1
            })
    return choices_list

def __choice_line(choice):
    # TODO: multiline title
    mark = (" ", "*")[int(choice['selected'])]
    print("{}{}{})\t{}".format(QUESTION_PREFIX, mark, choice['id'], choice['title']))

def select(choices, title=None, default=None, multiple=None):
    if title:
        print(title)

    choices = __prepare_choices(choices)

    while True:
        for choice in choices:
            __choice_line(choice)
        val = raw_input("[?]: ").strip()
        print val
        if val == "?":
            print "Help message. Clear?"
            raw_input()
        # TODO: 1,2,3 1 2 3, 12-14,15
        if val == "":
            # TODO: return valueS!
            return True

def success(message):
    message = fill(message, MAX_LENGTH)
    message = colored.green(message)
    print(message)

def warning(message):
    message = fill(message, MAX_LENGTH)
    message = colored.yellow(message)
    print(message)

def error(message):
    message = fill(message, MAX_LENGTH)
    message = colored.red(message)
    print(message)
<|endoftext|>


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

import common
import argparse
import numpy as np
import os
from rdkit.ML.Scoring import Scoring

__author__ = "David Hoksza"
__email__ = "david.hoksza@mff.cuni.cz"
__license__ = 'X11'

EF_FRACTIONS = [0.005, 0.01, 0.02, 0.05]

def evaluate_pair(fn_actives, fn_inactives):
    ranking = []
    iteration = [{"fn": fn_actives, "activity": 1}, {"fn": fn_inactives, "activity": 0}]
    for it in iteration:
        with common.open_file(it["fn"]) as f:
            for line in f:
                s_line = line.split(":")
                ranking.append({"mol": s_line[0].strip(),
                                "score": common.to_float(s_line[1].strip()),
                                "activity": it["activity"]})
    ranking = sorted(ranking, key=lambda x: x["score"], reverse=True)
    return {
        "auc": Scoring.CalcAUC(ranking, 'activity'),
        "ef": Scoring.CalcEnrichment(ranking, 'activity', EF_FRACTIONS)
        }

def evaluate_directory(dir):
    agg_results = {}
    for fn_actives in common.find_files_recursively(dir, "*_actives.out"):
        fn_inactives = fn_actives.replace("actives", "inactives")
        performance = evaluate_pair(fn_actives, fn_inactives)
        print("AUC: {}\n{}".format(fn_actives.replace("_actives", ""), performance["auc"]))
        for i in range(len(EF_FRACTIONS)):
            print("EF{}: {}".format(EF_FRACTIONS[i], performance["ef"][i]))

        s_fn = fn_inactives.replace("\\", "/").split("/")
        group = s_fn[args.group_index]
        target = s_fn[args.target_index]
        if group not in agg_results:
            agg_results[group] = {}
        if target not in agg_results[group]:
            agg_results[group][target] = []
        agg_results[group][target].append(performance)

    print("")
    for metrics in ["AUC"] + range(len(EF_FRACTIONS)):
        if metrics == "AUC": print("AUC")
        else: print("EF{}".format(EF_FRACTIONS[metrics]))
        for group in sorted(agg_results):
            for target in agg_results[group]:
                if metrics == "AUC":
                    print("{},{},{:.2f}".format(group, target, np.mean([x["auc"] for x in agg_results[group][target]])))
                else:
                    print("{},{},{:.2f}".format(group, target, np.mean([x["ef"][metrics] for x in agg_results[group][target]])))

def evaluate_logsdirectory(dir):
    results = []
    results_names = []
    results_file_names = []
    for log in common.find_files_recursively(dir, "*.log"):
        with common.open_file(log) as f:
            results_file_names.append(os.path.basename(log).replace(".log", ""))
            inside = False
            results.append([])
            for line in f:
                if line.startswith("8"): inside = True
                if inside:
                    s_line = line.split(",")
                    results[-1].append(common.to_float(s_line[2]))
                    if len(results_file_names) == 1:
                        results_names.append(s_line[0:2])

    l = len(results[0])
    equal_length = True
    for res in results:
        if len(res) != l:
            equal_length = False
            break
    if not equal_length:
        print ("The result sets differ in size (number of targets")
        for i in range(len(results_file_names)):
            print("{}: {}".format(results_file_names[i], len(results[i])))
        exit()

    print(",," + ",".join(results_file_names))
    for i in range(len(results_names)):
        values = ""
        for res in results:
            values += "{},".format(res[i])
        print("{},{},{}".format(results_names[i][0], results_names[i][1], values.strip(",")))

def main():
    if args.actives is not None and args.inactives is not None:
        print(evaluate_pair(args.actives, args.inactives))
    elif args.directory is not None:
        evaluate_directory(args.directory)
    elif args.logs_directory is not None:
        evaluate_logsdirectory(args.logs_directory)

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument("-a", "--actives",
                        metavar='FILE',
                        help="Actives ranking")
    parser.add_argument("-i", "--inactives",
                        metavar='FILE',
                        help="Inactives ranking")
    parser.add_argument("-t", "--type",
                        metavar='[roc|ef]',
                        help="Performance measure -'auc' (area under the ROC curve) "
                             "or 'ef' (enrichment factor)")
    parser.add_argument("-d", "--directory",
                        metavar='DIR',
                        help="Directory with pairs files to evaluate (*actives.out,*inactives.out)")
    parser.add_argument("-l", "--logs-directory",
                        metavar='LOGS_DIR',
                        help="Directory with logs")
    parser.add_argument("--target-index", default="-2", type=int,
                        help="Index of the target name in the directory path")
    parser.add_argument("--group-index", default="-4", type=int,
                        help="Index of the group name in the directory path")
    args = parser.parse_args()

    main()<commit_msg>Evaluate scricpt commented<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Computes performance of a simulated virtual screening campaign where actives and inactives
are known in advance.

The performance characteristics are:
    AUC - Arean Under the ROC (Receiver Operating Characteristics) Curve
    EFn - Enrichment factor computed on top n% of the database
"""

import common
import argparse
import numpy as np
import os
from rdkit.ML.Scoring import Scoring

__author__ = "David Hoksza"
__email__ = "david.hoksza@mff.cuni.cz"
__license__ = 'X11'

EF_FRACTIONS = [0.005, 0.01, 0.02, 0.05]

def evaluate_pair(fn_actives, fn_inactives):
    """
    For a pair of files with actives and inactives scores computes
    AUC (area under the ROC curve) and EF (enrichment factor).
    :param fn_actives: Name of the file with the active molecules scores.
    :param fn_inactives: Name of the file with the inactive molecules scores.
    :return: A dictionary with "auc" and "ef" keys. "auc" contains a single value, "ef" contains
    a list of EFs corresponding to EF_FRACTIONS fractions.
    """
    ranking = []
    iteration = [{"fn": fn_actives, "activity": 1}, {"fn": fn_inactives, "activity": 0}]
    for it in iteration:
        with common.open_file(it["fn"]) as f:
            for line in f:
                s_line = line.split(":")
                ranking.append({"mol": s_line[0].strip(),
                                "score": common.to_float(s_line[1].strip()),
                                "activity": it["activity"]})
    ranking = sorted(ranking, key=lambda x: x["score"], reverse=True)
    return {
        "auc": Scoring.CalcAUC(ranking, 'activity'),
        "ef": Scoring.CalcEnrichment(ranking, 'activity', EF_FRACTIONS)
        }

def evaluate_directory(dir):
    """
    Evaluates multiple simulated screens. The file with actives score is expected to have "actives.out" suffix
     while the file with inactives scores is expected to have "inactives.out" suffix. The prefix needs to be
     identical for results from one campaign (e.g., CDK2_actives.out and CDK2_inactives.out)

    :param dir: Directory to be recursively searched for the actives and inactives scoring files.
    :return:
    """
    agg_results = {}
    for fn_actives in common.find_files_recursively(dir, "*actives.out"):
        fn_inactives = fn_actives.replace("actives", "inactives")
        performance = evaluate_pair(fn_actives, fn_inactives)
        print("AUC: {}\n{}".format(fn_actives.replace("actives", ""), performance["auc"]))
        for i in range(len(EF_FRACTIONS)):
            print("EF{}: {}".format(EF_FRACTIONS[i], performance["ef"][i]))

        s_fn = fn_inactives.replace("\\", "/").split("/")
        group = s_fn[args.group_index]
        target = s_fn[args.target_index]
        if group not in agg_results:
            agg_results[group] = {}
        if target not in agg_results[group]:
            agg_results[group][target] = []
        agg_results[group][target].append(performance)

    print("")
    for metrics in ["AUC"] + range(len(EF_FRACTIONS)):
        if metrics == "AUC": print("AUC")
        else: print("EF{}".format(EF_FRACTIONS[metrics]))
        for group in sorted(agg_results):
            for target in agg_results[group]:
                if metrics == "AUC":
                    print("{},{},{:.2f}".format(group, target, np.mean([x["auc"] for x in agg_results[group][target]])))
                else:
                    print("{},{},{:.2f}".format(group, target, np.mean([x["ef"][metrics] for x in agg_results[group][target]])))

def evaluate_logsdirectory(dir):
    """
    The purpose of this function is to merge results of different parameter settings of Bayescreen. It is used
     solely for the purpose of results publication.
    :param dir: Directory to be scanned recursively for logs files  (files ending with .log suffix)
    :return:
    """
    results = []
    results_names = []
    results_file_names = []
    for log in common.find_files_recursively(dir, "*.log"):
        with common.open_file(log) as f:
            results_file_names.append(os.path.basename(log).replace(".log", ""))
            inside = False
            results.append([])
            for line in f:
                if line.startswith("8"): inside = True
                if inside:
                    s_line = line.split(",")
                    results[-1].append(common.to_float(s_line[2]))
                    if len(results_file_names) == 1:
                        results_names.append(s_line[0:2])

    l = len(results[0])
    equal_length = True
    for res in results:
        if len(res) != l:
            equal_length = False
            break
    if not equal_length:
        print ("The result sets differ in size (number of targets")
        for i in range(len(results_file_names)):
            print("{}: {}".format(results_file_names[i], len(results[i])))
        exit()

    print(",," + ",".join(results_file_names))
    for i in range(len(results_names)):
        values = ""
        for res in results:
            values += "{},".format(res[i])
        print("{},{},{}".format(results_names[i][0], results_names[i][1], values.strip(",")))

def main():
    if args.actives is not None and args.inactives is not None:
        print(evaluate_pair(args.actives, args.inactives))
    elif args.directory is not None:
        evaluate_directory(args.directory)
    elif args.logs_directory is not None:
        evaluate_logsdirectory(args.logs_directory)

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument("-a", "--actives",
                        metavar='FILE',
                        help="Actives ranking")
    parser.add_argument("-i", "--inactives",
                        metavar='FILE',
                        help="Inactives ranking")
    parser.add_argument("-t", "--type",
                        metavar='[roc|ef]',
                        help="Performance measure -'auc' (area under the ROC curve) "
                             "or 'ef' (enrichment factor)")
    parser.add_argument("-d", "--directory",
                        metavar='DIR',
                        help="Directory with pairs files to evaluate (*actives.out,*inactives.out)")
    parser.add_argument("-l", "--logs-directory",
                        metavar='LOGS_DIR',
                        help="Directory with logs")
    parser.add_argument("--target-index", default="-2", type=int,
                        help="Index of the target name in the directory path")
    parser.add_argument("--group-index", default="-4", type=int,
                        help="Index of the group name in the directory path")
    args = parser.parse_args()

    main()<|endoftext|>


<commit_before>"""Testing binary Heap."""

import pytest

@pytest.fixture
def heap():
    """Fixture for heap."""
    from src.binheap import Binheap
    bh = Binheap()
    return bh

def test_push_val_to_head(heap):
    """Test push first val adds to the head."""
    heap.push(3)
    assert heap.container == [None, 3]

def test_push_val_to_left(heap):
    """Test push second val adds to the tree."""
    heap.push(3)
    heap.push(2)
    assert heap.container == [None, 2, 3]
<commit_msg>added test to use push method<commit_after>"""Testing binary Heap."""

import pytest

@pytest.fixture
def empty_heap():
    """Fixture for empty_heap."""
    from src.binheap import Binheap
    bh = Binheap()
    return bh

def test_push_val_to_head(empty_heap):
    """Test push first val adds to the head."""
    empty_heap.push(3)
    assert empty_heap.container == [None, 3]

def test_push_val(empty_heap):
    """Test push second val adds to the tree."""
    empty_heap.push(3)
    empty_heap.push(2)
    assert empty_heap.container == [None, 3, 2]

def test_push_val_large(empty_heap):
    """Test push val for larger number."""
    empty_heap.push(3)
    empty_heap.push(2)
    empty_heap.push(1)
    empty_heap.push(16)
    assert empty_heap.container == [None, 16, 3, 1, 2]
<|endoftext|>


<commit_before>import os
import stat
import pwd
import shlex
import time
try:
    from cStringIO import StringIO
except ImportError:
    from StringIO import StringIO

QUOTE_CHARS = ['"', "'"]
SEEK_SET, SEEK_CUR, SEEK_END = range(0, 3)

def get_username():
    uid = os.geteuid()
    try:
        return pwd.getpwuid(uid).pw_name
    except:
        return uid

def token_split(text, quote_chars=QUOTE_CHARS):
    for char in [''] + quote_chars:
        try:
            return shlex.split(text + char)
        except ValueError:
            pass

    raise ValueError, "Quotation mismatch"

def tail(filename, wait=0.1):
    st = os.stat(filename)
    fp = open(filename, 'rb')

    # Read until file is truncated, collect results in a string buffer
    size = st[stat.ST_SIZE]
    line = StringIO()
    while True:
        char = fp.read(1)

        # Check if there was something for us to collect
        if char == '':
            st = os.stat(filename)
            if st[stat.ST_SIZE] < size:
                # File truncated
                break
            else:
                try:
                    time.sleep(wait)
                except KeyboardInterrupt:
                    break
        else:
            line.write(char)
            # Yield lines
            if char == '\n':
                yield line.getvalue()
                line.seek(0)
                line.truncate()

    fp.close()
<commit_msg>Added seek argument to tail<commit_after>import os
import stat
import pwd
import shlex
import time
try:
    from cStringIO import StringIO
except ImportError:
    from StringIO import StringIO

QUOTE_CHARS = ['"', "'"]
SEEK_SET, SEEK_CUR, SEEK_END = range(0, 3)

def get_username():
    uid = os.geteuid()
    try:
        return pwd.getpwuid(uid).pw_name
    except:
        return uid

def token_split(text, quote_chars=QUOTE_CHARS):
    for char in [''] + quote_chars:
        try:
            return shlex.split(text + char)
        except ValueError:
            pass

    raise ValueError, "Quotation mismatch"

def tail(filename, wait=0.1, seek=0):
    st = os.stat(filename)
    fp = open(filename, 'rb')

    # Seek to the end
    if seek <= 0:
        fp.seek(abs(seek), 2)
    else:
        fp.seek(seek)

    # Read until file is truncated, collect results in a string buffer
    size = st[stat.ST_SIZE]
    line = StringIO()
    while True:
        char = fp.read(1)

        # Check if there was something for us to collect
        if char == '':
            st = os.stat(filename)
            if st[stat.ST_SIZE] < size:
                # File truncated
                break
            else:
                try:
                    time.sleep(wait)
                except KeyboardInterrupt:
                    break
        else:
            line.write(char)
            # Yield lines
            if char == '\n':
                yield line.getvalue()
                line.seek(0)
                line.truncate()

    fp.close()
<|endoftext|>


<commit_before># coding: utf-8

from __future__ import unicode_literals, division
import datetime
from django.contrib.auth import get_user_model
from django.contrib.sites.models import get_current_site
from django.core.exceptions import PermissionDenied
from django.db import connection
from django.db.models import Count
from django.http import Http404
from django.shortcuts import redirect
from django.template.loader import render_to_string
from django.views.generic import DetailView, TemplateView
from registration.backends.default.views import RegistrationView
from cache_tools import cached_ugettext_lazy as _
from libretto.models import AncrageSpatioTemporel
from .models import HierarchicUser
from .forms import UserRegistrationForm

class GrantToAdmin(DetailView):
    model = get_user_model()
    template_name = 'accounts/grant_to_admin.html'

    def grant_user(self, user):
        user.is_staff = True
        user.save()
        site_url = 'http://' + get_current_site(self.request).domain
        email_content = render_to_string(
            'accounts/granted_to_admin_email.txt',
            {'user': user, 'site_url': site_url})
        user.email_user(
            '[Dezède] Accès autorisé à l’administration',
            email_content)

    def get_context_data(self, **kwargs):
        context = super(GrantToAdmin, self).get_context_data(**kwargs)
        current_user = self.request.user
        user_to_be_granted = self.object
        if current_user != user_to_be_granted.mentor:
            raise PermissionDenied
        if user_to_be_granted.is_staff:
            context['already_staff'] = True
        else:
            self.grant_user(user_to_be_granted)
        return context

class MyRegistrationView(RegistrationView):
    form_class = UserRegistrationForm

    def form_valid(self, request, form):
        # Taken from the overriden method.
        new_user = self.register(request, **form.cleaned_data)
        form.save(request, new_user)
        success_url = self.get_success_url(request, new_user)

        try:
            to, args, kwargs = success_url
            return redirect(to, *args, **kwargs)
        except ValueError:
            return redirect(success_url)

class EvenementsGraph(TemplateView):
    template_name = 'accounts/include/evenements_graph.svg'
    content_type = 'image/svg+xml'
    displayed_range = 150  # years
    row_length = 20  # years
    rect_size = 16  # pixels
    rect_margin = 4  # pixels
    # When we set the font size, the figures are smaller than
    # the specified size.
    figure_size_factor = 0.8
    hue = 0  # degrees
    legend_levels = 6

    def get_context_data(self, **kwargs):
        context = super(EvenementsGraph, self).get_context_data(**kwargs)

        qs = AncrageSpatioTemporel.objects.all()

        username = self.request.GET.get('username')

        if username is not None:
            User = get_user_model()
            if not User.objects.filter(username=username).exists():
                raise Http404

            qs = qs.filter(evenements_debuts__owner__username=username)
        else:
            qs = qs.filter(evenements_debuts__isnull=False)

        context['data'] = data = list(
            qs
            .extra({'year': connection.ops.date_trunc_sql('year', 'date')})
            .values('year').annotate(n=Count('evenements_debuts'))
            .order_by('year'))

        for d in data:
            d['year'] = getattr(d['year'], 'year')

        years = [d['year'] for d in data if d['year'] is not None]
        current_year = datetime.datetime.now().year
        if not years:
            years = [current_year]
            data = [{'year': current_year, 'n': 0}]
        min_year = min(years)
        max_year = max(years)

        margin = max(0, (self.displayed_range - (max_year - min_year)) // 2)

        max_upper_margin = max(0, current_year - max_year)
        margin_offset = max(0, margin - max_upper_margin)

        context['min_year'] = min_year = min_year - (margin + margin_offset)
        context['max_year'] = max_year = max_year + (margin - margin_offset)

        counts = [d['n'] for d in data] + [0]
        context['max_n'] = max(counts)

        # Fill data with missing years between min_year and max_year.
        for year in range(min_year, max_year + 1):
            if year not in years:
                data.append({'year': year, 'n': 0})
        context['data'] = sorted(data, key=lambda d: d['year'])

        def get_float(attr):
            return float(self.request.GET.get(attr) or getattr(self, attr))

        row_length = self.row_length

        context['row_length'] = row_length
        context['size'] = get_float('rect_size')
        context['margin'] = get_float('rect_margin')
        context['figure_size_factor'] = get_float('figure_size_factor')
        context['hue'] = get_float('hue')

        isolated_starting_years = min_year % row_length
        isolated_ending_years = max_year % row_length
        min_year -= isolated_starting_years
        max_year -= isolated_ending_years

        n_rows = (max_year - min_year) // row_length
        if isolated_ending_years > 0:
            n_rows += 1
        context['n_rows'] = n_rows

        def levels_iterator(start, end, n_steps):
            step = (end - start) / (n_steps - 1)
            i = start
            while i <= end:
                yield i
                i += step

        context['legend_levels'] = list(
            levels_iterator(0, 1, self.legend_levels))

        return context

class HierarchicUserDetail(DetailView):
    model = HierarchicUser
    slug_url_kwarg = 'username'
    slug_field = 'username'

    def get_context_data(self, **kwargs):
        context = super(HierarchicUserDetail, self).get_context_data(**kwargs)
        if self.object.legal_person:
            context['verboses'] = {
                'disciple': _('membre'),
                'disciples': _('membres'),
            }
        else:
            context['verboses'] = {
                'disciple': _('disciple'),
                'disciples': _('disciples'),
            }
        if getattr(self.object.mentor, 'legal_person', False):
            context['verboses']['mentor'] = _('appartenance')
        else:
            context['verboses']['mentor'] = _('mentor')
        return context
<commit_msg>Met une valeur par défaut explicite au getattr du commit précédent.<commit_after># coding: utf-8

from __future__ import unicode_literals, division
import datetime
from django.contrib.auth import get_user_model
from django.contrib.sites.models import get_current_site
from django.core.exceptions import PermissionDenied
from django.db import connection
from django.db.models import Count
from django.http import Http404
from django.shortcuts import redirect
from django.template.loader import render_to_string
from django.views.generic import DetailView, TemplateView
from registration.backends.default.views import RegistrationView
from cache_tools import cached_ugettext_lazy as _
from libretto.models import AncrageSpatioTemporel
from .models import HierarchicUser
from .forms import UserRegistrationForm

class GrantToAdmin(DetailView):
    model = get_user_model()
    template_name = 'accounts/grant_to_admin.html'

    def grant_user(self, user):
        user.is_staff = True
        user.save()
        site_url = 'http://' + get_current_site(self.request).domain
        email_content = render_to_string(
            'accounts/granted_to_admin_email.txt',
            {'user': user, 'site_url': site_url})
        user.email_user(
            '[Dezède] Accès autorisé à l’administration',
            email_content)

    def get_context_data(self, **kwargs):
        context = super(GrantToAdmin, self).get_context_data(**kwargs)
        current_user = self.request.user
        user_to_be_granted = self.object
        if current_user != user_to_be_granted.mentor:
            raise PermissionDenied
        if user_to_be_granted.is_staff:
            context['already_staff'] = True
        else:
            self.grant_user(user_to_be_granted)
        return context

class MyRegistrationView(RegistrationView):
    form_class = UserRegistrationForm

    def form_valid(self, request, form):
        # Taken from the overriden method.
        new_user = self.register(request, **form.cleaned_data)
        form.save(request, new_user)
        success_url = self.get_success_url(request, new_user)

        try:
            to, args, kwargs = success_url
            return redirect(to, *args, **kwargs)
        except ValueError:
            return redirect(success_url)

class EvenementsGraph(TemplateView):
    template_name = 'accounts/include/evenements_graph.svg'
    content_type = 'image/svg+xml'
    displayed_range = 150  # years
    row_length = 20  # years
    rect_size = 16  # pixels
    rect_margin = 4  # pixels
    # When we set the font size, the figures are smaller than
    # the specified size.
    figure_size_factor = 0.8
    hue = 0  # degrees
    legend_levels = 6

    def get_context_data(self, **kwargs):
        context = super(EvenementsGraph, self).get_context_data(**kwargs)

        qs = AncrageSpatioTemporel.objects.all()

        username = self.request.GET.get('username')

        if username is not None:
            User = get_user_model()
            if not User.objects.filter(username=username).exists():
                raise Http404

            qs = qs.filter(evenements_debuts__owner__username=username)
        else:
            qs = qs.filter(evenements_debuts__isnull=False)

        context['data'] = data = list(
            qs
            .extra({'year': connection.ops.date_trunc_sql('year', 'date')})
            .values('year').annotate(n=Count('evenements_debuts'))
            .order_by('year'))

        for d in data:
            d['year'] = getattr(d['year'], 'year', None)

        years = [d['year'] for d in data if d['year'] is not None]
        current_year = datetime.datetime.now().year
        if not years:
            years = [current_year]
            data = [{'year': current_year, 'n': 0}]
        min_year = min(years)
        max_year = max(years)

        margin = max(0, (self.displayed_range - (max_year - min_year)) // 2)

        max_upper_margin = max(0, current_year - max_year)
        margin_offset = max(0, margin - max_upper_margin)

        context['min_year'] = min_year = min_year - (margin + margin_offset)
        context['max_year'] = max_year = max_year + (margin - margin_offset)

        counts = [d['n'] for d in data] + [0]
        context['max_n'] = max(counts)

        # Fill data with missing years between min_year and max_year.
        for year in range(min_year, max_year + 1):
            if year not in years:
                data.append({'year': year, 'n': 0})
        context['data'] = sorted(data, key=lambda d: d['year'])

        def get_float(attr):
            return float(self.request.GET.get(attr) or getattr(self, attr))

        row_length = self.row_length

        context['row_length'] = row_length
        context['size'] = get_float('rect_size')
        context['margin'] = get_float('rect_margin')
        context['figure_size_factor'] = get_float('figure_size_factor')
        context['hue'] = get_float('hue')

        isolated_starting_years = min_year % row_length
        isolated_ending_years = max_year % row_length
        min_year -= isolated_starting_years
        max_year -= isolated_ending_years

        n_rows = (max_year - min_year) // row_length
        if isolated_ending_years > 0:
            n_rows += 1
        context['n_rows'] = n_rows

        def levels_iterator(start, end, n_steps):
            step = (end - start) / (n_steps - 1)
            i = start
            while i <= end:
                yield i
                i += step

        context['legend_levels'] = list(
            levels_iterator(0, 1, self.legend_levels))

        return context

class HierarchicUserDetail(DetailView):
    model = HierarchicUser
    slug_url_kwarg = 'username'
    slug_field = 'username'

    def get_context_data(self, **kwargs):
        context = super(HierarchicUserDetail, self).get_context_data(**kwargs)
        if self.object.legal_person:
            context['verboses'] = {
                'disciple': _('membre'),
                'disciples': _('membres'),
            }
        else:
            context['verboses'] = {
                'disciple': _('disciple'),
                'disciples': _('disciples'),
            }
        if getattr(self.object.mentor, 'legal_person', False):
            context['verboses']['mentor'] = _('appartenance')
        else:
            context['verboses']['mentor'] = _('mentor')
        return context
<|endoftext|>


<commit_before># -*- coding: utf8 -*-

from tuttle import workflow
from tuttle.invalidation import InvalidResourceCollector
from error import TuttleError
from project_parser import ProjectParser
from tuttle.project_parser import WorkflowError
from tuttle.workflow_builder import WorkflowBuilder
from workflow import Workflow

NOT_PRODUCED_BY_TUTTLE = "The existing resource has not been produced by tuttle"
USER_REQUEST = "User request"
PROCESS_HAS_FAILED = "The resource has been produced by a failing process"

def parse_project(tuttlefile):
    pp = ProjectParser()
    workflow = pp.parse_and_check_file(tuttlefile)
    workflow.static_check_processes()
    return workflow

def run(workflow):
    missing = workflow.missing_inputs()
    if missing:
        error_msg = "Missing the following resources to launch the workflow :\n"
        for mis in missing:
            error_msg += "* {}\n".format(mis.url)
        raise TuttleError(error_msg)
    failing_process = workflow.pick_a_failing_process()
    if failing_process:
        msg = "Workflow already failed on process '{}'. Fix the process and run tuttle again.".format(failing_process.id)
        msg += "\n\nIf failure has been caused by an external factor like a connection breakdown, " \
               'use "tuttle invalidate" to reset execution then "tuttle run" again.'
        raise TuttleError(msg)
    nb_process_run = workflow.run()
    return nb_process_run

def parse_invalidate_and_run(tuttlefile, threshold=-1):
        try:
            inv_collector = InvalidResourceCollector()
            workflow = parse_project(tuttlefile)
            workflow.run_pre_processes()
            previous_workflow = Workflow.load()

            shrunk = False
            if previous_workflow:
                workflow.retrieve_execution_info(previous_workflow)
                shrunk = workflow.retrieve_signatures(previous_workflow)
                different_res = previous_workflow.resources_not_created_the_same_way(workflow)
                inv_collector.collect_with_dependencies(different_res, previous_workflow)

            modified_primary_resources = workflow.update_primary_resource_signatures()
            inv_collector.collect_dependencies_only(modified_primary_resources, workflow)
            not_created = workflow.resources_not_created_by_tuttle()
            inv_collector.collect_resources(not_created, NOT_PRODUCED_BY_TUTTLE)

            workflow.reset_process_exec_info(inv_collector.urls())
            inv_collector.warn_and_remove(threshold)
            workflow.create_reports()
            workflow.dump()

            nb_process_run = run(workflow)
            if nb_process_run > 0 or shrunk:
                print("====")
                print("Done")
            else:
                print("Nothing to do")

        except TuttleError as e:
            print(e)
            return 2
        return 0

def get_resources(urls):
    result = []
    pb = WorkflowBuilder()
    for url in urls:
        resource = pb.build_resource(url)
        if resource is None:
            print("Tuttle cannot understand '{}' as a valid resource url".format(url))
            return False
        result.append(resource)
    return result

def invalidate_resources(tuttlefile, urls, threshold=-1):
    resources = get_resources(urls)
    if resources is False:
        return 2
    previous_workflow = Workflow.load()
    if previous_workflow is None:
        print("Tuttle has not run yet ! It has produced nothing, so there is nothing to invalidate.")
        return 2
    try:
        workflow = parse_project(tuttlefile)
    except TuttleError as e:
        print("Invalidation has failed because tuttlefile is has errors (a valid project is needed for "
              "clean invalidation) :")
        print(e)
        return 2

    inv_collector = InvalidResourceCollector()
    workflow.retrieve_execution_info(previous_workflow)
    workflow.retrieve_signatures(previous_workflow)
    different_res = previous_workflow.resources_not_created_the_same_way(workflow)
    inv_collector.collect_with_dependencies(different_res, previous_workflow)
    failed_res = workflow.failed_resources()
    inv_collector.collect_resources(failed_res, PROCESS_HAS_FAILED)
    modified_primary_resources = workflow.modified_primary_resources()
    inv_collector.collect_with_dependencies(modified_primary_resources, workflow)
    url_not_invalidated = inv_collector.not_invalidated(urls)
    to_invalidate = []
    for url in url_not_invalidated:
        resource = workflow.find_resource(url)
        if not resource:
            msg = "Ignoring {} : this resource does not belong to the workflow.".format(url)
            print(msg)
        elif not resource.exists():
            msg = "Ignoring {} : this resource has not been produced yet.".format(url)
            print(msg)
        elif resource.is_primary():
            msg = "Ignoring {} : primary resources can't be invalidated.".format(url)
            print(msg)
        else:
            to_invalidate.append(resource)
    inv_collector.collect_resources(to_invalidate, USER_REQUEST)
    inv_collector.collect_dependencies_only(to_invalidate, workflow)
    if inv_collector.urls() or previous_workflow.pick_a_failing_process():
        try:
            inv_collector.warn_and_remove(threshold)
        except TuttleError as e:
            print(e)
            return 2
        workflow.reset_process_exec_info(inv_collector.urls())
        workflow.dump()
        workflow.create_reports()
    else:
        print("Nothing to do")
    return 0
<commit_msg>Added TODO not to forget preprocessors in invalidation<commit_after># -*- coding: utf8 -*-

from tuttle import workflow
from tuttle.invalidation import InvalidResourceCollector
from error import TuttleError
from project_parser import ProjectParser
from tuttle.project_parser import WorkflowError
from tuttle.workflow_builder import WorkflowBuilder
from workflow import Workflow

NOT_PRODUCED_BY_TUTTLE = "The existing resource has not been produced by tuttle"
USER_REQUEST = "User request"
PROCESS_HAS_FAILED = "The resource has been produced by a failing process"

def parse_project(tuttlefile):
    pp = ProjectParser()
    workflow = pp.parse_and_check_file(tuttlefile)
    workflow.static_check_processes()
    return workflow

def run(workflow):
    missing = workflow.missing_inputs()
    if missing:
        error_msg = "Missing the following resources to launch the workflow :\n"
        for mis in missing:
            error_msg += "* {}\n".format(mis.url)
        raise TuttleError(error_msg)
    failing_process = workflow.pick_a_failing_process()
    if failing_process:
        msg = "Workflow already failed on process '{}'. Fix the process and run tuttle again.".format(failing_process.id)
        msg += "\n\nIf failure has been caused by an external factor like a connection breakdown, " \
               'use "tuttle invalidate" to reset execution then "tuttle run" again.'
        raise TuttleError(msg)
    nb_process_run = workflow.run()
    return nb_process_run

def parse_invalidate_and_run(tuttlefile, threshold=-1):
        try:
            inv_collector = InvalidResourceCollector()
            workflow = parse_project(tuttlefile)
            workflow.run_pre_processes()
            previous_workflow = Workflow.load()

            shrunk = False
            if previous_workflow:
                workflow.retrieve_execution_info(previous_workflow)
                shrunk = workflow.retrieve_signatures(previous_workflow)
                different_res = previous_workflow.resources_not_created_the_same_way(workflow)
                inv_collector.collect_with_dependencies(different_res, previous_workflow)

            modified_primary_resources = workflow.update_primary_resource_signatures()
            inv_collector.collect_dependencies_only(modified_primary_resources, workflow)
            not_created = workflow.resources_not_created_by_tuttle()
            inv_collector.collect_resources(not_created, NOT_PRODUCED_BY_TUTTLE)

            workflow.reset_process_exec_info(inv_collector.urls())
            inv_collector.warn_and_remove(threshold)
            workflow.create_reports()
            workflow.dump()

            nb_process_run = run(workflow)
            if nb_process_run > 0 or shrunk:
                print("====")
                print("Done")
            else:
                print("Nothing to do")

        except TuttleError as e:
            print(e)
            return 2
        return 0

def get_resources(urls):
    result = []
    pb = WorkflowBuilder()
    for url in urls:
        resource = pb.build_resource(url)
        if resource is None:
            print("Tuttle cannot understand '{}' as a valid resource url".format(url))
            return False
        result.append(resource)
    return result

def invalidate_resources(tuttlefile, urls, threshold=-1):
    resources = get_resources(urls)
    if resources is False:
        return 2
    previous_workflow = Workflow.load()
    if previous_workflow is None:
        print("Tuttle has not run yet ! It has produced nothing, so there is nothing to invalidate.")
        return 2
    try:
        workflow = parse_project(tuttlefile)
        # TODO : add preprocessors to invalidation
    except TuttleError as e:
        print("Invalidation has failed because tuttlefile is has errors (a valid project is needed for "
              "clean invalidation) :")
        print(e)
        return 2

    inv_collector = InvalidResourceCollector()
    workflow.retrieve_execution_info(previous_workflow)
    workflow.retrieve_signatures(previous_workflow)
    different_res = previous_workflow.resources_not_created_the_same_way(workflow)
    inv_collector.collect_with_dependencies(different_res, previous_workflow)
    failed_res = workflow.failed_resources()
    inv_collector.collect_resources(failed_res, PROCESS_HAS_FAILED)
    modified_primary_resources = workflow.modified_primary_resources()
    inv_collector.collect_with_dependencies(modified_primary_resources, workflow)
    url_not_invalidated = inv_collector.not_invalidated(urls)
    to_invalidate = []
    for url in url_not_invalidated:
        resource = workflow.find_resource(url)
        if not resource:
            msg = "Ignoring {} : this resource does not belong to the workflow.".format(url)
            print(msg)
        elif not resource.exists():
            msg = "Ignoring {} : this resource has not been produced yet.".format(url)
            print(msg)
        elif resource.is_primary():
            msg = "Ignoring {} : primary resources can't be invalidated.".format(url)
            print(msg)
        else:
            to_invalidate.append(resource)
    inv_collector.collect_resources(to_invalidate, USER_REQUEST)
    inv_collector.collect_dependencies_only(to_invalidate, workflow)
    if inv_collector.urls() or previous_workflow.pick_a_failing_process():
        try:
            inv_collector.warn_and_remove(threshold)
        except TuttleError as e:
            print(e)
            return 2
        workflow.reset_process_exec_info(inv_collector.urls())
        workflow.dump()
        workflow.create_reports()
    else:
        print("Nothing to do")
    return 0
<|endoftext|>


<commit_before>#!/usr/bin/env python2.5
#
# 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.

"""Module for the GSoC proposal page.
"""

__authors__ = [
  '"Daniel Hans" <daniel.m.hans@gmail.com>',
  ]

from django.conf.urls.defaults import url

from soc.views import forms

from soc.modules.gsoc.models.student_proposal import StudentProposal

from soc.modules.gsoc.views.base import RequestHandler
from soc.modules.gsoc.views.helper import access_checker
from soc.modules.gsoc.views.helper import url_patterns

class ProposalForm(forms.ModelForm):
  """Django form for the proposal page.
  """

  class Meta:
    model = StudentProposal
    exclude = ['link_id', 'user', 'scope', 'scope_path', 'status',
        'mentor', 'possible_mentors', 'org', 'program', 'created_on',
        'last_modified_on', 'score']

  #  widgets = forms.choiceWidgets(StudentProposal,
  #      ['res_country', 'ship_country',
  #       'tshirt_style', 'tshirt_size', 'gender'])

class ProposalPage(RequestHandler):
  """View for the submit proposal.
  """

  def djangoURLPatterns(self):
    return [
        url(r'^gsoc/proposal/submit/%s$' % url_patterns.ORG,
         self, name='submit_gsoc_proposal'),
    ]

  def checkAccess(self):
    check = access_checker.AccessChecker(self.data)
    check.isLoggedIn()
    check.isActiveStudent()
    check.canStudentPropose()

  def templatePath(self):
    return 'v2/modules/gsoc/proposal/base.html'

  def context(self):
    proposal_form = ProposalForm(self.data.POST or None)
    return {
        'page_name': 'Proposal',
        'proposal_form': proposal_form.render(),
        }

  def validate(self):
    proposal_form = ProposalForm(self.data.POST)

    if not proposal_form.is_valid():
      return False

    return True

  def post(self):
    """Handler for HTTP POST request.
    """

    if self.validate():
      self.redirect()
    else:
      self.get()
<commit_msg>Update proposal url added for Proposal view.<commit_after>#!/usr/bin/env python2.5
#
# 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.

"""Module for the GSoC proposal page.
"""

__authors__ = [
  '"Daniel Hans" <daniel.m.hans@gmail.com>',
  ]

from django.conf.urls.defaults import url

from soc.views import forms

from soc.modules.gsoc.models.student_proposal import StudentProposal

from soc.modules.gsoc.views.base import RequestHandler
from soc.modules.gsoc.views.helper import access_checker
from soc.modules.gsoc.views.helper import url_patterns

class ProposalForm(forms.ModelForm):
  """Django form for the proposal page.
  """

  class Meta:
    model = StudentProposal
    exclude = ['link_id', 'user', 'scope', 'scope_path', 'status',
        'mentor', 'possible_mentors', 'org', 'program', 'created_on',
        'last_modified_on', 'score']

  #  widgets = forms.choiceWidgets(StudentProposal,
  #      ['res_country', 'ship_country',
  #       'tshirt_style', 'tshirt_size', 'gender'])

class ProposalPage(RequestHandler):
  """View for the submit proposal.
  """

  def djangoURLPatterns(self):
    return [
        url(r'^gsoc/proposal/submit/%s$' % url_patterns.ORG,
         self, name='submit_gsoc_proposal'),
         url(r'^gsoc/proposal/update/%s$' % url_patterns.PROPOSAL,
         self, name='update_gsoc_proposal'),
    ]

  def checkAccess(self):
    check = access_checker.AccessChecker(self.data)
    check.isLoggedIn()
    check.isActiveStudent()
    check.canStudentPropose()

  def templatePath(self):
    return 'v2/modules/gsoc/proposal/base.html'

  def context(self):
    proposal_form = ProposalForm(self.data.POST or None)
    return {
        'page_name': 'Proposal',
        'proposal_form': proposal_form.render(),
        }

  def validate(self):
    proposal_form = ProposalForm(self.data.POST)

    if not proposal_form.is_valid():
      return False

    return True

  def post(self):
    """Handler for HTTP POST request.
    """

    if self.validate():
      self.redirect()
    else:
      self.get()
<|endoftext|>


<commit_before>from collections import defaultdict
from itertools import dropwhile, permutations

graphfile = None

class Graph:
    def __init__(self):
        self._pred = defaultdict(list)
        self._succ = defaultdict(list)
        self._vertices = {}

    def __str__(self):
        return 'Graph(vertices=' + str(self._vertices) + ', pred=' + str(self._pred) + ', succ=' + str(self._succ) + ')'

    def __contains__(self, (v, t)):
        if t == 'in':
            return (v in self._pred)
        if t == 'out':
            return (v in self._succ)
        if t == None:
            return (v in self._pred or v in self._succ)

    def successors(self, key):
        return self._succ[key]

    def predecessors(self, key):
        return self._pred[key]

    def vertex(self, k):
        return self._vertices[k]

    def set_vertex(self, k, v=None):
        self._vertices[k] = v

    def remove_vertices(self, ks):
        for k in ks:
            for p in self._pred[k]:
                self._succ[p].remove(k)
            for s in self._succ[k]:
                self._pred[s].remove(k)
            del self._pred[k]
            del self._succ[k]
            del self._vertices[k]

    def vertices(self):
        return self._vertices

    def deg_in(self, k):
        return len(self._pred[k])

    def deg_out(self, k):
        return len(self._succ[k])

    def add_edge(self, v_in, v_out):
        self._succ[v_in].append(v_out)
        self._pred[v_out].append(v_in)

    def remove_edge(self, v_in, v_out):
        self._succ[v_in].remove(v_out)
        self._pred[v_out].remove(v_in)

    def export(self, f, name, random=False):
        def block_label(block_type, block_loc, block):
            if block_type == 'block':
                return "block\\n{0:x}:{1:x}".format(block_loc, block[-1]['loc'])
            else:
                return "{0}\\n{1:x}".format(block_type, block_loc)

        if random:
            import random
            name += '_'+''.join(random.sample('0123456789abcdef', 8))

        f.write("\tsubgraph {0} {{\n".format(name))

        entries = filter(lambda k: self.deg_in(k) == 0, self.vertices())

        f.write("\t\t{0}_entry [label=\"{0}\"];\n".format(name))
        for e_type, e_loc in entries:
            f.write("\t\t{0}_entry -> {0}_{1}_{2:x};\n".format(name, e_type, e_loc))

        for (block_type, block_loc), block in self.vertices().iteritems():
            f.write("\t\t{0}_{1}_{2:x} [label=\"{3}\"];\n".format(name, block_type, block_loc, block_label(block_type, block_loc, block)))
            for v_type, v_out in self.successors((block_type, block_loc)):
                f.write("\t\t{0}_{1}_{2:x} -> {0}_{3}_{4:x};\n".format(name, block_type, block_loc, v_type, v_out))
        f.write("\t}\n")

def control_flow_graph(function, labels, name):
    '''
    Analyze the control flow graph (cfg) of the function
    '''

    graph = Graph()
    block_acc = []
    block_cur = None
    block_last = None
    block_change = True
    pass_through = False
    for ins in function:
        if ins['loc'] in labels or block_change:
            if block_last is not None:
                graph.set_vertex(block_last, block_acc)
            block_cur = ('block', ins['loc'])
            block_acc = []
            graph.set_vertex(block_cur)

        if ins['loc'] in labels and pass_through:
            # pass-through edge
            graph.add_edge(block_last, ('block', ins['loc']))

        block_change = False
        pass_through = True

        if ins['ins'][0][0] == 'j': # jumps (and only jumps)
            loc_next = ins['loc']+ins['length']
            loc_j = loc_next+int(ins['ins'][1], 16)
            graph.add_edge(block_cur, ('block', loc_j))
            block_change = True
            if ins['ins'][0] != 'jmp':
                graph.add_edge(block_cur, ('block', loc_next))
            else:
                pass_through = False
        block_last = block_cur
        block_acc.append(ins)

    graph.set_vertex(block_last, block_acc)

    if graphfile:
        graph.export(graphfile, name)

    return graph_transform(graph)

def flip(x):
    '''
    flip(x)(f) = f(x)
    '''
    def f(g):
        return g(x)
    return f

def graph_transform(graph):
    '''
    Perform one step transformations of the graph according to
     preset rules until no more transformations can be performed.

    The rewriting system used here is decreasing (i.e. all transformations
     decrease the size of the graph), because every transformation rule is
     guaranteed to be decreasing, therefore it is total (it will always stop
     at some point.

    Transformation rules are functions of the type

      Graph -> (Boolean, Graph)

    The boolean value signifies whether the transformation condition was
     satisfied and the transformation was applied successfully.

    If no further transformation can be performed, the process is stopped
     and the resulting graph is returned.
    '''
    def t_trivial(graph):
        return False, graph

    def t_while(graph):
        for v in graph.vertices():
            if graph.deg_out(v) == 2:
                succs = graph.successors(v)
                for s1, s2 in permutations(succs):
                    if graph.deg_out(s1) == 1 and graph.deg_in(s1) == 1 and v in graph.successors(s1):
                        v_type, v_start = v
                        v_new = ('while', v_start)
                        condition = 'cmp'
                        v_new_value = (condition, (v, graph.vertex(v)), (s1, graph.vertex(s1)))
                        graph.set_vertex(v_new, v_new_value)
                        for pred in graph.predecessors(v):
                            graph.add_edge(pred, v_new)
                        graph.add_edge(v_new, s2)
                        graph.remove_vertices([v,s1])

                        return (True, graph)

        return (False, graph)

    def t_if(graph):
        for v in graph.vertices():
            if graph.deg_out(v) == 2:
                succs = graph.successors(v)
                for s1, s2 in permutations(succs):
                    if graph.deg_out(s1) == 1:
                        s1_succ = graph.successors(s1)[0]
                        if s1_succ == s2:
                            s1_type, s1_start = s1
                            v_new = ('if', s1_start)
                            condition = 'cmp'
                            v_new_value = (condition, (s1, graph.vertex(s1)))
                            graph.set_vertex(v_new, v_new_value)
                            graph.add_edge(v, v_new)
                            graph.add_edge(v_new, s2)
                            graph.remove_edge(v, s2)
                            graph.remove_vertices([s1])
                            return (True, graph)

        return (False, graph)

    def t_ifelse(graph):
        for v in graph.vertices():
            succs = graph.successors(v)
            if len(succs) == 2:
                s, t = succs
                s_s, t_s = map(graph.successors, succs)
                s_p, t_p = map(graph.predecessors, succs)
                if map(len, [s_s, t_s, s_p, t_p]) == [1]*4 and s_s == t_s:
                    s_type, s_start = s
                    v_new = ('ifelse', s_start)
                    condition = 'cmp' # change that
                    # modify v
                    v_new_value = (condition,
                        (s, graph.vertex(s)), (t, graph.vertex(t)))
                    graph.set_vertex(v_new, v_new_value)
                    graph.add_edge(v_new, s_s[0])
                    graph.add_edge(v, v_new)
                    graph.remove_vertices([s, t])
                    return (True, graph)

        return (False, graph)

    def t_cons(graph):
        for v in graph.vertices():
            if graph.deg_out(v) == 1:
                s = graph.successors(v)[0]
                if graph.deg_in(s) == 1 and v != s:
                    v_type, v_start = v
                    s_type, s_start = s
                    if v_type == 'cons':
                        graph.vertex(v).append((s, graph.vertex(s)))
                        #graph.set_vertex(v, v_value)
                        for succ in graph.successors(s):
                            graph.add_edge(v, succ)
                        graph.remove_vertices([s])
                    else:
                        v_new = ('cons', v_start)
                        v_new_value = [(v, graph.vertex(v)), (s, graph.vertex(s))]
                        graph.set_vertex(v_new, v_new_value)
                        for pred in graph.predecessors(v):
                            graph.add_edge(pred, v_new)
                        for succ in graph.successors(s):
                            graph.add_edge(v_new, succ)
                        graph.remove_vertices([v,s])
                    return (True, graph)

        return (False, graph)

    rules = [t_trivial, t_ifelse, t_cons, t_if, t_while]

    i = dropwhile(lambda (x, y): not x, map(flip(graph), rules))
    try:
        true, graph = i.next()
        graph.export(graphfile, 'step', random=True)
        return graph_transform(graph)
    except StopIteration:
        if graphfile:
            graph.export(graphfile, 'transformed')
        return graph
<commit_msg>Added check for graph file.<commit_after>from collections import defaultdict
from itertools import dropwhile, permutations

graphfile = None

class Graph:
    def __init__(self):
        self._pred = defaultdict(list)
        self._succ = defaultdict(list)
        self._vertices = {}

    def __str__(self):
        return 'Graph(vertices=' + str(self._vertices) + ', pred=' + str(self._pred) + ', succ=' + str(self._succ) + ')'

    def __contains__(self, (v, t)):
        if t == 'in':
            return (v in self._pred)
        if t == 'out':
            return (v in self._succ)
        if t == None:
            return (v in self._pred or v in self._succ)

    def successors(self, key):
        return self._succ[key]

    def predecessors(self, key):
        return self._pred[key]

    def vertex(self, k):
        return self._vertices[k]

    def set_vertex(self, k, v=None):
        self._vertices[k] = v

    def remove_vertices(self, ks):
        for k in ks:
            for p in self._pred[k]:
                self._succ[p].remove(k)
            for s in self._succ[k]:
                self._pred[s].remove(k)
            del self._pred[k]
            del self._succ[k]
            del self._vertices[k]

    def vertices(self):
        return self._vertices

    def deg_in(self, k):
        return len(self._pred[k])

    def deg_out(self, k):
        return len(self._succ[k])

    def add_edge(self, v_in, v_out):
        self._succ[v_in].append(v_out)
        self._pred[v_out].append(v_in)

    def remove_edge(self, v_in, v_out):
        self._succ[v_in].remove(v_out)
        self._pred[v_out].remove(v_in)

    def export(self, f, name, random=False):
        def block_label(block_type, block_loc, block):
            if block_type == 'block':
                return "block\\n{0:x}:{1:x}".format(block_loc, block[-1]['loc'])
            else:
                return "{0}\\n{1:x}".format(block_type, block_loc)

        if random:
            import random
            name += '_'+''.join(random.sample('0123456789abcdef', 8))

        f.write("\tsubgraph {0} {{\n".format(name))

        entries = filter(lambda k: self.deg_in(k) == 0, self.vertices())

        f.write("\t\t{0}_entry [label=\"{0}\"];\n".format(name))
        for e_type, e_loc in entries:
            f.write("\t\t{0}_entry -> {0}_{1}_{2:x};\n".format(name, e_type, e_loc))

        for (block_type, block_loc), block in self.vertices().iteritems():
            f.write("\t\t{0}_{1}_{2:x} [label=\"{3}\"];\n".format(name, block_type, block_loc, block_label(block_type, block_loc, block)))
            for v_type, v_out in self.successors((block_type, block_loc)):
                f.write("\t\t{0}_{1}_{2:x} -> {0}_{3}_{4:x};\n".format(name, block_type, block_loc, v_type, v_out))
        f.write("\t}\n")

def control_flow_graph(function, labels, name):
    '''
    Analyze the control flow graph (cfg) of the function
    '''

    graph = Graph()
    block_acc = []
    block_cur = None
    block_last = None
    block_change = True
    pass_through = False
    for ins in function:
        if ins['loc'] in labels or block_change:
            if block_last is not None:
                graph.set_vertex(block_last, block_acc)
            block_cur = ('block', ins['loc'])
            block_acc = []
            graph.set_vertex(block_cur)

        if ins['loc'] in labels and pass_through:
            # pass-through edge
            graph.add_edge(block_last, ('block', ins['loc']))

        block_change = False
        pass_through = True

        if ins['ins'][0][0] == 'j': # jumps (and only jumps)
            loc_next = ins['loc']+ins['length']
            loc_j = loc_next+int(ins['ins'][1], 16)
            graph.add_edge(block_cur, ('block', loc_j))
            block_change = True
            if ins['ins'][0] != 'jmp':
                graph.add_edge(block_cur, ('block', loc_next))
            else:
                pass_through = False
        block_last = block_cur
        block_acc.append(ins)

    graph.set_vertex(block_last, block_acc)

    if graphfile:
        graph.export(graphfile, name)

    return graph_transform(graph)

def flip(x):
    '''
    flip(x)(f) = f(x)
    '''
    def f(g):
        return g(x)
    return f

def graph_transform(graph):
    '''
    Perform one step transformations of the graph according to
     preset rules until no more transformations can be performed.

    The rewriting system used here is decreasing (i.e. all transformations
     decrease the size of the graph), because every transformation rule is
     guaranteed to be decreasing, therefore it is total (it will always stop
     at some point.

    Transformation rules are functions of the type

      Graph -> (Boolean, Graph)

    The boolean value signifies whether the transformation condition was
     satisfied and the transformation was applied successfully.

    If no further transformation can be performed, the process is stopped
     and the resulting graph is returned.
    '''
    def t_trivial(graph):
        return False, graph

    def t_while(graph):
        for v in graph.vertices():
            if graph.deg_out(v) == 2:
                succs = graph.successors(v)
                for s1, s2 in permutations(succs):
                    if graph.deg_out(s1) == 1 and graph.deg_in(s1) == 1 and v in graph.successors(s1):
                        v_type, v_start = v
                        v_new = ('while', v_start)
                        condition = 'cmp'
                        v_new_value = (condition, (v, graph.vertex(v)), (s1, graph.vertex(s1)))
                        graph.set_vertex(v_new, v_new_value)
                        for pred in graph.predecessors(v):
                            graph.add_edge(pred, v_new)
                        graph.add_edge(v_new, s2)
                        graph.remove_vertices([v,s1])

                        return (True, graph)

        return (False, graph)

    def t_if(graph):
        for v in graph.vertices():
            if graph.deg_out(v) == 2:
                succs = graph.successors(v)
                for s1, s2 in permutations(succs):
                    if graph.deg_out(s1) == 1:
                        s1_succ = graph.successors(s1)[0]
                        if s1_succ == s2:
                            s1_type, s1_start = s1
                            v_new = ('if', s1_start)
                            condition = 'cmp'
                            v_new_value = (condition, (s1, graph.vertex(s1)))
                            graph.set_vertex(v_new, v_new_value)
                            graph.add_edge(v, v_new)
                            graph.add_edge(v_new, s2)
                            graph.remove_edge(v, s2)
                            graph.remove_vertices([s1])
                            return (True, graph)

        return (False, graph)

    def t_ifelse(graph):
        for v in graph.vertices():
            succs = graph.successors(v)
            if len(succs) == 2:
                s, t = succs
                s_s, t_s = map(graph.successors, succs)
                s_p, t_p = map(graph.predecessors, succs)
                if map(len, [s_s, t_s, s_p, t_p]) == [1]*4 and s_s == t_s:
                    s_type, s_start = s
                    v_new = ('ifelse', s_start)
                    condition = 'cmp' # change that
                    # modify v
                    v_new_value = (condition,
                        (s, graph.vertex(s)), (t, graph.vertex(t)))
                    graph.set_vertex(v_new, v_new_value)
                    graph.add_edge(v_new, s_s[0])
                    graph.add_edge(v, v_new)
                    graph.remove_vertices([s, t])
                    return (True, graph)

        return (False, graph)

    def t_cons(graph):
        for v in graph.vertices():
            if graph.deg_out(v) == 1:
                s = graph.successors(v)[0]
                if graph.deg_in(s) == 1 and v != s:
                    v_type, v_start = v
                    s_type, s_start = s
                    if v_type == 'cons':
                        graph.vertex(v).append((s, graph.vertex(s)))
                        #graph.set_vertex(v, v_value)
                        for succ in graph.successors(s):
                            graph.add_edge(v, succ)
                        graph.remove_vertices([s])
                    else:
                        v_new = ('cons', v_start)
                        v_new_value = [(v, graph.vertex(v)), (s, graph.vertex(s))]
                        graph.set_vertex(v_new, v_new_value)
                        for pred in graph.predecessors(v):
                            graph.add_edge(pred, v_new)
                        for succ in graph.successors(s):
                            graph.add_edge(v_new, succ)
                        graph.remove_vertices([v,s])
                    return (True, graph)

        return (False, graph)

    rules = [t_trivial, t_ifelse, t_cons, t_if, t_while]

    i = dropwhile(lambda (x, y): not x, map(flip(graph), rules))
    try:
        true, graph = i.next()
        if graphfile:
            graph.export(graphfile, 'step', random=True)
        return graph_transform(graph)
    except StopIteration:
        if graphfile:
            graph.export(graphfile, 'transformed')
        return graph
<|endoftext|>


<commit_before>import unittest
from unittest import mock

from flumine.markets.blotter import Blotter, OrderPackageType
from flumine.order.order import OrderStatus
from flumine.order.ordertype import MarketOnCloseOrder, LimitOrder

class BlotterTest(unittest.TestCase):
    def setUp(self) -> None:
        self.blotter = Blotter("1.23")

    def test_init(self):
        self.assertEqual(self.blotter.market_id, "1.23")
        self.assertEqual(self.blotter._orders, {})
        self.assertEqual(self.blotter.pending_place, [])
        self.assertEqual(self.blotter.pending_cancel, [])
        self.assertEqual(self.blotter.pending_update, [])
        self.assertEqual(self.blotter.pending_replace, [])
        self.assertEqual(self.blotter._live_orders, [])

    def test_strategy_orders(self):
        mock_order = mock.Mock()
        mock_order.trade.strategy = 69
        self.blotter._orders = {"12345": mock_order}
        self.assertEqual(self.blotter.strategy_orders(12), [])
        self.assertEqual(self.blotter.strategy_orders(69), [mock_order])

    @mock.patch("flumine.markets.blotter.Blotter._create_packages")
    def test_process_orders(self, mock__create_packages):
        mock_client = mock.Mock()
        self.blotter.pending_place = [1]
        self.assertEqual(
            self.blotter.process_orders(mock_client), mock__create_packages().__radd__()
        )
        self.blotter.pending_place = []
        self.blotter.pending_cancel = [2]
        self.assertEqual(
            self.blotter.process_orders(mock_client), mock__create_packages().__radd__()
        )
        self.blotter.pending_cancel = []
        self.blotter.pending_update = [3]
        self.assertEqual(
            self.blotter.process_orders(mock_client), mock__create_packages().__radd__()
        )
        self.blotter.pending_update = []
        self.blotter.pending_replace = [4]
        self.assertEqual(
            self.blotter.process_orders(mock_client), mock__create_packages().__radd__()
        )

    @mock.patch("flumine.markets.blotter.BetfairOrderPackage")
    def test___create_packages(self, mock_cls):
        mock_client = mock.Mock()
        mock_order = mock.Mock()
        mock_orders = [mock_order]
        packages = self.blotter._create_packages(
            mock_client, mock_orders, OrderPackageType.PLACE, 0
        )
        self.assertEqual(
            packages,
            [
                mock_cls(
                    client=None,
                    market_id=self.blotter.market_id,
                    orders=mock_orders,
                    package_type=OrderPackageType.PLACE,
                    bet_delay=0,
                )
            ],
        )
        self.assertEqual(mock_orders, [])

    def test_live_orders(self):
        self.assertEqual(list(self.blotter.live_orders), [])
        mock_order = mock.Mock(complete=False)
        self.blotter._live_orders = [mock_order]
        self.assertEqual(list(self.blotter.live_orders), [mock_order])

    def test_has_live_orders(self):
        self.assertFalse(self.blotter.has_live_orders)
        self.blotter._live_orders = [mock.Mock()]
        self.assertTrue(self.blotter.has_live_orders)

    def test_process_closed_market(self):
        mock_market_book = mock.Mock()
        mock_runner = mock.Mock(selection_id=123, handicap=0.0)
        mock_market_book.runners = [mock_runner]
        mock_order = mock.Mock(selection_id=123, handicap=0.0)
        self.blotter._orders = {"12345": mock_order}
        self.blotter.process_closed_market(mock_market_book)
        self.assertEqual(mock_order.runner_status, mock_runner.status)

    def test_process_cleared_orders(self):
        mock_cleared_orders = mock.Mock()
        self.assertEqual(self.blotter.process_cleared_orders(mock_cleared_orders), [])

    def test_selection_exposure(self):
        mock_strategy = mock.Mock()
        mock_trade = mock.Mock(strategy=mock_strategy)
        mock_order = mock.Mock(
            trade=mock_trade,
            lookup=(self.blotter.market_id, 123, 0),
            side="BACK",
            average_price_matched=5.6,
            size_matched=2.0,
            size_remaining=0.0,
            order_type=LimitOrder(price=5.6, size=2.0),
        )
        self.blotter._orders = {"12345": mock_order}
        self.assertEqual(
            self.blotter.selection_exposure(mock_strategy, mock_order.lookup),
            2.0,
        )

    def test_selection_exposure_with_price_none(self):
        """
        Check that selection_exposure works if order.order_type.price is None.
        If order.order_type.price is None, the controls will flag the order as a violation
        and it won't be set to the exchange, so there won't be any exposure and we can ignore it.
        :return:
        """
        mock_strategy = mock.Mock()
        mock_trade = mock.Mock(strategy=mock_strategy)
        lookup = (self.blotter.market_id, 123, 0)
        mock_order1 = mock.Mock(
            trade=mock_trade,
            lookup=lookup,
            side="BACK",
            average_price_matched=5.6,
            size_matched=2.0,
            size_remaining=0.0,
            order_type=LimitOrder(price=5.6, size=2.0),
        )
        mock_order2 = mock.Mock(
            trade=mock_trade,
            lookup=lookup,
            side="LAY",
            average_price_matched=5.6,
            size_matched=0.0,
            size_remaining=2.0,
            order_type=LimitOrder(price=None, size=2.0),
        )
        self.blotter._orders = {"12345": mock_order1, "23456": mock_order2}
        self.assertEqual(
            self.blotter.selection_exposure(mock_strategy, lookup),
            2.0,
        )

    def test_selection_exposure_no_match(self):
        mock_strategy = mock.Mock()
        mock_trade = mock.Mock(strategy=mock_strategy)
        mock_order = mock.Mock(
            trade=mock_trade,
            lookup=(self.blotter.market_id, 123, 0),
            side="BACK",
            average_price_matched=5.6,
            size_matched=0.0,
            size_remaining=0.0,
            order_type=LimitOrder(price=5.6, size=2.0),
        )
        self.blotter._orders = {"12345": mock_order}
        self.assertEqual(
            self.blotter.selection_exposure(mock_strategy, mock_order.lookup),
            0.0,
        )

    def test_selection_exposure_from_unmatched_back(self):
        mock_strategy = mock.Mock()
        mock_trade = mock.Mock(strategy=mock_strategy)
        mock_order = mock.Mock(
            trade=mock_trade,
            lookup=(self.blotter.market_id, 123, 0),
            side="BACK",
            average_price_matched=5.6,
            size_matched=2.0,
            size_remaining=2.0,
            order_type=LimitOrder(price=6, size=4.0),
        )
        self.blotter._orders = {"12345": mock_order}
        # On the win side, we have 2.0 * (5.6-1.0) = 9.2
        # On the lose side, we have -2.0-2.0=-4.0
        self.assertEqual(
            self.blotter.selection_exposure(mock_strategy, mock_order.lookup),
            4.0,
        )

    def test_selection_exposure_from_unmatched_lay(self):
        mock_strategy = mock.Mock()
        mock_trade = mock.Mock(strategy=mock_strategy)
        mock_order = mock.Mock(
            trade=mock_trade,
            lookup=(self.blotter.market_id, 123, 0),
            side="LAY",
            average_price_matched=5.6,
            size_matched=2.0,
            size_remaining=2.0,
            order_type=LimitOrder(price=6, size=4.0),
        )
        self.blotter._orders = {"12345": mock_order}
        # On the win side, we have -2.0 * (5.6-1.0) -2.0 * (6.0-1.0) = -19.2
        # On the lose side, we have 2.0 from size_matched
        self.assertEqual(
            self.blotter.selection_exposure(mock_strategy, mock_order.lookup),
            19.2,
        )

    def test_selection_exposure_from_market_on_close_back(self):
        mock_strategy = mock.Mock()
        mock_trade = mock.Mock(strategy=mock_strategy)
        mock_order = mock.Mock(
            trade=mock_trade,
            lookup=(self.blotter.market_id, 123, 0),
            side="BACK",
            order_type=MarketOnCloseOrder(liability=10.0),
        )
        self.blotter._orders = {"12345": mock_order}
        self.assertEqual(
            self.blotter.selection_exposure(mock_strategy, mock_order.lookup),
            10.0,
        )

    def test_selection_exposure_from_market_on_close_lay(self):
        mock_strategy = mock.Mock()
        mock_trade = mock.Mock(strategy=mock_strategy)
        mock_order = mock.Mock(
            trade=mock_trade,
            lookup=(self.blotter.market_id, 123, 0),
            side="LAY",
            order_type=MarketOnCloseOrder(liability=10.0),
        )
        self.blotter._orders = {"12345": mock_order}
        self.assertEqual(
            self.blotter.selection_exposure(mock_strategy, mock_order.lookup),
            10.0,
        )

    def test_complete_order(self):
        self.blotter._live_orders = ["test"]
        self.blotter.complete_order("test")

    def test__contains(self):
        self.blotter._orders = {"123": "test"}
        self.assertIn("123", self.blotter)
        self.assertNotIn("321", self.blotter)

    def test__setitem(self):
        self.blotter["123"] = "test"
        self.assertEqual(self.blotter._orders, {"123": "test"})
        self.assertEqual(self.blotter._live_orders, ["test"])

    def test__getitem(self):
        self.blotter._orders = {"12345": "test", "54321": "test2"}
        self.assertEqual(self.blotter["12345"], "test")
        self.assertEqual(self.blotter["54321"], "test2")

    def test__len(self):
        self.blotter._orders = {"12345": "test", "54321": "test"}
        self.assertEqual(len(self.blotter), 2)
<commit_msg>Removing unused import<commit_after>import unittest
from unittest import mock

from flumine.markets.blotter import Blotter, OrderPackageType
from flumine.order.ordertype import MarketOnCloseOrder, LimitOrder

class BlotterTest(unittest.TestCase):
    def setUp(self) -> None:
        self.blotter = Blotter("1.23")

    def test_init(self):
        self.assertEqual(self.blotter.market_id, "1.23")
        self.assertEqual(self.blotter._orders, {})
        self.assertEqual(self.blotter.pending_place, [])
        self.assertEqual(self.blotter.pending_cancel, [])
        self.assertEqual(self.blotter.pending_update, [])
        self.assertEqual(self.blotter.pending_replace, [])
        self.assertEqual(self.blotter._live_orders, [])

    def test_strategy_orders(self):
        mock_order = mock.Mock()
        mock_order.trade.strategy = 69
        self.blotter._orders = {"12345": mock_order}
        self.assertEqual(self.blotter.strategy_orders(12), [])
        self.assertEqual(self.blotter.strategy_orders(69), [mock_order])

    @mock.patch("flumine.markets.blotter.Blotter._create_packages")
    def test_process_orders(self, mock__create_packages):
        mock_client = mock.Mock()
        self.blotter.pending_place = [1]
        self.assertEqual(
            self.blotter.process_orders(mock_client), mock__create_packages().__radd__()
        )
        self.blotter.pending_place = []
        self.blotter.pending_cancel = [2]
        self.assertEqual(
            self.blotter.process_orders(mock_client), mock__create_packages().__radd__()
        )
        self.blotter.pending_cancel = []
        self.blotter.pending_update = [3]
        self.assertEqual(
            self.blotter.process_orders(mock_client), mock__create_packages().__radd__()
        )
        self.blotter.pending_update = []
        self.blotter.pending_replace = [4]
        self.assertEqual(
            self.blotter.process_orders(mock_client), mock__create_packages().__radd__()
        )

    @mock.patch("flumine.markets.blotter.BetfairOrderPackage")
    def test___create_packages(self, mock_cls):
        mock_client = mock.Mock()
        mock_order = mock.Mock()
        mock_orders = [mock_order]
        packages = self.blotter._create_packages(
            mock_client, mock_orders, OrderPackageType.PLACE, 0
        )
        self.assertEqual(
            packages,
            [
                mock_cls(
                    client=None,
                    market_id=self.blotter.market_id,
                    orders=mock_orders,
                    package_type=OrderPackageType.PLACE,
                    bet_delay=0,
                )
            ],
        )
        self.assertEqual(mock_orders, [])

    def test_live_orders(self):
        self.assertEqual(list(self.blotter.live_orders), [])
        mock_order = mock.Mock(complete=False)
        self.blotter._live_orders = [mock_order]
        self.assertEqual(list(self.blotter.live_orders), [mock_order])

    def test_has_live_orders(self):
        self.assertFalse(self.blotter.has_live_orders)
        self.blotter._live_orders = [mock.Mock()]
        self.assertTrue(self.blotter.has_live_orders)

    def test_process_closed_market(self):
        mock_market_book = mock.Mock()
        mock_runner = mock.Mock(selection_id=123, handicap=0.0)
        mock_market_book.runners = [mock_runner]
        mock_order = mock.Mock(selection_id=123, handicap=0.0)
        self.blotter._orders = {"12345": mock_order}
        self.blotter.process_closed_market(mock_market_book)
        self.assertEqual(mock_order.runner_status, mock_runner.status)

    def test_process_cleared_orders(self):
        mock_cleared_orders = mock.Mock()
        self.assertEqual(self.blotter.process_cleared_orders(mock_cleared_orders), [])

    def test_selection_exposure(self):
        mock_strategy = mock.Mock()
        mock_trade = mock.Mock(strategy=mock_strategy)
        mock_order = mock.Mock(
            trade=mock_trade,
            lookup=(self.blotter.market_id, 123, 0),
            side="BACK",
            average_price_matched=5.6,
            size_matched=2.0,
            size_remaining=0.0,
            order_type=LimitOrder(price=5.6, size=2.0),
        )
        self.blotter._orders = {"12345": mock_order}
        self.assertEqual(
            self.blotter.selection_exposure(mock_strategy, mock_order.lookup),
            2.0,
        )

    def test_selection_exposure_with_price_none(self):
        """
        Check that selection_exposure works if order.order_type.price is None.
        If order.order_type.price is None, the controls will flag the order as a violation
        and it won't be set to the exchange, so there won't be any exposure and we can ignore it.
        :return:
        """
        mock_strategy = mock.Mock()
        mock_trade = mock.Mock(strategy=mock_strategy)
        lookup = (self.blotter.market_id, 123, 0)
        mock_order1 = mock.Mock(
            trade=mock_trade,
            lookup=lookup,
            side="BACK",
            average_price_matched=5.6,
            size_matched=2.0,
            size_remaining=0.0,
            order_type=LimitOrder(price=5.6, size=2.0),
        )
        mock_order2 = mock.Mock(
            trade=mock_trade,
            lookup=lookup,
            side="LAY",
            average_price_matched=5.6,
            size_matched=0.0,
            size_remaining=2.0,
            order_type=LimitOrder(price=None, size=2.0),
        )
        self.blotter._orders = {"12345": mock_order1, "23456": mock_order2}
        self.assertEqual(
            self.blotter.selection_exposure(mock_strategy, lookup),
            2.0,
        )

    def test_selection_exposure_no_match(self):
        mock_strategy = mock.Mock()
        mock_trade = mock.Mock(strategy=mock_strategy)
        mock_order = mock.Mock(
            trade=mock_trade,
            lookup=(self.blotter.market_id, 123, 0),
            side="BACK",
            average_price_matched=5.6,
            size_matched=0.0,
            size_remaining=0.0,
            order_type=LimitOrder(price=5.6, size=2.0),
        )
        self.blotter._orders = {"12345": mock_order}
        self.assertEqual(
            self.blotter.selection_exposure(mock_strategy, mock_order.lookup),
            0.0,
        )

    def test_selection_exposure_from_unmatched_back(self):
        mock_strategy = mock.Mock()
        mock_trade = mock.Mock(strategy=mock_strategy)
        mock_order = mock.Mock(
            trade=mock_trade,
            lookup=(self.blotter.market_id, 123, 0),
            side="BACK",
            average_price_matched=5.6,
            size_matched=2.0,
            size_remaining=2.0,
            order_type=LimitOrder(price=6, size=4.0),
        )
        self.blotter._orders = {"12345": mock_order}
        # On the win side, we have 2.0 * (5.6-1.0) = 9.2
        # On the lose side, we have -2.0-2.0=-4.0
        self.assertEqual(
            self.blotter.selection_exposure(mock_strategy, mock_order.lookup),
            4.0,
        )

    def test_selection_exposure_from_unmatched_lay(self):
        mock_strategy = mock.Mock()
        mock_trade = mock.Mock(strategy=mock_strategy)
        mock_order = mock.Mock(
            trade=mock_trade,
            lookup=(self.blotter.market_id, 123, 0),
            side="LAY",
            average_price_matched=5.6,
            size_matched=2.0,
            size_remaining=2.0,
            order_type=LimitOrder(price=6, size=4.0),
        )
        self.blotter._orders = {"12345": mock_order}
        # On the win side, we have -2.0 * (5.6-1.0) -2.0 * (6.0-1.0) = -19.2
        # On the lose side, we have 2.0 from size_matched
        self.assertEqual(
            self.blotter.selection_exposure(mock_strategy, mock_order.lookup),
            19.2,
        )

    def test_selection_exposure_from_market_on_close_back(self):
        mock_strategy = mock.Mock()
        mock_trade = mock.Mock(strategy=mock_strategy)
        mock_order = mock.Mock(
            trade=mock_trade,
            lookup=(self.blotter.market_id, 123, 0),
            side="BACK",
            order_type=MarketOnCloseOrder(liability=10.0),
        )
        self.blotter._orders = {"12345": mock_order}
        self.assertEqual(
            self.blotter.selection_exposure(mock_strategy, mock_order.lookup),
            10.0,
        )

    def test_selection_exposure_from_market_on_close_lay(self):
        mock_strategy = mock.Mock()
        mock_trade = mock.Mock(strategy=mock_strategy)
        mock_order = mock.Mock(
            trade=mock_trade,
            lookup=(self.blotter.market_id, 123, 0),
            side="LAY",
            order_type=MarketOnCloseOrder(liability=10.0),
        )
        self.blotter._orders = {"12345": mock_order}
        self.assertEqual(
            self.blotter.selection_exposure(mock_strategy, mock_order.lookup),
            10.0,
        )

    def test_complete_order(self):
        self.blotter._live_orders = ["test"]
        self.blotter.complete_order("test")

    def test__contains(self):
        self.blotter._orders = {"123": "test"}
        self.assertIn("123", self.blotter)
        self.assertNotIn("321", self.blotter)

    def test__setitem(self):
        self.blotter["123"] = "test"
        self.assertEqual(self.blotter._orders, {"123": "test"})
        self.assertEqual(self.blotter._live_orders, ["test"])

    def test__getitem(self):
        self.blotter._orders = {"12345": "test", "54321": "test2"}
        self.assertEqual(self.blotter["12345"], "test")
        self.assertEqual(self.blotter["54321"], "test2")

    def test__len(self):
        self.blotter._orders = {"12345": "test", "54321": "test"}
        self.assertEqual(len(self.blotter), 2)
<|endoftext|>