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

"""Views for Clubs.
"""

__authors__ = [
    '"Sverre Rabbelier" <sverre@rabbelier.nl>',
    '"Lennard de Rijk" <ljvderijk@gmail.com>',
  ]

from google.appengine.api import users

from django import http
from django import forms

from soc.logic import dicts
from soc.logic.models import user as user_logic
from soc.logic.models import club_app as club_app_logic
from soc.logic.models import club as club_logic
from soc.views import out_of_band
from soc.views.helper import access
from soc.views.helper import decorators
from soc.views.helper import dynaform
from soc.views.helper import responses
from soc.views.helper import widgets
from soc.views.models import base

import soc.logic.models.club
import soc.views.helper

class View(base.View):
  """View methods for the Club model.
  """

  def __init__(self, params=None):
    """Defines the fields and methods required for the base View class
    to provide the user with list, public, create, edit and delete views.

    Params:
      params: a dict with params for this View
    """

    rights = {}
    rights['create'] = [access.checkIsHost]
    rights['edit'] = [access.checkIsClubAdminForClub]
    rights['delete'] = [access.checkIsHost]
    rights['list'] = [access.checkIsHost]
    rights['applicant'] = [access.checkIsApplicationAccepted(club_app_logic)]

    new_params = {}
    new_params['logic'] = soc.logic.models.club.logic
    new_params['rights'] = rights
    new_params['name'] = "Club"

    patterns = []

    page_name = "Club Creation via Accepted Application"
    patterns += [(r'^%(url_name)s/(?P<access_type>applicant)/%(key_fields)s$',
                  'soc.views.models.%(module_name)s.applicant', page_name)]

    new_params['extra_django_patterns'] = patterns

    new_params['extra_dynaexclude'] = ['founder', 'home']
    new_params['edit_extra_dynafields'] = {
        'founded_by': forms.CharField(widget=widgets.ReadOnlyInput(),
                                   required=False),
        }

    params = dicts.merge(params, new_params)

    super(View, self).__init__(params=params)

    # create and store the special form for applicants
    updated_fields = {
        'link_id': forms.CharField(widget=widgets.ReadOnlyInput(),
            required=False)}

    applicant_create_form = dynaform.extendDynaForm(
        dynaform = self._params['create_form'],
        dynafields = updated_fields)

    params['applicant_create_form'] = applicant_create_form

  @decorators.merge_params
  @decorators.check_access
  def applicant(self, request, access_type,
                page_name=None, params=None, **kwargs):
    """Handles the creation of a club via an approved club application.

    Args:
      request: the standard Django HTTP request object
      page_name: the page name displayed in templates as page and header title
      params: a dict with params for this View
      kwargs: the Key Fields for the specified entity
    """

    # get the context for this webpage
    context = responses.getUniversalContext(request)
    context['page_name'] = page_name

    if request.method == 'POST':
      return self.applicantPost(request, context, params, **kwargs)
    else:
      # request.method == 'GET'
      return self.applicantGet(request, context, params, **kwargs)

  def applicantGet(self, request, context, params, **kwargs):
    """Handles the GET request concerning the creation of a club via an
    approved club application.

    Args:
      request: the standard Django HTTP request object
      context: dictionary containing the context for this view
      params: a dict with params for this View
      kwargs: the Key Fields for the specified entity
    """

    # find the application
    key_fields = club_app_logic.logic.getKeyFieldsFromDict(kwargs)
    application = club_app_logic.logic.getFromFields(**key_fields)

    # extract the application fields
    field_names = application.properties().keys()
    fields = dict( [(i, getattr(application, i)) for i in field_names] )

    # create the form using the fields from the application as the initial value
    form = params['applicant_create_form'](initial=fields)

    # construct the appropriate response
    return super(View, self)._constructResponse(request, entity=None,
        context=context, form=form, params=params)

  def applicantPost(self, request, context, params, **kwargs):
    """Handles the POST request concerning the creation of a club via an
    approved club application.

    Args:
      request: the standard Django HTTP request object
      context: dictionary containing the context for this view
      params: a dict with params for this View
      kwargs: the Key Fields for the specified entity
    """

    # populate the form using the POST data
    form = params['applicant_create_form'](request.POST)

    if not form.is_valid():
      # return the invalid form response
      return self._constructResponse(request, entity=None, context=context,
          form=form, params=params)

    # collect the cleaned data from the valid form
    key_name, fields = soc.views.helper.forms.collectCleanedFields(form)

    # fill in the founder of the club
    account = users.get_current_user()
    user = user_logic.logic.getForFields({'account': account}, unique=True)
    fields['founder'] = user

    if not key_name:
      key_fields =  self._logic.getKeyFieldsFromDict(fields)
      key_name = self._logic.getKeyNameForFields(key_fields)

    # create the club entity
    entity = self._logic.updateOrCreateFromKeyName(fields, key_name)

    # redirect to notifications list to see the admin invite
    return http.HttpResponseRedirect('/notification/list')

  def _editGet(self, request, entity, form):
    """See base.View._editGet().
    """

    # fill in the founded_by with data from the entity
    form.fields['founded_by'].initial = entity.founder.name
    super(View, self)._editGet(request, entity, form)

  def _editPost(self, request, entity, fields):
    """See base.View._editPost().
    """

    if not entity:
      # only if we are creating a new entity we should fill in founder
      account = users.get_current_user()
      user = user_logic.logic.getForFields({'account': account}, unique=True)
      fields['founder'] = user

    super(View, self)._editPost(request, entity, fields)

view = View()

applicant = view.applicant
create = view.create
delete = view.delete
edit = view.edit
list = view.list
public = view.public
export = view.export

<commit_msg>Added missing comment to soc/views/models/club.py.<commit_after>#!/usr/bin/python2.5
#
# Copyright 2008 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.

"""Views for Clubs.
"""

__authors__ = [
    '"Sverre Rabbelier" <sverre@rabbelier.nl>',
    '"Lennard de Rijk" <ljvderijk@gmail.com>',
  ]

from google.appengine.api import users

from django import http
from django import forms

from soc.logic import dicts
from soc.logic.models import user as user_logic
from soc.logic.models import club_app as club_app_logic
from soc.logic.models import club as club_logic
from soc.views import out_of_band
from soc.views.helper import access
from soc.views.helper import decorators
from soc.views.helper import dynaform
from soc.views.helper import responses
from soc.views.helper import widgets
from soc.views.models import base

import soc.logic.models.club
import soc.views.helper

class View(base.View):
  """View methods for the Club model.
  """

  def __init__(self, params=None):
    """Defines the fields and methods required for the base View class
    to provide the user with list, public, create, edit and delete views.

    Params:
      params: a dict with params for this View
    """

    rights = {}
    rights['create'] = [access.checkIsHost]
    rights['edit'] = [access.checkIsClubAdminForClub]
    rights['delete'] = [access.checkIsHost]
    rights['list'] = [access.checkIsHost]
    rights['applicant'] = [access.checkIsApplicationAccepted(club_app_logic)]

    new_params = {}
    new_params['logic'] = soc.logic.models.club.logic
    new_params['rights'] = rights
    new_params['name'] = "Club"

    patterns = []

    page_name = "Club Creation via Accepted Application"
    patterns += [(r'^%(url_name)s/(?P<access_type>applicant)/%(key_fields)s$',
                  'soc.views.models.%(module_name)s.applicant', page_name)]

    new_params['extra_django_patterns'] = patterns

    new_params['extra_dynaexclude'] = ['founder', 'home']
    new_params['edit_extra_dynafields'] = {
        'founded_by': forms.CharField(widget=widgets.ReadOnlyInput(),
                                   required=False),
        }

    params = dicts.merge(params, new_params)

    super(View, self).__init__(params=params)

    # create and store the special form for applicants
    updated_fields = {
        'link_id': forms.CharField(widget=widgets.ReadOnlyInput(),
            required=False)}

    applicant_create_form = dynaform.extendDynaForm(
        dynaform = self._params['create_form'],
        dynafields = updated_fields)

    params['applicant_create_form'] = applicant_create_form

  @decorators.merge_params
  @decorators.check_access
  def applicant(self, request, access_type,
                page_name=None, params=None, **kwargs):
    """Handles the creation of a club via an approved club application.

    Args:
      request: the standard Django HTTP request object
      access_type : the name of the access type which should be checked
      page_name: the page name displayed in templates as page and header title
      params: a dict with params for this View
      kwargs: the Key Fields for the specified entity
    """

    # get the context for this webpage
    context = responses.getUniversalContext(request)
    context['page_name'] = page_name

    if request.method == 'POST':
      return self.applicantPost(request, context, params, **kwargs)
    else:
      # request.method == 'GET'
      return self.applicantGet(request, context, params, **kwargs)

  def applicantGet(self, request, context, params, **kwargs):
    """Handles the GET request concerning the creation of a club via an
    approved club application.

    Args:
      request: the standard Django HTTP request object
      context: dictionary containing the context for this view
      params: a dict with params for this View
      kwargs: the Key Fields for the specified entity
    """

    # find the application
    key_fields = club_app_logic.logic.getKeyFieldsFromDict(kwargs)
    application = club_app_logic.logic.getFromFields(**key_fields)

    # extract the application fields
    field_names = application.properties().keys()
    fields = dict( [(i, getattr(application, i)) for i in field_names] )

    # create the form using the fields from the application as the initial value
    form = params['applicant_create_form'](initial=fields)

    # construct the appropriate response
    return super(View, self)._constructResponse(request, entity=None,
        context=context, form=form, params=params)

  def applicantPost(self, request, context, params, **kwargs):
    """Handles the POST request concerning the creation of a club via an
    approved club application.

    Args:
      request: the standard Django HTTP request object
      context: dictionary containing the context for this view
      params: a dict with params for this View
      kwargs: the Key Fields for the specified entity
    """

    # populate the form using the POST data
    form = params['applicant_create_form'](request.POST)

    if not form.is_valid():
      # return the invalid form response
      return self._constructResponse(request, entity=None, context=context,
          form=form, params=params)

    # collect the cleaned data from the valid form
    key_name, fields = soc.views.helper.forms.collectCleanedFields(form)

    # fill in the founder of the club
    account = users.get_current_user()
    user = user_logic.logic.getForFields({'account': account}, unique=True)
    fields['founder'] = user

    if not key_name:
      key_fields =  self._logic.getKeyFieldsFromDict(fields)
      key_name = self._logic.getKeyNameForFields(key_fields)

    # create the club entity
    entity = self._logic.updateOrCreateFromKeyName(fields, key_name)

    # redirect to notifications list to see the admin invite
    return http.HttpResponseRedirect('/notification/list')

  def _editGet(self, request, entity, form):
    """See base.View._editGet().
    """

    # fill in the founded_by with data from the entity
    form.fields['founded_by'].initial = entity.founder.name
    super(View, self)._editGet(request, entity, form)

  def _editPost(self, request, entity, fields):
    """See base.View._editPost().
    """

    if not entity:
      # only if we are creating a new entity we should fill in founder
      account = users.get_current_user()
      user = user_logic.logic.getForFields({'account': account}, unique=True)
      fields['founder'] = user

    super(View, self)._editPost(request, entity, fields)

