<commit_before>
import pandas as pd
import json
import xmltodict
import warnings
from quantipy.core.tools.dp.prep import start_meta, condense_dichotomous_set

def quantipy_from_ascribe(path_xml, path_txt, text_key='main'):

    # Read the AScribe data (tab-delimited)
    meta_ascribe = xmltodict.parse(open(path_xml))
    data_ascribe = pd.DataFrame.from_csv(
        path_txt,
        sep='\t',
        header=0,
        encoding='utf-16'
    )
    data_ascribe[data_ascribe.index.name] = data_ascribe.index

    # Start a Quantipy meta document
    meta = start_meta(text_key=text_key)
    meta['columns']['responseid'] = {
        'type': 'int',
        'text': {text_key: 'responseid'}
    }
    meta['sets']['data file']['items'] = ['columns@responseid']

    MultiForm = meta_ascribe['CodedQuestions']['MultiForm']
    if not isinstance(MultiForm, list):
        meta_ascribe['CodedQuestions']['MultiForm'] = [MultiForm]

    # Container to record the names, in order, of the resulting
    # coded columns
    coded_names = []

    for var in meta_ascribe['CodedQuestions']['MultiForm']:
        name = var['Name']
        if var['Answers'] is None:
            msg = ("The variable '%s' has no answer codes "
                   "and will be skipped.") % (name)
            warnings.warn(msg)
            continue
        coded_names.append(name)
        coded_from = var['FormTexts']['FormText']['Title']
        var_text = var['FormTexts']['FormText']['Text']
        var_text = '' if var_text is None else var_text.replace('\n', ' ')
        if var_text is None: var_text = 'Label not provided'
        var_text = {text_key: var_text}
        columns = []
        values = []
        for val in var['Answers']['Answer']:
            value = int(val['@Precode'])
            if value==0:
                msg = (
                    "The value 0 has been assigned to a code for the "
                    "variable '%s'."
                ) % (name)
                warnings.warn(msg)
            val_text = val['Texts']['Text']['#text']
            val_text = '' if val_text is None else val_text.replace('\n', ' ')
            if val_text is None: val_text = 'Label not provided'
            val_text = {text_key: val_text}
            values.append({'value': value, 'text': val_text})
            columns.append('%s_%s' % (name, value))

        # Create a single series from the dichotomous set
        data_ascribe[name] = condense_dichotomous_set(
            data_ascribe[columns],
            sniff_single=True
        )

        # Determine the Quantipy type of the returned
        # series from its dtype (see 'sniff_sinlge' in
        # condense_dichotomous_set()
        if data_ascribe[columns].sum(axis=1).max()==1:
            col_type = 'single'
        else:
            col_type = 'delimited set'

        # Create the new Quantipy column meta
        column = {
            'type': col_type,
            'text': var_text,
            'values': values
        }

        # Add the newly defined column to the Quantipy meta
        meta['columns'][name] = column

    meta['sets']['data file']['items'].extend([
        'columns@%s' % (col_name)
        for col_name in coded_names
    ])

    # Keep only the slice that has been converted.
    data = data_ascribe[[data_ascribe.index.name]+coded_names]

    return meta, data
<commit_msg>add keys name and parent to converted ascribe files<commit_after>
import pandas as pd
import json
import xmltodict
import warnings
from quantipy.core.tools.dp.prep import start_meta, condense_dichotomous_set

def quantipy_from_ascribe(path_xml, path_txt, text_key='main'):

    # Read the AScribe data (tab-delimited)
    meta_ascribe = xmltodict.parse(open(path_xml))
    data_ascribe = pd.DataFrame.from_csv(
        path_txt,
        sep='\t',
        header=0,
        encoding='utf-16'
    )
    data_ascribe[data_ascribe.index.name] = data_ascribe.index

    # Start a Quantipy meta document
    meta = start_meta(text_key=text_key)
    meta['columns']['responseid'] = {
        'name': 'responseid',
        'type': 'int',
        'text': {text_key: 'responseid'},
        'parent': {}
    }
    meta['sets']['data file']['items'] = ['columns@responseid']

    MultiForm = meta_ascribe['CodedQuestions']['MultiForm']
    if not isinstance(MultiForm, list):
        meta_ascribe['CodedQuestions']['MultiForm'] = [MultiForm]

    # Container to record the names, in order, of the resulting
    # coded columns
    coded_names = []

    for var in meta_ascribe['CodedQuestions']['MultiForm']:
        name = var['Name']
        if var['Answers'] is None:
            msg = ("The variable '%s' has no answer codes "
                   "and will be skipped.") % (name)
            warnings.warn(msg)
            continue
        coded_names.append(name)
        coded_from = var['FormTexts']['FormText']['Title']
        var_text = var['FormTexts']['FormText']['Text']
        var_text = '' if var_text is None else var_text.replace('\n', ' ')
        if var_text is None: var_text = 'Label not provided'
        var_text = {text_key: var_text}
        columns = []
        values = []
        for val in var['Answers']['Answer']:
            value = int(val['@Precode'])
            if value==0:
                msg = (
                    "The value 0 has been assigned to a code for the "
                    "variable '%s'."
                ) % (name)
                warnings.warn(msg)
            val_text = val['Texts']['Text']['#text']
            val_text = '' if val_text is None else val_text.replace('\n', ' ')
            if val_text is None: val_text = 'Label not provided'
            val_text = {text_key: val_text}
            values.append({'value': value, 'text': val_text})
            columns.append('%s_%s' % (name, value))

        # Create a single series from the dichotomous set
        data_ascribe[name] = condense_dichotomous_set(
            data_ascribe[columns],
            sniff_single=True
        )

        # Determine the Quantipy type of the returned
        # series from its dtype (see 'sniff_sinlge' in
        # condense_dichotomous_set()
        if data_ascribe[columns].sum(axis=1).max()==1:
            col_type = 'single'
        else:
            col_type = 'delimited set'

        # Create the new Quantipy column meta
        column = {
            'name': name,
            'type': col_type,
            'text': var_text,
            'values': values,
            'parent': {}
        }

        # Add the newly defined column to the Quantipy meta
        meta['columns'][name] = column

    meta['sets']['data file']['items'].extend([
        'columns@%s' % (col_name)
        for col_name in coded_names
    ])

    # Keep only the slice that has been converted.
    data = data_ascribe[[data_ascribe.index.name]+coded_names]

    return meta, data
<|endoftext|>


<commit_before>import logging
import os

from ..statautils import Directory, Logger
from ..stataxml import PomInjector

""" Original pom.xml filename """
POM_FILENAME = 'pom.xml'

""" Custom pom.xml filename """
CUSTOM_POM_FILENAME = 'poir.xml'

""" Logger """
logger = logging.getLogger()

class MutationsTester:
    """ Mutations tests launcher. """

    def __init__(self, tests_directory, report_directory, postprocess_clean):
        self.tests_directory = tests_directory
        self.report_directory = report_directory
        self.postprocess_clean = postprocess_clean

    def clean(self):
        """
        Delete tests directory.
        """
        try:
            Directory.delete(self.tests_directory)
        except:
            Logger.log('[Warning] Error on cleaning tests directory ("%s")' % self.tests_directory)

    def inject_processors(self, processors, filename):
        """
        Inject processors in a custom pom.xml file.
        :param processors: processors to inject
        :param filename: custom pom.xml filename
        :return: path to the custom pom.xml
        """
        # Injector processors
        injector = PomInjector(POM_FILENAME)
        injector.inject_processors(processors)

        # Save to the new file
        injector.save(filename)
        return filename

    def process(self, name, processors=(), selectors=()):
        """
        Execute mutation and tests.
        :param name: output directory
        :param processors: processor to apply
        :param selectors: selectors to apply
        """
        self.clean()
        Logger.log('========================== Mutation "%s" ==========================' % name,
                   True)

        # Inject processors
        Logger.log('Injecting processors in "%s": %s' % (CUSTOM_POM_FILENAME, processors))
        pom_file = self.inject_processors(processors, CUSTOM_POM_FILENAME)

        # Prepare command to execute
        command = 'mvn package -f "%s"' % pom_file
        Logger.log('Executing command: %s' % command, False, True)

        # Post-process results
        if not (
                self.postprocess(
                    # Execute mutations and tests
                    os.system(command),
                    # Final output directory
                    os.path.join(self.report_directory, name),
                    pom_file
                )):
            Logger.log('Compilation failed for processors: %s' % (processors,), True)

    def postprocess(self, status, output_dir, pom_file):
        """
        Post-process.
        :param status: tests status
        :param output_dir: output directory
        :param pom_file: custom pom file
        :return True if compilation succeeded
        """
        try:
            # Copy results to output report directory
            Logger.log('Copying files from "%s" to "%s"...' % (self.tests_directory, output_dir))
            Directory.copy(self.tests_directory, output_dir)
            return True
        # Compilation failed
        except FileNotFoundError:
            # Compilation failed
            if status > 0:
                # Create an empty file to indicate the compilation failed
                Directory.touch(os.path.join(output_dir, '.compilation_failed'))
        finally:
            # Remove the temporary custom pom file
            if self.postprocess_clean:
                Logger.log('Removing temporary "%s" file...' % pom_file, True)
                os.remove(pom_file)
<commit_msg>[Fix] Execute "mvn tests" instead of "mvn package"<commit_after>import logging
import os

from ..statautils import Directory, Logger
from ..stataxml import PomInjector

""" Original pom.xml filename """
POM_FILENAME = 'pom.xml'

""" Custom pom.xml filename """
CUSTOM_POM_FILENAME = 'poir.xml'

""" Logger """
logger = logging.getLogger()

