<commit_before>#!/usr/bin/env python
#
#  Description:
#       This program is intended to generated the combinations for
#       the integer series A250001 which is described on oeis.org
#
#       Apart from generating the sequences, it will also create an
#       image for the various circle configurations
#
#  History:
#       2015-08-14 Martin Smits
#               Created some initial code which only handles
#               non-intersectinng circles
#

# modules we need
import os, sys
import argparse
import copy
import Image, ImageDraw

# some generic functions for outputting information
DEBUG = True
def debug(msg):
    if DEBUG:
        print "DEBUG: " + msg
def info(msg):
    print "Info: " + msg

#------------------------------------------------------------------------
#  Class for the complete image that supports drawing circles
#
class CirclesImage:
    def __init__(self, width, height):
        self.im = Image.new("RGB", (width, height), "white")
        self.canvas = ImageDraw.Draw(self.im)

    def draw_circle(self, x, y, r):
        self.canvas.ellipse((x-r, y-r, x+r, y+r), outline=(0,0,0))

    def draw_text(self, x, y, msg):
        self.canvas.text((x, y), msg, fill=(0, 0, 0))

    def save(self, filename):
        self.filename = filename
        self.im.save(self.filename)

    def show(self):
        self.im.show()

    def upload(self):
        os.system("scp " + self.filename + " ommos.net:public_html/OEIS_A250001")
        info("Image available at http://www.ommos.net/~msmits/OEIS_A250001/{}".format(self.filename))

#------------------------------------------------------------------------
#  A collection of configurations
#
class CirclesCollection:
    def __init__(self, level):
        self._level = level
        self.collection = []
        self.index = 0

    def __iter__(self):
        self.index = 0
        return self

    def next(self):
        if self.index >= len(self.collection):
            raise StopIteration
        self.index += 1
        return self.collection[self.index - 1]

    @staticmethod
    def new(level):
        return CirclesCollection(level)

    def next_level(self):
        debug("Creating new collection with level " + str(self.level() + 1))
        new_collection = CirclesCollection.new(self.level() + 1)
        for config in self.collection:
            # create new configs with one circle added
            new_configs = config.add_circle()
            for new_config in new_configs:
                equiv = False
                for test_config in new_collection:
                    equiv |= test_config.equivalent(new_config)
                if not equiv:
                    new_collection.add(new_config)
        return new_collection

    def add(self, configuration):
        self.collection.append(configuration)

    def count(self):
        return len(self.collection)

    def level(self):
        return self._level

    def create_image(self, upload):
        info("Create image for level {}.".format(self.level()))
        configs_image = CirclesImage(1024,2048)
        scale = 10
        offset_y = 0.5 * scale
        for config in self.collection:
            debug("configuration: " + str(config))
            circles = config.get_circles(config.get_nesting(), 0)
            radius_max = 0
            for circle in circles:
                if (circle[2] * scale) > radius_max:
                    radius_max = circle[2] * scale
            offset_x = (radius_max + 0.5 * scale)
            offset_y += radius_max
            configs_image.draw_text(300, offset_y, str(config))
            for circle in circles:
                configs_image.draw_circle(
                    circle[0] * 2.5 * scale + offset_x,
                    circle[1] * scale + offset_y,
                    circle[2] * scale
                )
            offset_y += (radius_max + 1.5 * scale)
        configs_image.save("circles_{}.png".format(self.level()))
        if upload:
            configs_image.upload()

#------------------------------------------------------------------------
#  Representation of one circles configuration
#
class CircleSet:
    def __init__(self):
        self.contents = []

    def __str__(self):
        if len(self.contents) == 0:
            contents = "[ ]"
        else:
            contents = "[ "
            first = True
            for c in sorted(self.contents, cmp=lambda x, y: cmp(y.get_nesting(), x.get_nesting())):
                if first:
                    contents += str(c)
                    first = False
                else:
                    contents += ", " + str(c)
            contents += " ]"
        return contents

    def add(self, what):
        self.contents.append(what)

    def add_circle(self):
        debug("Generating new circle configurations with one additional circle")
        # generate new configurations with one additional circle
        new_sets = []
        # new configuration can be:
        # - add circle outside on top-level
        new_set = copy.deepcopy(self)
        new_set.add(Circle())
        new_sets.append(new_set)
        # - inside anything existing
        for i in range(len(self.contents)):
            new_circles = self.contents[i].add_circle()
            for c in new_circles:
                new_set = copy.deepcopy(self)
                new_set.contents[i] = c
                new_sets.append(new_set)
        # return the new configurations
        return new_sets

    def equivalent(self, config):
        # check on equivalence with configs already in
        # the new collection
        debug("Comparing {} with {}".format(str(config), str(self)))
        return (str(config) == str(self))

    def get_nesting(self):
        if len(self.contents) == 0:
            return 0
        else:
            max_nesting = 0
            for c in self.contents:
                nesting = c.get_nesting()
                if nesting > max_nesting:
                    max_nesting = nesting
            return max_nesting

    def get_circles(self, nesting, offset):
        circles = []
        for c in self.contents:
            new_circles = c.get_circles(nesting, offset)
            for nc in new_circles:
                circles.append(nc)
            offset += nesting
        # debug("Drawable circles: " + str(circles))
        return circles

#------------------------------------------------------------------------
# Representation of a circle
#
class Circle:
    def __init__(self):
        self.contents = []
        # TODO Intersections
        #self.intersects = []

    def __str__(self):
        if len(self.contents) == 0:
            contents = "C"
        else:
            contents = "C "
            for c in self.contents:
                contents += str(c)
        return contents

    def add_circle(self):
        debug("Adding a circle to an existing one")
        # generate all variations for adding one circle
        if len(self.contents) == 0:
            circle = copy.deepcopy(self)
            # create new CircleSet with one Circle
            new_set = CircleSet()
            new_set.add(Circle())
            circle.contents.append(new_set)
            return [ circle ]
        else:
            new_circles = [ ]
            new_sets = self.contents[0].add_circle()
            for s in new_sets:
                new_circle = Circle()
                new_circle.contents.append(s)
                new_circles.append(new_circle)
            return new_circles

    def get_nesting(self):
        if len(self.contents) == 0:
            return 1
        else:
            max_nesting = 1
            for c in self.contents:
                nesting = c.get_nesting()
                if nesting + 1 > max_nesting:
                    max_nesting = nesting + 1
            return max_nesting

    def get_circles(self, nesting, offset):
        circles = [ ]
        count = 1
        if len(self.contents) != 0:
            count += len(self.contents) - 1
            sub_circles = self.contents[0].get_circles(nesting - 1, offset)
            for sc in sub_circles:
                circles.append(sc)
        circle = (1 + offset, 1, nesting * count)
        circles.append(circle)
        return circles

#========================================================================
# The main program
#========================================================================

parser = argparse.ArgumentParser(description="Generate A250001 circles")
parser.add_argument('circles', metavar='N', type=int, default=4, nargs='?',
                    help='the number of circles per configuration')
parser.add_argument('-image', dest='image', default=False, action='store_true',
                    help='output images for each level')
parser.add_argument('-upload', dest='upload', default=False, action='store_true',
                    help='upload the image to some website')
parser.add_argument('-debug', dest='debug', default=False, action='store_true',
                    help='turn on some debugging output')
args = parser.parse_args()
level = args.circles
image = args.image
upload = args.upload
DEBUG = args.debug

collections = [ CirclesCollection.new(0) ]
collections[0].add(CircleSet())

for i in range(level):
    c_new = collections[len(collections) - 1].next_level()
    collections.append(c_new)

print "{:10} {:10}".format("Level", "Count")
for c in collections:
    if c.level() > 0:
        print "{:<10} {:<10}".format(c.level(), c.count())
for c in collections:
    if c.level() > 0:
        if image:
            c.create_image(upload)
<commit_msg>updated some comments; updated the main program structure<commit_after>#!/usr/bin/env python
#
#  Description:
#       This program is intended to generated the combinations for
#       the integer series A250001 which is described on oeis.org
#
#       Apart from generating the sequences, it will also create an
#       image for the various circle configurations
#
#  History:
#       2015-08-14 Martin Smits
#               Created some initial code which only handles
#               non-intersecting circles
#

# modules we need
import os, sys
import argparse
import copy
import Image, ImageDraw

# some generic functions for outputting information
DEBUG = True
def debug(msg):
    if DEBUG:
        print "DEBUG: " + msg
def info(msg):
    print "Info: " + msg

#------------------------------------------------------------------------
#  Class for the complete image that supports drawing circles
#
class CirclesImage:
    def __init__(self, width, height):
        self.im = Image.new("RGB", (width, height), "white")
        self.canvas = ImageDraw.Draw(self.im)

    def draw_circle(self, x, y, r):
        self.canvas.ellipse((x-r, y-r, x+r, y+r), outline=(0,0,0))

    def draw_text(self, x, y, msg):
        self.canvas.text((x, y), msg, fill=(0, 0, 0))

    def save(self, filename):
        self.filename = filename
        self.im.save(self.filename)

    def show(self):
        self.im.show()

    def upload(self):
        os.system("scp " + self.filename + " ommos.net:public_html/OEIS_A250001")
        info("Image available at http://www.ommos.net/~msmits/OEIS_A250001/{}".format(self.filename))