view = View()

applicant = view.applicant
create = view.create
delete = view.delete
edit = view.edit
list = view.list
public = view.public
export = view.export

<|endoftext|>


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

"""Views for Cron.
"""

__authors__ = [
    '"Sverre Rabbelier" <sverre@rabbelier.nl>',
  ]

from django import http

from soc.logic import dicts
from soc.logic.models.priority_group import logic as priority_group_logic
from soc.logic.models.job import logic as job_logic
from soc.views.helper import access
from soc.views.models import base

import soc.cron.job

class View(base.View):
  """View methods for the Cron model.
  """

  def __init__(self, params=None):
    """Defines the fields and methods required for the base View class
    to provide the user with list, public, create, edit and delete views.

    Params:
      params: a dict with params for this View
    """

    rights = access.Checker(params)

    new_params = {}
    new_params['rights'] = rights
    new_params['logic'] = priority_group_logic

    new_params['name'] = "Cron"

    new_params['django_patterns_defaults'] = [
        (r'^%(url_name)s/(?P<access_type>add)$',
          'soc.views.models.%(module_name)s.add', 'Add %(name_short)s'),
        (r'^%(url_name)s/(?P<access_type>poke)$',
          'soc.views.models.%(module_name)s.poke', 'Poke %(name_short)s'),
        ]

    params = dicts.merge(params, new_params)

    super(View, self).__init__(params=params)

  def poke(self, request, access_type, page_name):
    """View called by the cron system that handles jobs.

    Args:
      request: the standard Django HTTP request object
      access_type : the name of the access type which should be checked
      page_name: the page name displayed in templates as page and header title
    """

    order = ['-priority']
    query = priority_group_logic.getQueryForFields(order=order)
    groups = priority_group_logic.getAll(query)
    handler = soc.cron.job.handler

    groups_completed = 0
    jobs_completed = 0

    for group in groups:
      filter = {
          'priority_group': group,
          'status': 'waiting',
          }

      query = job_logic.getQueryForFields(filter=filter)
      jobs = job_logic.getAll(query)

      for job in jobs:
        job_key = job.key().id()
        good = handler.handle(job_key)

        if not good:
          break

        jobs_completed += 1

      groups_completed += 1

    response = 'Completed %d jobs and %d groups completed.' % (
        jobs_completed, groups_completed)

    return http.HttpResponse(response)

view = View()

poke = view.poke
<commit_msg>Remove debug url too<commit_after>#!/usr/bin/python2.5
#
# Copyright 2009 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.

"""Views for Cron.
"""

__authors__ = [
    '"Sverre Rabbelier" <sverre@rabbelier.nl>',
  ]

from django import http

from soc.logic import dicts
from soc.logic.models.priority_group import logic as priority_group_logic
from soc.logic.models.job import logic as job_logic
from soc.views.helper import access
from soc.views.models import base

import soc.cron.job

class View(base.View):
  """View methods for the Cron model.
  """

  def __init__(self, params=None):
    """Defines the fields and methods required for the base View class
    to provide the user with list, public, create, edit and delete views.

    Params:
      params: a dict with params for this View
    """

    rights = access.Checker(params)

    new_params = {}
    new_params['rights'] = rights
    new_params['logic'] = priority_group_logic

    new_params['name'] = "Cron"

    new_params['django_patterns_defaults'] = [
        (r'^%(url_name)s/(?P<access_type>poke)$',
          'soc.views.models.%(module_name)s.poke', 'Poke %(name_short)s'),
        ]

    params = dicts.merge(params, new_params)

    super(View, self).__init__(params=params)

  def poke(self, request, access_type, page_name):
    """View called by the cron system that handles jobs.

    Args:
      request: the standard Django HTTP request object
      access_type : the name of the access type which should be checked
      page_name: the page name displayed in templates as page and header title
    """

    order = ['-priority']
    query = priority_group_logic.getQueryForFields(order=order)
    groups = priority_group_logic.getAll(query)
    handler = soc.cron.job.handler

    groups_completed = 0
    jobs_completed = 0

    for group in groups:
      filter = {
          'priority_group': group,
          'status': 'waiting',
          }

      query = job_logic.getQueryForFields(filter=filter)
      jobs = job_logic.getAll(query)

      for job in jobs:
        job_key = job.key().id()
        good = handler.handle(job_key)

        if not good:
          break

        jobs_completed += 1

      groups_completed += 1

    response = 'Completed %d jobs and %d groups completed.' % (
        jobs_completed, groups_completed)

    return http.HttpResponse(response)

view = View()

poke = view.poke
<|endoftext|>


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

"""Views for Site Settings.
"""

__authors__ = [
    '"Sverre Rabbelier" <sverre@rabbelier.nl>',
  ]

from google.appengine.ext import db
from google.appengine.api import users

from django import forms
from django.utils.translation import ugettext_lazy

from soc.logic import dicts
from soc.logic import validate
from soc.views import helper
from soc.views.helper import widgets
from soc.views.models import presence

import soc.models.site
import soc.logic.models.site
import soc.logic.dicts
import soc.views.helper
import soc.views.helper.widgets

class CreateForm(presence.SettingsValidationForm):
  """Django form displayed when creating or editing Site Settings.
  """

  class Meta:
    """Inner Meta class that defines some behavior for the form.
    """
    #: db.Model subclass for which the form will gather information
    model = soc.models.site.Site

    #: list of model fields which will *not* be gathered by the form
    exclude = ['inheritance_line', 'home', 'scope_path', 'link_id']

  scope_path = forms.CharField(widget=forms.HiddenInput)

  link_id = forms.CharField(widget=forms.HiddenInput)

class EditForm(CreateForm):
  """Django form displayed a Document is edited.
  """

  pass

class View(presence.View):
  """View methods for the Document model.
  """

  def __init__(self, original_params=None):
    """Defines the fields and methods required for the base View class
    to provide the user with list, public, create, edit and delete views.

    Params:
      original_params: a dict with params for this View
    """

    params = {}

    # add ugettext_lazy ?
    params['name'] = "Site Settings"
    params['name_short'] = "Site Settings"
    params['name_plural'] = "Site Settings"
    # lower name and replace " " with "/"
    # for module name lower name and replace " " with "_"
    params['url_name'] = "site/settings"
    params['module_name'] = "site"

    params['edit_form'] = EditForm
    params['create_form'] = CreateForm

    params['lists_template'] = {
      'list_main': 'soc/list/list_main.html',
      'list_pagination': 'soc/list/list_pagination.html',
      'list_row': 'soc/site/list/site_row.html',
      'list_heading': 'soc/site/list/site_heading.html',
    }

    params['delete_redirect'] = '/' + params['url_name'] + '/list'

    params['sidebar_additional'] = [
        ('/' + params['url_name'] + '/edit', 'Edit Main Site Settings')]

    params = dicts.merge(original_params, params)

    presence.View.__init__(self, original_params=params)

    self._logic = soc.logic.models.site.logic

  def main_public(self, request, page_name=None, **kwargs):
    """Displays the main site settings page.

    Args:
      request: the standard Django HTTP request object
      page_name: the page name displayed in templates as page and header title
      kwargs: not used
    """

    keys = self._logic.getKeyFieldNames()
    values = self._logic.getKeyValues()
    key_values = dicts.zip(keys, values)

    return self.public(request, page_name, **key_values)

  def main_edit(self, request, page_name=None, **kwargs):
    """Displays the edit page for the main site settings page.

    Args:
      request: the standard Django HTTP request object
      page_name: the page name displayed in templates as page and header title
      kwargs: not used
    """

    keys = self._logic.getKeyFieldNames()
    values = self._logic.getKeyValues()
    key_values = dicts.zip(keys, values)

    return self.edit(request, page_name, seed=key_values, **key_values)

  def getDjangoURLPatterns(self):
    """See base.View.getDjangoURLPatterns().
    """

    patterns = super(View, self).getDjangoURLPatterns()
    patterns += [(r'^$','soc.views.models.site.main_public')]
    patterns += [(r'^' + self._params['url_name'] + '/edit$',
                  'soc.views.models.site.main_edit')]
    return patterns

view = View()

create = view.create
edit = view.edit
delete = view.delete
list = view.list
public = view.public
main_public = view.main_public
main_edit = view.main_edit
<commit_msg>Add a page name for 'Edit Main Site Settings'<commit_after>#!/usr/bin/python2.5
#
# Copyright 2008 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.

"""Views for Site Settings.
"""

__authors__ = [
    '"Sverre Rabbelier" <sverre@rabbelier.nl>',
  ]

from google.appengine.ext import db
from google.appengine.api import users

from django import forms
from django.utils.translation import ugettext_lazy

from soc.logic import dicts
from soc.logic import validate
from soc.views import helper
from soc.views.helper import widgets
from soc.views.models import presence

import soc.models.site
import soc.logic.models.site
import soc.logic.dicts
import soc.views.helper
import soc.views.helper.widgets

class CreateForm(presence.SettingsValidationForm):
  """Django form displayed when creating or editing Site Settings.
  """

  class Meta:
    """Inner Meta class that defines some behavior for the form.
    """
    #: db.Model subclass for which the form will gather information
    model = soc.models.site.Site

    #: list of model fields which will *not* be gathered by the form
    exclude = ['inheritance_line', 'home', 'scope_path', 'link_id']

  scope_path = forms.CharField(widget=forms.HiddenInput)

  link_id = forms.CharField(widget=forms.HiddenInput)

class EditForm(CreateForm):
  """Django form displayed a Document is edited.
  """

  pass