class MutationsTester:
    """ Mutations tests launcher. """

    def __init__(self, tests_directory, report_directory, postprocess_clean):
        self.tests_directory = tests_directory
        self.report_directory = report_directory
        self.postprocess_clean = postprocess_clean

    def clean(self):
        """
        Delete tests directory.
        """
        try:
            Directory.delete(self.tests_directory)
        except:
            Logger.log('[Warning] Error on cleaning tests directory ("%s")' % self.tests_directory)

    def inject_processors(self, processors, filename):
        """
        Inject processors in a custom pom.xml file.
        :param processors: processors to inject
        :param filename: custom pom.xml filename
        :return: path to the custom pom.xml
        """
        # Injector processors
        injector = PomInjector(POM_FILENAME)
        injector.inject_processors(processors)

        # Save to the new file
        injector.save(filename)
        return filename

    def process(self, name, processors=(), selectors=()):
        """
        Execute mutation and tests.
        :param name: output directory
        :param processors: processor to apply
        :param selectors: selectors to apply
        """
        self.clean()
        Logger.log('========================== Mutation "%s" ==========================' % name,
                   True)

        # Inject processors
        Logger.log('Injecting processors in "%s": %s' % (CUSTOM_POM_FILENAME, processors))
        pom_file = self.inject_processors(processors, CUSTOM_POM_FILENAME)

        # Prepare command to execute
        command = 'mvn tests -f "%s"' % pom_file
        Logger.log('Executing command: %s' % command, False, True)

        # Post-process results
        if not (
                self.postprocess(
                    # Execute mutations and tests
                    os.system(command),
                    # Final output directory
                    os.path.join(self.report_directory, name),
                    pom_file
                )):
            Logger.log('Compilation failed for processors: %s' % (processors,), True)

    def postprocess(self, status, output_dir, pom_file):
        """
        Post-process.
        :param status: tests status
        :param output_dir: output directory
        :param pom_file: custom pom file
        :return True if compilation succeeded
        """
        try:
            # Copy results to output report directory
            Logger.log('Copying files from "%s" to "%s"...' % (self.tests_directory, output_dir))
            Directory.copy(self.tests_directory, output_dir)
            return True
        # Compilation failed
        except FileNotFoundError:
            # Compilation failed
            if status > 0:
                # Create an empty file to indicate the compilation failed
                Directory.touch(os.path.join(output_dir, '.compilation_failed'))
        finally:
            # Remove the temporary custom pom file
            if self.postprocess_clean:
                Logger.log('Removing temporary "%s" file...' % pom_file, True)
                os.remove(pom_file)
<|endoftext|>


<commit_before>import json

from django.conf import settings
from django.contrib import messages
from django.core.files.base import ContentFile
from django.core.paginator import Paginator
from django.db.models import Sum
from django.http import (
    HttpResponse,
    HttpResponseNotFound,
    HttpResponseRedirect,
    JsonResponse,
)
from django.shortcuts import render
from django.urls import reverse
from django.utils.decorators import method_decorator
from django.utils.translation import ugettext as _, ugettext_lazy
from django.views.decorators.http import require_POST

from django_prbac.utils import has_privilege
from memoized import memoized

from corehq.apps.accounting.decorators import always_allow_project_access
from corehq.apps.enterprise.decorators import require_enterprise_admin
from corehq.apps.enterprise.models import EnterprisePermissions
from couchexport.export import Format
from dimagi.utils.couch.cache.cache_core import get_redis_client

from corehq import privileges
from corehq.apps.accounting.models import (
    CustomerInvoice,
    CustomerBillingRecord,
)
from corehq.apps.accounting.utils import get_customer_cards, quantize_accounting_decimal, log_accounting_error
from corehq.apps.domain.decorators import (
    login_and_domain_required,
    require_superuser,
)
from corehq.apps.domain.views import DomainAccountingSettings, BaseDomainView
from corehq.apps.domain.views.accounting import PAYMENT_ERROR_MESSAGES, InvoiceStripePaymentView, \
    BulkStripePaymentView, WireInvoiceView, BillingStatementPdfView

from corehq.apps.enterprise.enterprise import EnterpriseReport

from corehq.apps.enterprise.forms import (
    EnterpriseSettingsForm,
)
from corehq.apps.enterprise.tasks import email_enterprise_report

from corehq.apps.export.utils import get_default_export_settings_if_available

from corehq.apps.hqwebapp.views import CRUDPaginatedViewMixin
from corehq.apps.users.decorators import require_can_edit_or_view_web_users

from corehq.const import USER_DATE_FORMAT

@always_allow_project_access
@require_enterprise_admin
@login_and_domain_required
def enterprise_dashboard(request, domain):
    if not has_privilege(request, privileges.PROJECT_ACCESS):
        return HttpResponseRedirect(reverse(EnterpriseBillingStatementsView.urlname, args=(domain,)))

    context = {
        'account': request.account,
        'domain': domain,
        'reports': [EnterpriseReport.create(slug, request.account.id, request.couch_user) for slug in (
            EnterpriseReport.DOMAINS,
            EnterpriseReport.WEB_USERS,
            EnterpriseReport.MOBILE_USERS,
            EnterpriseReport.FORM_SUBMISSIONS,
        )],
        'current_page': {
            'page_name': _('Enterprise Dashboard'),
            'title': _('Enterprise Dashboard'),
        }
    }
    return render(request, "enterprise/enterprise_dashboard.html", context)

@require_enterprise_admin
@login_and_domain_required
def enterprise_dashboard_total(request, domain, slug):
    report = EnterpriseReport.create(slug, request.account.id, request.couch_user)
    return JsonResponse({'total': report.total})

@require_enterprise_admin
@login_and_domain_required
def enterprise_dashboard_download(request, domain, slug, export_hash):
    report = EnterpriseReport.create(slug, request.account.id, request.couch_user)

    redis = get_redis_client()
    content = redis.get(export_hash)

    if content:
        file = ContentFile(content)
        response = HttpResponse(file, Format.FORMAT_DICT[Format.UNZIPPED_CSV])
        response['Content-Length'] = file.size
        response['Content-Disposition'] = 'attachment; filename="{}"'.format(report.filename)
        return response

    return HttpResponseNotFound(_("That report was not found. Please remember that "
                                  "download links expire after 24 hours."))

@require_enterprise_admin
@login_and_domain_required
def enterprise_dashboard_email(request, domain, slug):
    report = EnterpriseReport.create(slug, request.account.id, request.couch_user)
    email_enterprise_report.delay(domain, slug, request.couch_user)
    message = _("Generating {title} report, will email to {email} when complete.").format(**{
        'title': report.title,
        'email': request.couch_user.username,
    })
    return JsonResponse({'message': message})

@require_enterprise_admin
@login_and_domain_required
def enterprise_settings(request, domain):
    export_settings = get_default_export_settings_if_available(domain)

    if request.method == 'POST':
        form = EnterpriseSettingsForm(request.POST, domain=domain, account=request.account,
                                      username=request.user.username, export_settings=export_settings)
    else:
        form = EnterpriseSettingsForm(domain=domain, account=request.account, username=request.user.username,
                                      export_settings=export_settings)

    context = {
        'account': request.account,
        'accounts_email': settings.ACCOUNTS_EMAIL,
        'domain': domain,
        'restrict_signup': request.POST.get('restrict_signup', request.account.restrict_signup),
        'current_page': {
            'title': _('Enterprise Settings'),
            'page_name': _('Enterprise Settings'),
        },
        'settings_form': form,
    }
    return render(request, "enterprise/enterprise_settings.html", context)

@require_enterprise_admin
@login_and_domain_required
@require_POST
def edit_enterprise_settings(request, domain):
    export_settings = get_default_export_settings_if_available(domain)
    form = EnterpriseSettingsForm(request.POST, username=request.user.username,
                                  domain=domain,
                                  account=request.account, export_settings=export_settings)

    if form.is_valid():
        form.save(request.account)
        messages.success(request, "Account successfully updated.")
    else:
        return enterprise_settings(request, domain)

    return HttpResponseRedirect(reverse('enterprise_settings', args=[domain]))

@method_decorator(require_enterprise_admin, name='dispatch')
class BaseEnterpriseAdminView(BaseDomainView):
    section_name = ugettext_lazy("Enterprise Console")

    @property
    def section_url(self):
        return reverse('enterprise_dashboard', args=(self.domain,))

    @property
    def page_url(self):
        return reverse(self.urlname, args=(self.domain,))

@method_decorator(require_enterprise_admin, name='dispatch')
class EnterpriseBillingStatementsView(DomainAccountingSettings, CRUDPaginatedViewMixin):
    template_name = 'domain/billing_statements.html'
    urlname = 'enterprise_billing_statements'
    page_title = ugettext_lazy("Billing Statements")

    limit_text = ugettext_lazy("statements per page")
    empty_notification = ugettext_lazy("No Billing Statements match the current criteria.")
    loading_message = ugettext_lazy("Loading statements...")

    @property
    def stripe_cards(self):
        return get_customer_cards(self.request.user.username, self.domain)

    @property
    def show_hidden(self):
        if not self.request.user.is_superuser:
            return False
        return bool(self.request.POST.get('additionalData[show_hidden]'))

    @property
    def show_unpaid(self):
        try:
            return json.loads(self.request.POST.get('additionalData[show_unpaid]'))
        except TypeError:
            return False

    @property
    def invoices(self):
        invoices = CustomerInvoice.objects.filter(account=self.request.account)
        if not self.show_hidden:
            invoices = invoices.filter(is_hidden=False)
        if self.show_unpaid:
            invoices = invoices.filter(date_paid__exact=None)
        return invoices.order_by('-date_start', '-date_end')

    @property
    def total(self):
        return self.paginated_invoices.count

    @property
    @memoized
    def paginated_invoices(self):
        return Paginator(self.invoices, self.limit)

    @property
    def total_balance(self):
        """
        Returns the total balance of unpaid, unhidden invoices.
        Doesn't take into account the view settings on the page.
        """
        invoices = (CustomerInvoice.objects
                    .filter(account=self.request.account)
                    .filter(date_paid__exact=None)
                    .filter(is_hidden=False))
        return invoices.aggregate(
            total_balance=Sum('balance')
        ).get('total_balance') or 0.00

    @property
    def column_names(self):
        return [
            _("Statement No."),
            _("Billing Period"),
            _("Date Due"),
            _("Payment Status"),
            _("PDF"),
        ]

    @property
    def page_context(self):
        pagination_context = self.pagination_context
        pagination_context.update({
            'stripe_options': {
                'stripe_public_key': settings.STRIPE_PUBLIC_KEY,
                'stripe_cards': self.stripe_cards,
            },
            'payment_error_messages': PAYMENT_ERROR_MESSAGES,
            'payment_urls': {
                'process_invoice_payment_url': reverse(
                    InvoiceStripePaymentView.urlname,
                    args=[self.domain],
                ),
                'process_bulk_payment_url': reverse(
                    BulkStripePaymentView.urlname,
                    args=[self.domain],
                ),
                'process_wire_invoice_url': reverse(
                    WireInvoiceView.urlname,
                    args=[self.domain],
                ),
            },
            'total_balance': self.total_balance,
            'show_plan': False
        })
        return pagination_context

    @property
    def can_pay_invoices(self):
        return self.request.couch_user.is_domain_admin(self.domain)

    @property
    def paginated_list(self):
        for invoice in self.paginated_invoices.page(self.page).object_list:
            try:
                last_billing_record = CustomerBillingRecord.objects.filter(
                    invoice=invoice
                ).latest('date_created')
                if invoice.is_paid:
                    payment_status = (_("Paid on %s.")
                                      % invoice.date_paid.strftime(USER_DATE_FORMAT))
                    payment_class = "label label-default"
                else:
                    payment_status = _("Not Paid")
                    payment_class = "label label-danger"
                date_due = (
                    (invoice.date_due.strftime(USER_DATE_FORMAT)
                     if not invoice.is_paid else _("Already Paid"))
                    if invoice.date_due else _("None")
                )
                yield {
                    'itemData': {
                        'id': invoice.id,
                        'invoice_number': invoice.invoice_number,
                        'start': invoice.date_start.strftime(USER_DATE_FORMAT),
                        'end': invoice.date_end.strftime(USER_DATE_FORMAT),
                        'plan': None,
                        'payment_status': payment_status,
                        'payment_class': payment_class,
                        'date_due': date_due,
                        'pdfUrl': reverse(
                            BillingStatementPdfView.urlname,
                            args=[self.domain, last_billing_record.pdf_data_id]
                        ),
                        'canMakePayment': (not invoice.is_paid
                                           and self.can_pay_invoices),
                        'balance': "%s" % quantize_accounting_decimal(invoice.balance),
                    },
                    'template': 'statement-row-template',
                }
            except CustomerBillingRecord.DoesNotExist:
                log_accounting_error(
                    "An invoice was generated for %(invoice_id)d "
                    "(domain: %(domain)s), but no billing record!" % {
                        'invoice_id': invoice.id,
                        'domain': self.domain,
                    },
                    show_stack_trace=True
                )

    def refresh_item(self, item_id):
        pass

    def post(self, *args, **kwargs):
        return self.paginate_crud_response