#------------------------------------------------------------------------
#  A collection of configurations
#
class CirclesCollection:
    def __init__(self, level):
        self._level = level
        self.collection = []
        self.index = 0

    def __iter__(self):
        self.index = 0
        return self

    def next(self):
        if self.index >= len(self.collection):
            raise StopIteration
        self.index += 1
        return self.collection[self.index - 1]

    @staticmethod
    def new(level):
        return CirclesCollection(level)

    def next_level(self):
        debug("Creating new collection with level " + str(self.level() + 1))
        new_collection = CirclesCollection.new(self.level() + 1)
        for config in self.collection:
            # create new configs with one circle added
            new_configs = config.add_circle()
            for new_config in new_configs:
                equiv = False
                for test_config in new_collection:
                    equiv |= test_config.equivalent(new_config)
                if not equiv:
                    new_collection.add(new_config)
        return new_collection

    def add(self, configuration):
        self.collection.append(configuration)

    def count(self):
        return len(self.collection)

    def level(self):
        return self._level

    def create_image(self, upload):
        info("Create image for level {}.".format(self.level()))
        configs_image = CirclesImage(1024,2048)
        scale = 10
        offset_y = 0.5 * scale
        for config in self.collection:
            debug("configuration: " + str(config))
            circles = config.get_circles(config.get_nesting(), 0)
            radius_max = 0
            for circle in circles:
                if (circle[2] * scale) > radius_max:
                    radius_max = circle[2] * scale
            offset_x = (radius_max + 0.5 * scale)
            offset_y += radius_max
            configs_image.draw_text(300, offset_y, str(config))
            for circle in circles:
                configs_image.draw_circle(
                    circle[0] * 2.5 * scale + offset_x,
                    circle[1] * scale + offset_y,
                    circle[2] * scale
                )
            offset_y += (radius_max + 1.5 * scale)
        configs_image.save("circles_{}.png".format(self.level()))
        if upload:
            configs_image.upload()

    def create_text(self):
        info("Create textual representations for level {}.".format(self.level()))
        for config in self.collection:
            info(str(config))

#------------------------------------------------------------------------
#  Representation of separate side-by-side elements
#
class CircleSet:
    def __init__(self):
        self.contents = []

    def __str__(self):
        if len(self.contents) == 0:
            contents = "[ ]"
        else:
            contents = "[ "
            first = True
            for c in sorted(self.contents,
                            cmp=lambda x, y: cmp(y.get_nesting(), x.get_nesting())):
                if first:
                    contents += str(c)
                    first = False
                else:
                    contents += ", " + str(c)
            contents += " ]"
        return contents

    def add(self, what):
        self.contents.append(what)

    def add_circle(self):
        debug("Generating new circle configurations with one additional circle")
        # generate new configurations with one additional circle
        new_sets = []
        # new configuration can be:
        # - add circle outside on top-level
        new_set = copy.deepcopy(self)
        new_set.add(Circle())
        new_sets.append(new_set)
        # - inside anything existing
        for i in range(len(self.contents)):
            new_circles = self.contents[i].add_circle()
            for c in new_circles:
                new_set = copy.deepcopy(self)
                new_set.contents[i] = c
                new_sets.append(new_set)
        # return the new configurations
        return new_sets

    def equivalent(self, config):
        # check on equivalence with configs already in
        # the new collection
        debug("Comparing {} with {}".format(str(config), str(self)))
        return (str(config) == str(self))

    def get_nesting(self):
        if len(self.contents) == 0:
            return 0
        else:
            max_nesting = 0
            for c in self.contents:
                nesting = c.get_nesting()
                if nesting > max_nesting:
                    max_nesting = nesting
            return max_nesting

    def get_circles(self, nesting, offset):
        circles = []
        for c in self.contents:
            new_circles = c.get_circles(nesting, offset)
            for nc in new_circles:
                circles.append(nc)
            offset += nesting
        # debug("Drawable circles: " + str(circles))
        return circles

#------------------------------------------------------------------------
# Representation of a circle and its contents
#
class Circle:
    def __init__(self):
        self.contents = []
        # TODO Intersections
        self.intersects = []

    def __str__(self):
        if len(self.contents) == 0:
            contents = "C"
        else:
            contents = "C "
            for c in self.contents:
                contents += str(c)
        return contents

    def add_circle(self):
        debug("Adding a circle to an existing one")
        # generate all variations for adding one circle
        if len(self.contents) == 0:
            circle = copy.deepcopy(self)
            # create new CircleSet with one Circle
            new_set = CircleSet()
            new_set.add(Circle())
            circle.contents.append(new_set)
            return [ circle ]
        else:
            new_circles = [ ]
            new_sets = self.contents[0].add_circle()
            for s in new_sets:
                new_circle = Circle()
                new_circle.contents.append(s)
                new_circles.append(new_circle)
            return new_circles

    def get_nesting(self):
        if len(self.contents) == 0:
            return 1
        else:
            max_nesting = 1
            for c in self.contents:
                nesting = c.get_nesting()
                if nesting + 1 > max_nesting:
                    max_nesting = nesting + 1
            return max_nesting

    def get_circles(self, nesting, offset):
        circles = [ ]
        count = 1
        if len(self.contents) != 0:
            count += len(self.contents) - 1
            sub_circles = self.contents[0].get_circles(nesting - 1, offset)
            for sc in sub_circles:
                circles.append(sc)
        circle = (1 + offset, 1, nesting * count)
        circles.append(circle)
        return circles

#========================================================================
# The main program
#========================================================================
if __name__ == "__main__":
    parser = argparse.ArgumentParser(
        description="OEIS A250001: Number of arrangements of N circles in the affine plane")
    parser.add_argument('circles', metavar='N', type=int, default=4, nargs='?',
        help='the number of circles per configuration')
    parser.add_argument('-text', dest='text', default=False, action='store_true',
        help='output textual representations for each level')
    parser.add_argument('-image', dest='image', default=False, action='store_true',
        help='output images for each level')
    parser.add_argument('-upload', dest='upload', default=False, action='store_true',
        help='upload the image to some website')
    parser.add_argument('-debug', dest='debug', default=False, action='store_true',
        help='turn on some debugging output')
    args = parser.parse_args()
    level = args.circles
    text = args.text
    image = args.image
    upload = args.upload
    DEBUG = args.debug

    # TODO: intersections
    print "NOTE: intersecting cicles are not yet implemented."

    # Create the initial configuration with no circles
    collections = [ CirclesCollection.new(0) ]
    collections[0].add(CircleSet())

    # now create the next level until the reuqested one is reached
    for i in range(level):
        c_new = collections[len(collections) - 1].next_level()
        collections.append(c_new)

    # output overview of the number of configurations per level
    print "{:10} {:10}".format("Level", "Count")
    for c in collections:
        if c.level() >= 0:
            print "{:<10} {:<10}".format(c.level(), c.count())
    # if requested, generate the textual and/or the image representation
    for c in collections:
        if c.level() >= 0:
            if image:
                c.create_image(upload)
            if text:
                c.create_text();
<|endoftext|>


<commit_before>"""Translate cli commands to non-cli code."""
import json
import logging
import os
import re
from urllib.error import HTTPError, URLError

import requests

from kytos.utils.napps import NAppsManager

LOG = logging.getLogger(__name__)

