<commit_before>#!python
# -*- coding: utf-8 -*-

#
# Copyright (c) 2011-2015 Genestack Limited
# All Rights Reserved
# THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF GENESTACK LIMITED
# The copyright notice above does not evidence any
# actual or intended publication of such source code.
#

import sys
import os
import urllib2
import zipfile
import xml.dom.minidom as minidom
import json
from collections import namedtuple
from genestack import GenestackException
from genestack.GenestackShell import GenestackShell, Command

APPLICATION_ID = 'application-manager'

SCOPE_DICT = {
    'system': 'SYSTEM',
    'user': 'USER',
    'session': 'SESSION'
}
DEFAULT_SCOPE = 'user'

class Info(Command):
    COMMAND = 'info'
    DESCRIPTION = 'Read and show info from applications JAR file.'
    OFFLINE = True

    def update_parser(self, p):
        p.add_argument(
            '-f', '--with-filename', action='store_true',
            help='show file names for each JAR'
        )
        p.add_argument(
            '-F', '--no-filename', action='store_true',
            help='do not show file names'
        )
        p.add_argument(
            '--vendor', action='store_true',
            help='show only vendor for each JAR file'
        )
        p.add_argument(
            'files', metavar='<jar_file_or_folder>', nargs='+',
            help='file to upload or folder with single JAR file inside (recursively)'
        )

    def run(self):
        jar_files = [resolve_jar_file(f) for f in self.args.files]
        return show_info(
            jar_files, self.args.vendor,
            self.args.with_filename, self.args.no_filename
        )

class Install(Command):
    COMMAND = 'install'
    DESCRIPTION = 'Upload and install JAR files to Genestack system.'

    def update_parser(self, p):
        p.add_argument(
            '-o', '--override', action='store_true',
            help='overwrite old version of applications with the new one'
        )
        p.add_argument(
            '-s', '--stable', action='store_true',
            help='mark installed applications as stable'
        )
        p.add_argument(
            '-S', '--scope', metavar='<scope>', choices=SCOPE_DICT.keys(),
            default=DEFAULT_SCOPE,
            help='scope in which application will be stable'
                 ' (default is \'%s\'): %s' %
                 (DEFAULT_SCOPE, ' | '.join(SCOPE_DICT.keys()))
        )
        p.add_argument(
            'version', metavar='<version>',
            help='version of applications to upload'
        )
        p.add_argument(
            'files', metavar='<jar_file_or_folder>', nargs='+',
            help='file to upload or folder with single JAR file inside (recursively)'
        )

    def run(self):
        jar_files = [resolve_jar_file(f) for f in self.args.files]
        return upload_file(
            self.connection.application(APPLICATION_ID),
            jar_files, self.args.version, self.args.override,
            self.args.stable, self.args.scope
        )

class ListVersions(Command):
    COMMAND = 'versions'
    DESCRIPTION = 'Show information about available applications.'

    def update_parser(self, p):
        p.add_argument(
            '-s', action='store_true', dest='show_stable',
            help='display stable scopes in output (S: System, U: User, E: sEssion)'
        )
        p.add_argument(
            '-o', action='store_true', dest='show_owned',
            help='show only versions owned by current user'
        )
        p.add_argument(
            'app_id', metavar='<appId>',
            help='application identifier to show versions'
        )

    def run(self):
        app_id = self.args.app_id
        stable_versions = None
        if self.args.show_stable:
            stable_versions = self.connection.application(APPLICATION_ID).invoke('getStableVersions', app_id)
        result = self.connection.application(APPLICATION_ID).invoke('listVersions', app_id, self.args.show_owned)
        result.sort()
        for item in result:
            if stable_versions is None:
                print item
            else:
                print '%1s%1s%1s %s' % (
                    'S' if item == stable_versions.get('SYSTEM') else '-',
                    'U' if item == stable_versions.get('USER') else '-',
                    'E' if item == stable_versions.get('SESSION') else '-',
                    item
                )

class ListApplications(Command):
    COMMAND = 'applications'
    DESCRIPTION = 'Show information about available applications.'

    def run(self):
        result = self.connection.application(APPLICATION_ID).invoke('listApplications')
        result.sort()
        for item in result:
            print item

class MarkAsStable(Command):
    COMMAND = 'stable'
    description = 'Mark applications of the specified version as stable.'

    def update_parser(self, p):
        p.add_argument(
            'version', metavar='<version>',
            help='applications version or \'-\' (minus sign) to remove'
                 ' stable version'
        )
        p.add_argument(
            'app_id_list', metavar='<appId>', nargs='+',
            help='application identifier to mark as stable'
        )
        p.add_argument(
            '-S', '--scope', metavar='<scope>', choices=SCOPE_DICT.keys(),
            default=DEFAULT_SCOPE,
            help='scope in which application will be stable'
                 ' (default is \'%s\'): %s' %
                 (DEFAULT_SCOPE, ' | '.join(SCOPE_DICT.keys()))
        )

    def run(self):
        version = self.args.version
        if version == '-':
            version = None
        return mark_as_stable(
            self.connection.application(APPLICATION_ID), version, self.args.app_id_list,
            self.args.scope
        )

class Remove(Command):
    COMMAND = 'remove'
    DESCRIPTION = 'Remove specific version of applications'

    def update_parser(self, p):
        p.add_argument(
            'version', metavar='<version>', help='applications version'
        )
        p.add_argument(
            'app_id_list', metavar='<appId>', nargs='+',
            help='identifier of application to remove'
        )

    def run(self):
        return remove_applications(
            self.connection.application(APPLICATION_ID), self.args.version, self.args.app_id_list
        )

class Reload(Command):
    COMMAND = 'reload'
    DESCRIPTION = 'Reload specific version of applications'

    def update_parser(self, p):
        p.add_argument(
            'version', metavar='<version>', help='applications version'
        )
        p.add_argument(
            'app_id_list', metavar='<appId>', nargs='+',
            help='application identifier to mark as stable'
        )

    def run(self):
        return reload_applications(
            self.connection.application(APPLICATION_ID), self.args.version, self.args.app_id_list
        )

# FIXME: This class should be removed; it is written only for debug purposes:
class Invoke(Command):
    COMMAND = 'invoke'
    DESCRIPTION = 'Invoke method of stable application'

    def update_parser(self, p):
        p.add_argument(
            'app_id', metavar='<appId>',
            help='application identifier'
        )
        p.add_argument(
            'method_name', metavar='<method>',
            help='application method to call'
        )
        p.add_argument(
            'arguments', metavar='<args>', nargs='*',
            help='application method to call'
        )

    def run(self):
        application = self.connection.application(self.args.app_id)
        args = []
        for arg in self.args.arguments:
            try:
                args.append(json.loads(arg))
            except ValueError:
                args.append(arg)
        response = application.invoke(self.args.method_name, *args)
        if isinstance(response, list):
            for item in response:
                print item
        else:
            print response

def resolve_jar_file(file_path):
    if not os.path.isdir(file_path):
        return file_path

    jar_files = []
    for dirpath, dirnames, filenames in os.walk(file_path, followlinks=True):
        for f in filenames:
            if f.lower().endswith('.jar'):
                jar_files.append(os.path.join(dirpath, f))

    if len(jar_files) > 1:
        raise GenestackException('Too many JAR files found inside folder: %s' % file_path)
    elif not jar_files:
        raise GenestackException('No JAR files found inside folder: %s' % file_path)

    return jar_files[0]

def mark_as_stable(application, version, app_id_list, scope):
    try:
        print('Mark as stable (%s scope)' % scope)
        scope = SCOPE_DICT[scope]
        for app_id in app_id_list:
            sys.stdout.write('%-40s ... ' % app_id)
            sys.stdout.flush()
            application.invoke('markAsStable', app_id, scope, version)
            sys.stdout.write('ok\n')
            sys.stdout.flush()
    except Exception as e:
        sys.stdout.flush()
        sys.stderr.write('Exception received: %s\n' % e)
        sys.stderr.flush()
        return 1

def remove_applications(application, version, app_id_list):
    try:
        print('Removing applications')
        for app_id in app_id_list:
            sys.stdout.write('%s ... ' % app_id)
            sys.stdout.flush()
            application.invoke('removeApplication', app_id, version)
            sys.stdout.write('ok\n')
            sys.stdout.flush()
    except Exception as e:
        sys.stdout.flush()
        sys.stderr.write('Exception received: %s\n' % e)
        sys.stderr.flush()
        return 1

def reload_applications(application, version, app_id_list):
    try:
        print('Reloading applications')
        for app_id in app_id_list:
            sys.stdout.write('%s ... ' % app_id)
            sys.stdout.flush()
            application.invoke('reloadApplication', app_id, version)
            sys.stdout.write('ok\n')
            sys.stdout.flush()
    except Exception as e:
        sys.stdout.flush()
        sys.stderr.write('Exception received: %s\n' % e)
        sys.stderr.flush()
        return 1

def upload_file(application, files_list, version, override, stable, scope):
    for file_path in files_list:
        result = upload_single_file(
            application, file_path, version, override,
            stable, scope
        )
        if result is not None and result != 0:
            return result

def upload_single_file(application, file_path, version, override,
                       stable, scope):
    try:
        parameters = {'version': version, 'override': override}
        upload_token = application.invoke('getUploadToken', parameters)
    except Exception as e:
        sys.stdout.flush()
        sys.stderr.write('Exception received: %s\n' % e)
        sys.stderr.flush()
        return 1

    if upload_token is None:
        sys.stdout.flush()
        sys.stderr.write('Received null token, the upload is not accepted')
        sys.stderr.flush()
        return 1

    # upload_token, as returned by json.load(), is a Unicode string.
    # Without the conversion, urllib2.py passes a Unicode URL created from it
    # to httplib.py, and httplib.py fails in a non-graceful way
    # (http://bugs.python.org/issue12398)
    upload_token = upload_token.encode('UTF-8', 'ignore')
    try:
        result = application.upload_file(file_path, upload_token)
        # hack before fix ApplicationManagerApplication#processReceivedFile // TODO: return some useful information
        if result:
            print result

    except urllib2.HTTPError as e:
        sys.stdout.flush()
        sys.stderr.write('HTTP Error %s: %s\n' % (e.code, e.read()))
        sys.stderr.flush()
        return 1

    if not stable:
        return

    app_info = read_jar_file(file_path)

    return mark_as_stable(application, version, app_info.identifiers, scope)

AppInfo = namedtuple('AppInfo', [
    'vendor', 'identifiers'
])

def read_jar_file(file_path):
    with zipfile.ZipFile(file_path) as zip_file:
        try:
            info = zip_file.getinfo('applications.xml')
            with zip_file.open(info) as manifest:
                doc = minidom.parse(manifest)
                namespace = doc.documentElement.namespaceURI
                applications = doc.getElementsByTagNameNS(namespace, 'application')
                vendor = doc.getElementsByTagNameNS(namespace, 'vendor')[0].firstChild.nodeValue
                identifiers = [
                    vendor + '/' + a.getElementsByTagNameNS(namespace, 'id')[0].firstChild.nodeValue
                    for a in applications
                ]
        except KeyError:
            raise GenestackException('Unable to read applications.xml manifest from JAR')
        return AppInfo(vendor, identifiers)