@require_can_edit_or_view_web_users
@require_superuser
def enterprise_permissions(request, domain):
    config = EnterprisePermissions.get_by_domain(domain)
    all_domains = set(config.account.get_domains())
    ignored_domains = all_domains - set(config.domains) - {config.source_domain}

    context = {
        'domain': domain,
        'all_domains': sorted(all_domains),
        'is_enabled': config.is_enabled,
        'source_domain': config.source_domain,
        'ignored_domains': sorted(list(ignored_domains)),
        'controlled_domains': sorted(config.domains),
        'current_page': {
            'page_name': _('Enterprise Permissions'),
            'title': _('Enterprise Permissions'),
        }
    }
    return render(request, "enterprise/enterprise_permissions.html", context)

@require_superuser
@require_POST
def disable_enterprise_permissions(request, domain):
    config = EnterprisePermissions.get_by_domain(domain)
    config.is_enabled = False
    config.source_domain = None
    config.save()
    config.clear_cache_for_all_users()

    redirect = reverse("enterprise_permissions", args=[domain])
    messages.success(request, _('Enterprise permissions have been disabled.'))
    return HttpResponseRedirect(redirect)

@require_superuser
@require_POST
def add_enterprise_permissions_domain(request, domain, target_domain):
    config = EnterprisePermissions.get_by_domain(domain)

    redirect = reverse("enterprise_permissions", args=[domain])
    if target_domain not in config.account.get_domains():
        messages.error(request, _("Could not add {}}.").format(target_domain))
        return HttpResponseRedirect(redirect)

    if target_domain not in config.domains:
        config.domains.append(target_domain)
        config.save()
        if config.source_domain:
            config.clear_cache_for_all_users(config.source_domain)
    messages.success(request, _('Users in {} now have access to {}.').format(config.source_domain, target_domain))
    return HttpResponseRedirect(redirect)

@require_superuser
@require_POST
def remove_enterprise_permissions_domain(request, domain, target_domain):
    config = EnterprisePermissions.get_by_domain(domain)

    redirect = reverse("enterprise_permissions", args=[domain])
    if target_domain not in config.account.get_domains() or target_domain not in config.domains:
        messages.error(request, _("Could not remove {}.").format(target_domain))
        return HttpResponseRedirect(redirect)

    if target_domain in config.domains:
        config.domains.remove(target_domain)
        config.save()
        if config.source_domain:
            config.clear_cache_for_all_users(config.source_domain)
    messages.success(request, _('Users in {} no longer have access to {}.').format(config.source_domain,
                                                                                target_domain))
    return HttpResponseRedirect(redirect)

@require_superuser
@require_POST
def update_enterprise_permissions_source_domain(request, domain):
    source_domain = request.POST.get('source_domain')
    redirect = reverse("enterprise_permissions", args=[domain])

    config = EnterprisePermissions.get_by_domain(domain)
    if source_domain not in config.account.get_domains():
        messages.error(request, _("Please select a project."))
        return HttpResponseRedirect(redirect)

    config.is_enabled = True
    old_domain = config.source_domain
    config.source_domain = source_domain
    if source_domain in config.domains:
        config.domains.remove(source_domain)
    config.save()
    config.clear_cache_for_all_users(config.source_domain)
    config.clear_cache_for_all_users(old_domain)
    messages.success(request, _('Controlling domain set to {}.').format(source_domain))
    return HttpResponseRedirect(redirect)
<commit_msg>Added @require_enterprise_admin<commit_after>import json

from django.conf import settings
from django.contrib import messages
from django.core.files.base import ContentFile
from django.core.paginator import Paginator
from django.db.models import Sum
from django.http import (
    HttpResponse,
    HttpResponseNotFound,
    HttpResponseRedirect,
    JsonResponse,
)
from django.shortcuts import render
from django.urls import reverse
from django.utils.decorators import method_decorator
from django.utils.translation import ugettext as _, ugettext_lazy
from django.views.decorators.http import require_POST

from django_prbac.utils import has_privilege
from memoized import memoized

from corehq.apps.accounting.decorators import always_allow_project_access
from corehq.apps.enterprise.decorators import require_enterprise_admin
from corehq.apps.enterprise.models import EnterprisePermissions
from couchexport.export import Format
from dimagi.utils.couch.cache.cache_core import get_redis_client

from corehq import privileges
from corehq.apps.accounting.models import (
    CustomerInvoice,
    CustomerBillingRecord,
)
from corehq.apps.accounting.utils import get_customer_cards, quantize_accounting_decimal, log_accounting_error
from corehq.apps.domain.decorators import (
    login_and_domain_required,
    require_superuser,
)
from corehq.apps.domain.views import DomainAccountingSettings, BaseDomainView
from corehq.apps.domain.views.accounting import PAYMENT_ERROR_MESSAGES, InvoiceStripePaymentView, \
    BulkStripePaymentView, WireInvoiceView, BillingStatementPdfView

from corehq.apps.enterprise.enterprise import EnterpriseReport

from corehq.apps.enterprise.forms import (
    EnterpriseSettingsForm,
)
from corehq.apps.enterprise.tasks import email_enterprise_report

from corehq.apps.export.utils import get_default_export_settings_if_available

from corehq.apps.hqwebapp.views import CRUDPaginatedViewMixin
from corehq.apps.users.decorators import require_can_edit_or_view_web_users

from corehq.const import USER_DATE_FORMAT

@always_allow_project_access
@require_enterprise_admin
@login_and_domain_required
def enterprise_dashboard(request, domain):
    if not has_privilege(request, privileges.PROJECT_ACCESS):
        return HttpResponseRedirect(reverse(EnterpriseBillingStatementsView.urlname, args=(domain,)))

    context = {
        'account': request.account,
        'domain': domain,
        'reports': [EnterpriseReport.create(slug, request.account.id, request.couch_user) for slug in (
            EnterpriseReport.DOMAINS,
            EnterpriseReport.WEB_USERS,
            EnterpriseReport.MOBILE_USERS,
            EnterpriseReport.FORM_SUBMISSIONS,
        )],
        'current_page': {
            'page_name': _('Enterprise Dashboard'),
            'title': _('Enterprise Dashboard'),
        }
    }
    return render(request, "enterprise/enterprise_dashboard.html", context)

@require_enterprise_admin
@login_and_domain_required
def enterprise_dashboard_total(request, domain, slug):
    report = EnterpriseReport.create(slug, request.account.id, request.couch_user)
    return JsonResponse({'total': report.total})

@require_enterprise_admin
@login_and_domain_required
def enterprise_dashboard_download(request, domain, slug, export_hash):
    report = EnterpriseReport.create(slug, request.account.id, request.couch_user)

    redis = get_redis_client()
    content = redis.get(export_hash)

    if content:
        file = ContentFile(content)
        response = HttpResponse(file, Format.FORMAT_DICT[Format.UNZIPPED_CSV])
        response['Content-Length'] = file.size
        response['Content-Disposition'] = 'attachment; filename="{}"'.format(report.filename)
        return response

    return HttpResponseNotFound(_("That report was not found. Please remember that "
                                  "download links expire after 24 hours."))

@require_enterprise_admin
@login_and_domain_required
def enterprise_dashboard_email(request, domain, slug):
    report = EnterpriseReport.create(slug, request.account.id, request.couch_user)
    email_enterprise_report.delay(domain, slug, request.couch_user)
    message = _("Generating {title} report, will email to {email} when complete.").format(**{
        'title': report.title,
        'email': request.couch_user.username,
    })
    return JsonResponse({'message': message})

@require_enterprise_admin
@login_and_domain_required
def enterprise_settings(request, domain):
    export_settings = get_default_export_settings_if_available(domain)

    if request.method == 'POST':
        form = EnterpriseSettingsForm(request.POST, domain=domain, account=request.account,
                                      username=request.user.username, export_settings=export_settings)
    else:
        form = EnterpriseSettingsForm(domain=domain, account=request.account, username=request.user.username,
                                      export_settings=export_settings)

    context = {
        'account': request.account,
        'accounts_email': settings.ACCOUNTS_EMAIL,
        'domain': domain,
        'restrict_signup': request.POST.get('restrict_signup', request.account.restrict_signup),
        'current_page': {
            'title': _('Enterprise Settings'),
            'page_name': _('Enterprise Settings'),
        },
        'settings_form': form,
    }
    return render(request, "enterprise/enterprise_settings.html", context)