class NAppsAPI:
    """An API for the command-line interface.

    Use the config file only for required options. Static methods are called
    by the parser and they instantiate an object of this class to fulfill the
    request.
    """

    @classmethod
    def disable(cls, args):
        """Disable subcommand."""
        mgr = NAppsManager()

        if args['all']:
            napps = mgr.get_enabled()
        else:
            napps = args['<napp>']

        for napp in napps:
            mgr.set_napp(*napp)
            LOG.info('NApp %s:', mgr.napp_id)
            cls.disable_napp(mgr)

    @staticmethod
    def disable_napp(mgr):
        """Disable a NApp."""
        if mgr.is_enabled():
            LOG.info('  Disabling...')
            mgr.disable()
        LOG.info('  Disabled.')

    @classmethod
    def enable(cls, args):
        """Enable subcommand."""
        mgr = NAppsManager()

        if args['all']:
            napps = mgr.get_disabled()
        else:
            napps = args['<napp>']

        cls.enable_napps(napps)

    @classmethod
    def enable_napp(cls, mgr):
        """Install one NApp using NAppManager object."""
        try:
            if not mgr.is_enabled():
                LOG.info('  Enabling...')
                mgr.enable()
            LOG.info('  Enabled.')
            cls.enable_napps(mgr.dependencies())
        except (FileNotFoundError, PermissionError) as exception:
            LOG.error('  %s', exception)

    @classmethod
    def enable_napps(cls, napps):
        """Enable a list of NApps.

        Args:
            napps (list): List of NApps.
        """
        mgr = NAppsManager()
        for napp in napps:
            mgr.set_napp(*napp)
            LOG.info('NApp %s:', mgr.napp_id)
            cls.enable_napp(mgr)

    @classmethod
    def create(cls, args):  # pylint: disable=unused-argument
        """Bootstrap a basic NApp structure on the current folder."""
        NAppsManager.create_napp()

    @classmethod
    def upload(cls, args):  # pylint: disable=unused-argument
        """Upload the NApp to the NApps server.

        Create the NApp package and upload it to the NApp server.
        """
        try:
            NAppsManager().upload()
        except FileNotFoundError:
            LOG.error("Couldn't find kytos.json in current directory.")

    @classmethod
    def uninstall(cls, args):
        """Uninstall and delete NApps.

        For local installations, do not delete code outside install_path and
        enabled_path.
        """
        mgr = NAppsManager()
        for napp in args['<napp>']:
            mgr.set_napp(*napp)
            LOG.info('NApp %s:', mgr.napp_id)
            if mgr.is_installed():
                if mgr.is_enabled():
                    cls.disable_napp(mgr)
                LOG.info('  Uninstalling...')
                mgr.uninstall()
            LOG.info('  Uninstalled.')

    @classmethod
    def install(cls, args):
        """Install local or remote NApps."""
        cls.install_napps(args['<napp>'])

    @classmethod
    def install_napps(cls, napps):
        """Install local or remote NApps.

        This method is recursive, it will install each napps and your
        dependencies.
        """
        mgr = NAppsManager()
        for napp in napps:
            mgr.set_napp(*napp)
            LOG.info('NApp %s:', mgr.napp_id)
            if not mgr.is_installed():
                cls.install_napp(mgr)
            else:
                LOG.info('  Installed.')
                cls.enable_napp(mgr)
            napp_dependencies = mgr.dependencies()
            if napp_dependencies:
                LOG.info('Installing Dependencies:')
                cls.install_napps(napp_dependencies)

    @classmethod
    def install_napp(cls, mgr):
        """Install a NApp."""
        try:
            LOG.info('  Searching local NApp...')
            mgr.install_local()
            LOG.info('  Found and installed.')
            cls.enable_napp(mgr)
        except FileNotFoundError:
            LOG.info('  Not found. Downloading from NApps Server...')
            try:
                mgr.install_remote()
                LOG.info('  Downloaded and installed.')
                cls.enable_napp(mgr)
            except HTTPError as exception:
                if exception.code == 404:
                    LOG.error('  NApp not found.')
                else:
                    LOG.error('  NApps Server error: %s', exception)
            except URLError as exception:
                LOG.error('  NApps Server error: %s', str(exception.reason))

    @classmethod
    def search(cls, args):
        """Search for NApps in NApps server matching a pattern."""
        safe_shell_pat = re.escape(args['<pattern>']).replace(r'\*', '.*')
        pat_str = '.*{}.*'.format(safe_shell_pat)
        pattern = re.compile(pat_str, re.IGNORECASE)
        remote_json = NAppsManager.search(pattern)
        remote = set()
        for napp in remote_json:
            # WARNING: This will be changed in future versions, when 'author'
            # will be removed.
            username = napp.get('username', napp.get('author'))
            remote.add(((username, napp.get('name')), napp.get('description')))

        cls._print_napps(remote)

    @classmethod
    def _print_napps(cls, napp_list):
        """Format the NApp list to be printed."""
        mgr = NAppsManager()
        enabled = mgr.get_enabled()
        installed = mgr.get_installed()
        napps = []
        for napp, desc in sorted(napp_list):
            status = 'i' if napp in installed else '-'
            status += 'e' if napp in enabled else '-'
            status = '[{}]'.format(status)
            name = '{}/{}'.format(*napp)
            napps.append((status, name, desc))
        cls.print_napps(napps)

    @classmethod
    def list(cls, args):  # pylint: disable=unused-argument
        """List all installed NApps and inform whether they are enabled."""
        mgr = NAppsManager()

        # Add status
        napps = [napp + ('[ie]',) for napp in mgr.get_enabled()]
        napps += [napp + ('[i-]',) for napp in mgr.get_disabled()]

        # Sort, add description and reorder columns
        napps.sort()
        napps_ordered = []
        for user, name, status in napps:
            description = mgr.get_description(user, name)
            version = mgr.get_version(user, name)
            napp_id = f'{user}/{name}'
            if version:
                napp_id += f':{version}'

            napps_ordered.append((status, napp_id, description))

        cls.print_napps(napps_ordered)

    @staticmethod
    def print_napps(napps):
        """Print status, name and description."""
        if not napps:
            print('No NApps found.')
            return

        stat_w = 6  # We already know the size of Status col
        name_w = max(len(n[1]) for n in napps)
        desc_w = max(len(n[2]) for n in napps)
        term_w = os.popen('stty size', 'r').read().split()[1]
        remaining = int(term_w) - stat_w - name_w - 6
        desc_w = min(desc_w, remaining)
        widths = (stat_w, name_w, desc_w)

        header = '\n{:^%d} | {:^%d} | {:^%d}' % widths
        row = '{:^%d} | {:<%d} | {:<%d}' % widths
        print(header.format('Status', 'NApp ID', 'Description'))
        print('=+='.join('=' * w for w in widths))
        for user, name, desc in napps:
            desc = (desc[:desc_w-3] + '...') if len(desc) > desc_w else desc
            print(row.format(user, name, desc))

        print('\nStatus: (i)nstalled, (e)nabled\n')

    @staticmethod
    def delete(args):
        """Delete NApps from server."""
        mgr = NAppsManager()
        for napp in args['<napp>']:
            mgr.set_napp(*napp)
            LOG.info('Deleting NApp %s from server...', mgr.napp_id)
            try:
                mgr.delete()
                LOG.info('  Deleted.')
            except requests.HTTPError as exception:
                if exception.response.status_code == 405:
                    LOG.error('Delete Napp is not allowed yet.')
                else:
                    msg = json.loads(exception.response.content)
                    LOG.error('  Server error: %s - ', msg['error'])

    @classmethod
    def prepare(cls, args):  # pylint: disable=unused-argument
        """Create OpenAPI v3.0 spec skeleton."""
        mgr = NAppsManager()
        mgr.prepare()
<commit_msg>Show warning when a NApp is already installed<commit_after>"""Translate cli commands to non-cli code."""
import json
import logging
import os
import re
from urllib.error import HTTPError, URLError

import requests

from kytos.utils.napps import NAppsManager

LOG = logging.getLogger(__name__)

class NAppsAPI:
    """An API for the command-line interface.

    Use the config file only for required options. Static methods are called
    by the parser and they instantiate an object of this class to fulfill the
    request.
    """

    @classmethod
    def disable(cls, args):
        """Disable subcommand."""
        mgr = NAppsManager()

        if args['all']:
            napps = mgr.get_enabled()
        else:
            napps = args['<napp>']

        for napp in napps:
            mgr.set_napp(*napp)
            LOG.info('NApp %s:', mgr.napp_id)
            cls.disable_napp(mgr)

    @staticmethod
    def disable_napp(mgr):
        """Disable a NApp."""
        if mgr.is_enabled():
            LOG.info('  Disabling...')
            mgr.disable()
        LOG.info('  Disabled.')

    @classmethod
    def enable(cls, args):
        """Enable subcommand."""
        mgr = NAppsManager()

        if args['all']:
            napps = mgr.get_disabled()
        else:
            napps = args['<napp>']

        cls.enable_napps(napps)

    @classmethod
    def enable_napp(cls, mgr):
        """Install one NApp using NAppManager object."""
        try:
            if not mgr.is_enabled():
                LOG.info('  Enabling...')
                mgr.enable()
            LOG.info('  Enabled.')
            cls.enable_napps(mgr.dependencies())
        except (FileNotFoundError, PermissionError) as exception:
            LOG.error('  %s', exception)

    @classmethod
    def enable_napps(cls, napps):
        """Enable a list of NApps.

        Args:
            napps (list): List of NApps.
        """
        mgr = NAppsManager()
        for napp in napps:
            mgr.set_napp(*napp)
            LOG.info('NApp %s:', mgr.napp_id)
            cls.enable_napp(mgr)

    @classmethod
    def create(cls, args):  # pylint: disable=unused-argument
        """Bootstrap a basic NApp structure on the current folder."""
        NAppsManager.create_napp()

    @classmethod
    def upload(cls, args):  # pylint: disable=unused-argument
        """Upload the NApp to the NApps server.

        Create the NApp package and upload it to the NApp server.
        """
        try:
            NAppsManager().upload()
        except FileNotFoundError:
            LOG.error("Couldn't find kytos.json in current directory.")

    @classmethod
    def uninstall(cls, args):
        """Uninstall and delete NApps.

        For local installations, do not delete code outside install_path and
        enabled_path.
        """
        mgr = NAppsManager()
        for napp in args['<napp>']:
            mgr.set_napp(*napp)
            LOG.info('NApp %s:', mgr.napp_id)
            if mgr.is_installed():
                if mgr.is_enabled():
                    cls.disable_napp(mgr)
                LOG.info('  Uninstalling...')
                mgr.uninstall()
            LOG.info('  Uninstalled.')

    @classmethod
    def install(cls, args):
        """Install local or remote NApps."""
        cls.install_napps(args['<napp>'])

    @classmethod
    def install_napps(cls, napps):
        """Install local or remote NApps.

        This method is recursive, it will install each napps and your
        dependencies.
        """
        mgr = NAppsManager()
        for napp in napps:
            mgr.set_napp(*napp)
            LOG.info('NApp %s:', mgr.napp_id)
            if not mgr.is_installed():
                cls.install_napp(mgr)
                LOG.info('  Installed.')
            else:
                LOG.warning('  Napp already Installed.')
                cls.enable_napp(mgr)
            napp_dependencies = mgr.dependencies()
            if napp_dependencies:
                LOG.info('Installing Dependencies:')
                cls.install_napps(napp_dependencies)

    @classmethod
    def install_napp(cls, mgr):
        """Install a NApp."""
        try:
            LOG.info('  Searching local NApp...')
            mgr.install_local()
            LOG.info('  Found and installed.')
            cls.enable_napp(mgr)
        except FileNotFoundError:
            LOG.info('  Not found. Downloading from NApps Server...')
            try:
                mgr.install_remote()
                LOG.info('  Downloaded and installed.')
                cls.enable_napp(mgr)
            except HTTPError as exception:
                if exception.code == 404:
                    LOG.error('  NApp not found.')
                else:
                    LOG.error('  NApps Server error: %s', exception)
            except URLError as exception:
                LOG.error('  NApps Server error: %s', str(exception.reason))

    @classmethod
    def search(cls, args):
        """Search for NApps in NApps server matching a pattern."""
        safe_shell_pat = re.escape(args['<pattern>']).replace(r'\*', '.*')
        pat_str = '.*{}.*'.format(safe_shell_pat)
        pattern = re.compile(pat_str, re.IGNORECASE)
        remote_json = NAppsManager.search(pattern)
        remote = set()
        for napp in remote_json:
            # WARNING: This will be changed in future versions, when 'author'
            # will be removed.
            username = napp.get('username', napp.get('author'))
            remote.add(((username, napp.get('name')), napp.get('description')))

        cls._print_napps(remote)

    @classmethod
    def _print_napps(cls, napp_list):
        """Format the NApp list to be printed."""
        mgr = NAppsManager()
        enabled = mgr.get_enabled()
        installed = mgr.get_installed()
        napps = []
        for napp, desc in sorted(napp_list):
            status = 'i' if napp in installed else '-'
            status += 'e' if napp in enabled else '-'
            status = '[{}]'.format(status)
            name = '{}/{}'.format(*napp)
            napps.append((status, name, desc))
        cls.print_napps(napps)

    @classmethod
    def list(cls, args):  # pylint: disable=unused-argument
        """List all installed NApps and inform whether they are enabled."""
        mgr = NAppsManager()

        # Add status
        napps = [napp + ('[ie]',) for napp in mgr.get_enabled()]
        napps += [napp + ('[i-]',) for napp in mgr.get_disabled()]

        # Sort, add description and reorder columns
        napps.sort()
        napps_ordered = []
        for user, name, status in napps:
            description = mgr.get_description(user, name)
            version = mgr.get_version(user, name)
            napp_id = f'{user}/{name}'
            if version:
                napp_id += f':{version}'

            napps_ordered.append((status, napp_id, description))

        cls.print_napps(napps_ordered)

    @staticmethod
    def print_napps(napps):
        """Print status, name and description."""
        if not napps:
            print('No NApps found.')
            return

        stat_w = 6  # We already know the size of Status col
        name_w = max(len(n[1]) for n in napps)
        desc_w = max(len(n[2]) for n in napps)
        term_w = os.popen('stty size', 'r').read().split()[1]
        remaining = int(term_w) - stat_w - name_w - 6
        desc_w = min(desc_w, remaining)
        widths = (stat_w, name_w, desc_w)

        header = '\n{:^%d} | {:^%d} | {:^%d}' % widths
        row = '{:^%d} | {:<%d} | {:<%d}' % widths
        print(header.format('Status', 'NApp ID', 'Description'))
        print('=+='.join('=' * w for w in widths))
        for user, name, desc in napps:
            desc = (desc[:desc_w-3] + '...') if len(desc) > desc_w else desc
            print(row.format(user, name, desc))

        print('\nStatus: (i)nstalled, (e)nabled\n')

    @staticmethod
    def delete(args):
        """Delete NApps from server."""
        mgr = NAppsManager()
        for napp in args['<napp>']:
            mgr.set_napp(*napp)
            LOG.info('Deleting NApp %s from server...', mgr.napp_id)
            try:
                mgr.delete()
                LOG.info('  Deleted.')
            except requests.HTTPError as exception:
                if exception.response.status_code == 405:
                    LOG.error('Delete Napp is not allowed yet.')
                else:
                    msg = json.loads(exception.response.content)
                    LOG.error('  Server error: %s - ', msg['error'])

    @classmethod
    def prepare(cls, args):  # pylint: disable=unused-argument
        """Create OpenAPI v3.0 spec skeleton."""
        mgr = NAppsManager()
        mgr.prepare()