class View(presence.View):
  """View methods for the Document model.
  """

  def __init__(self, original_params=None):
    """Defines the fields and methods required for the base View class
    to provide the user with list, public, create, edit and delete views.

    Params:
      original_params: a dict with params for this View
    """

    params = {}

    # add ugettext_lazy ?
    params['name'] = "Site Settings"
    params['name_short'] = "Site Settings"
    params['name_plural'] = "Site Settings"
    # lower name and replace " " with "/"
    # for module name lower name and replace " " with "_"
    params['url_name'] = "site/settings"
    params['module_name'] = "site"

    params['edit_form'] = EditForm
    params['create_form'] = CreateForm

    params['lists_template'] = {
      'list_main': 'soc/list/list_main.html',
      'list_pagination': 'soc/list/list_pagination.html',
      'list_row': 'soc/site/list/site_row.html',
      'list_heading': 'soc/site/list/site_heading.html',
    }

    params['delete_redirect'] = '/' + params['url_name'] + '/list'

    params['sidebar_additional'] = [
        ('/' + params['url_name'] + '/edit', 'Edit Main Site Settings')]

    params = dicts.merge(original_params, params)

    presence.View.__init__(self, original_params=params)

    self._logic = soc.logic.models.site.logic

  def main_public(self, request, page_name=None, **kwargs):
    """Displays the main site settings page.

    Args:
      request: the standard Django HTTP request object
      page_name: the page name displayed in templates as page and header title
      kwargs: not used
    """

    keys = self._logic.getKeyFieldNames()
    values = self._logic.getKeyValues()
    key_values = dicts.zip(keys, values)

    return self.public(request, page_name, **key_values)

  def main_edit(self, request, page_name=None, **kwargs):
    """Displays the edit page for the main site settings page.

    Args:
      request: the standard Django HTTP request object
      page_name: the page name displayed in templates as page and header title
      kwargs: not used
    """

    keys = self._logic.getKeyFieldNames()
    values = self._logic.getKeyValues()
    key_values = dicts.zip(keys, values)

    return self.edit(request, page_name, seed=key_values, **key_values)

  def getDjangoURLPatterns(self):
    """See base.View.getDjangoURLPatterns().
    """

    patterns = super(View, self).getDjangoURLPatterns()
    patterns += [(r'^$','soc.views.models.site.main_public')]

    page_name = "Edit Site Settings"
    patterns += [(r'^' + self._params['url_name'] + '/edit$',
                  'soc.views.models.site.main_edit',
                  {'page_name': page_name}, page_name)]
    return patterns

view = View()

create = view.create
edit = view.edit
delete = view.delete
list = view.list
public = view.public
main_public = view.main_public
main_edit = view.main_edit
<|endoftext|>


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

"""Views for Site Settings.
"""

__authors__ = [
    '"Sverre Rabbelier" <sverre@rabbelier.nl>',
  ]

from django import forms
from django.utils.translation import ugettext

from soc.logic import accounts
from soc.logic import dicts
from soc.views.helper import access
from soc.views.helper import redirects
from soc.views.helper import widgets
from soc.views.models import document as document_view
from soc.views.models import presence_with_tos

import soc.models.site
import soc.logic.models.site
import soc.logic.dicts

class View(presence_with_tos.View):
  """View methods for the Document model.
  """

  def __init__(self, params=None):
    """Defines the fields and methods required for the base View class
    to provide the user with list, public, create, edit and delete views.

    Params:
      params: a dict with params for this View
    """

    rights = access.Checker(params)
    rights['unspecified'] = ['checkIsDeveloper']
    rights['any_access'] = ['allow']
    rights['show'] = ['checkIsDeveloper']

    new_params = {}
    new_params['logic'] = soc.logic.models.site.logic
    new_params['rights'] = rights

    new_params['name'] = "Site Settings"
    new_params['name_plural'] = new_params['name']
    new_params['name_short'] = "Site"

    new_params['sidebar_defaults'] = [('/%s/edit', 'Edit %(name)s', 'edit')]
    new_params['sidebar_heading'] = new_params['name_short']

    new_params['edit_template'] = 'soc/site/edit.html'
    new_params['home_template'] = 'soc/site/home.html'

    new_params['create_extra_dynafields'] = {
        'link_id': forms.CharField(widget=forms.HiddenInput, required=True),
        }
    new_params['edit_extra_dynafields'] = {
        'link_id': forms.CharField(widget=forms.HiddenInput, required=True),
        'home_link_id': widgets.ReferenceField(
            reference_url='document',
            required=False, label=ugettext('Home page Document link ID'),
            help_text=soc.models.work.Work.link_id.help_text),
        'tos_link_id': widgets.ReferenceField(
            reference_url='document',
            required=False, label=ugettext('Terms of Service Document link ID'),
            help_text=soc.models.work.Work.link_id.help_text),
        }

    patterns = []

    page_name = "Home Page"
    patterns += [(r'^$', 'soc.views.models.%(module_name)s.main_public',
                  page_name)]

    page_name = "Edit Site"
    patterns += [(r'^%(url_name)s/(?P<access_type>edit)$',
                  'soc.views.models.%(module_name)s.main_edit',
                  page_name)]

    new_params['extra_django_patterns'] = patterns

    params = dicts.merge(params, new_params)

    super(View, self).__init__(params=params)

  def getSidebarMenus(self, id, user, params=None):
    """See base.View.getSidebarMenus.

    Returns a custom sidebar entry for the 'site' singleton.
    """

    entity = self._logic.getSingleton()

    submenus = []

    if entity:
      submenus += document_view.view.getMenusForScope(entity, self._params)
      if accounts.isDeveloper(id, user):
        submenus += [(redirects.getCreateDocumentRedirect(entity, 'site'),
            "Create a New Document", 'any_access')]

    new_params = {}
    new_params['sidebar_additional'] = submenus

    params = dicts.merge(params, new_params)
    return super(View, self).getSidebarMenus(id, user, params=params)

  def mainPublic(self, request, page_name=None, **kwargs):
    """Displays the main site settings page.

    Args:
      request: the standard Django HTTP request object
      page_name: the page name displayed in templates as page and header title
      kwargs: not used
    """

    keys = self._logic.getKeyFieldNames()

    # No entity in this case, since Site key values are hard-coded for the
    # Site singleton, so pass in None to match parent method footprint.
    values = self._logic.getKeyValuesFromEntity(None)
    key_values = dicts.zip(keys, values)

    return self.home(request, "home", page_name=page_name, **key_values)

  def mainEdit(self, request, page_name=None, **kwargs):
    """Displays the edit page for the main site settings page.

    Args:
      request: the standard Django HTTP request object
      page_name: the page name displayed in templates as page and header title
      kwargs: not used
    """

    keys = self._logic.getKeyFieldNames()

    # No entity in this case, since Site key values are hard-coded for the
    # Site singleton, so pass in None to match parent method footprint.
    values = self._logic.getKeyValuesFromEntity(None)
    key_values = dicts.zip(keys, values)

    return self.edit(request, "edit", page_name, seed=key_values, **key_values)

view = View()

create = view.create
edit = view.edit
delete = view.delete
list = view.list
public = view.public
export = view.export
main_public = view.mainPublic
main_edit = view.mainEdit
home = view.home
<commit_msg>If there is no user account, don't show New Document link under Site<commit_after>#!/usr/bin/python2.5
#
# Copyright 2008 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.

"""Views for Site Settings.
"""

__authors__ = [
    '"Sverre Rabbelier" <sverre@rabbelier.nl>',
  ]

from django import forms
from django.utils.translation import ugettext

from soc.logic import accounts
from soc.logic import dicts
from soc.views.helper import access
from soc.views.helper import redirects
from soc.views.helper import widgets
from soc.views.models import document as document_view
from soc.views.models import presence_with_tos

import soc.models.site
import soc.logic.models.site
import soc.logic.dicts

class View(presence_with_tos.View):
  """View methods for the Document model.
  """

  def __init__(self, params=None):
    """Defines the fields and methods required for the base View class
    to provide the user with list, public, create, edit and delete views.

    Params:
      params: a dict with params for this View
    """

    rights = access.Checker(params)
    rights['unspecified'] = ['checkIsDeveloper']
    rights['any_access'] = ['allow']
    rights['show'] = ['checkIsDeveloper']

    new_params = {}
    new_params['logic'] = soc.logic.models.site.logic
    new_params['rights'] = rights

    new_params['name'] = "Site Settings"
    new_params['name_plural'] = new_params['name']
    new_params['name_short'] = "Site"

    new_params['sidebar_defaults'] = [('/%s/edit', 'Edit %(name)s', 'edit')]
    new_params['sidebar_heading'] = new_params['name_short']

    new_params['edit_template'] = 'soc/site/edit.html'
    new_params['home_template'] = 'soc/site/home.html'

    new_params['create_extra_dynafields'] = {
        'link_id': forms.CharField(widget=forms.HiddenInput, required=True),
        }
    new_params['edit_extra_dynafields'] = {
        'link_id': forms.CharField(widget=forms.HiddenInput, required=True),
        'home_link_id': widgets.ReferenceField(
            reference_url='document',
            required=False, label=ugettext('Home page Document link ID'),
            help_text=soc.models.work.Work.link_id.help_text),
        'tos_link_id': widgets.ReferenceField(
            reference_url='document',
            required=False, label=ugettext('Terms of Service Document link ID'),
            help_text=soc.models.work.Work.link_id.help_text),
        }

    patterns = []

    page_name = "Home Page"
    patterns += [(r'^$', 'soc.views.models.%(module_name)s.main_public',
                  page_name)]

    page_name = "Edit Site"
    patterns += [(r'^%(url_name)s/(?P<access_type>edit)$',
                  'soc.views.models.%(module_name)s.main_edit',
                  page_name)]

    new_params['extra_django_patterns'] = patterns

    params = dicts.merge(params, new_params)

    super(View, self).__init__(params=params)

  def getSidebarMenus(self, id, user, params=None):
    """See base.View.getSidebarMenus.

    Returns a custom sidebar entry for the 'site' singleton.
    """

    entity = self._logic.getSingleton()

    submenus = []

    if entity:
      submenus += document_view.view.getMenusForScope(entity, self._params)
      if user and accounts.isDeveloper(id, user):
        submenus += [(redirects.getCreateDocumentRedirect(entity, 'site'),
            "Create a New Document", 'any_access')]

    new_params = {}
    new_params['sidebar_additional'] = submenus

    params = dicts.merge(params, new_params)
    return super(View, self).getSidebarMenus(id, user, params=params)

  def mainPublic(self, request, page_name=None, **kwargs):
    """Displays the main site settings page.

    Args:
      request: the standard Django HTTP request object
      page_name: the page name displayed in templates as page and header title
      kwargs: not used
    """

    keys = self._logic.getKeyFieldNames()

    # No entity in this case, since Site key values are hard-coded for the
    # Site singleton, so pass in None to match parent method footprint.
    values = self._logic.getKeyValuesFromEntity(None)
    key_values = dicts.zip(keys, values)

    return self.home(request, "home", page_name=page_name, **key_values)

  def mainEdit(self, request, page_name=None, **kwargs):
    """Displays the edit page for the main site settings page.

    Args:
      request: the standard Django HTTP request object
      page_name: the page name displayed in templates as page and header title
      kwargs: not used
    """

    keys = self._logic.getKeyFieldNames()

    # No entity in this case, since Site key values are hard-coded for the
    # Site singleton, so pass in None to match parent method footprint.
    values = self._logic.getKeyValuesFromEntity(None)
    key_values = dicts.zip(keys, values)

    return self.edit(request, "edit", page_name, seed=key_values, **key_values)