@require_enterprise_admin
@login_and_domain_required
@require_POST
def edit_enterprise_settings(request, domain):
    export_settings = get_default_export_settings_if_available(domain)
    form = EnterpriseSettingsForm(request.POST, username=request.user.username,
                                  domain=domain,
                                  account=request.account, export_settings=export_settings)

    if form.is_valid():
        form.save(request.account)
        messages.success(request, "Account successfully updated.")
    else:
        return enterprise_settings(request, domain)

    return HttpResponseRedirect(reverse('enterprise_settings', args=[domain]))

@method_decorator(require_enterprise_admin, name='dispatch')
class BaseEnterpriseAdminView(BaseDomainView):
    section_name = ugettext_lazy("Enterprise Console")

    @property
    def section_url(self):
        return reverse('enterprise_dashboard', args=(self.domain,))

    @property
    def page_url(self):
        return reverse(self.urlname, args=(self.domain,))

@method_decorator(require_enterprise_admin, name='dispatch')
class EnterpriseBillingStatementsView(DomainAccountingSettings, CRUDPaginatedViewMixin):
    template_name = 'domain/billing_statements.html'
    urlname = 'enterprise_billing_statements'
    page_title = ugettext_lazy("Billing Statements")

    limit_text = ugettext_lazy("statements per page")
    empty_notification = ugettext_lazy("No Billing Statements match the current criteria.")
    loading_message = ugettext_lazy("Loading statements...")

    @property
    def stripe_cards(self):
        return get_customer_cards(self.request.user.username, self.domain)

    @property
    def show_hidden(self):
        if not self.request.user.is_superuser:
            return False
        return bool(self.request.POST.get('additionalData[show_hidden]'))

    @property
    def show_unpaid(self):
        try:
            return json.loads(self.request.POST.get('additionalData[show_unpaid]'))
        except TypeError:
            return False

    @property
    def invoices(self):
        invoices = CustomerInvoice.objects.filter(account=self.request.account)
        if not self.show_hidden:
            invoices = invoices.filter(is_hidden=False)
        if self.show_unpaid:
            invoices = invoices.filter(date_paid__exact=None)
        return invoices.order_by('-date_start', '-date_end')

    @property
    def total(self):
        return self.paginated_invoices.count

    @property
    @memoized
    def paginated_invoices(self):
        return Paginator(self.invoices, self.limit)

    @property
    def total_balance(self):
        """
        Returns the total balance of unpaid, unhidden invoices.
        Doesn't take into account the view settings on the page.
        """
        invoices = (CustomerInvoice.objects
                    .filter(account=self.request.account)
                    .filter(date_paid__exact=None)
                    .filter(is_hidden=False))
        return invoices.aggregate(
            total_balance=Sum('balance')
        ).get('total_balance') or 0.00

    @property
    def column_names(self):
        return [
            _("Statement No."),
            _("Billing Period"),
            _("Date Due"),
            _("Payment Status"),
            _("PDF"),
        ]

    @property
    def page_context(self):
        pagination_context = self.pagination_context
        pagination_context.update({
            'stripe_options': {
                'stripe_public_key': settings.STRIPE_PUBLIC_KEY,
                'stripe_cards': self.stripe_cards,
            },
            'payment_error_messages': PAYMENT_ERROR_MESSAGES,
            'payment_urls': {
                'process_invoice_payment_url': reverse(
                    InvoiceStripePaymentView.urlname,
                    args=[self.domain],
                ),
                'process_bulk_payment_url': reverse(
                    BulkStripePaymentView.urlname,
                    args=[self.domain],
                ),
                'process_wire_invoice_url': reverse(
                    WireInvoiceView.urlname,
                    args=[self.domain],
                ),
            },
            'total_balance': self.total_balance,
            'show_plan': False
        })
        return pagination_context

    @property
    def can_pay_invoices(self):
        return self.request.couch_user.is_domain_admin(self.domain)

    @property
    def paginated_list(self):
        for invoice in self.paginated_invoices.page(self.page).object_list:
            try:
                last_billing_record = CustomerBillingRecord.objects.filter(
                    invoice=invoice
                ).latest('date_created')
                if invoice.is_paid:
                    payment_status = (_("Paid on %s.")
                                      % invoice.date_paid.strftime(USER_DATE_FORMAT))
                    payment_class = "label label-default"
                else:
                    payment_status = _("Not Paid")
                    payment_class = "label label-danger"
                date_due = (
                    (invoice.date_due.strftime(USER_DATE_FORMAT)
                     if not invoice.is_paid else _("Already Paid"))
                    if invoice.date_due else _("None")
                )
                yield {
                    'itemData': {
                        'id': invoice.id,
                        'invoice_number': invoice.invoice_number,
                        'start': invoice.date_start.strftime(USER_DATE_FORMAT),
                        'end': invoice.date_end.strftime(USER_DATE_FORMAT),
                        'plan': None,
                        'payment_status': payment_status,
                        'payment_class': payment_class,
                        'date_due': date_due,
                        'pdfUrl': reverse(
                            BillingStatementPdfView.urlname,
                            args=[self.domain, last_billing_record.pdf_data_id]
                        ),
                        'canMakePayment': (not invoice.is_paid
                                           and self.can_pay_invoices),
                        'balance': "%s" % quantize_accounting_decimal(invoice.balance),
                    },
                    'template': 'statement-row-template',
                }
            except CustomerBillingRecord.DoesNotExist:
                log_accounting_error(
                    "An invoice was generated for %(invoice_id)d "
                    "(domain: %(domain)s), but no billing record!" % {
                        'invoice_id': invoice.id,
                        'domain': self.domain,
                    },
                    show_stack_trace=True
                )

    def refresh_item(self, item_id):
        pass

    def post(self, *args, **kwargs):
        return self.paginate_crud_response

# This view, and related views, require enterprise admin permissions to be consistent
# with other views in this area. They also require superuser access because these views
# used to be in another part of HQ, where they were limited to superusers, and we don't
# want them to be visible to any external users until we're ready to GA this feature.
@require_can_edit_or_view_web_users
@require_superuser
@require_enterprise_admin
def enterprise_permissions(request, domain):
    config = EnterprisePermissions.get_by_domain(domain)
    all_domains = set(config.account.get_domains())
    ignored_domains = all_domains - set(config.domains) - {config.source_domain}

    context = {
        'domain': domain,
        'all_domains': sorted(all_domains),
        'is_enabled': config.is_enabled,
        'source_domain': config.source_domain,
        'ignored_domains': sorted(list(ignored_domains)),
        'controlled_domains': sorted(config.domains),
        'current_page': {
            'page_name': _('Enterprise Permissions'),
            'title': _('Enterprise Permissions'),
        }
    }
    return render(request, "enterprise/enterprise_permissions.html", context)

@require_superuser
@require_enterprise_admin
@require_POST
def disable_enterprise_permissions(request, domain):
    config = EnterprisePermissions.get_by_domain(domain)
    config.is_enabled = False
    config.source_domain = None
    config.save()
    config.clear_cache_for_all_users()

    redirect = reverse("enterprise_permissions", args=[domain])
    messages.success(request, _('Enterprise permissions have been disabled.'))
    return HttpResponseRedirect(redirect)

@require_superuser
@require_enterprise_admin
@require_POST
def add_enterprise_permissions_domain(request, domain, target_domain):
    config = EnterprisePermissions.get_by_domain(domain)

    redirect = reverse("enterprise_permissions", args=[domain])
    if target_domain not in config.account.get_domains():
        messages.error(request, _("Could not add {}}.").format(target_domain))
        return HttpResponseRedirect(redirect)

    if target_domain not in config.domains:
        config.domains.append(target_domain)
        config.save()
        if config.source_domain:
            config.clear_cache_for_all_users(config.source_domain)
    messages.success(request, _('Users in {} now have access to {}.').format(config.source_domain, target_domain))
    return HttpResponseRedirect(redirect)

@require_superuser
@require_enterprise_admin
@require_POST
def remove_enterprise_permissions_domain(request, domain, target_domain):
    config = EnterprisePermissions.get_by_domain(domain)

    redirect = reverse("enterprise_permissions", args=[domain])
    if target_domain not in config.account.get_domains() or target_domain not in config.domains:
        messages.error(request, _("Could not remove {}.").format(target_domain))
        return HttpResponseRedirect(redirect)

    if target_domain in config.domains:
        config.domains.remove(target_domain)
        config.save()
        if config.source_domain:
            config.clear_cache_for_all_users(config.source_domain)
    messages.success(request, _('Users in {} no longer have access to {}.').format(config.source_domain,
                                                                                target_domain))
    return HttpResponseRedirect(redirect)

@require_superuser
@require_enterprise_admin
@require_POST
def update_enterprise_permissions_source_domain(request, domain):
    source_domain = request.POST.get('source_domain')
    redirect = reverse("enterprise_permissions", args=[domain])

    config = EnterprisePermissions.get_by_domain(domain)
    if source_domain not in config.account.get_domains():
        messages.error(request, _("Please select a project."))
        return HttpResponseRedirect(redirect)

    config.is_enabled = True
    old_domain = config.source_domain
    config.source_domain = source_domain
    if source_domain in config.domains:
        config.domains.remove(source_domain)
    config.save()
    config.clear_cache_for_all_users(config.source_domain)
    config.clear_cache_for_all_users(old_domain)
    messages.success(request, _('Controlling domain set to {}.').format(source_domain))
    return HttpResponseRedirect(redirect)
<|endoftext|>


<commit_before># -*- coding: utf-8; -*-
# Copyright 2014 Google Inc. All Rights Reserved.
#
# 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.

"""Functions used for Course Builder locale support."""

__author__ = 'John Orr (jorr@google.com)'

import logging
import os

import appengine_config