<|endoftext|>


<commit_before># Copyright (C) 2009  Renato Lima - Akretion
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html

from odoo import fields, models

class City(models.Model):
    """ Este objeto persite todos os municípios relacionado a um estado.
    No Brasil é necesário em alguns documentos fiscais informar o código
    do IBGE dos município envolvidos na transação.
    """

    _inherit = "res.city"

    ibge_code = fields.Char(string="IBGE Code", size=7, index=True)
<commit_msg>Update res_city.py<commit_after># Copyright (C) 2009  Renato Lima - Akretion
# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html

from odoo import fields, models

class City(models.Model):
    """ Este objeto persite todos os municípios relacionado a um estado.
    No Brasil é necesário em alguns documentos fiscais informar o código
    do IBGE dos município envolvidos na transação.
    """

    _inherit = "res.city"

    ibge_code = fields.Char(string="IBGE Code", size=7, index=True)
    siafi_code = fields.Char(string="SIAFI Code", size=4)
    anp_code = fields.Char(string="ANP Code", size=4)
<|endoftext|>


<commit_before># Copyright 2019 Ecosoft Co., Ltd (http://ecosoft.co.th/)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html)

import json
import base64
import time
from odoo.addons.web.controllers import main as report
from odoo.http import content_disposition, route, request
from odoo.tools.safe_eval import safe_eval

class ReportController(report.ReportController):

    @route()
    def report_routes(self, reportname, docids=None, converter=None, **data):
        if converter == 'excel':
            report = request.env['ir.actions.report']._get_report_from_name(
                reportname)
            context = dict(request.env.context)
            if docids:
                docids = [int(i) for i in docids.split(',')]
            if data.get('options'):
                data.update(json.loads(data.pop('options')))
            if data.get('context'):
                # Ignore 'lang' here, because the context in data is the one
                # from the webclient *but* if the user explicitely wants to
                # change the lang, this mechanism overwrites it.
                data['context'] = json.loads(data['context'])
                if data['context'].get('lang'):
                    del data['context']['lang']
                context.update(data['context'])
            excel = report.with_context(context).render_excel(
                docids, data=data
            )[0]
            excel = base64.decodestring(excel)
            report_name = report.report_file
            if report.print_report_name and not len(docids) > 1:
                obj = request.env[report.model].browse(docids[0])
                report_name = safe_eval(report.print_report_name,
                                        {'object': obj, 'time': time})
            excelhttpheaders = [
                ('Content-Type', 'application/vnd.openxmlformats-'
                                 'officedocument.spreadsheetml.sheet'),
                ('Content-Length', len(excel)),
                (
                    'Content-Disposition',
                    content_disposition(report_name + '.xlsx')
                )
            ]
            return request.make_response(excel, headers=excelhttpheaders)
        return super(ReportController, self).report_routes(
            reportname, docids, converter, **data
        )
<commit_msg>[12.0][FIX] excel_import_export, fix wrong file name on report_action<commit_after># Copyright 2019 Ecosoft Co., Ltd (http://ecosoft.co.th/)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html)

import json
import base64
import time
from odoo.addons.web.controllers import main as report
from odoo.http import content_disposition, route, request
from odoo.tools.safe_eval import safe_eval

class ReportController(report.ReportController):

    @route()
    def report_routes(self, reportname, docids=None, converter=None, **data):
        if converter == 'excel':
            report = request.env['ir.actions.report']._get_report_from_name(
                reportname)
            context = dict(request.env.context)
            if docids:
                docids = [int(i) for i in docids.split(',')]
            if data.get('options'):
                data.update(json.loads(data.pop('options')))
            if data.get('context'):
                # Ignore 'lang' here, because the context in data is the one
                # from the webclient *but* if the user explicitely wants to
                # change the lang, this mechanism overwrites it.
                data['context'] = json.loads(data['context'])
                if data['context'].get('lang'):
                    del data['context']['lang']
                context.update(data['context'])
            excel, report_name = report.with_context(context).render_excel(
                docids, data=data
            )
            excel = base64.decodestring(excel)
            if report.print_report_name and not len(docids) > 1:
                obj = request.env[report.model].browse(docids[0])
                file_ext = report_name.split('.')[-1:].pop()
                report_name = safe_eval(report.print_report_name,
                                        {'object': obj, 'time': time})
                report_name = '%s.%s' % (report_name, file_ext)
            excelhttpheaders = [
                ('Content-Type', 'application/vnd.openxmlformats-'
                                 'officedocument.spreadsheetml.sheet'),
                ('Content-Length', len(excel)),
                (
                    'Content-Disposition',
                    content_disposition(report_name)
                )
            ]
            return request.make_response(excel, headers=excelhttpheaders)
        return super(ReportController, self).report_routes(
            reportname, docids, converter, **data
        )
<|endoftext|>


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

{
    'name': 'Brazilian Localisation Data Extension for zip codes',
    'description': 'Brazilian Localization Data Extension for zip codes',
    'license': 'AGPL-3',
    'author': 'Akretion, OpenERP Brasil',
    'version': '0.1',
    'depends': [
        'l10n_br_base',
    ],
    'data': [
#        'zip.sql',
        'l10n_br_data_zip_view.xml',
        'res_partner_view.xml',
        'wizard/l10n_br_data_zip_search_view.xml',
        'security/ir.model.access.csv',
    ],
    'demo': [],
    'category': 'Localization',
    'active': False,
    'installable': True
}
<commit_msg>[MERGE] migração do módulo l10n_br_data_zip para versão 7.0, removido comentário<commit_after># -*- encoding: utf-8 -*-
###############################################################################
#                                                                             #
# Copyright (C) 2009  Renato Lima - Akretion                                  #
#                                                                             #
#This program is free software: you can redistribute it and/or modify         #
#it under the terms of the GNU Affero General Public License as published by  #
#the Free Software Foundation, either version 3 of the License, or            #
#(at your option) any later version.                                          #
#                                                                             #
#This program is distributed in the hope that it will be useful,              #
#but WITHOUT ANY WARRANTY; without even the implied warranty of               #
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                #
#GNU Affero General Public License for more details.                          #
#                                                                             #
#You should have received a copy of the GNU Affero General Public License     #
#along with this program.  If not, see <http://www.gnu.org/licenses/>.        #
###############################################################################

{
    'name': 'Brazilian Localisation Data Extension for zip codes',
    'description': 'Brazilian Localization Data Extension for zip codes',
    'license': 'AGPL-3',
    'author': 'Akretion, OpenERP Brasil',
    'version': '0.1',
    'depends': [
        'l10n_br_base',
    ],
    'data': [
        'zip.sql',
        'l10n_br_data_zip_view.xml',
        'res_partner_view.xml',
        'wizard/l10n_br_data_zip_search_view.xml',
        'security/ir.model.access.csv',
    ],
    'demo': [],
    'category': 'Localization',
    'active': False,
    'installable': True
}
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
##############################################################################
#
#    OpenERP, Open Source Management Solution
#    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as
#    published by the Free Software Foundation, either version 3 of the
#    License, or (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################

from lxml import etree

from osv import osv, fields
from tools.translate import _
import tools