view = View()

create = view.create
edit = view.edit
delete = view.delete
list = view.list
public = view.public
export = view.export
main_public = view.mainPublic
main_edit = view.mainEdit
home = view.home
<|endoftext|>


<commit_before>from copy import deepcopy
from flask import render_template
from totalimpactwebapp import product_configs

def prep_product(product, verbose=False):

    product["biblio"] = make_biblio(product)
    product["metrics"] = make_metrics(product)
    product["awards"] = make_awards(product)
    product["markup"] = make_markup(product, verbose)
    product = add_sort_keys(product)

    return product

"""
biblio stuff
"""

def make_biblio(product_dict):
    biblio = product_dict["biblio"]

    try:
        biblio["url"] = product_dict["aliases"]["url"][0]
    except KeyError:
        biblio["url"] = False

    if "title" not in biblio.keys():
        biblio["title"] = "no title"

    try:
        auths = ",".join(biblio["authors"].split(",")[0:3])
        if len(auths) < len(biblio["authors"]):
            auths += " et al."
        biblio["authors"] = auths
    except KeyError:
        pass

    return biblio

"""
Metrics stuff
"""

def make_metrics(product_dict):
    metrics = product_dict["metrics"]
    config_dict = product_configs.get_metric_configs()

    try:
        year = product_dict["biblio"]["year"]
    except KeyError:
        year = None

    ret = {}
    for metric_name, metric in metrics.iteritems():
        audience = config_dict[metric_name]["audience"]

        if audience is not None:
            metric.update(config_dict[metric_name])
            metric.update(metric_metadata(metric, year))
            metric.update(metric_percentiles(metric))
            metric["award"] = make_award_for_single_metric(metric)
            ret[metric_name] = metric

    return ret

def metric_metadata(metric, year):
    interaction_display_names = {
        "f1000": "recommendations",
        "pmc_citations": "citations"
    }

    ret = {}

    raw_count = metric["values"]["raw"]
    ret["display_count"] = raw_count

    # deal with F1000's troublesome "count" of "Yes." Can add others later.
    print "RAW COUNT", raw_count
    if "Yes" in raw_count:
        ret["actual_count"] = 1
    else:
        ret["actual_count"] = raw_count

    ret["environment"] = metric["static_meta"]["provider"]
    interaction = metric["name"].split(":")[1].replace("_", " ")

    try:
        interaction = interaction_display_names[interaction]
    except KeyError:
        pass

    if ret["actual_count"] <= 1:
        ret["display_interaction"] = interaction[:-1]  # de-pluralize
    else:
        ret["display_interaction"] = interaction

    ret["refset_year"] = year

    return ret

def metric_percentiles(metric):
    ret = {}
    refsets_config = {
        "WoS": ["Web of Science", "indexed by"],
        "dryad": ["Dryad", "added to"],
        "figshare": ["figshare", "added to"],
        "github": ["GitHub", "added to"]
    }

    for refset_key, normalized_values in metric["values"].iteritems():
        if refset_key == "raw":
            continue
        else:
            # This will arbitrarily pick on percentile reference set and
            # make it be the only one that counts. Works fine as long as
            # there is just one.

            ret["percentiles"] = normalized_values
            ret["top_percent"] = 100 - normalized_values["CI95_lower"]
            ret["refset"] = refsets_config[refset_key][0]
            ret["refset_storage_verb"] = refsets_config[refset_key][1]

    return ret

"""
Awards stuff
"""

def make_awards(product):
    metrics = product["metrics"]
    awards_dict = {}

    for metric_name, metric in metrics.iteritems():
        this_award = deepcopy(metric["award"])
        this_award["metrics"] = [metric]
        this_award_key = (this_award["audience"], this_award["engagement_type"])
        this_award["top_metric"] = None

        if this_award_key in awards_dict:
            # we've got this award. add to its metrics
            awards_dict[this_award_key]["metrics"].append(metric)

        else:
            awards_dict[this_award_key] = this_award

    for k, award in awards_dict.iteritems():
        award["top_metric"] = get_top_metric(award["metrics"])

    return awards_dict.values()

def get_top_metric(metrics):

    max_actual_count = max([m["actual_count"] for m in metrics])

    def sort_key(m):
        raw_count_contribution = m["actual_count"] / max_actual_count
        raw_count_contribution -= .0001  # always <1

        try:
            return m["percentiles"]["CI95_lower"] + raw_count_contribution
        except KeyError:
            return raw_count_contribution

    sorted_by_metric_percentile_then_raw_counts = sorted(
        metrics,
        key=sort_key,
        reverse=True
    )
    return sorted_by_metric_percentile_then_raw_counts[0]

def make_award_for_single_metric(metric):
    config = product_configs.award_configs

    display_order = config[metric["engagement_type"]][1]
    is_highly = calculate_is_highly(metric)

    if metric["audience"] == "scholars":
        display_order += 10

    if is_highly:
        display_order += 100

    return {
        "engagement_type_noun": config[metric["engagement_type"]][0],
        "engagement_type": metric["engagement_type"],
        "audience": metric["audience"],
        "display_order": display_order,
        "is_highly": is_highly,
        "display_audience": metric["audience"].replace("public", "the public")
    }

def calculate_is_highly(metric):
    try:
        percentile_high_enough = metric["percentiles"]["CI95_lower"] > 75
        raw_high_enough = metric["actual_count"] >= metric["min_for_award"]

        if percentile_high_enough and raw_high_enough:
            return True
        else:
            return False

    except KeyError:  # no percentiles listed
        return False

"""
Sorting stuff
"""

def add_sort_keys(product):
    try:
        product["genre"] = product["biblio"]["genre"]
    except KeyError:
        product["genre"] = "unknown"

    try:
        product["account"] = product["biblio"]["account"]
    except KeyError:
        product["account"] = None

    product["metric_raw_sum"] = sum_metric_raw_values(product)
    product["awardedness_score"] = get_awardedness_score(product)
    product["has_metrics"] = bool(product["metrics"])
    product["has_percentiles"] = has_percentiles(product)

    return product

def get_awardedness_score(product):
    one_highly_award_is_as_good_as_this_many_regular_awards = 3
    score = 0

    for award in product["awards"]:
        if award["is_highly"]:
            score += one_highly_award_is_as_good_as_this_many_regular_awards
        else:
            score += 1

    return score

def sum_metric_raw_values(product):
    raw_values_sum = 0
    try:
        for metric_name, metric in product["metrics"].iteritems():
            raw_values_sum += metric["values"]["raw"]
    except KeyError:
        pass

    return raw_values_sum

def has_percentiles(product):
    for metric_name, metric in product["metrics"].iteritems():

        for refset_value in metric["values"].values():
            try:
                if "CI95_lower" in refset_value.keys():
                    return True
            except AttributeError:
                pass

    return False

"""
Markup stuff
"""

def make_markup(product_dict, verbose):
    template_root = "product"
    if verbose:
        template_root += "-verbose"

    return render_template(
        template_root + ".html",
        product=product_dict
    )

<commit_msg>replace all "count" strings with 1.<commit_after>from copy import deepcopy
from flask import render_template
from totalimpactwebapp import product_configs

def prep_product(product, verbose=False):

    product["biblio"] = make_biblio(product)
    product["metrics"] = make_metrics(product)
    product["awards"] = make_awards(product)
    product["markup"] = make_markup(product, verbose)
    product = add_sort_keys(product)

    return product

"""
biblio stuff
"""

def make_biblio(product_dict):
    biblio = product_dict["biblio"]

    try:
        biblio["url"] = product_dict["aliases"]["url"][0]
    except KeyError:
        biblio["url"] = False

    if "title" not in biblio.keys():
        biblio["title"] = "no title"

    try:
        auths = ",".join(biblio["authors"].split(",")[0:3])
        if len(auths) < len(biblio["authors"]):
            auths += " et al."
        biblio["authors"] = auths
    except KeyError:
        pass

    return biblio

"""
Metrics stuff
"""

def make_metrics(product_dict):
    metrics = product_dict["metrics"]
    config_dict = product_configs.get_metric_configs()

    try:
        year = product_dict["biblio"]["year"]
    except KeyError:
        year = None

    ret = {}
    for metric_name, metric in metrics.iteritems():
        audience = config_dict[metric_name]["audience"]

        if audience is not None:
            metric.update(config_dict[metric_name])
            metric.update(metric_metadata(metric, year))
            metric.update(metric_percentiles(metric))
            metric["award"] = make_award_for_single_metric(metric)
            ret[metric_name] = metric

    return ret

def metric_metadata(metric, year):
    interaction_display_names = {
        "f1000": "recommendations",
        "pmc_citations": "citations"
    }

    ret = {}

    raw_count = metric["values"]["raw"]
    ret["display_count"] = raw_count

    # deal with F1000's troublesome "count" of "Yes." Can add others later.
    if isinstance(raw_count, basestring):
        ret["actual_count"] = 1
    else:
        ret["actual_count"] = raw_count

    ret["environment"] = metric["static_meta"]["provider"]
    interaction = metric["name"].split(":")[1].replace("_", " ")

    try:
        interaction = interaction_display_names[interaction]
    except KeyError:
        pass

    if ret["actual_count"] <= 1:
        ret["display_interaction"] = interaction[:-1]  # de-pluralize
    else:
        ret["display_interaction"] = interaction

    ret["refset_year"] = year

    return ret