# Locale description information based on Babel Locale.display_name. However
# the names are collected here because (i) Babel does not have correct display
# names for all of the locales included, and (ii) Babel cannot access its
# localeinfo data when it is loaded as a Zip file.
LOCALES_DISPLAY_NAMES = {
    'af': u'Afrikaans (af)',
    'am': u'አማርኛ (am)',
    'ar': u'العربية (ar)',
    'bg': u'български (bg)',
    'bn': u'বাংলা (bn)',
    'ca': u'català (ca)',
    'cs': u'čeština (cs)',
    'da': u'dansk (da)',
    'de': u'Deutsch (de)',
    'el': u'Ελληνικά (el)',
    'en_GB': u'British English (en_GB)',
    'en_US': u'U.S. English (en_US)',
    'es': u'español (es)',
    'et': u'eesti (et)',
    'eu': u'euskara (eu)',
    'fa': u'فارسی (fa)',
    'fi': u'suomi (fi)',
    'fil': u'Filipino (fil)',
    'fr': u'français (fr)',
    'gl': u'galego (gl)',
    'gu': u'ગુજરાતી (gu)',
    'hi': u'हिन्दी (hi)',
    'hr': u'hrvatski (hr)',
    'hu': u'magyar (hu)',
    'id': u'Bahasa Indonesia (id)',
    'is': u'íslenska (is)',
    'it': u'italiano (it)',
    'iw': u'עברית (iw)',  # Former ISO-639 code for Hebrew; should now be he
    'ja': u'日本語 (ja)',
    'kn': u'ಕನ್ನಡ (kn)',
    'ko': u'한국어 (ko)',
    'ln': u'Pig Latin',
    'lt': u'lietuvių (lt)',
    'lv': u'latviešu (lv)',
    'ml': u'മലയാളം (ml)',
    'mr': u'मराठी (mr)',
    'ms': u'Bahasa Melayu (ms)',
    'nl': u'Nederlands (nl)',
    'no': u'Nynorsk (no)',  # Correct ISO-369-1 is nn and ISO-369-2 is nno
    'pl': u'polski (pl)',
    'pt_BR': u'português do Brasil (pt_BR)',
    'pt_PT': u'português europeu (pt_PT)',
    'ro': u'română (ro)',
    'ru': u'русский (ru)',
    'sk': u'slovenský (sk)',
    'sl': u'slovenščina (sl)',
    'sr': u'Српски (sr)',
    'sv': u'svenska (sv)',
    'sw': u'Kiswahili (sw)',
    'ta': u'தமிழ் (ta)',
    'te': u'తెలుగు (te)',
    'th': u'ไทย (th)',
    'tr': u'Türkçe (tr)',
    'uk': u'українська (uk)',
    'ur': u'اردو (ur)',
    'vi': u'Tiếng Việt (vi)',
    'zh_CN': u'中文 (简体) (zh_CN)',  # Chinese (Simplified)
    'zh_TW': u'中文 (繁體) (zh_TW)',  # Chinese (Traditional)
    'zu': u'isiZulu (zu)',
}

def get_system_supported_locales():
    translations_path = os.path.join(
        appengine_config.BUNDLE_ROOT, 'modules/i18n/resources/locale')
    return sorted(os.listdir(translations_path) + ['ln'])

def get_locale_display_name(locale):
    return LOCALES_DISPLAY_NAMES.get(locale, locale)

def parse_accept_language(accept_language_str):
    """Parse a RFC 2616 Accept-Language string.

    Accept-Language strings are of the form
        en-US,en;q=0.8,el;q=0.6
    where each language string (en-US, en, el) may be followed by a quality
    score (q). So in the example US English has default quality score (1),
    English has quality score 0.8, and Greek has quality score 0.6.

    Args:
        accept_language_str: str. A string in RFC 2616 format. If the string is
        None or empty, an empty list is return.

    Returns:
        A list of pairs. The first element of the pair is the language code
        (a str) and the second element is either a float between 0 and 1.
        The list is sorted in decreasing order by q, so that the highest
        quality language is the first element of the list.

    Refs:
        http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14
    """
    if not accept_language_str:
        return []
    assert len(accept_language_str) < 8 * 1024

    parsed = []
    try:
        for item in accept_language_str.split(','):
            lang = item
            q = 1.0
            if ';' in item:
                lang, q_str = item.split(';')
                q = float(q_str[2:]) if q_str.startswith('q=') else float(q_str)
            lang = lang.replace('-', '_')
            parsed.append((lang, q))
        return sorted(parsed, None, lambda x: -x[1])
    except Exception:  # pylint: disable-msg=broad-except
        logging.exception('Bad Accept-Languager: %s', accept_language_str)
    return []
<commit_msg>Fix name of "Pig Latin" to something more generic<commit_after># -*- coding: utf-8; -*-
# Copyright 2014 Google Inc. All Rights Reserved.
#
# 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.

"""Functions used for Course Builder locale support."""

__author__ = 'John Orr (jorr@google.com)'

import logging
import os

import appengine_config

# Locale description information based on Babel Locale.display_name. However
# the names are collected here because (i) Babel does not have correct display
# names for all of the locales included, and (ii) Babel cannot access its
# localeinfo data when it is loaded as a Zip file.
LOCALES_DISPLAY_NAMES = {
    'af': u'Afrikaans (af)',
    'am': u'አማርኛ (am)',
    'ar': u'العربية (ar)',
    'bg': u'български (bg)',
    'bn': u'বাংলা (bn)',
    'ca': u'català (ca)',
    'cs': u'čeština (cs)',
    'da': u'dansk (da)',
    'de': u'Deutsch (de)',
    'el': u'Ελληνικά (el)',
    'en_GB': u'British English (en_GB)',
    'en_US': u'U.S. English (en_US)',
    'es': u'español (es)',
    'et': u'eesti (et)',
    'eu': u'euskara (eu)',
    'fa': u'فارسی (fa)',
    'fi': u'suomi (fi)',
    'fil': u'Filipino (fil)',
    'fr': u'français (fr)',
    'gl': u'galego (gl)',
    'gu': u'ગુજરાતી (gu)',
    'hi': u'हिन्दी (hi)',
    'hr': u'hrvatski (hr)',
    'hu': u'magyar (hu)',
    'id': u'Bahasa Indonesia (id)',
    'is': u'íslenska (is)',
    'it': u'italiano (it)',
    'iw': u'עברית (iw)',  # Former ISO-639 code for Hebrew; should now be he
    'ja': u'日本語 (ja)',
    'kn': u'ಕನ್ನಡ (kn)',
    'ko': u'한국어 (ko)',
    'ln': u'Fake Translation (ln)',
    'lt': u'lietuvių (lt)',
    'lv': u'latviešu (lv)',
    'ml': u'മലയാളം (ml)',
    'mr': u'मराठी (mr)',
    'ms': u'Bahasa Melayu (ms)',
    'nl': u'Nederlands (nl)',
    'no': u'Nynorsk (no)',  # Correct ISO-369-1 is nn and ISO-369-2 is nno
    'pl': u'polski (pl)',
    'pt_BR': u'português do Brasil (pt_BR)',
    'pt_PT': u'português europeu (pt_PT)',
    'ro': u'română (ro)',
    'ru': u'русский (ru)',
    'sk': u'slovenský (sk)',
    'sl': u'slovenščina (sl)',
    'sr': u'Српски (sr)',
    'sv': u'svenska (sv)',
    'sw': u'Kiswahili (sw)',
    'ta': u'தமிழ் (ta)',
    'te': u'తెలుగు (te)',
    'th': u'ไทย (th)',
    'tr': u'Türkçe (tr)',
    'uk': u'українська (uk)',
    'ur': u'اردو (ur)',
    'vi': u'Tiếng Việt (vi)',
    'zh_CN': u'中文 (简体) (zh_CN)',  # Chinese (Simplified)
    'zh_TW': u'中文 (繁體) (zh_TW)',  # Chinese (Traditional)
    'zu': u'isiZulu (zu)',
}

def get_system_supported_locales():
    translations_path = os.path.join(
        appengine_config.BUNDLE_ROOT, 'modules/i18n/resources/locale')
    return sorted(os.listdir(translations_path) + ['ln'])

def get_locale_display_name(locale):
    return LOCALES_DISPLAY_NAMES.get(locale, locale)

def parse_accept_language(accept_language_str):
    """Parse a RFC 2616 Accept-Language string.

    Accept-Language strings are of the form
        en-US,en;q=0.8,el;q=0.6
    where each language string (en-US, en, el) may be followed by a quality
    score (q). So in the example US English has default quality score (1),
    English has quality score 0.8, and Greek has quality score 0.6.

    Args:
        accept_language_str: str. A string in RFC 2616 format. If the string is
        None or empty, an empty list is return.

    Returns:
        A list of pairs. The first element of the pair is the language code
        (a str) and the second element is either a float between 0 and 1.
        The list is sorted in decreasing order by q, so that the highest
        quality language is the first element of the list.

    Refs:
        http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14
    """
    if not accept_language_str:
        return []
    assert len(accept_language_str) < 8 * 1024

    parsed = []
    try:
        for item in accept_language_str.split(','):
            lang = item
            q = 1.0
            if ';' in item:
                lang, q_str = item.split(';')
                q = float(q_str[2:]) if q_str.startswith('q=') else float(q_str)
            lang = lang.replace('-', '_')
            parsed.append((lang, q))
        return sorted(parsed, None, lambda x: -x[1])
    except Exception:  # pylint: disable-msg=broad-except
        logging.exception('Bad Accept-Languager: %s', accept_language_str)
    return []
<|endoftext|>


<commit_before>"""Test writing for graphs."""
import pytest

from crimemapper.graph_calcs import random_colors, offense_counter

def test_random_colors_type():
    """Assert that result is a string object."""
    result = random_colors()
    assert type(result) is str

def test_random_colors_format_front():
    """Assert that front format is correctly formated."""
    result = random_colors()
    assert result[:4] == 'rgb('

def test_random_colors_format_end():
    """Assert that the end of string is formatted correctly."""
    result = random_colors()
    assert result[-1] == ')'

def test_random_colors_ints():
    """Assert that numbers are int the correct place."""
    result = random_colors()
    result = result[4:-1]
    num_list = result.split(',')
    assert type(int(num_list[0])) is int
    assert type(int(num_list[1])) is int
    assert type(int(num_list[2])) is int

def test_random_colors_range():
    """Assert that numbers are int the correct place."""
    result = random_colors()
    result = result[4:-1]
    num_list = result.split(',')
    assert 0 <= int(num_list[0]) <= 255
    assert 0 <= int(num_list[1]) <= 255
    assert 0 <= int(num_list[2]) <= 255

def test_offense_counter_obj():
    """Assert that function returns a list."""
    test_list = ['cat', 'dog', 'cat', 'potato', 'potato']
    result = offense_counter(test_list)
    assert type(result) == list

def test_offense_counter_contains():
    """Assert that function returns a list of tuples."""
    test_list = ['cat', 'dog', 'cat', 'potato', 'potato']
    result = offense_counter(test_list)
    assert type(result[0]) == tuple