def show_info(files, vendor_only, with_filename, no_filename):
    first_file = True
    for file_path in files:
        app_info = read_jar_file(file_path)

        if vendor_only:
            if no_filename:
                print app_info.vendor
            else:
                print '%s %s' % (file_path, app_info.vendor)
            continue

        if with_filename or not no_filename and len(files) > 1:
            if not first_file:
                print ''
            print 'File:', file_path

        print 'Vendor:', app_info.vendor
        print 'Applications:'
        for app_id in app_info.identifiers:
            print '\t%s' % app_id

        first_file = False

class ApplicationManager(GenestackShell):
    DESCRIPTION = ('Application manager is a script that lets you to add new applications into the system, '
                   'remove your uploaded applications from the system, '
                   'list available applications and do other related things.')
    INTRO = "Application manager shell.\nType 'help' for list of available commands.\n\n"
    COMMAND_LIST = [Info, Install, ListVersions, ListApplications, MarkAsStable, Remove, Reload, Invoke]

if __name__ == '__main__':
    shell = ApplicationManager()
    shell.cmdloop()
<commit_msg>Add missed description for stable.<commit_after>#!python
# -*- coding: utf-8 -*-

#
# Copyright (c) 2011-2015 Genestack Limited
# All Rights Reserved
# THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF GENESTACK LIMITED
# The copyright notice above does not evidence any
# actual or intended publication of such source code.
#

import sys
import os
import urllib2
import zipfile
import xml.dom.minidom as minidom
import json
from collections import namedtuple
from genestack import GenestackException
from genestack.GenestackShell import GenestackShell, Command

APPLICATION_ID = 'application-manager'

SCOPE_DICT = {
    'system': 'SYSTEM',
    'user': 'USER',
    'session': 'SESSION'
}
DEFAULT_SCOPE = 'user'

class Info(Command):
    COMMAND = 'info'
    DESCRIPTION = 'Read and show info from applications JAR file.'
    OFFLINE = True

    def update_parser(self, p):
        p.add_argument(
            '-f', '--with-filename', action='store_true',
            help='show file names for each JAR'
        )
        p.add_argument(
            '-F', '--no-filename', action='store_true',
            help='do not show file names'
        )
        p.add_argument(
            '--vendor', action='store_true',
            help='show only vendor for each JAR file'
        )
        p.add_argument(
            'files', metavar='<jar_file_or_folder>', nargs='+',
            help='file to upload or folder with single JAR file inside (recursively)'
        )

    def run(self):
        jar_files = [resolve_jar_file(f) for f in self.args.files]
        return show_info(
            jar_files, self.args.vendor,
            self.args.with_filename, self.args.no_filename
        )

class Install(Command):
    COMMAND = 'install'
    DESCRIPTION = 'Upload and install JAR files to Genestack system.'

    def update_parser(self, p):
        p.add_argument(
            '-o', '--override', action='store_true',
            help='overwrite old version of applications with the new one'
        )
        p.add_argument(
            '-s', '--stable', action='store_true',
            help='mark installed applications as stable'
        )
        p.add_argument(
            '-S', '--scope', metavar='<scope>', choices=SCOPE_DICT.keys(),
            default=DEFAULT_SCOPE,
            help='scope in which application will be stable'
                 ' (default is \'%s\'): %s' %
                 (DEFAULT_SCOPE, ' | '.join(SCOPE_DICT.keys()))
        )
        p.add_argument(
            'version', metavar='<version>',
            help='version of applications to upload'
        )
        p.add_argument(
            'files', metavar='<jar_file_or_folder>', nargs='+',
            help='file to upload or folder with single JAR file inside (recursively)'
        )

    def run(self):
        jar_files = [resolve_jar_file(f) for f in self.args.files]
        return upload_file(
            self.connection.application(APPLICATION_ID),
            jar_files, self.args.version, self.args.override,
            self.args.stable, self.args.scope
        )

class ListVersions(Command):
    COMMAND = 'versions'
    DESCRIPTION = 'Show information about available applications.'

    def update_parser(self, p):
        p.add_argument(
            '-s', action='store_true', dest='show_stable',
            help='display stable scopes in output (S: System, U: User, E: sEssion)'
        )
        p.add_argument(
            '-o', action='store_true', dest='show_owned',
            help='show only versions owned by current user'
        )
        p.add_argument(
            'app_id', metavar='<appId>',
            help='application identifier to show versions'
        )

    def run(self):
        app_id = self.args.app_id
        stable_versions = None
        if self.args.show_stable:
            stable_versions = self.connection.application(APPLICATION_ID).invoke('getStableVersions', app_id)
        result = self.connection.application(APPLICATION_ID).invoke('listVersions', app_id, self.args.show_owned)
        result.sort()
        for item in result:
            if stable_versions is None:
                print item
            else:
                print '%1s%1s%1s %s' % (
                    'S' if item == stable_versions.get('SYSTEM') else '-',
                    'U' if item == stable_versions.get('USER') else '-',
                    'E' if item == stable_versions.get('SESSION') else '-',
                    item
                )

class ListApplications(Command):
    COMMAND = 'applications'
    DESCRIPTION = 'Show information about available applications.'

    def run(self):
        result = self.connection.application(APPLICATION_ID).invoke('listApplications')
        result.sort()
        for item in result:
            print item

class MarkAsStable(Command):
    COMMAND = 'stable'
    DESCRIPTION = 'Mark applications of the specified version as stable.'

    def update_parser(self, p):
        p.add_argument(
            'version', metavar='<version>',
            help='applications version or \'-\' (minus sign) to remove'
                 ' stable version'
        )
        p.add_argument(
            'app_id_list', metavar='<appId>', nargs='+',
            help='application identifier to mark as stable'
        )
        p.add_argument(
            '-S', '--scope', metavar='<scope>', choices=SCOPE_DICT.keys(),
            default=DEFAULT_SCOPE,
            help='scope in which application will be stable'
                 ' (default is \'%s\'): %s' %
                 (DEFAULT_SCOPE, ' | '.join(SCOPE_DICT.keys()))
        )

    def run(self):
        version = self.args.version
        if version == '-':
            version = None
        return mark_as_stable(
            self.connection.application(APPLICATION_ID), version, self.args.app_id_list,
            self.args.scope
        )

class Remove(Command):
    COMMAND = 'remove'
    DESCRIPTION = 'Remove specific version of applications'

    def update_parser(self, p):
        p.add_argument(
            'version', metavar='<version>', help='applications version'
        )
        p.add_argument(
            'app_id_list', metavar='<appId>', nargs='+',
            help='identifier of application to remove'
        )

    def run(self):
        return remove_applications(
            self.connection.application(APPLICATION_ID), self.args.version, self.args.app_id_list
        )

class Reload(Command):
    COMMAND = 'reload'
    DESCRIPTION = 'Reload specific version of applications'

    def update_parser(self, p):
        p.add_argument(
            'version', metavar='<version>', help='applications version'
        )
        p.add_argument(
            'app_id_list', metavar='<appId>', nargs='+',
            help='application identifier to mark as stable'
        )

    def run(self):
        return reload_applications(
            self.connection.application(APPLICATION_ID), self.args.version, self.args.app_id_list
        )

# FIXME: This class should be removed; it is written only for debug purposes:
class Invoke(Command):
    COMMAND = 'invoke'
    DESCRIPTION = 'Invoke method of stable application'

    def update_parser(self, p):
        p.add_argument(
            'app_id', metavar='<appId>',
            help='application identifier'
        )
        p.add_argument(
            'method_name', metavar='<method>',
            help='application method to call'
        )
        p.add_argument(
            'arguments', metavar='<args>', nargs='*',
            help='application method to call'
        )

    def run(self):
        application = self.connection.application(self.args.app_id)
        args = []
        for arg in self.args.arguments:
            try:
                args.append(json.loads(arg))
            except ValueError:
                args.append(arg)
        response = application.invoke(self.args.method_name, *args)
        if isinstance(response, list):
            for item in response:
                print item
        else:
            print response

def resolve_jar_file(file_path):
    if not os.path.isdir(file_path):
        return file_path

    jar_files = []
    for dirpath, dirnames, filenames in os.walk(file_path, followlinks=True):
        for f in filenames:
            if f.lower().endswith('.jar'):
                jar_files.append(os.path.join(dirpath, f))

    if len(jar_files) > 1:
        raise GenestackException('Too many JAR files found inside folder: %s' % file_path)
    elif not jar_files:
        raise GenestackException('No JAR files found inside folder: %s' % file_path)

    return jar_files[0]

def mark_as_stable(application, version, app_id_list, scope):
    try:
        print('Mark as stable (%s scope)' % scope)
        scope = SCOPE_DICT[scope]
        for app_id in app_id_list:
            sys.stdout.write('%-40s ... ' % app_id)
            sys.stdout.flush()
            application.invoke('markAsStable', app_id, scope, version)
            sys.stdout.write('ok\n')
            sys.stdout.flush()
    except Exception as e:
        sys.stdout.flush()
        sys.stderr.write('Exception received: %s\n' % e)
        sys.stderr.flush()
        return 1

def remove_applications(application, version, app_id_list):
    try:
        print('Removing applications')
        for app_id in app_id_list:
            sys.stdout.write('%s ... ' % app_id)
            sys.stdout.flush()
            application.invoke('removeApplication', app_id, version)
            sys.stdout.write('ok\n')
            sys.stdout.flush()
    except Exception as e:
        sys.stdout.flush()
        sys.stderr.write('Exception received: %s\n' % e)
        sys.stderr.flush()
        return 1

def reload_applications(application, version, app_id_list):
    try:
        print('Reloading applications')
        for app_id in app_id_list:
            sys.stdout.write('%s ... ' % app_id)
            sys.stdout.flush()
            application.invoke('reloadApplication', app_id, version)
            sys.stdout.write('ok\n')
            sys.stdout.flush()
    except Exception as e:
        sys.stdout.flush()
        sys.stderr.write('Exception received: %s\n' % e)
        sys.stderr.flush()
        return 1

def upload_file(application, files_list, version, override, stable, scope):
    for file_path in files_list:
        result = upload_single_file(
            application, file_path, version, override,
            stable, scope
        )
        if result is not None and result != 0:
            return result