def metric_percentiles(metric):
    ret = {}
    refsets_config = {
        "WoS": ["Web of Science", "indexed by"],
        "dryad": ["Dryad", "added to"],
        "figshare": ["figshare", "added to"],
        "github": ["GitHub", "added to"]
    }

    for refset_key, normalized_values in metric["values"].iteritems():
        if refset_key == "raw":
            continue
        else:
            # This will arbitrarily pick on percentile reference set and
            # make it be the only one that counts. Works fine as long as
            # there is just one.

            ret["percentiles"] = normalized_values
            ret["top_percent"] = 100 - normalized_values["CI95_lower"]
            ret["refset"] = refsets_config[refset_key][0]
            ret["refset_storage_verb"] = refsets_config[refset_key][1]

    return ret

"""
Awards stuff
"""

def make_awards(product):
    metrics = product["metrics"]
    awards_dict = {}

    for metric_name, metric in metrics.iteritems():
        this_award = deepcopy(metric["award"])
        this_award["metrics"] = [metric]
        this_award_key = (this_award["audience"], this_award["engagement_type"])
        this_award["top_metric"] = None

        if this_award_key in awards_dict:
            # we've got this award. add to its metrics
            awards_dict[this_award_key]["metrics"].append(metric)

        else:
            awards_dict[this_award_key] = this_award

    for k, award in awards_dict.iteritems():
        award["top_metric"] = get_top_metric(award["metrics"])

    return awards_dict.values()

def get_top_metric(metrics):

    max_actual_count = max([m["actual_count"] for m in metrics])

    def sort_key(m):
        raw_count_contribution = m["actual_count"] / max_actual_count
        raw_count_contribution -= .0001  # always <1

        try:
            return m["percentiles"]["CI95_lower"] + raw_count_contribution
        except KeyError:
            return raw_count_contribution

    sorted_by_metric_percentile_then_raw_counts = sorted(
        metrics,
        key=sort_key,
        reverse=True
    )
    return sorted_by_metric_percentile_then_raw_counts[0]

def make_award_for_single_metric(metric):
    config = product_configs.award_configs

    display_order = config[metric["engagement_type"]][1]
    is_highly = calculate_is_highly(metric)

    if metric["audience"] == "scholars":
        display_order += 10

    if is_highly:
        display_order += 100

    return {
        "engagement_type_noun": config[metric["engagement_type"]][0],
        "engagement_type": metric["engagement_type"],
        "audience": metric["audience"],
        "display_order": display_order,
        "is_highly": is_highly,
        "display_audience": metric["audience"].replace("public", "the public")
    }

def calculate_is_highly(metric):
    try:
        percentile_high_enough = metric["percentiles"]["CI95_lower"] > 75
        raw_high_enough = metric["actual_count"] >= metric["min_for_award"]

        if percentile_high_enough and raw_high_enough:
            return True
        else:
            return False

    except KeyError:  # no percentiles listed
        return False

"""
Sorting stuff
"""

def add_sort_keys(product):
    try:
        product["genre"] = product["biblio"]["genre"]
    except KeyError:
        product["genre"] = "unknown"

    try:
        product["account"] = product["biblio"]["account"]
    except KeyError:
        product["account"] = None

    product["metric_raw_sum"] = sum_metric_raw_values(product)
    product["awardedness_score"] = get_awardedness_score(product)
    product["has_metrics"] = bool(product["metrics"])
    product["has_percentiles"] = has_percentiles(product)

    return product

def get_awardedness_score(product):
    one_highly_award_is_as_good_as_this_many_regular_awards = 3
    score = 0

    for award in product["awards"]:
        if award["is_highly"]:
            score += one_highly_award_is_as_good_as_this_many_regular_awards
        else:
            score += 1

    return score

def sum_metric_raw_values(product):
    raw_values_sum = 0
    try:
        for metric_name, metric in product["metrics"].iteritems():
            raw_values_sum += metric["values"]["raw"]
    except KeyError:
        pass

    return raw_values_sum

def has_percentiles(product):
    for metric_name, metric in product["metrics"].iteritems():

        for refset_value in metric["values"].values():
            try:
                if "CI95_lower" in refset_value.keys():
                    return True
            except AttributeError:
                pass

    return False

"""
Markup stuff
"""

def make_markup(product_dict, verbose):
    template_root = "product"
    if verbose:
        template_root += "-verbose"

    return render_template(
        template_root + ".html",
        product=product_dict
    )

<|endoftext|>


<commit_before>import re
from trac.core import *
from trac.util import escape, Markup, sorted
from trac.wiki.api import WikiSystem, IWikiSyntaxProvider, IWikiChangeListener
from trac.config import *
try:
    set = set
except:
    from sets import Set as set

class AutoWikify(Component):
    """ Automatically create links for all known Wiki pages, even those that
    are not in CamelCase. """
    implements(IWikiSyntaxProvider, IWikiChangeListener)

    minimum_length = IntOption('autowikify', 'minimum_length', 3,
        """Minimum page length to perform auto-wikification on.""")
    explicitly_wikify = ListOption('autowikify', 'explicitly_wikify', doc=
        """List of Wiki pages to always Wikify, regardless of size.""")
    exclude = ListOption('autowikify', 'exclude', doc=
        """List of Wiki pages to exclude from auto-wikification.""")

    pages = set()
    pages_re = None

    def __init__(self):
        self._all_pages()
        self._update()

    # IWikiChangeListener methods
    def wiki_page_added(self, page):
        self.pages.add(page.name)
        self._update()

    def wiki_page_changed(self, page, version, t, comment, author, ipnr):
        pass

    def wiki_page_deleted(self, page):
        if page.name in self.pages:
            self.pages.remove(page.name)
        else:
            self._all_pages()
        self._update()

    def wiki_page_version_deleted(self, page):
        pass

    # IWikiSyntaxProvider methods
    def get_wiki_syntax(self):
        yield (self.pages_re, self._page_formatter)

    def get_link_resolvers(self):
        return []

    # Internal methods
    def _all_pages(self):
        self.pages = set(WikiSystem(self.env).get_pages())

    def _update(self):
        explicitly_wikified = set([p.strip() for p in (self.env.config.get('autowikify', 'explicitly_wikify') or '').split(',') if p.strip()])
        pages = set([p for p in self.pages if len(p) >= self.minimum_length])
        pages.update(self.explicitly_wikify)
        pages.difference_update(self.exclude)
        pattern = r'\b(?P<autowiki>' + '|'.join(pages) + r')\b'
        self.pages_re = pattern
        WikiSystem(self.env)._compiled_rules = None

    def _page_formatter(self, f, n, match):
        page = match.group('autowiki')
        return Markup('%s'
                      % (self.env.href.wiki(page),
                         escape(page)))
<commit_msg>AutoWikifyPlugin:<commit_after>import re
from trac.core import *
from trac.util import escape, Markup, sorted
from trac.wiki.api import WikiSystem, IWikiSyntaxProvider, IWikiChangeListener
from trac.config import *
try:
    set = set
except:
    from sets import Set as set

class AutoWikify(Component):
    """ Automatically create links for all known Wiki pages, even those that
    are not in CamelCase. """
    implements(IWikiSyntaxProvider, IWikiChangeListener)

    minimum_length = IntOption('autowikify', 'minimum_length', 3,
        """Minimum page length to perform auto-wikification on.""")
    explicitly_wikify = ListOption('autowikify', 'explicitly_wikify', doc=
        """List of Wiki pages to always Wikify, regardless of size.""")
    exclude = ListOption('autowikify', 'exclude', doc=
        """List of Wiki pages to exclude from auto-wikification.""")

    pages = set()
    pages_re = None

    def __init__(self):
        self._all_pages()
        self._update()

    # IWikiChangeListener methods
    def wiki_page_added(self, page):
        self.pages.add(page.name)
        self._update()

    def wiki_page_changed(self, page, version, t, comment, author, ipnr):
        pass

    def wiki_page_deleted(self, page):
        if page.name in self.pages:
            self.pages.remove(page.name)
        else:
            self._all_pages()
        self._update()

    def wiki_page_version_deleted(self, page):
        pass

    # IWikiSyntaxProvider methods
    def get_wiki_syntax(self):
        yield (self.pages_re, self._page_formatter)

    def get_link_resolvers(self):
        return []

    # Internal methods
    def _all_pages(self):
        self.pages = set(WikiSystem(self.env).get_pages())

    def _update(self):
        explicitly_wikified = set([p.strip() for p in (self.env.config.get('autowikify', 'explicitly_wikify') or '').split(',') if p.strip()])
        pages = set([p for p in self.pages if len(p) >= self.minimum_length])
        pages.update(self.explicitly_wikify)
        pages.difference_update(self.exclude)
        pattern = r'\b(?P<autowiki>' + '|'.join([re.escape(page) for page in pages]) + r')\b'
        self.pages_re = pattern
        WikiSystem(self.env)._compiled_rules = None

    def _page_formatter(self, f, n, match):
        page = match.group('autowiki')
        return Markup('%s'
                      % (self.env.href.wiki(page),
                         escape(page)))
<|endoftext|>


<commit_before>from flask.ext.testing import TestCase
import unittest
import json