def test_offense_counter_contents_1():
    """Assert that first item in tuple is the offense."""
    test_list = ['cat', 'dog', 'cat', 'potato', 'potato']
    result = offense_counter(test_list)
    assert type(result[0][0]) == str

def test_offense_counter_contents_2():
    """Assert that second item in tuple is the the number of times counted."""
    test_list = ['cat', 'dog', 'cat', 'potato', 'potato']
    result = offense_counter(test_list)
    assert type(result[0][1]) == int
<commit_msg>Added one more for offense_counter.<commit_after>"""Test writing for graphs."""
import pytest

from crimemapper.graph_calcs import random_colors, offense_counter

def test_random_colors_type():
    """Assert that result is a string object."""
    result = random_colors()
    assert type(result) is str

def test_random_colors_format_front():
    """Assert that front format is correctly formated."""
    result = random_colors()
    assert result[:4] == 'rgb('

def test_random_colors_format_end():
    """Assert that the end of string is formatted correctly."""
    result = random_colors()
    assert result[-1] == ')'

def test_random_colors_ints():
    """Assert that numbers are int the correct place."""
    result = random_colors()
    result = result[4:-1]
    num_list = result.split(',')
    assert type(int(num_list[0])) is int
    assert type(int(num_list[1])) is int
    assert type(int(num_list[2])) is int

def test_random_colors_range():
    """Assert that numbers are int the correct place."""
    result = random_colors()
    result = result[4:-1]
    num_list = result.split(',')
    assert 0 <= int(num_list[0]) <= 255
    assert 0 <= int(num_list[1]) <= 255
    assert 0 <= int(num_list[2]) <= 255

def test_offense_counter_obj():
    """Assert that function returns a list."""
    test_list = ['cat', 'dog', 'cat', 'potato', 'potato']
    result = offense_counter(test_list)
    assert type(result) == list

def test_offense_counter_contains():
    """Assert that function returns a list of tuples."""
    test_list = ['cat', 'dog', 'cat', 'potato', 'potato']
    result = offense_counter(test_list)
    assert type(result[0]) == tuple

def test_offense_counter_tuple():
    """Assert that function returns a list of tuples with two items in each."""
    test_list = ['cat', 'dog', 'cat', 'potato', 'potato']
    result = offense_counter(test_list)
    assert len(result[0]) == 2

def test_offense_counter_contents_1():
    """Assert that first item in tuple is the offense."""
    test_list = ['cat', 'dog', 'cat', 'potato', 'potato']
    result = offense_counter(test_list)
    assert type(result[0][0]) == str

def test_offense_counter_contents_2():
    """Assert that second item in tuple is the the number of times counted."""
    test_list = ['cat', 'dog', 'cat', 'potato', 'potato']
    result = offense_counter(test_list)
    assert type(result[0][1]) == int
<|endoftext|>


<commit_before>import sqlite3

# get connection to sqlite3 terminology database
def get_connection():
    connection = sqlite3.connect('db/terminology.db')
    connection.row_factory = sqlite3.Row
    return connection

# execute submitted sql that must retrieve a resultset
# with two fields named 'code' and 'name'
# function returns [{code: 'code1', name: 'name1'}, {code: 'code2', name: 'name2'}, ...]
def get_code_name_list_result(sql, querytokens=None):
    connection = get_connection()
    results = []
    try:
        cursor = connection.cursor()
        if querytokens:
            cursor.execute(sql, querytokens)
        else:
            cursor.execute(sql)
        for row in cursor.fetchall():
            results.append({'code': row['code'], 'name': row['name']})
        cursor.close()
    except sqlite3.Error as e:
        print("An error occurred:", e.args[0])
    return results

# get a single row or a single field as a string
def get_single_string_result(sql, querytokens=None):
    connection = get_connection()
    result = None
    try:
        cursor = connection.cursor()
        if querytokens:
            cursor.execute(sql, querytokens)
        else:
            cursor.execute(sql)
        if cursor.arraysize > 0:
            result = cursor.fetchone()[0]
        cursor.close()
    except sqlite3.Error as e:
        print("An error occurred:", e.args[0])
    return result

def search_cancertypes_by_substring(query):
    sql = 'select code, name from ncit ' \
          'where semantic_type = "Neoplastic Process" ' \
          'or semantic_type = "Anatomical Structure"' \
          'and (name like ? or synonyms like ?)'
    querytokens = ['%' + query + '%', '%' + query + '%']
    results = get_code_name_list_result(sql, querytokens)
    return results

def search_biomarkers_by_substring(query):
    sql = 'select code, name from biomarkers where name like ?'
    querytokens = ['%' + query + '%']
    results = get_code_name_list_result(sql, querytokens)
    return results

def get_child_codes(code):
    sql = 'select code, name from ncit where parent_codes like ? or parent_codes like ?'
    # parent codes are in a pipe (|) delimited list
    # just matching on the first term we get spurious substring matches
    # such as C8461 matching C84615
    querytokens = ['%' + code, '%' + code + '|%']
    results = get_code_name_list_result(sql, querytokens)
    return results

def get_parent_codes(code):
    sql = 'select parent_codes from ncit where code = ?'
    parent_codes = get_single_string_result(sql, [code])
    results = []
    # parent codes are in a pipe (|) delimited list
    for parent_code in parent_codes.split('|'):
        sql = 'select code, name from ncit where code = ?'
        results.extend(get_code_name_list_result(sql, [parent_code]))
    return results

def get_name_for_code(domain, code):
    if domain == 'biomarkers':
        table = 'biomarkers'
    elif domain == 'diseases':
        table = 'neoplasm_core'
    else:
        table = 'ncit'

    sql = 'select name from ' + table + ' where code = ?'
    name = get_single_string_result(sql, [code])

    if name:
        return name

    sql = 'select name from ncit where code = ?'
    name = get_single_string_result(sql, [code])
    return name
<commit_msg>replaced print statement with logger<commit_after>import sqlite3
import logging

# create logger
logger = logging.getLogger('terminology')

# get connection to sqlite3 terminology database
def get_connection():
    connection = sqlite3.connect('db/terminology.db')
    connection.row_factory = sqlite3.Row
    return connection

# execute submitted sql that must retrieve a resultset
# with two fields named 'code' and 'name'
# function returns [{code: 'code1', name: 'name1'}, {code: 'code2', name: 'name2'}, ...]
def get_code_name_list_result(sql, querytokens=None):
    connection = get_connection()
    results = []
    try:
        cursor = connection.cursor()
        if querytokens:
            cursor.execute(sql, querytokens)
        else:
            cursor.execute(sql)
        for row in cursor.fetchall():
            results.append({'code': row['code'], 'name': row['name']})
        cursor.close()
    except sqlite3.Error as e:
        logger.error("An error occurred:", e.args[0])
    return results

# get a single row or a single field as a string
def get_single_string_result(sql, querytokens=None):
    connection = get_connection()
    result = None
    try:
        cursor = connection.cursor()
        if querytokens:
            cursor.execute(sql, querytokens)
        else:
            cursor.execute(sql)
        if cursor.arraysize > 0:
            result = cursor.fetchone()[0]
        cursor.close()
    except sqlite3.Error as e:
        logger.error("An error occurred:", e.args[0])
    return result

def search_cancertypes_by_substring(query):
    sql = 'select code, name from ncit ' \
          'where semantic_type = "Neoplastic Process" ' \
          'or semantic_type = "Anatomical Structure"' \
          'and (name like ? or synonyms like ?)'
    querytokens = ['%' + query + '%', '%' + query + '%']
    results = get_code_name_list_result(sql, querytokens)
    return results

def search_biomarkers_by_substring(query):
    sql = 'select code, name from biomarkers where name like ?'
    querytokens = ['%' + query + '%']
    results = get_code_name_list_result(sql, querytokens)
    return results

def get_child_codes(code):
    sql = 'select code, name from ncit where parent_codes like ? or parent_codes like ?'
    # parent codes are in a pipe (|) delimited list
    # just matching on the first term we get spurious substring matches
    # such as C8461 matching C84615
    querytokens = ['%' + code, '%' + code + '|%']
    results = get_code_name_list_result(sql, querytokens)
    return results

def get_parent_codes(code):
    sql = 'select parent_codes from ncit where code = ?'
    parent_codes = get_single_string_result(sql, [code])
    results = []
    # parent codes are in a pipe (|) delimited list
    for parent_code in parent_codes.split('|'):
        sql = 'select code, name from ncit where code = ?'
        results.extend(get_code_name_list_result(sql, [parent_code]))
    return results

def get_name_for_code(domain, code):
    if domain == 'biomarkers':
        table = 'biomarkers'
    elif domain == 'diseases':
        table = 'neoplasm_core'
    else:
        table = 'ncit'

    sql = 'select name from ' + table + ' where code = ?'
    name = get_single_string_result(sql, [code])

    if name:
        return name

    sql = 'select name from ncit where code = ?'
    name = get_single_string_result(sql, [code])
    return name
<|endoftext|>


<commit_before>__author__ = 'czue'
<commit_msg>[ci skip] remove authorship tag<commit_after>
<|endoftext|>


<commit_before># Copyright (c) 2015, The MITRE Corporation. All rights reserved.
# See LICENSE.txt for complete terms.

import unittest

from cybox.common import HashName, VocabString
import cybox.test
from cybox.utils import normalize_to_xml

class TestVocabString(unittest.TestCase):

    def test_plain(self):
        a = VocabString("test_value")
        self.assertTrue(a.is_plain())

    def test_is_plain_hashname(self):
        md5 = HashName("MD5")
        self.assertTrue(md5.is_plain())

    def test_is_plain_hashname(self):
        md5 = HashName("MD5")
        md5.xsi_type = "Some Other xsi:type"
        self.assertFalse(md5.is_plain())

    def test_round_trip(self):
        vocab_dict = {
                        'value': "test_value",
                        'vocab_name': "test_a",
                        'vocab_reference': "test_b",

                        'condition': "test_d",
                        # Leave out apply_condition since value is not a list.
                        'bit_mask': "test_1",
                        'pattern_type': "test_e",
                        'regex_syntax': "test_f",
                        'has_changed': "test_j",
                        'trend': "test_k",
                     }

        vocab_dict2 = cybox.test.round_trip_dict(VocabString, vocab_dict)
        cybox.test.assert_equal_ignore(vocab_dict, vocab_dict2, ['xsi:type'])

    # https://github.com/CybOXProject/python-cybox/issues/158
    def test_xsi_type_unicode(self):
        string = u"test\u2010value"
        vocab_dict = {
                        'value': string,
                        'condition': u"Equals",
                        'xsi:type': u"some_xsi_type",
                     }

        vocab_dict2 = cybox.test.round_trip_dict(VocabString, vocab_dict)
        self.assertEqual(vocab_dict, vocab_dict2)
        xml = VocabString.from_dict(vocab_dict).to_xml()
        string_utf8 = string.encode("utf-8")
        self.assertTrue(string_utf8 in xml)

    def test_round_trip_list(self):
        vocab_dict = {
                        'value': ['Value1', 'Value2', 'Value3'],
                        'condition': "Equals",
                        'apply_condition': "ALL",
                        'vocab_name': "Test",
                     }

        vocab_dict2 = cybox.test.round_trip_dict(VocabString, vocab_dict)
        cybox.test.assert_equal_ignore(vocab_dict, vocab_dict2, ['xsi:type'])

    def test_add_bad_value(self):
        from cybox.common import Hash

        def set_type(h):
            h.type_ = "Bad Value"

        h = Hash()
        self.assertRaises(ValueError, set_type, h)