def upload_single_file(application, file_path, version, override,
                       stable, scope):
    try:
        parameters = {'version': version, 'override': override}
        upload_token = application.invoke('getUploadToken', parameters)
    except Exception as e:
        sys.stdout.flush()
        sys.stderr.write('Exception received: %s\n' % e)
        sys.stderr.flush()
        return 1

    if upload_token is None:
        sys.stdout.flush()
        sys.stderr.write('Received null token, the upload is not accepted')
        sys.stderr.flush()
        return 1

    # upload_token, as returned by json.load(), is a Unicode string.
    # Without the conversion, urllib2.py passes a Unicode URL created from it
    # to httplib.py, and httplib.py fails in a non-graceful way
    # (http://bugs.python.org/issue12398)
    upload_token = upload_token.encode('UTF-8', 'ignore')
    try:
        result = application.upload_file(file_path, upload_token)
        # hack before fix ApplicationManagerApplication#processReceivedFile // TODO: return some useful information
        if result:
            print result

    except urllib2.HTTPError as e:
        sys.stdout.flush()
        sys.stderr.write('HTTP Error %s: %s\n' % (e.code, e.read()))
        sys.stderr.flush()
        return 1

    if not stable:
        return

    app_info = read_jar_file(file_path)

    return mark_as_stable(application, version, app_info.identifiers, scope)

AppInfo = namedtuple('AppInfo', [
    'vendor', 'identifiers'
])

def read_jar_file(file_path):
    with zipfile.ZipFile(file_path) as zip_file:
        try:
            info = zip_file.getinfo('applications.xml')
            with zip_file.open(info) as manifest:
                doc = minidom.parse(manifest)
                namespace = doc.documentElement.namespaceURI
                applications = doc.getElementsByTagNameNS(namespace, 'application')
                vendor = doc.getElementsByTagNameNS(namespace, 'vendor')[0].firstChild.nodeValue
                identifiers = [
                    vendor + '/' + a.getElementsByTagNameNS(namespace, 'id')[0].firstChild.nodeValue
                    for a in applications
                ]
        except KeyError:
            raise GenestackException('Unable to read applications.xml manifest from JAR')
        return AppInfo(vendor, identifiers)

def show_info(files, vendor_only, with_filename, no_filename):
    first_file = True
    for file_path in files:
        app_info = read_jar_file(file_path)

        if vendor_only:
            if no_filename:
                print app_info.vendor
            else:
                print '%s %s' % (file_path, app_info.vendor)
            continue

        if with_filename or not no_filename and len(files) > 1:
            if not first_file:
                print ''
            print 'File:', file_path

        print 'Vendor:', app_info.vendor
        print 'Applications:'
        for app_id in app_info.identifiers:
            print '\t%s' % app_id

        first_file = False

class ApplicationManager(GenestackShell):
    DESCRIPTION = ('Application manager is a script that lets you to add new applications into the system, '
                   'remove your uploaded applications from the system, '
                   'list available applications and do other related things.')
    INTRO = "Application manager shell.\nType 'help' for list of available commands.\n\n"
    COMMAND_LIST = [Info, Install, ListVersions, ListApplications, MarkAsStable, Remove, Reload, Invoke]

if __name__ == '__main__':
    shell = ApplicationManager()
    shell.cmdloop()
<|endoftext|>


<commit_before>"""Extract informaton about angular module dependencies.

For some of the concepts, see http://almossawi.com/firefox/
"""

import subprocess
import os
import re
import argparse
import json

CATEGORIES = ['peripheral', 'control', 'shared', 'core']

class SetEncoder(json.JSONEncoder):
    # https://stackoverflow.com/questions/8230315
    def default(self, obj):
       if isinstance(obj, set):
          return list(obj)
       return json.JSONEncoder.default(self, obj)

def normpath(path):
    """Strip everything until 'Packages' from the beginning of the path."""
    parts = path.split('/')
    if 'Packages' in parts:
        parts = parts[parts.index('Packages') + 1:]
    return os.path.normpath('/'.join(parts))

def color(name):
    """Get pseudo-random color."""
    n = int.from_bytes(name.encode('utf8'), byteorder='big')
    h = (n % 41) / 41
    s = (n % 37) / 37
    return '"{:.4} {:.4} {:.4}"'.format(h, s, 0.5)

def get_modules():
    """Get a dictionary of existing modules and their dependencies."""
    modules = {}

    lines = subprocess.check_output(['git', 'grep', 'moduleName = '])

    for line in lines.decode('utf8').split('\n'):
        if 'ts:' in line:
            path, name = line.split(':export var moduleName = ')
            dirname = os.path.dirname(path)
            name = name.strip('";')
            imports = []

            with open(path) as fh:
                for line in fh:
                    match = re.match('import \* as .* from "(.*)";', line)
                    if match:
                        import_path = match.groups()[0] + '.ts'
                        if import_path.endswith('Module.ts'):
                            joined = os.path.join(dirname, import_path)
                            imports.append(normpath(joined))

            modules[normpath(path)] = {
                'name': name,
                'imports': imports
            }

    return modules

def add_counts(modules):
    """Add import_count/export_count to an existing dict of modules."""
    for module in modules.values():
        module['exports'] = set()

    for path, module in modules.items():
        for imp in module['imports']:
            modules[imp]['exports'].add(path)

    for path, module in modules.items():
        module['import_count'] = len(module['imports'])
        module['export_count'] = len(module['exports'])

def add_recursive_counts(modules):
    """Add fan_in/fan_out to an existing dict of modules.

    These are like import_count/export_count, but recursive.
    """
    def set_recursive_imports(module):
        k = 'recursive_imports'
        if k not in module:
            module[k] = set(module['imports'])
            for key in module['imports']:
                imp = modules[key]
                set_recursive_imports(imp)
                module[k] = module[k].union(imp[k])

    def set_recursive_exports(module):
        k = 'recursive_exports'
        if k not in module:
            module[k] = set(module['exports'])
            for key in module['exports']:
                exp = modules[key]
                set_recursive_exports(exp)
                module[k] = module[k].union(exp[k])

    for module in modules.values():
        set_recursive_imports(module)
        module['fan_in'] = len(module['recursive_imports'])
        set_recursive_exports(module)
        module['fan_out'] = len(module['recursive_exports'])

def add_rank(modules):
    """Add rank to an existing dict of modules.

    The rank of a module is always greater that that of its dependencies.
    """
    done = []

    while len(done) < len(modules):
        for path, module in modules.items():
            imports = module['imports']

            if path not in done and all((p in done for p in imports)):
                if not imports:
                    module['rank'] = 0
                else:
                    ranks = [modules[imp]['rank'] for imp in imports]
                    module['rank'] = max(ranks) + 1
                done.append(path)

    return max([m['rank'] for m in modules.values()])

def _filter(modules, args):
    """Remove some modules from the dict according to command line args."""
    remove = set()
    for key, module in modules.items():
        if not include(module, args):
            remove.add(key)

    for key in remove:
        del modules[key]

    for module in modules.values():
        module['imports'] = [i for i in module['imports'] if i in modules]

def add_category(modules):
    """Mark a module as 'peripheral', 'control', 'shared', or 'core'."""
    n = len(modules)
    average_in = sum(m['fan_in'] for m in modules.values()) / float(n)
    average_out = sum(m['fan_out'] for m in modules.values()) / float(n)

    for module in modules.values():
        i = 0
        if module['fan_in'] > average_in:
            i += 1
        if module['fan_out'] > average_out:
            i += 2
        module['category'] = CATEGORIES[i]

def render_module(module):
    """Render a module to string."""
    opts = ['color=%s' % color(module['name'])]

    if module['import_count'] == 0:
        opts.append('shape=box')
    if module['export_count'] == 0:
        opts.append('style=dotted')

    return '    %s [%s];' % (module['name'], ','.join(opts))

def include(module, args):
    """Return True if the module should be included in the output."""
    if not (args.min_rank <= module['rank'] <= args.max_rank):
        return False
    if any((re.search(x, module['name'], re.I) for x in args.exclude)):
        return False
    return True

def adjacency_matrix(modules, direct=False):
    keys = list(modules.keys())
    keys.sort(key=lambda k: (-modules[k]['fan_out'], k))
    names = [modules[key]['name'] for key in keys]

    m = []
    for row_key in keys:
        module = modules[row_key]
        row = []
        for column_key in keys:
            if direct:
                row.append(column_key in module['imports'])
            else:
                row.append(column_key in module['recursive_imports'])
        m.append(row)

    return m, names

def print_matrix(matrix, names):
    print('P1')
    for name in names:
        print('# %s' % name)
    n = len(matrix)
    print('%i %i' % (n, n))
    for row in matrix:
        print(' '.join([str(int(i)) for i in row]))

def print_stats(modules, verbose=True):
    n = len(modules)
    print('total modules: %i' % n)
    for category in CATEGORIES:
        mods = [m for m in modules.values() if m['category'] == category]
        k = len(mods)
        names = sorted([m['name'] for m in mods])
        print('%s modules: %i, %i%%' % (category, k, 100 * k / n))
        if verbose:
            for name in names:
                print('  %s' % name)
    matrix, _names = adjacency_matrix(modules)
    propagation_cost = sum([sum(row) for row in matrix]) / n
    print('propagation cost: %i, %i%%' % (propagation_cost, 100 * propagation_cost / n))
    print('max rank: %i' % max((m['rank'] for m in modules.values())))

def print_dot(modules):
    ranks = [m['rank'] for m in modules.values()]

    print('digraph adhocracy_frontend {')
    print('  graph [splines=ortho];')

    for rank in range(min(ranks), max(ranks) + 1):
        print('  subgraph rank%i {' % rank)
        print('    rank = same;')
        for path, module in modules.items():
            if module['rank'] == rank:
                print(render_module(module))
        print('  }')

    for module in modules.values():
        for imp in module['imports']:
            print('  %s->%s [color=%s];' % (
                modules[imp]['name'],
                module['name'],
                color(modules[imp]['name'])))

    print('}')

def parse_args():
    """Parse command line argumants."""
    parser = argparse.ArgumentParser()
    parser.add_argument('-i', '--input', default=None)

    parser.add_argument('--min-rank', type=int, default=0)
    parser.add_argument('--max-rank', type=int, default=None)
    parser.add_argument('-x', '--exclude', nargs='*', default=[])

    parser.add_argument('--matrix', action='store_true', help='Output '
        'dependency matrix as PBM. If you want to only include direct '
        'dependencies, use the --direct switch')
    parser.add_argument('--direct', action='store_true')

    parser.add_argument('--stats', action='store_true', help='Output '
        'some general stats')
    parser.add_argument('-v', '--verbose', action='store_true')

    parser.add_argument('--dump', action='store_true')

    return parser.parse_args()

def main():
    """Print module graph in DOT format to stdout."""
    args = parse_args()
    if args.input is None:
        modules = get_modules()

        max_rank = add_rank(modules)
        if args.max_rank is None:
            args.max_rank = max_rank
        _filter(modules, args)
        add_counts(modules)
        add_recursive_counts(modules)
        add_category(modules)
    else:
        with open(args.input) as fh:
            modules = json.load(fh)

    if args.matrix:
        m, names = adjacency_matrix(modules, direct=args.direct)
        print_matrix(m, names)
    elif args.stats:
        print_stats(modules, verbose=args.verbose)
    elif args.dump:
        print(json.dumps(modules, indent=2, separators=(',', ': '), sort_keys=True, ensure_ascii=False, cls=SetEncoder))
    else:
        print_dot(modules)