genotype_response = [{'rs1695': 'AG', 'rs72921001': 'AC', 'rs2472297': 'CC', 'rs1800955': 'CC', 'rs806380': 'AG', 'id': '28170b36a71d740c', 'rs1815739': 'CT', 'rs1800497': 'AG', 'rs1537415': 'CG', 'rs6152': '__', 'rs8177374': 'CT', 'rs7574865': 'GG', 'rs6025': 'CC', 'rs662799': 'AA', 'rs9939609': 'AT', 'rs4988235': 'GG', 'rs1799971': 'AG', 'rs4680': 'AA', 'rs12913832': 'GG', 'rs53576': 'GG', 'rs17822931': 'CC', 'rs909525': 'TT'}]
user_response = {'id': 'd22c07d33cf86333', 'profiles': [{'genotyped': True, 'id': '28170b36a71d740c'}], 'email': 'Jzup90@gmail.com'}
name_response = {'first_name': 'Justin', 'last_name': 'Zupnick', 'id': '28170b36a71d740c'}
relatives_response = { 'count' : 3, 'relatives': [{'last_name': 'Miller', 'match_id': '69d6b534987843b6', 'similarity': 0.0373, 'predicted_relationship_code': 29, 'updated': None, 'share_status': None, 'sex': 'Male', 'shared_segments': 17, 'birthplace': None, 'range': [], 'profile_picture_urls': None, 'intro_status': None, 'birth_year': None, 'paternal_side': False, 'added': 1437017446, 'relationship': '2nd Cousin', 'maternal_haplogroup': 'N9a3', 'user_relationship_code': None, 'first_name': 'Joel', 'ancestry': None, 'paternal_haplogroup': 'J2', 'residence': None, 'notes': None, 'family_surnames': [], 'maternal_side': False, 'family_locations': []}, {'last_name': None, 'match_id': '53a9891c1926e158', 'similarity': 0.014, 'predicted_relationship_code': 29, 'updated': None, 'share_status': None, 'sex': 'Male', 'shared_segments': 12, 'birthplace': None, 'range': [], 'profile_picture_urls': None, 'intro_status': None, 'birth_year': 1952, 'paternal_side': False, 'added': 1295900703, 'relationship': '2nd Cousin', 'maternal_haplogroup': 'K1a1b1a', 'user_relationship_code': None, 'first_name': None, 'ancestry': None, 'paternal_haplogroup': 'E1a1', 'residence': None, 'notes': None, 'family_surnames': [], 'maternal_side': False, 'family_locations': ['Satmar, Rumania', 'Ukraine', 'Hungary']}, {'last_name': 'Greplin', 'match_id': 'c15265825b7b2e06', 'similarity': 0.0137, 'predicted_relationship_code': 29, 'updated': None, 'share_status': None, 'sex': 'Male', 'shared_segments': 12, 'birthplace': None, 'range': [], 'profile_picture_urls': None, 'intro_status': None, 'birth_year': None, 'paternal_side': False, 'added': 1434196871, 'relationship': '2nd Cousin', 'maternal_haplogroup': 'H3', 'user_relationship_code': None, 'first_name': None, 'ancestry': None, 'paternal_haplogroup': 'J1e', 'residence': None, 'notes': None, 'family_surnames': [], 'maternal_side': False, 'family_locations': []}]}

#CreateNewUser will be called in server.py when a user logging in has not been found in database
def createNewUser(name_response, relatives_response, genotype_response, user_response):
    #Grab the dnaPairs at relative snps
    genome_data = genotype_response.pop()
    #Define the user's basic information
    user_first_name = name_response['first_name']
    user_last_name = name_response['last_name']
    user_id = genome_data['id']
    user_email = user_response
    relative = relatives_response['relatives'].pop()
    new_user = {'relatives' : [], 'first_name' : 'Test', 'last_name' : 'Testly', 'location' : 'San Francisco'}
    new_user['relatives'].append(relative)

    # Add the user to the database and commit it
    return new_user

class MyTest(unittest.TestCase):
    @classmethod
    def setUpClass(self):
        self.testUser = createNewUser(name_response, relatives_response, genotype_response, user_response)

    def test_equal_numbers(self):
        # import controller
        relative = self.testUser['relatives'][0]
        intro_status = relative['intro_status']
        maternal_haplogroup = relative['maternal_haplogroup']
        paternal_haplogroup = relative['paternal_haplogroup']
        last_name = relative['last_name']
        match_id = relative['match_id']

        self.assertEqual(intro_status, None)
        self.assertEqual(maternal_haplogroup, 'H3')
        self.assertEqual(paternal_haplogroup, 'J1e')
        self.assertEqual(last_name, 'Greplin')
        self.assertEqual(match_id, 'c15265825b7b2e06')

if __name__ == '__main__':
    unittest.main()
<commit_msg>Delete tests.py<commit_after><|endoftext|>


<commit_before># -*- encoding: utf-8 -*-
##############################################################################
#
#    SEPA Credit Transfer module for OpenERP
#    Copyright (C) 2010-2013 Akretion (http://www.akretion.com)
#    @author: Alexis de Lattre <alexis.delattre@akretion.com>
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as
#    published by the Free Software Foundation, either version 3 of the
#    License, or (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################

from openerp.osv import orm, fields
from openerp.tools.translate import _
from openerp import workflow
from lxml import etree

class BankingExportSepaWizard(orm.TransientModel):
    _name = 'banking.export.sepa.wizard'
    _inherit = ['banking.export.pain']
    _description = 'Export SEPA Credit Transfer File'

    _columns = {
        'state': fields.selection([('create', 'Create'),
                                   ('finish', 'Finish')], 'State',
                                  readonly=True),
        'batch_booking': fields.boolean(
            'Batch Booking',
            help="If true, the bank statement will display only one debit "
            "line for all the wire transfers of the SEPA XML file ; if "
            "false, the bank statement will display one debit line per wire "
            "transfer of the SEPA XML file."),
        'charge_bearer': fields.selection(
            [('SLEV', 'Following Service Level'),
             ('SHAR', 'Shared'),
             ('CRED', 'Borne by Creditor'),
             ('DEBT', 'Borne by Debtor')], 'Charge Bearer', required=True,
            help="Following service level : transaction charges are to be "
                 "applied following the rules agreed in the service level "
                 "and/or scheme (SEPA Core messages must use this). Shared : "
                 "transaction charges on the debtor side are to be borne by "
                 "the debtor, transaction charges on the creditor side are to "
                 "be borne by the creditor. Borne by creditor : all "
                 "transaction charges are to be borne by the creditor. Borne "
                 "by debtor : all transaction charges are to be borne by the "
                 "debtor."),
        'nb_transactions': fields.related(
            'file_id', 'nb_transactions', type='integer',
            string='Number of Transactions', readonly=True),
        'total_amount': fields.related(
            'file_id', 'total_amount', type='float', string='Total Amount',
            readonly=True),
        'file_id': fields.many2one(
            'banking.export.sepa', 'SEPA XML File', readonly=True),
        'file': fields.related(
            'file_id', 'file', string="File", type='binary', readonly=True),
        'filename': fields.related(
            'file_id', 'filename', string="Filename", type='char',
            size=256, readonly=True),
        'payment_order_ids': fields.many2many(
            'payment.order', 'wiz_sepa_payorders_rel', 'wizard_id',
            'payment_order_id', 'Payment Orders', readonly=True),
    }

    _defaults = {
        'charge_bearer': 'SLEV',
        'state': 'create',
    }

    def create(self, cr, uid, vals, context=None):
        payment_order_ids = context.get('active_ids', [])
        vals.update({
            'payment_order_ids': [[6, 0, payment_order_ids]],
        })
        return super(BankingExportSepaWizard, self).create(
            cr, uid, vals, context=context)

    def create_sepa(self, cr, uid, ids, context=None):
        """Creates the SEPA Credit Transfer file. That's the important code!"""
        if context is None:
            context = {}
        sepa_export = self.browse(cr, uid, ids[0], context=context)
        pain_flavor = sepa_export.payment_order_ids[0].mode.type.code
        convert_to_ascii = \
            sepa_export.payment_order_ids[0].mode.convert_to_ascii
        if pain_flavor == 'pain.001.001.02':
            bic_xml_tag = 'BIC'
            name_maxsize = 70
            root_xml_tag = 'pain.001.001.02'
        elif pain_flavor == 'pain.001.001.03':
            bic_xml_tag = 'BIC'
            # size 70 -> 140 for <Nm> with pain.001.001.03
            # BUT the European Payment Council, in the document
            # "SEPA Credit Transfer Scheme Customer-to-bank
            # Implementation guidelines" v6.0 available on
            # http://www.europeanpaymentscouncil.eu/knowledge_bank.cfm
            # says that 'Nm' should be limited to 70
            # so we follow the "European Payment Council"
            # and we put 70 and not 140
            name_maxsize = 70
            root_xml_tag = 'CstmrCdtTrfInitn'
        elif pain_flavor == 'pain.001.001.04':
            bic_xml_tag = 'BICFI'
            name_maxsize = 140
            root_xml_tag = 'CstmrCdtTrfInitn'
        elif pain_flavor == 'pain.001.001.05':
            bic_xml_tag = 'BICFI'
            name_maxsize = 140
            root_xml_tag = 'CstmrCdtTrfInitn'
        else:
            raise orm.except_orm(
                _('Error:'),
                _("Payment Type Code '%s' is not supported. The only "
                  "Payment Type Codes supported for SEPA Credit Transfers "
                  "are 'pain.001.001.02', 'pain.001.001.03', "
                  "'pain.001.001.04' and 'pain.001.001.05'.") %
                pain_flavor)
        gen_args = {
            'bic_xml_tag': bic_xml_tag,
            'name_maxsize': name_maxsize,
            'convert_to_ascii': convert_to_ascii,
            'payment_method': 'TRF',
            'pain_flavor': pain_flavor,
            'sepa_export': sepa_export,
            'file_obj': self.pool['banking.export.sepa'],
            'pain_xsd_file':
            'account_banking_sepa_credit_transfer/data/%s.xsd'
            % pain_flavor,
        }
        pain_ns = {
            'xsi': 'http://www.w3.org/2001/XMLSchema-instance',
            None: 'urn:iso:std:iso:20022:tech:xsd:%s' % pain_flavor,
        }
        xml_root = etree.Element('Document', nsmap=pain_ns)
        pain_root = etree.SubElement(xml_root, root_xml_tag)
        pain_03_to_05 = \
            ['pain.001.001.03', 'pain.001.001.04', 'pain.001.001.05']
        # A. Group header
        group_header_1_0, nb_of_transactions_1_6, control_sum_1_7 = \
            self.generate_group_header_block(
                cr, uid, pain_root, gen_args, context=context)
        transactions_count_1_6 = 0
        total_amount = 0.0
        amount_control_sum_1_7 = 0.0
        lines_per_group = {}
        # key = (requested_date, priority)
        # values = list of lines as object
        today = fields.date.context_today(self, cr, uid, context=context)
        for payment_order in sepa_export.payment_order_ids:
            total_amount = total_amount + payment_order.total
            for line in payment_order.line_ids:
                priority = line.priority
                if payment_order.date_prefered == 'due':
                    requested_date = line.ml_maturity_date or today
                elif payment_order.date_prefered == 'fixed':
                    requested_date = payment_order.date_scheduled or today
                else:
                    requested_date = today
                key = (requested_date, priority)
                if key in lines_per_group:
                    lines_per_group[key].append(line)
                else:
                    lines_per_group[key] = [line]
                # Write requested_date on 'Payment date' of the pay line
                if requested_date != line.date:
                    self.pool['payment.line'].write(
                        cr, uid, line.id,
                        {'date': requested_date}, context=context)
        for (requested_date, priority), lines in lines_per_group.items():
            # B. Payment info
            payment_info_2_0, nb_of_transactions_2_4, control_sum_2_5 = \
                self.generate_start_payment_info_block(
                    cr, uid, pain_root,
                    "sepa_export.payment_order_ids[0].reference + '-' "
                    "+ requested_date.replace('-', '')  + '-' + priority",
                    priority, False, False, requested_date, {
                        'sepa_export': sepa_export,
                        'priority': priority,
                        'requested_date': requested_date,
                    }, gen_args, context=context)
            self.generate_party_block(
                cr, uid, payment_info_2_0, 'Dbtr', 'B',
                'sepa_export.payment_order_ids[0].mode.bank_id.partner_id.'
                'name',
                'sepa_export.payment_order_ids[0].mode.bank_id.acc_number',
                'sepa_export.payment_order_ids[0].mode.bank_id.bank.bic',
                {'sepa_export': sepa_export},
                gen_args, context=context)
            charge_bearer_2_24 = etree.SubElement(payment_info_2_0, 'ChrgBr')
            charge_bearer_2_24.text = sepa_export.charge_bearer
            transactions_count_2_4 = 0
            amount_control_sum_2_5 = 0.0
            for line in lines:
                transactions_count_1_6 += 1
                transactions_count_2_4 += 1
                # C. Credit Transfer Transaction Info
                credit_transfer_transaction_info_2_27 = etree.SubElement(
                    payment_info_2_0, 'CdtTrfTxInf')
                payment_identification_2_28 = etree.SubElement(
                    credit_transfer_transaction_info_2_27, 'PmtId')
                end2end_identification_2_30 = etree.SubElement(
                    payment_identification_2_28, 'EndToEndId')
                end2end_identification_2_30.text = self._prepare_field(
                    cr, uid, 'End to End Identification', 'line.name',
                    {'line': line}, 35, gen_args=gen_args,
                    context=context)
                currency_name = self._prepare_field(
                    cr, uid, 'Currency Code', 'line.currency.name',
                    {'line': line}, 3, gen_args=gen_args,
                    context=context)
                amount_2_42 = etree.SubElement(
                    credit_transfer_transaction_info_2_27, 'Amt')
                instructed_amount_2_43 = etree.SubElement(
                    amount_2_42, 'InstdAmt', Ccy=currency_name)
                instructed_amount_2_43.text = '%.2f' % line.amount_currency
                amount_control_sum_1_7 += line.amount_currency
                amount_control_sum_2_5 += line.amount_currency
                if not line.bank_id:
                    raise orm.except_orm(
                        _('Error:'),
                        _("Missing Bank Account on invoice '%s' (payment "
                            "order line reference '%s').")
                        % (line.ml_inv_ref.number, line.name))
                self.generate_party_block(
                    cr, uid, credit_transfer_transaction_info_2_27, 'Cdtr',
                    'C', 'line.partner_id.name', 'line.bank_id.acc_number',
                    'line.bank_id.bank.bic', {'line': line}, gen_args,
                    context=context)
                self.generate_remittance_info_block(
                    cr, uid, credit_transfer_transaction_info_2_27,
                    line, gen_args, context=context)
            if pain_flavor in pain_03_to_05:
                nb_of_transactions_2_4.text = str(transactions_count_2_4)
                control_sum_2_5.text = '%.2f' % amount_control_sum_2_5
        if pain_flavor in pain_03_to_05:
            nb_of_transactions_1_6.text = str(transactions_count_1_6)
            control_sum_1_7.text = '%.2f' % amount_control_sum_1_7
        else:
            nb_of_transactions_1_6.text = str(transactions_count_1_6)
            control_sum_1_7.text = '%.2f' % amount_control_sum_1_7
        return self.finalize_sepa_file_creation(
            cr, uid, ids, xml_root, total_amount, transactions_count_1_6,
            gen_args, context=context)

    def cancel_sepa(self, cr, uid, ids, context=None):
        """Cancel the SEPA file: just drop the file"""
        sepa_export = self.browse(cr, uid, ids[0], context=context)
        self.pool['banking.export.sepa'].unlink(
            cr, uid, sepa_export.file_id.id, context=context)
        return {'type': 'ir.actions.act_window_close'}

    def save_sepa(self, cr, uid, ids, context=None):
        """Save the SEPA file: send the done signal to all payment
        orders in the file. With the default workflow, they will
        transition to 'done', while with the advanced workflow in
        account_banking_payment they will transition to 'sent' waiting
        reconciliation.
        """
        sepa_export = self.browse(cr, uid, ids[0], context=context)
        self.pool['banking.export.sepa'].write(
            cr, uid, sepa_export.file_id.id, {'state': 'sent'},
            context=context)
        for order in sepa_export.payment_order_ids:
            workflow.trg_validate(uid, 'payment.order', order.id, 'done', cr)
        return {'type': 'ir.actions.act_window_close'}