if __name__ == "__main__":
    unittest.main()
<commit_msg>Added more VocabString unit tests<commit_after># Copyright (c) 2015, The MITRE Corporation. All rights reserved.
# See LICENSE.txt for complete terms.

import unittest

from cybox.common import HashName, VocabString
import cybox.test
from cybox.utils import normalize_to_xml

class TestVocabString(unittest.TestCase):

    def test_plain(self):
        a = VocabString("test_value")
        self.assertTrue(a.is_plain())

    def test_is_plain_hashname(self):
        md5 = HashName("MD5")
        self.assertTrue(md5.is_plain())

    def test_is_plain_hashname(self):
        md5 = HashName("MD5")
        md5.xsi_type = "Some Other xsi:type"
        self.assertFalse(md5.is_plain())

    def test_round_trip(self):
        vocab_dict = {
                        'value': "test_value",
                        'vocab_name': "test_a",
                        'vocab_reference': "test_b",

                        'condition': "test_d",
                        # Leave out apply_condition since value is not a list.
                        'bit_mask': "test_1",
                        'pattern_type': "test_e",
                        'regex_syntax': "test_f",
                        'has_changed': "test_j",
                        'trend': "test_k",
                     }

        vocab_dict2 = cybox.test.round_trip_dict(VocabString, vocab_dict)
        cybox.test.assert_equal_ignore(vocab_dict, vocab_dict2, ['xsi:type'])

    # https://github.com/CybOXProject/python-cybox/issues/158
    def test_xsi_type_unicode(self):
        string = u"test\u2010value"
        vocab_dict = {
                        'value': string,
                        'condition': u"Equals",
                        'xsi:type': u"some_xsi_type",
                     }

        vocab_dict2 = cybox.test.round_trip_dict(VocabString, vocab_dict)
        self.assertEqual(vocab_dict, vocab_dict2)
        xml = VocabString.from_dict(vocab_dict).to_xml()
        string_utf8 = string.encode("utf-8")
        self.assertTrue(string_utf8 in xml)

    def test_round_trip_list(self):
        vocab_dict = {
                        'value': ['Value1', 'Value2', 'Value3'],
                        'condition': "Equals",
                        'apply_condition': "ALL",
                        'vocab_name': "Test",
                     }

        vocab_dict2 = cybox.test.round_trip_dict(VocabString, vocab_dict)
        cybox.test.assert_equal_ignore(vocab_dict, vocab_dict2, ['xsi:type'])

    def test_add_bad_value(self):
        from cybox.common import Hash

        h = Hash()
        self.assertRaises(
            ValueError,
            setattr,
            h,
            'type_',
            "BAD VALUE"
        )

    def test_add_vocabstring(self):
        from cybox.common import Hash
        from cybox.common.vocabs import ActionName

        action = ActionName(ActionName.TERM_ADD_USER)
        h = Hash()
        h.type_ = action

        self.assertEqual(action, h.type_)

    def test_to_dict(self):
        from cybox.common.vocabs import ActionName
        d = ActionName(ActionName.TERM_ADD_USER).to_dict()
        self.assertEqual(d['xsi:type'], ActionName._XSI_TYPE)
        self.assertEqual(d['value'], ActionName.TERM_ADD_USER)

if __name__ == "__main__":
    unittest.main()
<|endoftext|>


<commit_before>import os

from dadd.worker.processes import WorkerProcess
from dadd.worker.utils import printf, call_cmd

class PythonWorkerProcess(WorkerProcess):

    def install_virtualenv(self):
        printf('Installing virtualenv package', self.output)
        call_cmd('pip install --upgrade virtualenv', self.output)

    def create_virtualenv(self, name='dadd-worker-venv'):
        self.install_virtualenv()
        printf('Creating the virtualenv', self.output)
        call_cmd(['virtualenv', name], self.output)

        venv_bin = os.path.abspath(os.path.join(name, 'bin'))
        os.environ['PATH'] = venv_bin + ':' + os.environ['PATH']
        self.log('Updated Path: %s' % os.environ['PATH'])

    def install_python_deps(self):
        self.create_virtualenv()

        # Make sure we have a list
        if isinstance(self.spec['python_deps'], basestring):
            self.spec['python_deps'] = [self.spec['python_deps']]

        for dep in self.spec['python_deps']:
            cmd = ['pip', 'install']

            if self.spec.get('python_cheeseshop'):
                cmd.extend(['-i', self.spec['python_cheeseshop']])

            cmd.append(dep)
            self.log('Running: %s' % ' '.join(cmd))
            call_cmd(cmd, self.output)

    def setup(self):
        super(PythonWorkerProcess, self).setup()
        if 'python_deps' in self.spec:
            self.install_python_deps()
<commit_msg>Allow specifying args per python dep.<commit_after>import os

from dadd.worker.processes import WorkerProcess
from dadd.worker.utils import printf, call_cmd

class PythonWorkerProcess(WorkerProcess):

    def install_virtualenv(self):
        printf('Installing virtualenv package', self.output)
        call_cmd('pip install --upgrade virtualenv', self.output)

    def create_virtualenv(self, name='dadd-worker-venv'):
        self.install_virtualenv()
        printf('Creating the virtualenv', self.output)
        call_cmd(['virtualenv', name], self.output)

        venv_bin = os.path.abspath(os.path.join(name, 'bin'))
        os.environ['PATH'] = venv_bin + ':' + os.environ['PATH']
        self.log('Updated Path: %s' % os.environ['PATH'])

    def install_python_deps(self):
        self.create_virtualenv()

        # Make sure we have a list
        if isinstance(self.spec['python_deps'], basestring):
            self.spec['python_deps'] = [self.spec['python_deps']]

        for dep in self.spec['python_deps']:
            cmd = ['pip', 'install']

            if self.spec.get('python_cheeseshop'):
                cmd.extend(['-i', self.spec['python_cheeseshop']])

            # a dep might be specific to a cheeseshop, so we are
            # implicitly allowing a dependency to do something like:
            #
            #   `-i http://mycheese.net mypkg>=3.0`
            #
            # We want each arg to be passed to the comand.
            cmd.extend(dep.split())
            self.log('Running: %s' % ' '.join(cmd))
            call_cmd(cmd, self.output)

    def setup(self):
        super(PythonWorkerProcess, self).setup()
        if 'python_deps' in self.spec:
            self.install_python_deps()
<|endoftext|>


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

# Copyright 2010 Theo Crevon
#
# 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.

import os
import sys

import License

class Stamper:
    """ Class defining methods allowing to
    create a language specific commented license
    in order to apply it as a file header"""

    def __init__(self):
        """Constructor"""
        pass

    def _getFilesList(self, path):
        """
        Recursively retrieves a given path files
        as a list

        path                    String : path to retrieve files from.
        """
        listed_elems = []

        for root, dirs, files in os.walk(path):
            for name in files:
                filename = os.path.join(root, name)
                listed_elem.append(filename)

        return(listed_elems)

    def _dumpFileContent(self, path):
        """
        Method dumping a file content to a list

        path                    String : file to dump path
        """
        fileDump = []

        try:
            fd = open(path, 'r')
            fileDump = fd.readlines()
            fileDump.append("\n\n")
            fd.close()
        except IOError as (errno, strerror):
            print "I/O error({0}): {1}".format(errno, strerror)

        return (fileDump)

    def _dumpFiles(self, files_list):
        """

        """
#        for f in files_list:
#            self.files_content.append(self._dumpFileContent(f))

    def _writeHeaderToFile(self, dest_filename, headerToWrite):
        """
        Method adding a given license list at the begining
        of a file

        dest_filename           String : candidate filename which license should
                                be applied to.
        header                  String : Formatted, license content to write
                                as a given destination file header.
        """
        try:
            fileDump =  self._dumpFileContentToList(dest_filename)
            fd = open(dest_filename, 'w')
            fd.seek(0)
            fd.writelines(headerToWrite + fileDump)
            fd.close()
        except IOError as (errno, strerror):
            print "I/O error({0}): {1}".format(errno, strerror)

    def applyLicense(self, license, path):
        """
        """
        self
<commit_msg>Updating getFilesList method in order to return a list of tuples containing, file extension and file path instead of only the file path.<commit_after>#!/usr/bin/env python

# Copyright 2010 Theo Crevon
#
# 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.

import os
import sys

import License

class Stamper:
    """ Class defining methods allowing to
    create a language specific commented license
    in order to apply it as a file header"""

    def __init__(self):
        """Constructor"""
        pass

    def _getFileExtension(self, filepath):
        """
        Extracts extension from file path.
        """
        file_name, file_extension = os.path.splitext(filepath)

        # return file_extension without it's
        # starting point
        return file_extension[1:]

    def _getFilesList(self, path, exclude_dotted=True):
        """
        Recursively retrieves a given path files
        as a list of tuples (file extension, file path).

        path                    String : path to retrieve files from.
        exclude_dotted          Boolean : Wheter to ignore paths beggining
                                with a dot while walking dirs.
                                Ex : .git .svn .emacs
        """
        listed_elems = []

        for root, dirs, files in os.walk(path):
            # If bool param is True, exclude dotted
            # dirs from computing.
            if exclude_dotted:
                for (counter, dir) in enumerate(dirs):
                    if dir.startswith('.'):
                        del dirs[counter - 1]
            for name in files:
                file_path = os.path.join(root, name)
                file_extension = self._getFileExtension(file_path)
                listed_elems.append((file_extension, file_path))

        return(listed_elems)

    def _dumpFileContent(self, path):
        """
        Method dumping a file content to a list

        path                    String : file to dump path
        """
        fileDump = []

        try:
            fd = open(path, 'r')
            fileDump = fd.readlines()
            fileDump.append("\n\n")
            fd.close()
        except IOError as (errno, strerror):
            print "I/O error({0}): {1}".format(errno, strerror)

        return (fileDump)

    def _dumpFiles(self, files_list):
        """

        """