class account_move_journal(osv.osv_memory):
    _name = "account.move.journal"
    _description = "Move journal"

    _columns = {
       'target_move': fields.selection([('posted', 'All Posted Entries'),
                                        ('all', 'All Entries'),
                                        ], 'Target Moves', required=True),
    }

    _defaults = {
        'target_move': 'posted'
    }
    def _get_period(self, cr, uid, context={}):
        """
        Return  default account period value
        """
        account_period_obj = self.pool.get('account.period')
        ids = account_period_obj.find(cr, uid, context=context)
        period_id = False
        if ids:
            period_id = ids[0]
        return period_id

    def _get_journal(self, cr, uid, context=None):
        """
        Return journal based on the journal type
        """

        journal_id = False

        journal_pool = self.pool.get('account.journal')
        if context.get('journal_type', False):
            jids = journal_pool.search(cr, uid, [('type','=', context.get('journal_type'))])
            if not jids:
                raise osv.except_osv(_('Configuration Error !'), _('Can\'t find any account journal of %s type for this company.\n\nYou can create one in the menu: \nConfiguration/Financial Accounting/Accounts/Journals.') % context.get('journal_type'))
            journal_id = jids[0]

        return journal_id

    def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
        """
        Returns views and fields for current model where view will depend on {view_type}.
        @param cr: A database cursor
        @param user: ID of the user currently logged in
        @param view_id: list of fields, which required to read signatures
        @param view_type: defines a view type. it can be one of (form, tree, graph, calender, gantt, search, mdx)
        @param context: context arguments, like lang, time zone
        @param toolbar: contains a list of reports, wizards, and links related to current model

        @return: Returns a dict that contains definition for fields, views, and toolbars
        """

        res = super(account_move_journal, self).fields_view_get(cr, uid, view_id, view_type, context, toolbar, submenu)

        if not view_id:
            return res

        period_pool = self.pool.get('account.period')
        journal_pool = self.pool.get('account.journal')

        journal_id = self._get_journal(cr, uid, context)
        period_id = self._get_period(cr, uid, context)

        journal = False
        if journal_id:
            journal = journal_pool.read(cr, uid, [journal_id], ['name'])[0]['name']
            journal_string = _("Journal: %s") % tools.ustr(journal)
        else:
            journal_string = _("Journal: All")

        period = False
        if period_id:
            period = period_pool.browse(cr, uid, [period_id], ['name'])[0]['name']
            period_string = _("Period: %s") % tools.ustr(period)

        view = """<?xml version="1.0" encoding="utf-8"?>
        <form string="Standard entries">
            <separator string="Open Journal Items !" colspan="4"/>
            <field name="target_move" />
            <newline/>
            <group colspan="4" >
                <label width="300" string="%s"/>
                <newline/>
                <label width="300" string="%s"/>
            </group>
            <group colspan="4" col="4">
                <label string ="" colspan="2"/>
                <button icon="gtk-cancel" special="cancel" string="Cancel"/>
                <button icon="terp-gtk-go-back-rtl" string="Open" name="action_open_window" default_focus="1" type="object"/>
            </group>
        </form>""" % (journal_string, period_string)

        view = etree.fromstring(view.encode('utf8'))
        xarch, xfields = self._view_look_dom_arch(cr, uid, view, view_id, context=context)
        view = xarch
        res.update({
            'arch': view
        })
        return res

    def action_open_window(self, cr, uid, ids, context=None):
        """
        This function Open action move line window on given period and  Journal/Payment Mode
        @param cr: the current row, from the database cursor,
        @param uid: the current user’s ID for security checks,
        @param ids: account move journal’s ID or list of IDs
        @return: dictionary of Open action move line window on given period and  Journal/Payment Mode
        """

        period_pool = self.pool.get('account.journal.period')
        data_pool = self.pool.get('ir.model.data')
        journal_pool = self.pool.get('account.journal')
        account_period_obj = self.pool.get('account.period')

        if context is None:
            context = {}

        journal_id = self._get_journal(cr, uid, context)
        period_id = self._get_period(cr, uid, context)
        target_move = self.read(cr, uid, ids, [])[0]['target_move']

        name = _("Journal Items")
        if journal_id:
            ids = period_pool.search(cr, uid, [('journal_id', '=', journal_id), ('period_id', '=', period_id)], context=context)

            if not ids:
                journal = journal_pool.browse(cr, uid, journal_id, context=context)
                period = account_period_obj.browse(cr, uid, period_id, context=context)

                name = journal.name
                state = period.state

                if state == 'done':
                    raise osv.except_osv(_('UserError'), _('This period is already closed !'))

                company = period.company_id.id
                res = {
                    'name': name,
                    'period_id': period_id,
                    'journal_id': journal_id,
                    'company_id': company
                }
                period_pool.create(cr, uid, res,context=context)

            ids = period_pool.search(cr, uid, [('journal_id', '=', journal_id), ('period_id', '=', period_id)], context=context)
            period = period_pool.browse(cr, uid, ids[0], context=context)
            name = (period.journal_id.code or '') + ':' + (period.period_id.code or '')

        result = data_pool.get_object_reference(cr, uid, 'account', 'view_account_move_line_filter')
        res_id = result and result[1] or False
        move = 0
        if target_move == 'posted':
            move = 1
        return {
            'name': name,
            'view_type': 'form',
            'view_mode': 'tree,graph,form',
            'res_model': 'account.move.line',
            'view_id': False,
            'context': "{'search_default_posted': %d, 'visible_id':%s, 'search_default_journal_id':%d, 'search_default_period_id':%d}" % (move, journal_id, journal_id, period_id),
            'type': 'ir.actions.act_window',
            'search_view_id': res_id
        }

account_move_journal()

# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
<commit_msg>[FIX] account/translation: computed view has now all terms available via gettext.<commit_after># -*- coding: utf-8 -*-
##############################################################################
#
#    OpenERP, Open Source Management Solution
#    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as
#    published by the Free Software Foundation, either version 3 of the
#    License, or (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################

from lxml import etree

from osv import osv, fields
from tools.translate import _
import tools

class account_move_journal(osv.osv_memory):
    _name = "account.move.journal"
    _description = "Move journal"

    _columns = {
       'target_move': fields.selection([('posted', 'All Posted Entries'),
                                        ('all', 'All Entries'),
                                        ], 'Target Moves', required=True),
    }

    _defaults = {
        'target_move': 'posted'
    }
    def _get_period(self, cr, uid, context={}):
        """
        Return  default account period value
        """
        account_period_obj = self.pool.get('account.period')
        ids = account_period_obj.find(cr, uid, context=context)
        period_id = False
        if ids:
            period_id = ids[0]
        return period_id

    def _get_journal(self, cr, uid, context=None):
        """
        Return journal based on the journal type
        """

        journal_id = False

        journal_pool = self.pool.get('account.journal')
        if context.get('journal_type', False):
            jids = journal_pool.search(cr, uid, [('type','=', context.get('journal_type'))])
            if not jids:
                raise osv.except_osv(_('Configuration Error !'), _('Can\'t find any account journal of %s type for this company.\n\nYou can create one in the menu: \nConfiguration/Financial Accounting/Accounts/Journals.') % context.get('journal_type'))
            journal_id = jids[0]

        return journal_id

    def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
        """
        Returns views and fields for current model where view will depend on {view_type}.
        @param cr: A database cursor
        @param user: ID of the user currently logged in
        @param view_id: list of fields, which required to read signatures
        @param view_type: defines a view type. it can be one of (form, tree, graph, calender, gantt, search, mdx)
        @param context: context arguments, like lang, time zone
        @param toolbar: contains a list of reports, wizards, and links related to current model

        @return: Returns a dict that contains definition for fields, views, and toolbars
        """

        res = super(account_move_journal, self).fields_view_get(cr, uid, view_id, view_type, context, toolbar, submenu)

        if not view_id:
            return res

        period_pool = self.pool.get('account.period')
        journal_pool = self.pool.get('account.journal')

        journal_id = self._get_journal(cr, uid, context)
        period_id = self._get_period(cr, uid, context)

        journal = False
        if journal_id:
            journal = journal_pool.read(cr, uid, [journal_id], ['name'])[0]['name']
            journal_string = _("Journal: %s") % tools.ustr(journal)
        else:
            journal_string = _("Journal: All")

        period = False
        if period_id:
            period = period_pool.browse(cr, uid, [period_id], ['name'])[0]['name']
            period_string = _("Period: %s") % tools.ustr(period)

        separator_string = _("Open Journal Items !")
        cancel_string = _("Cancel")
        open_string = _("Open")
        view = """<?xml version="1.0" encoding="utf-8"?>
        <form string="Standard entries">
            <separator string="%s" colspan="4"/>
            <field name="target_move" />
            <newline/>
            <group colspan="4" >
                <label width="300" string="%s"/>
                <newline/>
                <label width="300" string="%s"/>
            </group>
            <group colspan="4" col="4">
                <label string ="" colspan="2"/>
                <button icon="gtk-cancel" special="cancel" string="%s"/>
                <button icon="terp-gtk-go-back-rtl" string="%s" name="action_open_window" default_focus="1" type="object"/>
            </group>
        </form>""" % (separator_string, journal_string, period_string, cancel_string, open_string)

        view = etree.fromstring(view.encode('utf8'))
        xarch, xfields = self._view_look_dom_arch(cr, uid, view, view_id, context=context)
        view = xarch
        res.update({
            'arch': view
        })
        return res

    def action_open_window(self, cr, uid, ids, context=None):
        """
        This function Open action move line window on given period and  Journal/Payment Mode
        @param cr: the current row, from the database cursor,
        @param uid: the current user’s ID for security checks,
        @param ids: account move journal’s ID or list of IDs
        @return: dictionary of Open action move line window on given period and  Journal/Payment Mode
        """

        period_pool = self.pool.get('account.journal.period')
        data_pool = self.pool.get('ir.model.data')
        journal_pool = self.pool.get('account.journal')
        account_period_obj = self.pool.get('account.period')

        if context is None:
            context = {}

        journal_id = self._get_journal(cr, uid, context)
        period_id = self._get_period(cr, uid, context)
        target_move = self.read(cr, uid, ids, [])[0]['target_move']

        name = _("Journal Items")
        if journal_id:
            ids = period_pool.search(cr, uid, [('journal_id', '=', journal_id), ('period_id', '=', period_id)], context=context)

            if not ids:
                journal = journal_pool.browse(cr, uid, journal_id, context=context)
                period = account_period_obj.browse(cr, uid, period_id, context=context)

                name = journal.name
                state = period.state

                if state == 'done':
                    raise osv.except_osv(_('UserError'), _('This period is already closed !'))

                company = period.company_id.id
                res = {
                    'name': name,
                    'period_id': period_id,
                    'journal_id': journal_id,
                    'company_id': company
                }
                period_pool.create(cr, uid, res,context=context)

            ids = period_pool.search(cr, uid, [('journal_id', '=', journal_id), ('period_id', '=', period_id)], context=context)
            period = period_pool.browse(cr, uid, ids[0], context=context)
            name = (period.journal_id.code or '') + ':' + (period.period_id.code or '')

        result = data_pool.get_object_reference(cr, uid, 'account', 'view_account_move_line_filter')
        res_id = result and result[1] or False
        move = 0
        if target_move == 'posted':
            move = 1
        return {
            'name': name,
            'view_type': 'form',
            'view_mode': 'tree,graph,form',
            'res_model': 'account.move.line',
            'view_id': False,
            'context': "{'search_default_posted': %d, 'visible_id':%s, 'search_default_journal_id':%d, 'search_default_period_id':%d}" % (move, journal_id, journal_id, period_id),
            'type': 'ir.actions.act_window',
            'search_view_id': res_id
        }