<commit_msg>[IMP] sepa credit tfr: get BIC from bank account if not available on bank<commit_after># -*- encoding: utf-8 -*-
##############################################################################
#
#    SEPA Credit Transfer module for OpenERP
#    Copyright (C) 2010-2013 Akretion (http://www.akretion.com)
#    @author: Alexis de Lattre <alexis.delattre@akretion.com>
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as
#    published by the Free Software Foundation, either version 3 of the
#    License, or (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################

from openerp.osv import orm, fields
from openerp.tools.translate import _
from openerp import workflow
from lxml import etree

class BankingExportSepaWizard(orm.TransientModel):
    _name = 'banking.export.sepa.wizard'
    _inherit = ['banking.export.pain']
    _description = 'Export SEPA Credit Transfer File'

    _columns = {
        'state': fields.selection([('create', 'Create'),
                                   ('finish', 'Finish')], 'State',
                                  readonly=True),
        'batch_booking': fields.boolean(
            'Batch Booking',
            help="If true, the bank statement will display only one debit "
            "line for all the wire transfers of the SEPA XML file ; if "
            "false, the bank statement will display one debit line per wire "
            "transfer of the SEPA XML file."),
        'charge_bearer': fields.selection(
            [('SLEV', 'Following Service Level'),
             ('SHAR', 'Shared'),
             ('CRED', 'Borne by Creditor'),
             ('DEBT', 'Borne by Debtor')], 'Charge Bearer', required=True,
            help="Following service level : transaction charges are to be "
                 "applied following the rules agreed in the service level "
                 "and/or scheme (SEPA Core messages must use this). Shared : "
                 "transaction charges on the debtor side are to be borne by "
                 "the debtor, transaction charges on the creditor side are to "
                 "be borne by the creditor. Borne by creditor : all "
                 "transaction charges are to be borne by the creditor. Borne "
                 "by debtor : all transaction charges are to be borne by the "
                 "debtor."),
        'nb_transactions': fields.related(
            'file_id', 'nb_transactions', type='integer',
            string='Number of Transactions', readonly=True),
        'total_amount': fields.related(
            'file_id', 'total_amount', type='float', string='Total Amount',
            readonly=True),
        'file_id': fields.many2one(
            'banking.export.sepa', 'SEPA XML File', readonly=True),
        'file': fields.related(
            'file_id', 'file', string="File", type='binary', readonly=True),
        'filename': fields.related(
            'file_id', 'filename', string="Filename", type='char',
            size=256, readonly=True),
        'payment_order_ids': fields.many2many(
            'payment.order', 'wiz_sepa_payorders_rel', 'wizard_id',
            'payment_order_id', 'Payment Orders', readonly=True),
    }

    _defaults = {
        'charge_bearer': 'SLEV',
        'state': 'create',
    }

    def create(self, cr, uid, vals, context=None):
        payment_order_ids = context.get('active_ids', [])
        vals.update({
            'payment_order_ids': [[6, 0, payment_order_ids]],
        })
        return super(BankingExportSepaWizard, self).create(
            cr, uid, vals, context=context)

    def create_sepa(self, cr, uid, ids, context=None):
        """Creates the SEPA Credit Transfer file. That's the important code!"""
        if context is None:
            context = {}
        sepa_export = self.browse(cr, uid, ids[0], context=context)
        pain_flavor = sepa_export.payment_order_ids[0].mode.type.code
        convert_to_ascii = \
            sepa_export.payment_order_ids[0].mode.convert_to_ascii
        if pain_flavor == 'pain.001.001.02':
            bic_xml_tag = 'BIC'
            name_maxsize = 70
            root_xml_tag = 'pain.001.001.02'
        elif pain_flavor == 'pain.001.001.03':
            bic_xml_tag = 'BIC'
            # size 70 -> 140 for <Nm> with pain.001.001.03
            # BUT the European Payment Council, in the document
            # "SEPA Credit Transfer Scheme Customer-to-bank
            # Implementation guidelines" v6.0 available on
            # http://www.europeanpaymentscouncil.eu/knowledge_bank.cfm
            # says that 'Nm' should be limited to 70
            # so we follow the "European Payment Council"
            # and we put 70 and not 140
            name_maxsize = 70
            root_xml_tag = 'CstmrCdtTrfInitn'
        elif pain_flavor == 'pain.001.001.04':
            bic_xml_tag = 'BICFI'
            name_maxsize = 140
            root_xml_tag = 'CstmrCdtTrfInitn'
        elif pain_flavor == 'pain.001.001.05':
            bic_xml_tag = 'BICFI'
            name_maxsize = 140
            root_xml_tag = 'CstmrCdtTrfInitn'
        else:
            raise orm.except_orm(
                _('Error:'),
                _("Payment Type Code '%s' is not supported. The only "
                  "Payment Type Codes supported for SEPA Credit Transfers "
                  "are 'pain.001.001.02', 'pain.001.001.03', "
                  "'pain.001.001.04' and 'pain.001.001.05'.") %
                pain_flavor)
        gen_args = {
            'bic_xml_tag': bic_xml_tag,
            'name_maxsize': name_maxsize,
            'convert_to_ascii': convert_to_ascii,
            'payment_method': 'TRF',
            'pain_flavor': pain_flavor,
            'sepa_export': sepa_export,
            'file_obj': self.pool['banking.export.sepa'],
            'pain_xsd_file':
            'account_banking_sepa_credit_transfer/data/%s.xsd'
            % pain_flavor,
        }
        pain_ns = {
            'xsi': 'http://www.w3.org/2001/XMLSchema-instance',
            None: 'urn:iso:std:iso:20022:tech:xsd:%s' % pain_flavor,
        }
        xml_root = etree.Element('Document', nsmap=pain_ns)
        pain_root = etree.SubElement(xml_root, root_xml_tag)
        pain_03_to_05 = \
            ['pain.001.001.03', 'pain.001.001.04', 'pain.001.001.05']
        # A. Group header
        group_header_1_0, nb_of_transactions_1_6, control_sum_1_7 = \
            self.generate_group_header_block(
                cr, uid, pain_root, gen_args, context=context)
        transactions_count_1_6 = 0
        total_amount = 0.0
        amount_control_sum_1_7 = 0.0
        lines_per_group = {}
        # key = (requested_date, priority)
        # values = list of lines as object
        today = fields.date.context_today(self, cr, uid, context=context)
        for payment_order in sepa_export.payment_order_ids:
            total_amount = total_amount + payment_order.total
            for line in payment_order.line_ids:
                priority = line.priority
                if payment_order.date_prefered == 'due':
                    requested_date = line.ml_maturity_date or today
                elif payment_order.date_prefered == 'fixed':
                    requested_date = payment_order.date_scheduled or today
                else:
                    requested_date = today
                key = (requested_date, priority)
                if key in lines_per_group:
                    lines_per_group[key].append(line)
                else:
                    lines_per_group[key] = [line]
                # Write requested_date on 'Payment date' of the pay line
                if requested_date != line.date:
                    self.pool['payment.line'].write(
                        cr, uid, line.id,
                        {'date': requested_date}, context=context)
        for (requested_date, priority), lines in lines_per_group.items():
            # B. Payment info
            payment_info_2_0, nb_of_transactions_2_4, control_sum_2_5 = \
                self.generate_start_payment_info_block(
                    cr, uid, pain_root,
                    "sepa_export.payment_order_ids[0].reference + '-' "
                    "+ requested_date.replace('-', '')  + '-' + priority",
                    priority, False, False, requested_date, {
                        'sepa_export': sepa_export,
                        'priority': priority,
                        'requested_date': requested_date,
                    }, gen_args, context=context)
            self.generate_party_block(
                cr, uid, payment_info_2_0, 'Dbtr', 'B',
                'sepa_export.payment_order_ids[0].mode.bank_id.partner_id.'
                'name',
                'sepa_export.payment_order_ids[0].mode.bank_id.acc_number',
                'sepa_export.payment_order_ids[0].mode.bank_id.bank.bic or '
                'sepa_export.payment_order_ids[0].mode.bank_id.bank_bic',
                {'sepa_export': sepa_export},
                gen_args, context=context)
            charge_bearer_2_24 = etree.SubElement(payment_info_2_0, 'ChrgBr')
            charge_bearer_2_24.text = sepa_export.charge_bearer
            transactions_count_2_4 = 0
            amount_control_sum_2_5 = 0.0
            for line in lines:
                transactions_count_1_6 += 1
                transactions_count_2_4 += 1
                # C. Credit Transfer Transaction Info
                credit_transfer_transaction_info_2_27 = etree.SubElement(
                    payment_info_2_0, 'CdtTrfTxInf')
                payment_identification_2_28 = etree.SubElement(
                    credit_transfer_transaction_info_2_27, 'PmtId')
                end2end_identification_2_30 = etree.SubElement(
                    payment_identification_2_28, 'EndToEndId')
                end2end_identification_2_30.text = self._prepare_field(
                    cr, uid, 'End to End Identification', 'line.name',
                    {'line': line}, 35, gen_args=gen_args,
                    context=context)
                currency_name = self._prepare_field(
                    cr, uid, 'Currency Code', 'line.currency.name',
                    {'line': line}, 3, gen_args=gen_args,
                    context=context)
                amount_2_42 = etree.SubElement(
                    credit_transfer_transaction_info_2_27, 'Amt')
                instructed_amount_2_43 = etree.SubElement(
                    amount_2_42, 'InstdAmt', Ccy=currency_name)
                instructed_amount_2_43.text = '%.2f' % line.amount_currency
                amount_control_sum_1_7 += line.amount_currency
                amount_control_sum_2_5 += line.amount_currency
                if not line.bank_id:
                    raise orm.except_orm(
                        _('Error:'),
                        _("Missing Bank Account on invoice '%s' (payment "
                            "order line reference '%s').")
                        % (line.ml_inv_ref.number, line.name))
                self.generate_party_block(
                    cr, uid, credit_transfer_transaction_info_2_27, 'Cdtr',
                    'C', 'line.partner_id.name', 'line.bank_id.acc_number',
                    'line.bank_id.bank.bic or '
                    'line.bank_id.bank_bic', {'line': line}, gen_args,
                    context=context)
                self.generate_remittance_info_block(
                    cr, uid, credit_transfer_transaction_info_2_27,
                    line, gen_args, context=context)
            if pain_flavor in pain_03_to_05:
                nb_of_transactions_2_4.text = str(transactions_count_2_4)
                control_sum_2_5.text = '%.2f' % amount_control_sum_2_5
        if pain_flavor in pain_03_to_05:
            nb_of_transactions_1_6.text = str(transactions_count_1_6)
            control_sum_1_7.text = '%.2f' % amount_control_sum_1_7
        else:
            nb_of_transactions_1_6.text = str(transactions_count_1_6)
            control_sum_1_7.text = '%.2f' % amount_control_sum_1_7
        return self.finalize_sepa_file_creation(
            cr, uid, ids, xml_root, total_amount, transactions_count_1_6,
            gen_args, context=context)

    def cancel_sepa(self, cr, uid, ids, context=None):
        """Cancel the SEPA file: just drop the file"""
        sepa_export = self.browse(cr, uid, ids[0], context=context)
        self.pool['banking.export.sepa'].unlink(
            cr, uid, sepa_export.file_id.id, context=context)
        return {'type': 'ir.actions.act_window_close'}

    def save_sepa(self, cr, uid, ids, context=None):
        """Save the SEPA file: send the done signal to all payment
        orders in the file. With the default workflow, they will
        transition to 'done', while with the advanced workflow in
        account_banking_payment they will transition to 'sent' waiting
        reconciliation.
        """
        sepa_export = self.browse(cr, uid, ids[0], context=context)
        self.pool['banking.export.sepa'].write(
            cr, uid, sepa_export.file_id.id, {'state': 'sent'},
            context=context)
        for order in sepa_export.payment_order_ids:
            workflow.trg_validate(uid, 'payment.order', order.id, 'done', cr)
        return {'type': 'ir.actions.act_window_close'}