#        for f in files_list:
#            self.files_content.append(self._dumpFileContent(f))

    def _writeHeaderToFile(self, dest_filename, headerToWrite):
        """
        Method adding a given license list at the begining
        of a file

        dest_filename           String : candidate filename which license should
                                be applied to.
        header                  String : Formatted, license content to write
                                as a given destination file header.
        """
        try:
            fileDump =  self._dumpFileContentToList(dest_filename)
            fd = open(dest_filename, 'w')
            fd.seek(0)
            fd.writelines(headerToWrite + fileDump)
            fd.close()
        except IOError as (errno, strerror):
            print "I/O error({0}): {1}".format(errno, strerror)

    def applyLicense(self, license, path):
        """
        """
        files_in_path = self._getFilesList(path)
        print files_in_path<|endoftext|>


<commit_before>from subdaap import monkey # noqa

from subdaap.application import Application

from subdaap.utils import VerboseAction, PathAction, NewPathAction

import argparse
import logging
import atexit
import sys
import gc
import os

# Logger instance
logger = logging.getLogger(__name__)

def parse_arguments():
    """
    Parse commandline arguments.
    """

    parser = argparse.ArgumentParser()

    # Add options
    parser.add_argument(
        "-D", "--daemon", action="store_true", help="run as daemon")
    parser.add_argument(
        "-v", "--verbose", nargs="?", action=VerboseAction, default=0,
        help="toggle verbose mode (-vv, -vvv for more)")
    parser.add_argument(
        "-c", "--config-file", action=PathAction, default="config.ini",
        help="config file")
    parser.add_argument(
        "-d", "--data-dir", action=PathAction, default=os.getcwd(),
        help="data directory")
    parser.add_argument(
        "-p", "--pid-file", action=NewPathAction, help="pid file")
    parser.add_argument(
        "-l", "--log-file", action=NewPathAction, help="log file")

    # Parse command line
    return parser.parse_args(), parser

def setup_logging(console=True, log_file=False, verbose=False):
    """
    """

    # Configure logging
    formatter = logging.Formatter(
        "%(asctime)s - %(name)s - %(levelname)s - %(message)s")
    level = logging.DEBUG if verbose else logging.INFO

    # Add console output
    if console:
        console_log_handler = logging.StreamHandler()
        console_log_handler.setLevel(level)
        console_log_handler.setFormatter(formatter)
        logging.getLogger().addHandler(console_log_handler)

    # Add file output
    if log_file:
        file_log_handler = logging.FileHandler(log_file)
        file_log_handler.setLevel(level)
        file_log_handler.setFormatter(formatter)
        logging.getLogger().addHandler(file_log_handler)

    logging.getLogger().setLevel(level)
    logger.info("Verbose level is %d", verbose)

def daemonize(pid_file=None):
    """
    Daemonize the current process. Returns the PID of the continuing child
    process. As an extra option, the PID of the child process can be written to
    a specified pid file.
    """

    # Dependency check to make sure the imports are OK. Saves you from a lot of
    # debugging trouble.
    assert atexit.register and os.fork and sys.stdout and gc.collect

    # Force cleanup old resources to minimize the risk of sharing them.
    gc.collect()

    # First fork
    try:
        if os.fork() > 0:
            os._exit(0)
    except OSError as e:
        sys.stderr.write("Unable to fork: %d (%s)\n" % (e.errno, e.strerror))
        sys.exit(1)

    # Decouple from parent
    os.setsid()
    os.umask(0)

    # Second fork
    try:
        if os.fork() > 0:
            os._exit(0)
    except OSError as e:
        sys.stderr.write("Unable to fork: %d (%s)\n" % (e.errno, e.strerror))
        sys.exit(1)

    # Redirect file descriptors
    sys.stdout.flush()
    sys.stderr.flush()

    stdin = file("/dev/null", "r")
    stdout = file("/dev/null", "a+")
    stderr = file("/dev/null", "a+", 0)

    os.dup2(stdin.fileno(), sys.stdin.fileno())
    os.dup2(stdout.fileno(), sys.stdout.fileno())
    os.dup2(stderr.fileno(), sys.stderr.fileno())

    # Write PID file
    if pid_file:
        atexit.register(os.remove, pid_file)

        with open(pid_file, "w+") as fp:
            fp.write("%d" % os.getpid())

    # Return the PID
    return os.getpid()

def main():
    """
    Main entry point. Parses arguments, daemonize and creates the application.
    """

    # Parse arguments and configure application instance.
    arguments, parser = parse_arguments()

    if arguments.daemon:
        daemonize(arguments.pid_file)

    setup_logging(not arguments.daemon, arguments.log_file, arguments.verbose)

    # Change to data directory
    os.chdir(arguments.data_dir)

    # Create application instance and run it.
    try:
        application = Application(
            config_file=arguments.config_file, data_dir=arguments.data_dir,
            verbose=arguments.verbose)
    except Exception as e:
        logger.error("One or more components failed to initialize: %s", e)
        raise
        return 1

    try:
        application.start()
    except KeyboardInterrupt:
        application.stop()

# E.g. `python SubDaap.py --daemonize --config-file=config.ini"
if __name__ == "__main__":
    sys.exit(main())
<commit_msg>Docs.<commit_after>from subdaap import monkey # noqa

from subdaap.application import Application

from subdaap.utils import VerboseAction, PathAction, NewPathAction

import argparse
import logging
import atexit
import sys
import gc
import os

# Logger instance
logger = logging.getLogger(__name__)

def parse_arguments():
    """
    Parse commandline arguments.
    """

    parser = argparse.ArgumentParser()

    # Add options
    parser.add_argument(
        "-D", "--daemon", action="store_true", help="run as daemon")
    parser.add_argument(
        "-v", "--verbose", nargs="?", action=VerboseAction, default=0,
        help="toggle verbose mode (-vv, -vvv for more)")
    parser.add_argument(
        "-c", "--config-file", action=PathAction, default="config.ini",
        help="config file")
    parser.add_argument(
        "-d", "--data-dir", action=PathAction, default=os.getcwd(),
        help="data directory")
    parser.add_argument(
        "-p", "--pid-file", action=NewPathAction, help="pid file")
    parser.add_argument(
        "-l", "--log-file", action=NewPathAction, help="log file")

    # Parse command line
    return parser.parse_args(), parser

def setup_logging(console=True, log_file=False, verbose=False):
    """
    """

    # Configure logging
    formatter = logging.Formatter(
        "%(asctime)s - %(name)s - %(levelname)s - %(message)s")
    level = logging.DEBUG if verbose else logging.INFO

    # Add console output handler
    if console:
        console_log_handler = logging.StreamHandler()
        console_log_handler.setLevel(level)
        console_log_handler.setFormatter(formatter)
        logging.getLogger().addHandler(console_log_handler)

    # Add file output handler
    if log_file:
        file_log_handler = logging.FileHandler(log_file)
        file_log_handler.setLevel(level)
        file_log_handler.setFormatter(formatter)
        logging.getLogger().addHandler(file_log_handler)

    logging.getLogger().setLevel(level)
    logger.info("Verbose level is %d", verbose)

def daemonize(pid_file=None):
    """
    Daemonize the current process. Returns the PID of the continuing child
    process. As an extra option, the PID of the child process can be written to
    a specified PID file.

    Note that parent process ends with `os._exit` instead of `sys.exit`. The
    first will not trigger any cleanups that may have been set. These are left
    for the child process that continues.

    :param str pid_file: Path to PID file to write process ID into. Must be in
                         a writeable folder. If left `None`, no file will be
                         written.
    :return: Process ID
    :rtype: int
    """

    # Dependency check to make sure the imports are OK. Saves you from a lot of
    # debugging trouble when you forget to import them.
    assert atexit.register and os.fork and sys.stdout and gc.collect

    # Force cleanup old resources to minimize the risk of sharing them.
    gc.collect()

    # First fork
    try:
        if os.fork() > 0:
            os._exit(0)
    except OSError as e:
        sys.stderr.write("Unable to fork: %d (%s)\n" % (e.errno, e.strerror))
        sys.exit(1)

    # Decouple from parent
    os.setsid()
    os.umask(0)

    # Second fork
    try:
        if os.fork() > 0:
            os._exit(0)
    except OSError as e:
        sys.stderr.write("Unable to fork: %d (%s)\n" % (e.errno, e.strerror))
        sys.exit(1)

    # Redirect file descriptors
    sys.stdout.flush()
    sys.stderr.flush()

    stdin = file("/dev/null", "r")
    stdout = file("/dev/null", "a+")
    stderr = file("/dev/null", "a+", 0)

    os.dup2(stdin.fileno(), sys.stdin.fileno())
    os.dup2(stdout.fileno(), sys.stdout.fileno())
    os.dup2(stderr.fileno(), sys.stderr.fileno())

    # Write PID file
    if pid_file:
        atexit.register(os.remove, pid_file)

        with open(pid_file, "w+") as fp:
            fp.write("%d" % os.getpid())

    # Return the PID
    return os.getpid()

def main():
    """
    Main entry point. Parses arguments, daemonize and creates the application.
    """

    # Parse arguments and configure application instance.
    arguments, parser = parse_arguments()

    if arguments.daemon:
        daemonize(arguments.pid_file)

    setup_logging(not arguments.daemon, arguments.log_file, arguments.verbose)

    # Change to data directory
    os.chdir(arguments.data_dir)

    # Create application instance and run it.
    try:
        application = Application(
            config_file=arguments.config_file, data_dir=arguments.data_dir,
            verbose=arguments.verbose)
    except Exception as e:
        logger.error("One or more components failed to initialize: %s", e)
        raise
        return 1

    try:
        application.start()
    except KeyboardInterrupt:
        application.stop()

# E.g. `python SubDaap.py --daemonize --config-file=config.ini"
if __name__ == "__main__":
    sys.exit(main())
<|endoftext|>