if __name__ == '__main__':
    main()
<commit_msg>Gardening (Fixup to #1980)<commit_after>"""Extract informaton about angular module dependencies.

For some of the concepts, see http://almossawi.com/firefox/
"""

import subprocess
import os
import re
import argparse
import json

CATEGORIES = ['peripheral', 'control', 'shared', 'core']

class SetEncoder(json.JSONEncoder):
    # https://stackoverflow.com/questions/8230315
    def default(self, obj):
        if isinstance(obj, set):
            return list(obj)
        return json.JSONEncoder.default(self, obj)

def normpath(path):
    """Strip everything until 'Packages' from the beginning of the path."""
    parts = path.split('/')
    if 'Packages' in parts:
        parts = parts[parts.index('Packages') + 1:]
    return os.path.normpath('/'.join(parts))

def color(name):
    """Get pseudo-random color."""
    n = int.from_bytes(name.encode('utf8'), byteorder='big')
    h = (n % 41) / 41
    s = (n % 37) / 37
    return '"{:.4} {:.4} {:.4}"'.format(h, s, 0.5)

def get_modules():
    """Get a dictionary of existing modules and their dependencies."""
    modules = {}

    lines = subprocess.check_output(['git', 'grep', 'moduleName = '])

    for line in lines.decode('utf8').split('\n'):
        if 'ts:' in line:
            path, name = line.split(':export var moduleName = ')
            dirname = os.path.dirname(path)
            name = name.strip('";')
            imports = []

            with open(path) as fh:
                for line in fh:
                    match = re.match('import \* as .* from "(.*)";', line)
                    if match:
                        import_path = match.groups()[0] + '.ts'
                        if import_path.endswith('Module.ts'):
                            joined = os.path.join(dirname, import_path)
                            imports.append(normpath(joined))

            modules[normpath(path)] = {
                'name': name,
                'imports': imports
            }

    return modules

def add_counts(modules):
    """Add import_count/export_count to an existing dict of modules."""
    for module in modules.values():
        module['exports'] = set()

    for path, module in modules.items():
        for imp in module['imports']:
            modules[imp]['exports'].add(path)

    for path, module in modules.items():
        module['import_count'] = len(module['imports'])
        module['export_count'] = len(module['exports'])

def add_recursive_counts(modules):
    """Add fan_in/fan_out to an existing dict of modules.

    These are like import_count/export_count, but recursive.
    """
    def set_recursive_imports(module):
        k = 'recursive_imports'
        if k not in module:
            module[k] = set(module['imports'])
            for key in module['imports']:
                imp = modules[key]
                set_recursive_imports(imp)
                module[k] = module[k].union(imp[k])

    def set_recursive_exports(module):
        k = 'recursive_exports'
        if k not in module:
            module[k] = set(module['exports'])
            for key in module['exports']:
                exp = modules[key]
                set_recursive_exports(exp)
                module[k] = module[k].union(exp[k])

    for module in modules.values():
        set_recursive_imports(module)
        module['fan_in'] = len(module['recursive_imports'])
        set_recursive_exports(module)
        module['fan_out'] = len(module['recursive_exports'])

def add_rank(modules):
    """Add rank to an existing dict of modules.

    The rank of a module is always greater that that of its dependencies.
    """
    done = []

    while len(done) < len(modules):
        for path, module in modules.items():
            imports = module['imports']

            if path not in done and all((p in done for p in imports)):
                if not imports:
                    module['rank'] = 0
                else:
                    ranks = [modules[imp]['rank'] for imp in imports]
                    module['rank'] = max(ranks) + 1
                done.append(path)

    return max([m['rank'] for m in modules.values()])

def _filter(modules, args):
    """Remove some modules from the dict according to command line args."""
    remove = set()
    for key, module in modules.items():
        if not include(module, args):
            remove.add(key)

    for key in remove:
        del modules[key]

    for module in modules.values():
        module['imports'] = [i for i in module['imports'] if i in modules]

def add_category(modules):
    """Mark a module as 'peripheral', 'control', 'shared', or 'core'."""
    n = len(modules)
    average_in = sum(m['fan_in'] for m in modules.values()) / float(n)
    average_out = sum(m['fan_out'] for m in modules.values()) / float(n)

    for module in modules.values():
        i = 0
        if module['fan_in'] > average_in:
            i += 1
        if module['fan_out'] > average_out:
            i += 2
        module['category'] = CATEGORIES[i]

def render_module(module):
    """Render a module to string."""
    opts = ['color=%s' % color(module['name'])]

    if module['import_count'] == 0:
        opts.append('shape=box')
    if module['export_count'] == 0:
        opts.append('style=dotted')

    return '    %s [%s];' % (module['name'], ','.join(opts))

def include(module, args):
    """Return True if the module should be included in the output."""
    if not (args.min_rank <= module['rank'] <= args.max_rank):
        return False
    if any((re.search(x, module['name'], re.I) for x in args.exclude)):
        return False
    return True

def adjacency_matrix(modules, direct=False):
    """Create adjacency matrix for a dict of modules."""
    keys = list(modules.keys())
    keys.sort(key=lambda k: (-modules[k]['fan_out'], k))
    names = [modules[key]['name'] for key in keys]

    m = []
    for row_key in keys:
        module = modules[row_key]
        row = []
        for column_key in keys:
            if direct:
                row.append(column_key in module['imports'])
            else:
                row.append(column_key in module['recursive_imports'])
        m.append(row)

    return m, names

def print_matrix(matrix, names):
    """Print a matrix as generated with adjacency_matrix as PBM."""
    print('P1')
    for name in names:
        print('# %s' % name)
    n = len(matrix)
    print('%i %i' % (n, n))
    for row in matrix:
        print(' '.join([str(int(i)) for i in row]))

def print_stats(modules, verbose=True):
    """Print some general stats."""
    n = len(modules)
    print('total modules: %i' % n)
    for category in CATEGORIES:
        mods = [m for m in modules.values() if m['category'] == category]
        k = len(mods)
        names = sorted([m['name'] for m in mods])
        print('%s modules: %i, %i%%' % (category, k, 100 * k / n))
        if verbose:
            for name in names:
                print('  %s' % name)
    matrix, _names = adjacency_matrix(modules)
    propagation_cost = sum([sum(row) for row in matrix]) / n
    print('propagation cost: %i, %i%%' % (
        propagation_cost, 100 * propagation_cost / n))
    print('max rank: %i' % max((m['rank'] for m in modules.values())))

def print_dot(modules):
    """Print dependency graph as DOT."""
    ranks = [m['rank'] for m in modules.values()]

    print('digraph adhocracy_frontend {')
    print('  graph [splines=ortho];')

    for rank in range(min(ranks), max(ranks) + 1):
        print('  subgraph rank%i {' % rank)
        print('    rank = same;')
        for path, module in modules.items():
            if module['rank'] == rank:
                print(render_module(module))
        print('  }')

    for module in modules.values():
        for imp in module['imports']:
            print('  %s->%s [color=%s];' % (
                modules[imp]['name'],
                module['name'],
                color(modules[imp]['name'])))

    print('}')

def parse_args():
    """Parse command line argumants."""
    parser = argparse.ArgumentParser()
    parser.add_argument('-i', '--input', default=None)

    parser.add_argument('--min-rank', type=int, default=0)
    parser.add_argument('--max-rank', type=int, default=None)
    parser.add_argument('-x', '--exclude', nargs='*', default=[])

    parser.add_argument('--matrix', action='store_true', help='Output '
                        'dependency matrix as PBM. If you want to only '
                        'include direct dependencies, use the --direct '
                        'switch')
    parser.add_argument('--direct', action='store_true')

    parser.add_argument('--stats', action='store_true', help='Output '
                        'some general stats')
    parser.add_argument('-v', '--verbose', action='store_true')

    parser.add_argument('--dump', action='store_true')

    return parser.parse_args()

def main():
    """Print module graph in DOT format to stdout."""
    args = parse_args()
    if args.input is None:
        modules = get_modules()

        max_rank = add_rank(modules)
        if args.max_rank is None:
            args.max_rank = max_rank
        _filter(modules, args)
        add_counts(modules)
        add_recursive_counts(modules)
        add_category(modules)
    else:
        with open(args.input) as fh:
            modules = json.load(fh)

    if args.matrix:
        m, names = adjacency_matrix(modules, direct=args.direct)
        print_matrix(m, names)
    elif args.stats:
        print_stats(modules, verbose=args.verbose)
    elif args.dump:
        print(json.dumps(
            modules,
            indent=2,
            separators=(',', ': '),
            sort_keys=True,
            ensure_ascii=False,
            cls=SetEncoder))
    else:
        print_dot(modules)

if __name__ == '__main__':
    main()
<|endoftext|>


<commit_before>"""Common settings and globals."""

from os.path import abspath, basename, dirname, join, normpath
from sys import path

########## PATH CONFIGURATION
# Absolute filesystem path to the Django project directory:
DJANGO_ROOT = dirname(dirname(abspath(__file__)))

# Absolute filesystem path to the top-level project folder:
SITE_ROOT = dirname(DJANGO_ROOT)

# Site name:
SITE_NAME = basename(DJANGO_ROOT)

# Add our project to our pythonpath, this way we don't need to type our project
# name in our dotted import paths:
path.append(DJANGO_ROOT)
########## END PATH CONFIGURATION

########## DEBUG CONFIGURATION
# See: https://docs.djangoproject.com/en/dev/ref/settings/#debug
DEBUG = False

# See: https://docs.djangoproject.com/en/dev/ref/settings/#template-debug
TEMPLATE_DEBUG = DEBUG
########## END DEBUG CONFIGURATION

########## MANAGER CONFIGURATION
# See: https://docs.djangoproject.com/en/dev/ref/settings/#admins
ADMINS = (
    ('Your Name', 'your_email@example.com'),
)

# See: https://docs.djangoproject.com/en/dev/ref/settings/#managers
MANAGERS = ADMINS
########## END MANAGER CONFIGURATION

########## DATABASE CONFIGURATION
# See: https://docs.djangoproject.com/en/dev/ref/settings/#databases
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.',
        'NAME': '',
        'USER': '',
        'PASSWORD': '',
        'HOST': '',
        'PORT': '',
    }
}
########## END DATABASE CONFIGURATION

########## GENERAL CONFIGURATION
# See: https://docs.djangoproject.com/en/dev/ref/settings/#time-zone
TIME_ZONE = 'America/Los_Angeles'

# See: https://docs.djangoproject.com/en/dev/ref/settings/#language-code
LANGUAGE_CODE = 'en-us'

# See: https://docs.djangoproject.com/en/dev/ref/settings/#site-id
SITE_ID = 1

# See: https://docs.djangoproject.com/en/dev/ref/settings/#use-i18n
USE_I18N = True

# See: https://docs.djangoproject.com/en/dev/ref/settings/#use-l10n
USE_L10N = True

# See: https://docs.djangoproject.com/en/dev/ref/settings/#use-tz
USE_TZ = True
########## END GENERAL CONFIGURATION

########## AUTHENTICATION CONFIGURATION
AUTHENTICATION_BACKENDS = ('django.contrib.auth.backends.ModelBackend',
                           'accounts.auth_backends.EmailBackend',)

AUTH_USER_MODEL = 'accounts.GenoomyUser'
########## END AUTHENTICATION CONFIGURATION

########## MEDIA CONFIGURATION
# See: https://docs.djangoproject.com/en/dev/ref/settings/#media-root
MEDIA_ROOT = normpath(join(SITE_ROOT, 'media'))

# See: https://docs.djangoproject.com/en/dev/ref/settings/#media-url
MEDIA_URL = '/media/'
########## END MEDIA CONFIGURATION

########## STATIC FILE CONFIGURATION
# See: https://docs.djangoproject.com/en/dev/ref/settings/#static-root
STATIC_ROOT = normpath(join(SITE_ROOT, 'assets'))

# See: https://docs.djangoproject.com/en/dev/ref/settings/#static-url
STATIC_URL = '/static/'

# See: https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#std:setting-STATICFILES_DIRS
STATICFILES_DIRS = (
    normpath(join(SITE_ROOT, 'static')),
)

# See: https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#staticfiles-finders
STATICFILES_FINDERS = (
    'django.contrib.staticfiles.finders.FileSystemFinder',
    'django.contrib.staticfiles.finders.AppDirectoriesFinder',
)
########## END STATIC FILE CONFIGURATION

########## SECRET CONFIGURATION
# See: https://docs.djangoproject.com/en/dev/ref/settings/#secret-key
# Note: This key should only be used for development and testing.
SECRET_KEY = r"%s8r#(!aas0&k-8d4h9fj^=lf%86_89ex*(@%r@rfrknq4dz2^"
########## END SECRET CONFIGURATION

########## SITE CONFIGURATION
# Hosts/domain names that are valid for this site
# See https://docs.djangoproject.com/en/1.5/ref/settings/#allowed-hosts
ALLOWED_HOSTS = []
########## END SITE CONFIGURATION

########## FIXTURE CONFIGURATION
# See: https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-FIXTURE_DIRS
FIXTURE_DIRS = (
    normpath(join(SITE_ROOT, 'fixtures')),
)
########## END FIXTURE CONFIGURATION

########## TEMPLATE CONFIGURATION
# See: https://docs.djangoproject.com/en/dev/ref/settings/#template-context-processors
TEMPLATE_CONTEXT_PROCESSORS = (
    'django.contrib.auth.context_processors.auth',
    'django.core.context_processors.debug',
    'django.core.context_processors.i18n',
    'django.core.context_processors.media',
    'django.core.context_processors.static',
    'django.core.context_processors.tz',
    'django.contrib.messages.context_processors.messages',
    'django.core.context_processors.request',
)

# See: https://docs.djangoproject.com/en/dev/ref/settings/#template-loaders
TEMPLATE_LOADERS = (
    'django.template.loaders.filesystem.Loader',
    'django.template.loaders.app_directories.Loader',
)

# See: https://docs.djangoproject.com/en/dev/ref/settings/#template-dirs
TEMPLATE_DIRS = (
    normpath(join(SITE_ROOT, 'templates')),
)
########## END TEMPLATE CONFIGURATION

########## MIDDLEWARE CONFIGURATION
# See: https://docs.djangoproject.com/en/dev/ref/settings/#middleware-classes
MIDDLEWARE_CLASSES = (
    # Default Django middleware.
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'django.contrib.flatpages.middleware.FlatpageFallbackMiddleware',
)
########## END MIDDLEWARE CONFIGURATION

########## URL CONFIGURATION
# See: https://docs.djangoproject.com/en/dev/ref/settings/#root-urlconf
ROOT_URLCONF = '%s.urls' % SITE_NAME
########## END URL CONFIGURATION

########## APP CONFIGURATION
DJANGO_APPS = (
    # Default Django apps:
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    # Useful template tags:
    # 'django.contrib.humanize',

    # Admin panel and documentation:
    'django.contrib.admin',
    # 'django.contrib.admindocs',
    'django.contrib.flatpages',
)

# Apps specific for this project go here.
LOCAL_APPS = (
    'accounts',
    'disease',
    'payment_bitpay',
    'payments',

    'widget_tweaks',
    'coupons',
    'colorful',
    'django_markdown',
    'paypal.standard.ipn',
)

# See: https://docs.djangoproject.com/en/dev/ref/settings/#installed-apps
INSTALLED_APPS = DJANGO_APPS + LOCAL_APPS
########## END APP CONFIGURATION

########## LOGGING CONFIGURATION
# See: https://docs.djangoproject.com/en/dev/ref/settings/#logging
# A sample logging configuration. The only tangible logging
# performed by this configuration is to send an email to
# the site admins on every HTTP 500 error when DEBUG=False.
# See http://docs.djangoproject.com/en/dev/topics/logging for
# more details on how to customize your logging configuration.
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'verbose': {
            'format' : "[%(asctime)s] %(levelname)s [%(name)s:%(lineno)s] %(message)s",
            'datefmt' : "%d/%b/%Y %H:%M:%S"
        },
        'simple': {
            'format': '%(levelname)s %(message)s'
        },
    },
    'filters': {
        'require_debug_false': {
            '()': 'django.utils.log.RequireDebugFalse'
        },
        'require_debug_true': {
            '()': 'django.utils.log.RequireDebugTrue'
        },
    },
    'handlers': {
        'console': {
            'level': 'DEBUG',
            'filters': ['require_debug_true'],
            'class': 'logging.StreamHandler',
            'formatter': 'verbose'
        },
        'mail_admins': {
            'level': 'ERROR',
            'filters': ['require_debug_false'],
            'class': 'django.utils.log.AdminEmailHandler'
        }
    },
    'loggers': {
        'django.request': {
            'handlers': ['mail_admins', 'console'],
            'level': 'ERROR',
            'propagate': True,
        },
        'disease': {
            'handlers': ['mail_admins', 'console'],
            'level': 'DEBUG',
            'propagate': True
        }
    }
}
########## END LOGGING CONFIGURATION

########## WSGI CONFIGURATION
# See: https://docs.djangoproject.com/en/dev/ref/settings/#wsgi-application
WSGI_APPLICATION = '%s.wsgi.application' % SITE_NAME
########## END WSGI CONFIGURATION

FILE_UPLOAD_HANDLERS = ('disease.upload_handlers.UploadProgressCachedHandler', ) + ('django.core.files.uploadhandler.MemoryFileUploadHandler', 'django.core.files.uploadhandler.TemporaryFileUploadHandler')
FILE_UPLOAD_PERMISSIONS = 644

########## CELERY CONFIGURATION
# http://docs.celeryproject.org/en/latest/getting-started/first-steps-with-celery.html#configuration
BROKER_URL = 'redis://localhost:6379/1'
# CELERY_RESULT_BACKEND = 'redis://localhost:6379/2'
# CELERY_TASK_SERIALIZER = 'json'
# CELERY_ACCEPT_CONTENT = ['json']  # Ignore other content
# CELERY_RESULT_SERIALIZER = 'json'
CELERY_TIMEZONE = 'Europe/Warsaw'
CELERY_ENABLE_UTC = True
########## END CELERY CONFIGURATION

########## BITPAY CONFIGURATION
BITPAY_API = 'https://bitpay.com'
########## END BITPAY CONFIGURATION

########## PAYPAL CONFIGURATION
PAYPAL_RECEIVER_EMAIL = "yourpaypalemail@example.com"
########## END PAYPAL CONFIGURATION
<commit_msg>Remove uploaded files permissions setting<commit_after>"""Common settings and globals."""

from os.path import abspath, basename, dirname, join, normpath
from sys import path

########## PATH CONFIGURATION
# Absolute filesystem path to the Django project directory:
DJANGO_ROOT = dirname(dirname(abspath(__file__)))

# Absolute filesystem path to the top-level project folder:
SITE_ROOT = dirname(DJANGO_ROOT)

# Site name:
SITE_NAME = basename(DJANGO_ROOT)

# Add our project to our pythonpath, this way we don't need to type our project
# name in our dotted import paths:
path.append(DJANGO_ROOT)
########## END PATH CONFIGURATION

########## DEBUG CONFIGURATION
# See: https://docs.djangoproject.com/en/dev/ref/settings/#debug
DEBUG = False

# See: https://docs.djangoproject.com/en/dev/ref/settings/#template-debug
TEMPLATE_DEBUG = DEBUG
########## END DEBUG CONFIGURATION

########## MANAGER CONFIGURATION
# See: https://docs.djangoproject.com/en/dev/ref/settings/#admins
ADMINS = (
    ('Your Name', 'your_email@example.com'),
)

# See: https://docs.djangoproject.com/en/dev/ref/settings/#managers
MANAGERS = ADMINS
########## END MANAGER CONFIGURATION

########## DATABASE CONFIGURATION
# See: https://docs.djangoproject.com/en/dev/ref/settings/#databases
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.',
        'NAME': '',
        'USER': '',
        'PASSWORD': '',
        'HOST': '',
        'PORT': '',
    }
}
########## END DATABASE CONFIGURATION

########## GENERAL CONFIGURATION
# See: https://docs.djangoproject.com/en/dev/ref/settings/#time-zone
TIME_ZONE = 'America/Los_Angeles'

# See: https://docs.djangoproject.com/en/dev/ref/settings/#language-code
LANGUAGE_CODE = 'en-us'

# See: https://docs.djangoproject.com/en/dev/ref/settings/#site-id
SITE_ID = 1

# See: https://docs.djangoproject.com/en/dev/ref/settings/#use-i18n
USE_I18N = True

# See: https://docs.djangoproject.com/en/dev/ref/settings/#use-l10n
USE_L10N = True

# See: https://docs.djangoproject.com/en/dev/ref/settings/#use-tz
USE_TZ = True
########## END GENERAL CONFIGURATION

########## AUTHENTICATION CONFIGURATION
AUTHENTICATION_BACKENDS = ('django.contrib.auth.backends.ModelBackend',
                           'accounts.auth_backends.EmailBackend',)

AUTH_USER_MODEL = 'accounts.GenoomyUser'
########## END AUTHENTICATION CONFIGURATION

########## MEDIA CONFIGURATION
# See: https://docs.djangoproject.com/en/dev/ref/settings/#media-root
MEDIA_ROOT = normpath(join(SITE_ROOT, 'media'))

# See: https://docs.djangoproject.com/en/dev/ref/settings/#media-url
MEDIA_URL = '/media/'
########## END MEDIA CONFIGURATION

########## STATIC FILE CONFIGURATION
# See: https://docs.djangoproject.com/en/dev/ref/settings/#static-root
STATIC_ROOT = normpath(join(SITE_ROOT, 'assets'))

# See: https://docs.djangoproject.com/en/dev/ref/settings/#static-url
STATIC_URL = '/static/'

# See: https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#std:setting-STATICFILES_DIRS
STATICFILES_DIRS = (
    normpath(join(SITE_ROOT, 'static')),
)

# See: https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#staticfiles-finders
STATICFILES_FINDERS = (
    'django.contrib.staticfiles.finders.FileSystemFinder',
    'django.contrib.staticfiles.finders.AppDirectoriesFinder',
)
########## END STATIC FILE CONFIGURATION

########## SECRET CONFIGURATION
# See: https://docs.djangoproject.com/en/dev/ref/settings/#secret-key
# Note: This key should only be used for development and testing.
SECRET_KEY = r"%s8r#(!aas0&k-8d4h9fj^=lf%86_89ex*(@%r@rfrknq4dz2^"
########## END SECRET CONFIGURATION

########## SITE CONFIGURATION
# Hosts/domain names that are valid for this site
# See https://docs.djangoproject.com/en/1.5/ref/settings/#allowed-hosts
ALLOWED_HOSTS = []
########## END SITE CONFIGURATION

########## FIXTURE CONFIGURATION
# See: https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-FIXTURE_DIRS
FIXTURE_DIRS = (
    normpath(join(SITE_ROOT, 'fixtures')),
)
########## END FIXTURE CONFIGURATION

########## TEMPLATE CONFIGURATION
# See: https://docs.djangoproject.com/en/dev/ref/settings/#template-context-processors
TEMPLATE_CONTEXT_PROCESSORS = (
    'django.contrib.auth.context_processors.auth',
    'django.core.context_processors.debug',
    'django.core.context_processors.i18n',
    'django.core.context_processors.media',
    'django.core.context_processors.static',
    'django.core.context_processors.tz',
    'django.contrib.messages.context_processors.messages',
    'django.core.context_processors.request',
)

# See: https://docs.djangoproject.com/en/dev/ref/settings/#template-loaders
TEMPLATE_LOADERS = (
    'django.template.loaders.filesystem.Loader',
    'django.template.loaders.app_directories.Loader',
)

# See: https://docs.djangoproject.com/en/dev/ref/settings/#template-dirs
TEMPLATE_DIRS = (
    normpath(join(SITE_ROOT, 'templates')),
)
########## END TEMPLATE CONFIGURATION

########## MIDDLEWARE CONFIGURATION
# See: https://docs.djangoproject.com/en/dev/ref/settings/#middleware-classes
MIDDLEWARE_CLASSES = (
    # Default Django middleware.
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'django.contrib.flatpages.middleware.FlatpageFallbackMiddleware',
)
########## END MIDDLEWARE CONFIGURATION

########## URL CONFIGURATION
# See: https://docs.djangoproject.com/en/dev/ref/settings/#root-urlconf
ROOT_URLCONF = '%s.urls' % SITE_NAME
########## END URL CONFIGURATION

########## APP CONFIGURATION
DJANGO_APPS = (
    # Default Django apps:
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    # Useful template tags:
    # 'django.contrib.humanize',

    # Admin panel and documentation:
    'django.contrib.admin',
    # 'django.contrib.admindocs',
    'django.contrib.flatpages',
)

# Apps specific for this project go here.
LOCAL_APPS = (
    'accounts',
    'disease',
    'payment_bitpay',
    'payments',

    'widget_tweaks',
    'coupons',
    'colorful',
    'django_markdown',
    'paypal.standard.ipn',
)

# See: https://docs.djangoproject.com/en/dev/ref/settings/#installed-apps
INSTALLED_APPS = DJANGO_APPS + LOCAL_APPS
########## END APP CONFIGURATION

########## LOGGING CONFIGURATION
# See: https://docs.djangoproject.com/en/dev/ref/settings/#logging
# A sample logging configuration. The only tangible logging
# performed by this configuration is to send an email to
# the site admins on every HTTP 500 error when DEBUG=False.
# See http://docs.djangoproject.com/en/dev/topics/logging for
# more details on how to customize your logging configuration.
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'verbose': {
            'format' : "[%(asctime)s] %(levelname)s [%(name)s:%(lineno)s] %(message)s",
            'datefmt' : "%d/%b/%Y %H:%M:%S"
        },
        'simple': {
            'format': '%(levelname)s %(message)s'
        },
    },
    'filters': {
        'require_debug_false': {
            '()': 'django.utils.log.RequireDebugFalse'
        },
        'require_debug_true': {
            '()': 'django.utils.log.RequireDebugTrue'
        },
    },
    'handlers': {
        'console': {
            'level': 'DEBUG',
            'filters': ['require_debug_true'],
            'class': 'logging.StreamHandler',
            'formatter': 'verbose'
        },
        'mail_admins': {
            'level': 'ERROR',
            'filters': ['require_debug_false'],
            'class': 'django.utils.log.AdminEmailHandler'
        }
    },
    'loggers': {
        'django.request': {
            'handlers': ['mail_admins', 'console'],
            'level': 'ERROR',
            'propagate': True,
        },
        'disease': {
            'handlers': ['mail_admins', 'console'],
            'level': 'DEBUG',
            'propagate': True
        }
    }
}
########## END LOGGING CONFIGURATION

########## WSGI CONFIGURATION
# See: https://docs.djangoproject.com/en/dev/ref/settings/#wsgi-application
WSGI_APPLICATION = '%s.wsgi.application' % SITE_NAME
########## END WSGI CONFIGURATION

FILE_UPLOAD_HANDLERS = ('disease.upload_handlers.UploadProgressCachedHandler', ) + ('django.core.files.uploadhandler.MemoryFileUploadHandler', 'django.core.files.uploadhandler.TemporaryFileUploadHandler')

########## CELERY CONFIGURATION
# http://docs.celeryproject.org/en/latest/getting-started/first-steps-with-celery.html#configuration
BROKER_URL = 'redis://localhost:6379/1'
# CELERY_RESULT_BACKEND = 'redis://localhost:6379/2'
# CELERY_TASK_SERIALIZER = 'json'
# CELERY_ACCEPT_CONTENT = ['json']  # Ignore other content
# CELERY_RESULT_SERIALIZER = 'json'
CELERY_TIMEZONE = 'Europe/Warsaw'
CELERY_ENABLE_UTC = True
########## END CELERY CONFIGURATION

########## BITPAY CONFIGURATION
BITPAY_API = 'https://bitpay.com'
########## END BITPAY CONFIGURATION

########## PAYPAL CONFIGURATION
PAYPAL_RECEIVER_EMAIL = "yourpaypalemail@example.com"
########## END PAYPAL CONFIGURATION
<|endoftext|>


<commit_before># Copyright 2014 Altera Corporation. All Rights Reserved.
# Author: John McGehee
#
# Copyright 2014 John McGehee.  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.

"""A base class for unit tests using the :py:class:`pyfakefs` module.

This class searches `sys.modules` for modules that import the `os`, `glob`,
`shutil`, and `tempfile` modules.

The `setUp()` method binds these modules to the corresponding fake
modules from `pyfakefs`.  Further, the built in functions `file()` and
`open()` are bound to fake functions.

The `tearDownPyfakefs()` method returns the module bindings to their original
state.

It is expected that `setUp()` be invoked at the beginning of the derived
class' `setUp()` method, and `tearDownPyfakefs()` be invoked at the end of the
derived class' `tearDown()` method.

During the test, everything uses the fake file system and modules.  This means
that even in your test, you can use familiar functions like `open()` and
`os.makedirs()` to manipulate the fake file system.

This also means existing unit tests that use the real file system can be
retro-fitted to use `pyfakefs` by simply changing their base class from
`:py:class`unittest.TestCase` to
`:py:class`pyfakefs.fake_filesystem_unittest.TestCase`.
"""

import sys
import unittest
import doctest
import inspect
import fake_filesystem
import fake_filesystem_glob
import fake_filesystem_shutil
import fake_tempfile

import mock

def load_doctests(loader, tests, ignore, module):
    '''Load the doctest tests for the specified module into unittest.'''
    stubber = Stubber()
    globs = stubber.replaceGlobs(vars(module))
    tests.addTests(doctest.DocTestSuite(module,
                                        globs=globs,
                                        setUp=stubber.setUp,
                                        tearDown=stubber.tearDown))
    return tests

class TestCase(unittest.TestCase):
    def __init__(self, methodName='runTest'):
        super(TestCase, self).__init__(methodName)
        self.stubber = Stubber()

    @property
    def fs(self):
        return self.stubber.fs

    @property
    def patches(self):
        return self.stubber.patches

    def setUpPyfakefs(self):
        '''Bind the file-related modules to the :py:class:`pyfakefs` fake file
        system instead of the real file system.  Also bind the fake `file()` and
        `open()` functions.

        Invoke this at the beginning of the `setUp()` method in your unit test
        class.
        '''
        self.stubber.setUp()

    def tearDownPyfakefs(self):
        '''Clear the fake file system bindings created by `setUp()`.

        Invoke this at the end of the `tearDown()` method in your unit test
        class.
        '''
        self.stubber.tearDown()

class Stubber(object):
    '''
    Instantiate a stub creator to bind and un-bind the file-related modules to
    the :py:module:`pyfakefs` fake modules.
    '''
    SKIPMODULES = set([None, fake_filesystem, fake_filesystem_glob,
                      fake_filesystem_shutil, fake_tempfile, unittest,
                      sys])
    '''Stub nothing that is imported within these modules.
    `sys` is included to prevent `sys.path` from being stubbed with the fake
    `os.path`.
    '''
    assert None in SKIPMODULES, "sys.modules contains 'None' values; must skip them."

    SKIPNAMES = set(['os', 'glob', 'path', 'shutil', 'tempfile'])

    def __init__(self):
        # Attributes set by _findModules()
        self._osModules = None
        self._globModules = None
        self._pathModules = None
        self._shutilModules = None
        self._tempfileModules = None
        self._findModules()
        assert None not in vars(self).values(), \
                "_findModules() missed the initialization of an instance variable"

        # Attributes set by refresh()
        self.fs = None
        self.fake_os = None
        self.fake_glob = None
        self.fake_path = None
        self.fake_shutil = None
        self.fake_tempfile_ = None
        self.fake_open = None
        # _isStale is set by tearDown(), reset by refresh()
        self._isStale = True
        self.refresh()
        assert None not in vars(self).values(), \
                "refresh() missed the initialization of an instance variable"
        assert self._isStale == False, "refresh() did not reset _isStale"

    def _findModules(self):
        '''Find and cache all modules that import file system modules.
        Later, `setUp()` will stub these with the fake file system
        modules.
        '''
        self._osModules = set()
        self._globModules = set()
        self._pathModules = set()
        self._shutilModules = set()
        self._tempfileModules = set()
        for name, module in set(sys.modules.items()):
            if module in self.SKIPMODULES or name in self.SKIPNAMES or (not inspect.ismodule(module)):
                continue
            if 'os' in module.__dict__ and inspect.ismodule(module.__dict__['os']):
                self._osModules.add(name + '.os')
            if 'glob' in module.__dict__:
                self._globModules.add(name + '.glob')
            if 'path' in module.__dict__:
                self._pathModules.add(name + '.path')
            if 'shutil' in module.__dict__:
                self._shutilModules.add(name + '.shutil')
            if 'tempfile' in module.__dict__:
                self._tempfileModules.add(name + '.tempfile')

    def refresh(self):
        '''Renew the fake file system and set the _isStale flag to `False`.'''
        self._stopAllPatches()

        self.fs = fake_filesystem.FakeFilesystem()
        self.fake_os = fake_filesystem.FakeOsModule(self.fs)
        self.fake_glob = fake_filesystem_glob.FakeGlobModule(self.fs)
        self.fake_path = fake_filesystem.FakePathModule(self.fs)
        self.fake_shutil = fake_filesystem_shutil.FakeShutilModule(self.fs)
        self.fake_tempfile_ = fake_tempfile.FakeTempfileModule(self.fs)
        self.fake_open = fake_filesystem.FakeFileOpen(self.fs)

        self._isStale = False

    def _stopAllPatches(self):
        '''Stop (undo) all active patches.'''
        mock.patch.stopall()

    def setUp(self, doctester=None):
        '''Bind the file-related modules to the :py:class:`pyfakefs` fake
        modules real ones.  Also bind the fake `file()` and `open()` functions.
        '''
        if self._isStale:
            self.refresh()

        if doctester is not None:
            doctester.globs = self.replaceGlobs(doctester.globs)

        def startPatch(self, realModuleName, fakeModule):
            if realModuleName == 'unittest.main.os':
                # Known issue with unittest.main resolving to unittest.main.TestProgram
                # See mock module bug 250, https://code.google.com/p/mock/issues/detail?id=250.
                return
            patch = mock.patch(realModuleName, new=fakeModule)
            try:
                patch.start()
            except:
                target, attribute = realModuleName.rsplit('.', 1)
                print("Warning: Could not patch '{}' on module '{}' because '{}' resolves to {}".format(attribute, target, target, patch.getter()))
                print("         See mock module bug 250, https://code.google.com/p/mock/issues/detail?id=250")

        startPatch(self, '__builtin__.file', self.fake_open)
        startPatch(self, '__builtin__.open', self.fake_open)

        for module in self._osModules:
            startPatch(self, module, self.fake_os)
        for module in self._globModules:
            startPatch(self, module, self.fake_glob)
        for module in self._pathModules:
            startPatch(self, module, self.fake_path)
        for module in self._shutilModules:
            startPatch(self, module, self.fake_shutil)
        for module in self._tempfileModules:
            startPatch(self, module, self.fake_tempfile_)

    def replaceGlobs(self, globs_):
        globs = globs_.copy()
        if self._isStale:
            self.refresh()
        if 'os' in globs:
            globs['os'] = fake_filesystem.FakeOsModule(self.fs)
        if 'glob' in globs:
            globs['glob'] = fake_filesystem_glob.FakeGlobModule(self.fs)
        if 'path' in globs:
            globs['path'] =  fake_filesystem.FakePathModule(self.fs)
        if 'shutil' in globs:
            globs['shutil'] = fake_filesystem_shutil.FakeShutilModule(self.fs)
        if 'tempfile' in globs:
            globs['tempfile'] = fake_tempfile.FakeTempfileModule(self.fs)
        return globs

    def tearDown(self, doctester=None):
        '''Clear the fake filesystem bindings created by `setUp()`.

        Invoke this at the end of the `tearDown()` method in your unit test
        class.
        '''
        self._isStale = True
        self._stopAllPatches()
<commit_msg>Fix FakePathModule deprecation in Stubber<commit_after># Copyright 2014 Altera Corporation. All Rights Reserved.
# Author: John McGehee
#
# Copyright 2014 John McGehee.  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.

"""A base class for unit tests using the :py:class:`pyfakefs` module.

This class searches `sys.modules` for modules that import the `os`, `glob`,
`shutil`, and `tempfile` modules.

The `setUp()` method binds these modules to the corresponding fake
modules from `pyfakefs`.  Further, the built in functions `file()` and
`open()` are bound to fake functions.

The `tearDownPyfakefs()` method returns the module bindings to their original
state.

It is expected that `setUp()` be invoked at the beginning of the derived
class' `setUp()` method, and `tearDownPyfakefs()` be invoked at the end of the
derived class' `tearDown()` method.

During the test, everything uses the fake file system and modules.  This means
that even in your test, you can use familiar functions like `open()` and
`os.makedirs()` to manipulate the fake file system.

This also means existing unit tests that use the real file system can be
retro-fitted to use `pyfakefs` by simply changing their base class from
`:py:class`unittest.TestCase` to
`:py:class`pyfakefs.fake_filesystem_unittest.TestCase`.
"""

import sys
import unittest
import doctest
import inspect
import fake_filesystem
import fake_filesystem_glob
import fake_filesystem_shutil
import fake_tempfile

import mock

def load_doctests(loader, tests, ignore, module):
    '''Load the doctest tests for the specified module into unittest.'''
    stubber = Stubber()
    globs = stubber.replaceGlobs(vars(module))
    tests.addTests(doctest.DocTestSuite(module,
                                        globs=globs,
                                        setUp=stubber.setUp,
                                        tearDown=stubber.tearDown))
    return tests

class TestCase(unittest.TestCase):
    def __init__(self, methodName='runTest'):
        super(TestCase, self).__init__(methodName)
        self.stubber = Stubber()

    @property
    def fs(self):
        return self.stubber.fs

    @property
    def patches(self):
        return self.stubber.patches

    def setUpPyfakefs(self):
        '''Bind the file-related modules to the :py:class:`pyfakefs` fake file
        system instead of the real file system.  Also bind the fake `file()` and
        `open()` functions.

        Invoke this at the beginning of the `setUp()` method in your unit test
        class.
        '''
        self.stubber.setUp()

    def tearDownPyfakefs(self):
        '''Clear the fake file system bindings created by `setUp()`.

        Invoke this at the end of the `tearDown()` method in your unit test
        class.
        '''
        self.stubber.tearDown()

class Stubber(object):
    '''
    Instantiate a stub creator to bind and un-bind the file-related modules to
    the :py:module:`pyfakefs` fake modules.
    '''
    SKIPMODULES = set([None, fake_filesystem, fake_filesystem_glob,
                      fake_filesystem_shutil, fake_tempfile, unittest,
                      sys])
    '''Stub nothing that is imported within these modules.
    `sys` is included to prevent `sys.path` from being stubbed with the fake
    `os.path`.
    '''
    assert None in SKIPMODULES, "sys.modules contains 'None' values; must skip them."

    SKIPNAMES = set(['os', 'glob', 'path', 'shutil', 'tempfile'])

    def __init__(self):
        # Attributes set by _findModules()
        self._osModules = None
        self._globModules = None
        self._pathModules = None
        self._shutilModules = None
        self._tempfileModules = None
        self._findModules()
        assert None not in vars(self).values(), \
                "_findModules() missed the initialization of an instance variable"

        # Attributes set by refresh()
        self.fs = None
        self.fake_os = None
        self.fake_glob = None
        self.fake_path = None
        self.fake_shutil = None
        self.fake_tempfile_ = None
        self.fake_open = None
        # _isStale is set by tearDown(), reset by refresh()
        self._isStale = True
        self.refresh()
        assert None not in vars(self).values(), \
                "refresh() missed the initialization of an instance variable"
        assert self._isStale == False, "refresh() did not reset _isStale"

    def _findModules(self):
        '''Find and cache all modules that import file system modules.
        Later, `setUp()` will stub these with the fake file system
        modules.
        '''
        self._osModules = set()
        self._globModules = set()
        self._pathModules = set()
        self._shutilModules = set()
        self._tempfileModules = set()
        for name, module in set(sys.modules.items()):
            if module in self.SKIPMODULES or name in self.SKIPNAMES or (not inspect.ismodule(module)):
                continue
            if 'os' in module.__dict__ and inspect.ismodule(module.__dict__['os']):
                self._osModules.add(name + '.os')
            if 'glob' in module.__dict__:
                self._globModules.add(name + '.glob')
            if 'path' in module.__dict__:
                self._pathModules.add(name + '.path')
            if 'shutil' in module.__dict__:
                self._shutilModules.add(name + '.shutil')
            if 'tempfile' in module.__dict__:
                self._tempfileModules.add(name + '.tempfile')

    def refresh(self):
        '''Renew the fake file system and set the _isStale flag to `False`.'''
        self._stopAllPatches()

        self.fs = fake_filesystem.FakeFilesystem()
        self.fake_os = fake_filesystem.FakeOsModule(self.fs)
        self.fake_glob = fake_filesystem_glob.FakeGlobModule(self.fs)
        self.fake_path = self.fake_os.path
        self.fake_shutil = fake_filesystem_shutil.FakeShutilModule(self.fs)
        self.fake_tempfile_ = fake_tempfile.FakeTempfileModule(self.fs)
        self.fake_open = fake_filesystem.FakeFileOpen(self.fs)

        self._isStale = False

    def _stopAllPatches(self):
        '''Stop (undo) all active patches.'''
        mock.patch.stopall()

    def setUp(self, doctester=None):
        '''Bind the file-related modules to the :py:class:`pyfakefs` fake
        modules real ones.  Also bind the fake `file()` and `open()` functions.
        '''
        if self._isStale:
            self.refresh()

        if doctester is not None:
            doctester.globs = self.replaceGlobs(doctester.globs)

        def startPatch(self, realModuleName, fakeModule):
            if realModuleName == 'unittest.main.os':
                # Known issue with unittest.main resolving to unittest.main.TestProgram
                # See mock module bug 250, https://code.google.com/p/mock/issues/detail?id=250.
                return
            patch = mock.patch(realModuleName, new=fakeModule)
            try:
                patch.start()
            except:
                target, attribute = realModuleName.rsplit('.', 1)
                print("Warning: Could not patch '{}' on module '{}' because '{}' resolves to {}".format(attribute, target, target, patch.getter()))
                print("         See mock module bug 250, https://code.google.com/p/mock/issues/detail?id=250")

        startPatch(self, '__builtin__.file', self.fake_open)
        startPatch(self, '__builtin__.open', self.fake_open)

        for module in self._osModules:
            startPatch(self, module, self.fake_os)
        for module in self._globModules:
            startPatch(self, module, self.fake_glob)
        for module in self._pathModules:
            startPatch(self, module, self.fake_path)
        for module in self._shutilModules:
            startPatch(self, module, self.fake_shutil)
        for module in self._tempfileModules:
            startPatch(self, module, self.fake_tempfile_)

    def replaceGlobs(self, globs_):
        globs = globs_.copy()
        if self._isStale:
            self.refresh()
        if 'os' in globs:
            globs['os'] = fake_filesystem.FakeOsModule(self.fs)
        if 'glob' in globs:
            globs['glob'] = fake_filesystem_glob.FakeGlobModule(self.fs)
        if 'path' in globs:
            globs['path'] =  fake_filesystem.FakePathModule(self.fs)
        if 'shutil' in globs:
            globs['shutil'] = fake_filesystem_shutil.FakeShutilModule(self.fs)
        if 'tempfile' in globs:
            globs['tempfile'] = fake_tempfile.FakeTempfileModule(self.fs)
        return globs

    def tearDown(self, doctester=None):
        '''Clear the fake filesystem bindings created by `setUp()`.

        Invoke this at the end of the `tearDown()` method in your unit test
        class.
        '''
        self._isStale = True
        self._stopAllPatches()
<|endoftext|>


<commit_before>from django.conf import settings
from django.db.models import F
from django.db.models.aggregates import Count
from django.http import HttpResponseRedirect
from django.urls import reverse
from rest_framework import decorators
from django_filters.rest_framework.backends import DjangoFilterBackend
from rest_framework import viewsets
from rest_framework.permissions import IsAuthenticatedOrReadOnly

from geotrek.api.v2 import serializers as api_serializers, \
    viewsets as api_viewsets, filters as api_filters
from geotrek.api.v2.functions import Transform, Length, Length3D
from geotrek.trekking import models as trekking_models

class TrekViewSet(api_viewsets.GeotrekViewset):
    filter_backends = (DjangoFilterBackend,
                       api_filters.GeotrekQueryParamsFilter,
                       api_filters.GeotrekInBBoxFilter,
                       api_filters.GeotrekDistanceToPointFilter,
                       api_filters.GeotrekPublishedFilter,
                       api_filters.GeotrekTrekQueryParamsFilter)
    serializer_class = api_serializers.TrekListSerializer
    serializer_detail_class = api_serializers.TrekDetailSerializer
    queryset = trekking_models.Trek.objects.existing() \
        .select_related('topo_object', 'difficulty', 'practice') \
        .prefetch_related('topo_object__aggregations', 'themes', 'accessibilities', 'networks', 'attachments') \
        .annotate(geom2d_transformed=Transform(F('geom'), settings.API_SRID),
                  geom3d_transformed=Transform(F('geom_3d'), settings.API_SRID),
                  length_2d_m=Length('geom'),
                  length_3d_m=Length3D('geom_3d')) \
        .order_by('pk')  # Required for reliable pagination
    filterset_fields = ('difficulty', 'themes', 'networks', 'practice')

    @decorators.action(detail=False, methods=['get'])
    def practices(self, request, *args, **kwargs):
        return HttpResponseRedirect(reverse('apiv2:practice-list', args=args))

    @decorators.action(detail=False, methods=['get'])
    def networks(self, request, *args, **kwargs):
        return HttpResponseRedirect(reverse('apiv2:network-list', args=args))

    @decorators.action(detail=False, methods=['get'])
    def difficulties(self, request, *args, **kwargs):
        return HttpResponseRedirect(reverse('apiv2:difficulty-list', args=args))

class TourViewSet(TrekViewSet):
    serializer_class = api_serializers.TourListSerializer
    serializer_detail_class = api_serializers.TourDetailSerializer
    queryset = TrekViewSet.queryset.annotate(count_children=Count('trek_children')) \
        .filter(count_children__gt=0)

class PracticeViewSet(viewsets.ReadOnlyModelViewSet):
    serializer_class = api_serializers.TrekPracticeSerializer
    serializer_detail_class = api_serializers.TrekPracticeInTrekSerializer
    queryset = trekking_models.Practice.objects.all()
    permission_classes = [IsAuthenticatedOrReadOnly]

class NetworksViewSet(viewsets.ReadOnlyModelViewSet):
    serializer_class = api_serializers.TrekNetworkSerializer
    serializer_detail_class = api_serializers.TrekNetworkSerializer
    queryset = trekking_models.TrekNetwork.objects.all()
    permission_classes = [IsAuthenticatedOrReadOnly]

class DifficultyViewSet(viewsets.ReadOnlyModelViewSet):
    serializer_class = api_serializers.TrekDifficultySerializer
    serializer_detail_class = api_serializers.TrekDifficultySerializer
    queryset = trekking_models.DifficultyLevel.objects.all()
    permission_classes = [IsAuthenticatedOrReadOnly]

class POIViewSet(api_viewsets.GeotrekViewset):
    serializer_class = api_serializers.POIListSerializer
    serializer_detail_class = api_serializers.POIDetailSerializer
    queryset = trekking_models.POI.objects.existing() \
        .select_related('topo_object', 'type', ) \
        .prefetch_related('topo_object__aggregations', 'attachments') \
        .annotate(geom2d_transformed=Transform(F('geom'), settings.API_SRID),
                  geom3d_transformed=Transform(F('geom_3d'), settings.API_SRID)) \
        .order_by('pk')  # Required for reliable pagination
    filterset_fields = ('type',)

class POITypesViewSet(viewsets.ReadOnlyModelViewSet):
    serializer_class = api_serializers.POITypeSerializer
    serializer_detail_class = api_serializers.POITypeSerializer
    queryset = trekking_models.POIType.objects.all()
    permission_classes = [IsAuthenticatedOrReadOnly]

class AccessibilityViewSet(viewsets.ReadOnlyModelViewSet):
    serializer_class = api_serializers.AccessibilitySerializer
    serializer_detail_class = api_serializers.AccessibilitySerializer
    queryset = trekking_models.Accessibility.objects.all()
    permission_classes = [IsAuthenticatedOrReadOnly]

class RouteViewSet(viewsets.ReadOnlyModelViewSet):
    serializer_class = api_serializers.RouteSerializer
    serializer_detail_class = api_serializers.RouteSerializer
    queryset = trekking_models.Route.objects.all()
    permission_classes = [IsAuthenticatedOrReadOnly]
<commit_msg>Remove duplicated endpoints<commit_after>from django.conf import settings
from django.db.models import F
from django.db.models.aggregates import Count
from django.http import HttpResponseRedirect
from django.urls import reverse
from rest_framework import decorators
from django_filters.rest_framework.backends import DjangoFilterBackend
from rest_framework import viewsets
from rest_framework.permissions import IsAuthenticatedOrReadOnly

from geotrek.api.v2 import serializers as api_serializers, \
    viewsets as api_viewsets, filters as api_filters
from geotrek.api.v2.functions import Transform, Length, Length3D
from geotrek.trekking import models as trekking_models

class TrekViewSet(api_viewsets.GeotrekViewset):
    filter_backends = (DjangoFilterBackend,
                       api_filters.GeotrekQueryParamsFilter,
                       api_filters.GeotrekInBBoxFilter,
                       api_filters.GeotrekDistanceToPointFilter,
                       api_filters.GeotrekPublishedFilter,
                       api_filters.GeotrekTrekQueryParamsFilter)
    serializer_class = api_serializers.TrekListSerializer
    serializer_detail_class = api_serializers.TrekDetailSerializer
    queryset = trekking_models.Trek.objects.existing() \
        .select_related('topo_object', 'difficulty', 'practice') \
        .prefetch_related('topo_object__aggregations', 'themes', 'accessibilities', 'networks', 'attachments') \
        .annotate(geom2d_transformed=Transform(F('geom'), settings.API_SRID),
                  geom3d_transformed=Transform(F('geom_3d'), settings.API_SRID),
                  length_2d_m=Length('geom'),
                  length_3d_m=Length3D('geom_3d')) \
        .order_by('pk')  # Required for reliable pagination
    filterset_fields = ('difficulty', 'themes', 'networks', 'practice')

class TourViewSet(TrekViewSet):
    serializer_class = api_serializers.TourListSerializer
    serializer_detail_class = api_serializers.TourDetailSerializer
    queryset = TrekViewSet.queryset.annotate(count_children=Count('trek_children')) \
        .filter(count_children__gt=0)

class PracticeViewSet(viewsets.ReadOnlyModelViewSet):
    serializer_class = api_serializers.TrekPracticeSerializer
    serializer_detail_class = api_serializers.TrekPracticeInTrekSerializer
    queryset = trekking_models.Practice.objects.all()
    permission_classes = [IsAuthenticatedOrReadOnly]

class NetworksViewSet(viewsets.ReadOnlyModelViewSet):
    serializer_class = api_serializers.TrekNetworkSerializer
    serializer_detail_class = api_serializers.TrekNetworkSerializer
    queryset = trekking_models.TrekNetwork.objects.all()
    permission_classes = [IsAuthenticatedOrReadOnly]

class DifficultyViewSet(viewsets.ReadOnlyModelViewSet):
    serializer_class = api_serializers.TrekDifficultySerializer
    serializer_detail_class = api_serializers.TrekDifficultySerializer
    queryset = trekking_models.DifficultyLevel.objects.all()
    permission_classes = [IsAuthenticatedOrReadOnly]

class POIViewSet(api_viewsets.GeotrekViewset):
    serializer_class = api_serializers.POIListSerializer
    serializer_detail_class = api_serializers.POIDetailSerializer
    queryset = trekking_models.POI.objects.existing() \
        .select_related('topo_object', 'type', ) \
        .prefetch_related('topo_object__aggregations', 'attachments') \
        .annotate(geom2d_transformed=Transform(F('geom'), settings.API_SRID),
                  geom3d_transformed=Transform(F('geom_3d'), settings.API_SRID)) \
        .order_by('pk')  # Required for reliable pagination
    filterset_fields = ('type',)

class POITypesViewSet(viewsets.ReadOnlyModelViewSet):
    serializer_class = api_serializers.POITypeSerializer
    serializer_detail_class = api_serializers.POITypeSerializer
    queryset = trekking_models.POIType.objects.all()
    permission_classes = [IsAuthenticatedOrReadOnly]

class AccessibilityViewSet(viewsets.ReadOnlyModelViewSet):
    serializer_class = api_serializers.AccessibilitySerializer
    serializer_detail_class = api_serializers.AccessibilitySerializer
    queryset = trekking_models.Accessibility.objects.all()
    permission_classes = [IsAuthenticatedOrReadOnly]

class RouteViewSet(viewsets.ReadOnlyModelViewSet):
    serializer_class = api_serializers.RouteSerializer
    serializer_detail_class = api_serializers.RouteSerializer
    queryset = trekking_models.Route.objects.all()
    permission_classes = [IsAuthenticatedOrReadOnly]
<|endoftext|>