<|endoftext|>


<commit_before>from contextlib import contextmanager
import sys

from io import StringIO

@contextmanager
def captured_output():
    """Allows to safely capture stdout and stderr in a context manager."""
    new_out, new_err = StringIO(), StringIO()
    old_out, old_err = sys.stdout, sys.stderr
    try:
        sys.stdout, sys.stderr = new_out, new_err
        yield sys.stdout, sys.stderr
    finally:
        sys.stdout, sys.stderr = old_out, old_err
<commit_msg>Organize imports<commit_after>import sys
from contextlib import contextmanager
from io import StringIO

@contextmanager
def captured_output():
    """Allows to safely capture stdout and stderr in a context manager."""
    new_out, new_err = StringIO(), StringIO()
    old_out, old_err = sys.stdout, sys.stderr
    try:
        sys.stdout, sys.stderr = new_out, new_err
        yield sys.stdout, sys.stderr
    finally:
        sys.stdout, sys.stderr = old_out, old_err
<|endoftext|>


<commit_before>
from __future__ import print_function

from model_test_setup import ModelTestSetup

import subprocess as sp
import os
import shlex

class TestBuild(ModelTestSetup):

    def __init__(self):
        super(TestBuild, self).__init__()

    def do_basic_build(self, exp):

        exp_path = os.path.join('payu-experiments/access/', exp)
        os.chdir(exp_path)
        cmd = 'payu build --laboratory {}'.format(self.lab_path)
        ret = sp.call(shlex.split(cmd))
        assert(ret == 0)

        os.chdir(self.my_path)

    def test_ACCESS_OM_tiny(self):
        """
        Build executables for ACCESS-OM_tiny experiment.
        """

        self.do_basic_build('access-om_tiny')

    def test_ACCESS_CM_tiny(self):
        """
        Build executables for ACCESS-CM_tiny experiment.
        """

        self.do_basic_build('access-cm_tiny')

    def test_ACCESS_OM(self):
        """
        Build executables for ACCESS-OM experiment.

        These are the same as ACCESS-OM_tiny
        """

        self.do_basic_build('access-om')

    def test_ACCESS_CM(self):
        """
        Build executables for ACCESS-CM_tiny experiment.

        These are the same as ACCESS-CM_tiny
        """

        self.do_basic_build('access-cm')

    def test_ACCESS_OM_1440x1080(self):
        """
        Build executables for ACCESS-OM_1440x1080 experiment.
        """

        self.do_basic_build('access-om_1440x1080')

    def test_ACCESS_CM_1440x1080(self):
        """
        Build executables for ACCESS-CM_1440x1080 experiment.
        """

        self.do_basic_build('access-cm_1440x1080')
<commit_msg>Differentiate between fast and slow tests.<commit_after>
from __future__ import print_function

from model_test_setup import ModelTestSetup

import subprocess as sp
import os
import shlex

class TestBuild(ModelTestSetup):

    def __init__(self):
        super(TestBuild, self).__init__()

    def do_basic_build(self, exp):

        exp_path = os.path.join('payu-experiments/access/', exp)
        os.chdir(exp_path)
        cmd = 'payu build --laboratory {}'.format(self.lab_path)
        ret = sp.call(shlex.split(cmd))

        os.chdir(self.my_path)
        assert(ret == 0)

    @attr('fast')
    def test_ACCESS_OM_tiny(self):
        """
        Build executables for ACCESS-OM_tiny experiment.
        """

        self.do_basic_build('access-om_tiny')

    @attr('fast')
    def test_ACCESS_CM_tiny(self):
        """
        Build executables for ACCESS-CM_tiny experiment.
        """

        self.do_basic_build('access-cm_tiny')

    def test_ACCESS_OM(self):
        """
        Build executables for ACCESS-OM experiment.

        These are the same as ACCESS-OM_tiny
        """

        self.do_basic_build('access-om')

    def test_ACCESS_CM(self):
        """
        Build executables for ACCESS-CM_tiny experiment.

        These are the same as ACCESS-CM_tiny
        """

        self.do_basic_build('access-cm')

    @attr('slow')
    def test_ACCESS_OM_1440x1080(self):
        """
        Build executables for ACCESS-OM_1440x1080 experiment.
        """

        self.do_basic_build('access-om_1440x1080')

    @attr('slow')
    def test_ACCESS_CM_1440x1080(self):
        """
        Build executables for ACCESS-CM_1440x1080 experiment.
        """

        self.do_basic_build('access-cm_1440x1080')
<|endoftext|>