account_move_journal()

# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
<|endoftext|>


<commit_before>##############################################################################
#
# Copyright (c) 2005-2006 TINY SPRL. (http://tiny.be) All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
#
##############################################################################

import time
import wizard
import ir
import pooler
from osv.osv import except_osv

delivery_form = """<?xml version="1.0"?>
<form string="Create deliveries">
	<separator colspan="4" string="Delivery Method" />
	<field name="carrier_id" />
</form>
"""

delivery_fields = {
	'carrier_id' : {'string':'Delivery Method', 'type':'many2one', 'relation': 'delivery.carrier','required':True}
}

def _delivery_default(self, cr, uid, data, context):
	order_obj = pooler.get_pool(cr.dbname).get('sale.order')
	order = order_obj.browse(cr, uid, data['ids'])[0]
	if not order.state in ('draft'):
		raise wizard.except_wizard('Order not in draft state !', 'The order state have to be draft to add delivery lines.')

	carrier_id = order.partner_id.property_delivery_carrier.id
	return {'carrier_id': carrier_id}

def _delivery_set(self, cr, uid, data, context):
	order_obj = pooler.get_pool(cr.dbname).get('sale.order')
	line_obj = pooler.get_pool(cr.dbname).get('sale.order.line')
	order_objs = order_obj.browse(cr, uid, data['ids'], context)

	for order in order_objs:
		grid_id = pooler.get_pool(cr.dbname).get('delivery.carrier').grid_get(cr, uid, [data['form']['carrier_id']],order.partner_shipping_id.id)
		if not grid_id:
			raise except_osv('No grid avaible !', 'No grid matching for this carrier !')
		grid = pooler.get_pool(cr.dbname).get('delivery.grid').browse(cr, uid, [grid_id])[0]

		line_obj.create(cr, uid, {
			'order_id': order.id,
			'name': grid.carrier_id.name,
			'product_uom_qty': 1,
			'product_uom': grid.carrier_id.product_id.uom_id.id,
			'product_id': grid.carrier_id.product_id.id,
			'price_unit': grid.get_price(cr, uid, grid.id, order, time.strftime('%Y-%m-%d'), context),
			'tax_id': [(6,0,[ x.id for x in grid.carrier_id.product_id.taxes_id])],
			'type': 'make_to_stock'
			})

	return {}

class make_delivery(wizard.interface):
	states = {
		'init' : {
			'actions' : [_delivery_default],
			'result' : {'type' : 'form', 'arch' : delivery_form, 'fields' : delivery_fields, 'state' : [('end', 'Cancel'),('delivery', 'Create delivery line') ]}
		},
		'delivery' : {
			'actions' : [_delivery_set],
			'result' : {'type' : 'state', 'state' : 'end'}
		},
	}
make_delivery("delivery.sale.order")
<commit_msg>Fix error message when there is no delivery grid<commit_after>##############################################################################
#
# Copyright (c) 2005-2006 TINY SPRL. (http://tiny.be) All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
#
##############################################################################

import time
import wizard
import ir
import pooler

delivery_form = """<?xml version="1.0"?>
<form string="Create deliveries">
	<separator colspan="4" string="Delivery Method" />
	<field name="carrier_id" />
</form>
"""

delivery_fields = {
	'carrier_id' : {'string':'Delivery Method', 'type':'many2one', 'relation': 'delivery.carrier','required':True}
}

def _delivery_default(self, cr, uid, data, context):
	order_obj = pooler.get_pool(cr.dbname).get('sale.order')
	order = order_obj.browse(cr, uid, data['ids'])[0]
	if not order.state in ('draft'):
		raise wizard.except_wizard('Order not in draft state !', 'The order state have to be draft to add delivery lines.')

	carrier_id = order.partner_id.property_delivery_carrier.id
	return {'carrier_id': carrier_id}

def _delivery_set(self, cr, uid, data, context):
	order_obj = pooler.get_pool(cr.dbname).get('sale.order')
	line_obj = pooler.get_pool(cr.dbname).get('sale.order.line')
	order_objs = order_obj.browse(cr, uid, data['ids'], context)

	for order in order_objs:
		grid_id = pooler.get_pool(cr.dbname).get('delivery.carrier').grid_get(cr, uid, [data['form']['carrier_id']],order.partner_shipping_id.id)
		if not grid_id:
			raise wizard.except_wizard('No grid avaible !', 'No grid matching for this carrier !')
		grid = pooler.get_pool(cr.dbname).get('delivery.grid').browse(cr, uid, [grid_id])[0]

		line_obj.create(cr, uid, {
			'order_id': order.id,
			'name': grid.carrier_id.name,
			'product_uom_qty': 1,
			'product_uom': grid.carrier_id.product_id.uom_id.id,
			'product_id': grid.carrier_id.product_id.id,
			'price_unit': grid.get_price(cr, uid, grid.id, order, time.strftime('%Y-%m-%d'), context),
			'tax_id': [(6,0,[ x.id for x in grid.carrier_id.product_id.taxes_id])],
			'type': 'make_to_stock'
			})

	return {}

class make_delivery(wizard.interface):
	states = {
		'init' : {
			'actions' : [_delivery_default],
			'result' : {'type' : 'form', 'arch' : delivery_form, 'fields' : delivery_fields, 'state' : [('end', 'Cancel'),('delivery', 'Create delivery line') ]}
		},
		'delivery' : {
			'actions' : [_delivery_set],
			'result' : {'type' : 'state', 'state' : 'end'}
		},
	}
make_delivery("delivery.sale.order")
<|endoftext|>


<commit_before>from django.db import models

# Create your models here.
<commit_msg>Collection model added<commit_after>from django.db import models
from markupfield.fields import MarkupField
from taggit.managers import TaggableManager
import datetime

class Collection(models.Model):
    owner = models.ForeignKey('users.User', related_name='owner_relation')
    project = models.ForeignKey('project.Project', related_name='project_relation')
    name = models.CharField(max_length = 128)
    description = MarkupField(markup_type='markdown')

    # See this for background: http://stackoverflow.com/questions/1737017/django-auto-now-and-auto-now-add/1737078#1737078
    created     = models.DateTimeField(editable=False)
    modified    = models.DateTimeField()

    def save(self, *args, **kwargs):
        ''' On save, update timestamps '''
        if not self.id:
            self.created = datetime.datetime.today()
        self.modified = datetime.datetime.today()
        return super(Collection, self).save(*args, **kwargs)

    def __unicode__(self):
        return self.project.name + ":" + self.name<|endoftext|>


<commit_before>import datetime
import json
import re
from urlparse import urljoin

from behave import given, when, then
import pytz

from django.conf import settings

from inthe_am.taskmanager.models import TaskStore

def get_store():
    return TaskStore.objects.get(user__email=settings.TESTING_LOGIN_USER)

def get_json_value(value):
    if re.match(r'^\d{8}T\d{6}Z$', value):
        return datetime.datetime.strptime(
            value,
            '%Y%m%dT%H%M%SZ'
        ).replace(tzinfo=pytz.UTC)
    return json.loads(value)

@then(u'a task with the {field} "{value}" will exist')
def task_with_field_exists(context, field, value):
    store = get_store()
    matches = store.client.filter_tasks({
        field: value
    })
    assert len(matches) > 0, "No task found with %s == %s" % (
        field, value
    )

@then(u'a single {status} task with the following details will exist')
def task_with_details(context, status):
    store = get_store()
    tasks = store.client.filter_tasks({'status': status})
    assert len(tasks) == 1, "Asserted single task to be found, found %s" % (
        len(tasks)
    )
    task = tasks[0]
    for key, value in context.table.rows:
        assert task[key] == get_json_value(value), (
            "Task field %s's value is %s, not %s" % (
                key,
                task[key],
                value,
            )
        )

@then(u'a single {status} task will have its "{field}" field set')
def task_non_null_field(context, status, field):
    store = get_store()
    tasks = store.client.filter_tasks({'status': status})
    assert len(tasks) == 1, "Asserted single task to be found, found %s" % (
        len(tasks)
    )
    task = tasks[0]
    assert task.get(field)

@then(u'a single {status} task will not have its "{field}" field set')
def task_null_field(context, status, field):
    store = get_store()
    tasks = store.client.filter_tasks({'status': status})
    assert len(tasks) == 1, "Asserted single task to be found, found %s" % (
        len(tasks)
    )
    task = tasks[0]
    assert not task.get(field)

@given(u'a task with the {field} "{value}" exists')
def task_existing_with_value(context, field, value):
    store = get_store()
    basic_task = {
        'description': 'Gather at Terminus for Hari Seldon\'s Address',
        'project': 'terminus_empire',
        'tags': ['next_steps', 'mule'],
    }
    if field == 'tags':
        value = value.split(',')
    basic_task[field] = value
    task = store.client.task_add(**basic_task)
    context.created_task_id = task['uuid']

@then(u'a task named "{value}" is visible in the task list')
def task_with_description_visible(context, value):
    context.execute_steps(u'''
        then the element at CSS selector "{selector}" has text "{value}"
    '''.format(
        selector='div.task-list-item p.description',
        value=value
    ))

@then(u'a task named "{value}" is the opened task')
def task_with_description_visible_main(context, value):
    context.execute_steps(u'''
        then the element at CSS selector "{selector}" has text "{value}"
    '''.format(
        selector='h1.title',
        value=value
    ))

@when(u'the user creates a new task with the description "{value}"')
def task_with_new_description(context, value):
    context.execute_steps(u'''
        When the user clicks the link "New"
        And the user waits for 1 seconds
        And the user enters the text "{val}" into the field named "description"
        And the user clicks the button labeled "Save"
        And the user waits for 1 seconds
    '''.format(
        val=value
    ))

@given(u'the user is viewing an existing task with the {field} "{value}"')
def logged_in_and_viewing_task(context, field, value):
    context.execute_steps(u'''
        Given the user is logged-in
        And a task with the {field} "{value}" exists
        And the user goes to the task's URL
    '''.format(
        field=field,
        value=value,
    ))

@when(u'the user goes to the task\'s URL')
def user_goes_to_tasks_url(context):
    url = urljoin(
        context.config.server_url, '/tasks/%s' % context.created_task_id
    )
    context.browser.visit(url)

@given(u'a task with the following details exists')
def existing_task_with_details(context):
    task = {
        'description': 'Untitled'
    }
    for key, value in context.table.rows:
        task[key] = get_json_value(value)

    store = get_store()
    description = task.pop('description')
    task = store.client.task_add(description, **task)
    context.created_task_id = task['uuid']

@then(u"the following values are visible in the task's details")
def following_values_visible_details(context):
    visible_data = {}
    for row in context.browser.find_by_xpath("//table[@class='details']//tr"):
        key = row.find_by_tag('th')[0].text
        value = row.find_by_tag('td')[0].text
        visible_data[key] = value

    for key, value in context.table.rows:
        actual_value = visible_data.get(key, None)
        assert actual_value == value, "%s != %s" % (
            actual_value,
            value,
        )
<commit_msg>Convert testing step type from 'when' to 'step'.<commit_after>import datetime
import json
import re
from urlparse import urljoin

from behave import given, when, then, step
import pytz

from django.conf import settings

from inthe_am.taskmanager.models import TaskStore

def get_store():
    return TaskStore.objects.get(user__email=settings.TESTING_LOGIN_USER)

def get_json_value(value):
    if re.match(r'^\d{8}T\d{6}Z$', value):
        return datetime.datetime.strptime(
            value,
            '%Y%m%dT%H%M%SZ'
        ).replace(tzinfo=pytz.UTC)
    return json.loads(value)

@then(u'a task with the {field} "{value}" will exist')
def task_with_field_exists(context, field, value):
    store = get_store()
    matches = store.client.filter_tasks({
        field: value
    })
    assert len(matches) > 0, "No task found with %s == %s" % (
        field, value
    )

@then(u'a single {status} task with the following details will exist')
def task_with_details(context, status):
    store = get_store()
    tasks = store.client.filter_tasks({'status': status})
    assert len(tasks) == 1, "Asserted single task to be found, found %s" % (
        len(tasks)
    )
    task = tasks[0]
    for key, value in context.table.rows:
        assert task[key] == get_json_value(value), (
            "Task field %s's value is %s, not %s" % (
                key,
                task[key],
                value,
            )
        )

@then(u'a single {status} task will have its "{field}" field set')
def task_non_null_field(context, status, field):
    store = get_store()
    tasks = store.client.filter_tasks({'status': status})
    assert len(tasks) == 1, "Asserted single task to be found, found %s" % (
        len(tasks)
    )
    task = tasks[0]
    assert task.get(field)

@then(u'a single {status} task will not have its "{field}" field set')
def task_null_field(context, status, field):
    store = get_store()
    tasks = store.client.filter_tasks({'status': status})
    assert len(tasks) == 1, "Asserted single task to be found, found %s" % (
        len(tasks)
    )
    task = tasks[0]
    assert not task.get(field)

@given(u'a task with the {field} "{value}" exists')
def task_existing_with_value(context, field, value):
    store = get_store()
    basic_task = {
        'description': 'Gather at Terminus for Hari Seldon\'s Address',
        'project': 'terminus_empire',
        'tags': ['next_steps', 'mule'],
    }
    if field == 'tags':
        value = value.split(',')
    basic_task[field] = value
    task = store.client.task_add(**basic_task)
    context.created_task_id = task['uuid']

@then(u'a task named "{value}" is visible in the task list')
def task_with_description_visible(context, value):
    context.execute_steps(u'''
        then the element at CSS selector "{selector}" has text "{value}"
    '''.format(
        selector='div.task-list-item p.description',
        value=value
    ))

@then(u'a task named "{value}" is the opened task')
def task_with_description_visible_main(context, value):
    context.execute_steps(u'''
        then the element at CSS selector "{selector}" has text "{value}"
    '''.format(
        selector='h1.title',
        value=value
    ))

@when(u'the user creates a new task with the description "{value}"')
def task_with_new_description(context, value):
    context.execute_steps(u'''
        When the user clicks the link "New"
        And the user waits for 1 seconds
        And the user enters the text "{val}" into the field named "description"
        And the user clicks the button labeled "Save"
        And the user waits for 1 seconds
    '''.format(
        val=value
    ))

@given(u'the user is viewing an existing task with the {field} "{value}"')
def logged_in_and_viewing_task(context, field, value):
    context.execute_steps(u'''
        Given the user is logged-in
        And a task with the {field} "{value}" exists
        And the user goes to the task's URL
    '''.format(
        field=field,
        value=value,
    ))

@step(u'the user goes to the task\'s URL')
def user_goes_to_tasks_url(context):
    url = urljoin(
        context.config.server_url, '/tasks/%s' % context.created_task_id
    )
    context.browser.visit(url)

@given(u'a task with the following details exists')
def existing_task_with_details(context):
    task = {
        'description': 'Untitled'
    }
    for key, value in context.table.rows:
        task[key] = get_json_value(value)

    store = get_store()
    description = task.pop('description')
    task = store.client.task_add(description, **task)
    context.created_task_id = task['uuid']

@then(u"the following values are visible in the task's details")
def following_values_visible_details(context):
    visible_data = {}
    for row in context.browser.find_by_xpath("//table[@class='details']//tr"):
        key = row.find_by_tag('th')[0].text
        value = row.find_by_tag('td')[0].text
        visible_data[key] = value

    for key, value in context.table.rows:
        actual_value = visible_data.get(key, None)
        assert actual_value == value, "%s != %s" % (
            actual_value,
            value,
        )
<|endoftext|>


<commit_before>import discord
from discord.ext import commands
import transliterate

class Translit:
    def __init__(self, bot):
        self.bot = bot
        self.avail = transliterate.get_available_language_codes()

    @commands.command(pass_context=True)
    async def translit(self, ctx, target: str, *text: str):
        if target not in self.avail:
            await self.bot.reply("Unknown target language charset code. "
                                 "Supported: {}".format(", ".join(self.avail)))
        else:
            text = " ".join(text)
            await self.bot.reply(transliterate.translit(text, target))

    @commands.command(pass_context=True)
    async def untranslit(self, ctx, target: str, *text: str):
        if target not in self.avail:
            await self.bot.reply("Unknown target language charset code. "
                                 "Supported: {}".format(", ".join(self.avail)))
        else:
            text = " ".join(text)
            await self.bot.reply(transliterate.translit(text, target, reversed=True))

def setup(bot):
    bot.add_cog(Translit(bot))
<commit_msg>rename target to source in untranslit cmd<commit_after>import discord
from discord.ext import commands
import transliterate

class Translit:
    def __init__(self, bot):
        self.bot = bot
        self.avail = transliterate.get_available_language_codes()

    @commands.command(pass_context=True)
    async def translit(self, ctx, target: str, *text: str):
        if target not in self.avail:
            await self.bot.reply("Unknown target language charset code. "
                                 "Supported: {}".format(", ".join(self.avail)))
        else:
            text = " ".join(text)
            await self.bot.reply(transliterate.translit(text, target))

    @commands.command(pass_context=True)
    async def untranslit(self, ctx, source: str, *text: str):
        if source not in self.avail:
            await self.bot.reply("Unknown source language charset code. "
                                 "Supported: {}".format(", ".join(self.avail)))
        else:
            text = " ".join(text)
            await self.bot.reply(transliterate.translit(text, source, reversed=True))

def setup(bot):
    bot.add_cog(Translit(bot))
<|endoftext|>


<commit_before># Kenozooid - software stack to support different capabilities of dive
# computers.
#
# Copyright (C) 2009 by Artur Wroblewski <wrobell@pld-linux.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
# Modifications by PAB to override reference text

import os.path
from docutils import nodes
import sys
import re

__Reference_re = re.compile('\s*(.*)\s+<(.*)>\s*$', re.MULTILINE + re.DOTALL)

def api_role(role, rawtext, text, lineno, inliner, options={}, content=[]):
    """
    Role `:api:` bridges generated API documentation by tool like EpyDoc
    with Sphinx Python Documentation Generator.

    Other tools, other than EpyDoc, can be easily supported as well.

    First generate the documentation to be referenced, i.e. with EpyDoc::

        $ mkdir -p doc/html/api
        $ epydoc -o doc/html/api ...

    Next step is to generate documentation with Sphinx::

        $ sphinx-build doc doc/html

    """
    basedir = 'api'
    prefix = 'html/' # fixme: fetch it from configuration
    exists = lambda f: os.path.exists(prefix + f)

    # assume module is references

    #print 'Text "%s"' % (text,)
    mo = __Reference_re.match(text)
    label = None
    if mo is not None:
        ( label, text ) = mo.group(1, 2)
    name = text.strip()

    uri = file = '%s/%s-module.html' % (basedir, text)
    chunks = text.split('.')

    #print 'Trying module file %s' % (file,)

    # if not module, then a class
    if not exists(file):
        name = text.split('.')[-1]
        uri = file = '%s/%s-class.html' % (basedir, text)
    #print 'Trying class file %s' % (file,)

    # if not a class, then function or class method
    if not exists(file):
        method = chunks[-1]
        fprefix = '.'.join(chunks[:-1])
        # assume function is referenced
        file = '%s/%s-module.html' % (basedir, fprefix)
        #print 'Trying method file %s' % (file,)
        if exists(file):
            uri = '%s#%s' % (file, method)
        else:
            # class method is references
            file = '%s/%s-class.html' % (basedir, fprefix)
            if exists(file):
                name = '.'.join(chunks[-2:]) # name should be Class.method
                uri = '%s/%s-class.html#%s' % (basedir, fprefix, method)

    if label is None:
        label = name
    if exists(file):
        node = nodes.reference(rawtext, label, refuri=uri, **options)
    else:
        # cannot find reference, then just inline the text
        print 'WARNING: Unable to find %s in API' % (text,)
        node = nodes.literal(rawtext, text)

    return [node], []

def ticket_role(role, rawtext, text, lineno, inliner, options={}, content=[]):
    """
    Role `:ticket:` generates references to Trac tickets.
    """
    trac_root = 'https://sourceforge.net/apps/trac/pyxb'

    # assume module is references

    #print 'Text "%s"' % (text,)
    mo = __Reference_re.match(text)
    label = None
    if mo is not None:
        ( label, text ) = mo.group(1, 2)
    ticket = text.strip()

    uri = '%s/ticket/%s' % (trac_root, ticket)
    if label is None:
        label = '#%s' % (ticket,)
    node = nodes.reference(rawtext, label, refuri=uri, **options)

    return [node], []

def setup(app):
    app.add_role('api', api_role)
    app.add_config_value('epydoc_basedir', 'api', False)
    app.add_config_value('epydoc_prefix', 'doc/html/', False)
    app.add_role('ticket', ticket_role)
    app.add_config_value('epydoc_track_root', 'http://sourceforge.net/apps/track/project', False)

<commit_msg>New role for references to Python exceptions.  Created under misapprehension (wanted this for the API documentation, not Sphinx)<commit_after># Kenozooid - software stack to support different capabilities of dive
# computers.
#
# Copyright (C) 2009 by Artur Wroblewski <wrobell@pld-linux.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
# Modifications by PAB to override reference text

import os.path
from docutils import nodes
import sys
import re

__Reference_re = re.compile('\s*(.*)\s+<(.*)>\s*$', re.MULTILINE + re.DOTALL)

def api_role(role, rawtext, text, lineno, inliner, options={}, content=[]):
    """
    Role `:api:` bridges generated API documentation by tool like EpyDoc
    with Sphinx Python Documentation Generator.

    Other tools, other than EpyDoc, can be easily supported as well.

    First generate the documentation to be referenced, i.e. with EpyDoc::

        $ mkdir -p doc/html/api
        $ epydoc -o doc/html/api ...

    Next step is to generate documentation with Sphinx::

        $ sphinx-build doc doc/html

    """
    basedir = 'api'
    prefix = 'html/' # fixme: fetch it from configuration
    exists = lambda f: os.path.exists(prefix + f)

    # assume module is references

    #print 'Text "%s"' % (text,)
    mo = __Reference_re.match(text)
    label = None
    if mo is not None:
        ( label, text ) = mo.group(1, 2)
    name = text.strip()

    uri = file = '%s/%s-module.html' % (basedir, text)
    chunks = text.split('.')

    #print 'Trying module file %s' % (file,)

    # if not module, then a class
    if not exists(file):
        name = text.split('.')[-1]
        uri = file = '%s/%s-class.html' % (basedir, text)
    #print 'Trying class file %s' % (file,)

    # if not a class, then function or class method
    if not exists(file):
        method = chunks[-1]
        fprefix = '.'.join(chunks[:-1])
        # assume function is referenced
        file = '%s/%s-module.html' % (basedir, fprefix)
        #print 'Trying method file %s' % (file,)
        if exists(file):
            uri = '%s#%s' % (file, method)
        else:
            # class method is references
            file = '%s/%s-class.html' % (basedir, fprefix)
            if exists(file):
                name = '.'.join(chunks[-2:]) # name should be Class.method
                uri = '%s/%s-class.html#%s' % (basedir, fprefix, method)

    if label is None:
        label = name
    if exists(file):
        node = nodes.reference(rawtext, label, refuri=uri, **options)
    else:
        # cannot find reference, then just inline the text
        print 'WARNING: Unable to find %s in API' % (text,)
        node = nodes.literal(rawtext, text)

    return [node], []

def ticket_role(role, rawtext, text, lineno, inliner, options={}, content=[]):
    """
    Role `:ticket:` generates references to Trac tickets.
    """
    trac_root = 'https://sourceforge.net/apps/trac/pyxb'

    # assume module is references

    #print 'Text "%s"' % (text,)
    mo = __Reference_re.match(text)
    label = None
    if mo is not None:
        ( label, text ) = mo.group(1, 2)
    ticket = text.strip()

    uri = '%s/ticket/%s' % (trac_root, ticket)
    if label is None:
        label = '#%s' % (ticket,)
    node = nodes.reference(rawtext, label, refuri=uri, **options)

    return [node], []

def pyex_role(role, rawtext, text, lineno, inliner, options={}, content=[]):
    """
    Role `:pyex:` generates reference to Python exception classes.
    """

    pyex_fmt = 'http://docs.python.org/library/exceptions.html#exceptions.%s'
    mo = __Reference_re.match(text)
    label = None
    if mo is not None:
        ( label, text ) = mo.group(1, 2)
    exc = text.strip()
    print 'Python exception %s as %s' % (text, label)

    uri = pyex_fmt % (exc,)
    if label is None:
        label = '%s' % (exc,)
    node = nodes.reference(rawtext, label, refuri=uri, **options)

    return [node], []

def setup(app):
    app.add_role('api', api_role)
    app.add_config_value('epydoc_basedir', 'api', False)
    app.add_config_value('epydoc_prefix', 'doc/html/', False)
    app.add_role('ticket', ticket_role)
    app.add_config_value('epydoc_track_root', 'http://sourceforge.net/apps/track/project', False)
    app.add_role('pyex', pyex_role)

<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations

class Migration(migrations.Migration):

    def create_virtual_groups(apps, schema_editor):
        Org = apps.get_model('orgs', 'Org')
        ContactGroup = apps.get_model('contacts', 'ContactGroup')
        Contact = apps.get_model('contacts', 'Contact')

        # creates and populates all our system groups
        for org in Org.objects.all():
            print "Populating groups for: %s" % org.name

            all_contacts = ContactGroup.objects.create(name="All Contacts",
                                                       group_type='A',
                                                       created_by=org.created_by,
                                                       modified_by=org.modified_by,
                                                       org=org)
            all_contacts.contacts.add(*Contact.objects.filter(org=org, is_active=True, is_test=False,
                                                              is_blocked=False))

            blocked_contacts = ContactGroup.objects.create(name="Blocked Contacts",
                                                           group_type='B',
                                                           created_by=org.created_by,
                                                           modified_by=org.modified_by,
                                                           org=org)
            blocked_contacts.contacts.add(*Contact.objects.filter(org=org, is_active=True, is_test=False,
                                                                  is_blocked=True))

            failed_contacts = ContactGroup.objects.create(name="Failed Contacts",
                                                          group_type='F',
                                                          created_by=org.created_by,
                                                          modified_by=org.modified_by,
                                                          org=org)
            failed_contacts.contacts.add(*Contact.objects.filter(org=org, is_active=True, is_test=False,
                                                                 is_blocked=False, is_failed=True))
    dependencies = [
        ('orgs', '0003_auto_20150313_1624'),
        ('contacts', '0013_contactgroup_group_type')
    ]

    operations = [
        migrations.RunPython(
            create_virtual_groups,
        ),
    ]
<commit_msg>Remove printout<commit_after># -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations

class Migration(migrations.Migration):

    def create_virtual_groups(apps, schema_editor):
        Org = apps.get_model('orgs', 'Org')
        ContactGroup = apps.get_model('contacts', 'ContactGroup')
        Contact = apps.get_model('contacts', 'Contact')

        # creates and populates all our system groups
        for org in Org.objects.all():
            #print "Populating groups for: %s" % org.name

            all_contacts = ContactGroup.objects.create(name="All Contacts",
                                                       group_type='A',
                                                       created_by=org.created_by,
                                                       modified_by=org.modified_by,
                                                       org=org)
            all_contacts.contacts.add(*Contact.objects.filter(org=org, is_active=True, is_test=False,
                                                              is_blocked=False))

            blocked_contacts = ContactGroup.objects.create(name="Blocked Contacts",
                                                           group_type='B',
                                                           created_by=org.created_by,
                                                           modified_by=org.modified_by,
                                                           org=org)
            blocked_contacts.contacts.add(*Contact.objects.filter(org=org, is_active=True, is_test=False,
                                                                  is_blocked=True))

            failed_contacts = ContactGroup.objects.create(name="Failed Contacts",
                                                          group_type='F',
                                                          created_by=org.created_by,
                                                          modified_by=org.modified_by,
                                                          org=org)
            failed_contacts.contacts.add(*Contact.objects.filter(org=org, is_active=True, is_test=False,
                                                                 is_blocked=False, is_failed=True))
    dependencies = [
        ('orgs', '0003_auto_20150313_1624'),
        ('contacts', '0013_contactgroup_group_type')
    ]

    operations = [
        migrations.RunPython(
            create_virtual_groups,
        ),
    ]
<|endoftext|>