<commit_before>
from clastic.errors import Forbidden
from boltons.strutils import slugify

from rdb import CoordinatorDAO
from server import get_admin_round

# TODO: flex
# TODO: support "required"

# TODO: clastic add a bind-time middleware callback (application
# creation fails unless middleware signs off on success)

def get_admin_campaign(rdb_session, user, campaign_id):
    """
    Some non-API related facts.

    # API spec

    Summary: Get admin-level details for a campaign, identified by campaign ID.

    Request model:
        campaign_id:
            type: int64

    Response model name: CampaignDetails
    Response model:
        id:
            type: int64
        name:
            type: string
        rounds:
            type: array
            items:
                type: RoundDetails
        coordinators:
            type: array
            items:
                type: CoordDetails
        url_name:
            type:string

    Errors:
       403: User does not have permission to access requested campaign
       404: Campaign not found

    # End API spec

    More facts
    """
    coord_dao = CoordinatorDAO(rdb_session=rdb_session, user=user)
    campaign = coord_dao.get_campaign(campaign_id)
    if campaign is None:
        raise Forbidden('not a coordinator on this campaign')
    info = {'id': campaign.id,
            'name': campaign.name,
            'rounds': [],
            'coords': [u.username for u in campaign.coords]}
    for rnd in campaign.rounds:
        info['rounds'].append(get_admin_round(rdb_session, user, rnd.id))

    info['canonical_url_name'] = slugify(info['name'], '-')

    return info

models = """
"""

######

import re
import json
import yaml
import collections
from pprint import pprint

from clastic import GET
from boltons.strutils import under2camel
from boltons.iterutils import remap

_api_spec_start_re = re.compile('# API Spec', re.I)
_api_spec_end_re = re.compile('# End API Spec', re.I)

def attach_api_schema(func):
    parts = _api_spec_start_re.split(func.__doc__, maxsplit=1)
    if len(parts) == 1:
        # no match found, continuing
        return None
    elif len(parts) > 2:
        raise ValueError('expected only one API Spec section')

    spec_to_end = parts[1]

    spec_text = _api_spec_end_re.split(spec_to_end)[0]

    spec_dict = yaml.load(spec_text)

    def format_spec_key(path, key, value):
        return str(key).lower().replace(' ', '_'), value

    # should remap have a maxdepth? technically len(p) gives you the depth
    spec_dict = remap(spec_dict, format_spec_key)

    # pprint(spec_dict)

    func.spec_dict = spec_dict

    return spec_dict

def _pprint_od(od):
    ded = remap(od, lambda p, k, v: (k, dict(v) if isinstance(v, dict) else v))
    pprint(ded)

class APISpecMiddleware(object):
    pass

class APISpecBroker(object):
    def __init__(self):
        self.api_version = '0.1'
        self.title = ''
        self.description = ''
        self.contact = ''  # TODO name/etc.?

        self.host = ''
        self.base_path = '/'
        self.schemes = ['http']
        self.consumes = ['application/json']
        self.produces = ['application/json']

        self.def_map = collections.OrderedDict()
        self.path_map = collections.OrderedDict()

        """
        example_path = {'get': {'description': '',
                                'operationId': 'get_rounds',
                                'produces': ['application/json'],
                                'parameters': [{'name': '<request_message_name>',
                                                'in': 'body',
                                                'description': '...',
                                                'required': True,
                                                'schema': {'$ref': '#/definitions/RoundRequestInfo'}}]}}
        """

    def register_route(self, route, autoskip=True):
        warnings = []
        if autoskip and not route.methods:
            warnings.append('skipping %r, no methods specified' % route)
            return
        endpoint_func = route.endpoint
        spec_dict = attach_api_schema(endpoint_func)
        if not spec_dict:
            return []  # TODO

        path = route.pattern  # TODO: curly-brace formatted
        op_id = route.endpoint.func_name

        _pprint_od(dict(spec_dict))

        param_list = []  # TODO: url path params

        req_def_name = spec_dict.get('request_model_name')
        if req_def_name:
            self.def_map[req_def_name] = None

        req_def = spec_dict.get('request_model')
        if req_def:
            cc_op_id = under2camel(op_id)
            default_req_def_name = '%sRequestModel' % (cc_op_id,)
            req_def_name = req_def_name or default_req_def_name
            req_param = {'name': op_id + '_request_message',
                         'in': 'body',
                         'description': 'JSON-encoded request message for %s' % (op_id,),
                         'required': True,
                         'schema': {'$ref': '#/definitions/' + req_def_name}}
            param_list.append(req_param)

            self.def_map[req_def_name] = req_def

        path_dict = {'description': spec_dict.get('summary', ''),
                     'operationId': op_id,
                     'produces': spec_dict.get('produces', self.produces),
                     'parameters': param_list}

        self.path_map[path] = path_dict

        # TODO: response schema

        return []

    def register_app_routes(self, app, autoskip=True):
        warnings = []
        for rt in app.routes:
            ws = self.register_route(rt, autoskip=autoskip)
            warnings.extend(ws)
        return warnings

    def resolve(self):
        pass

    def get_openapi_spec_dict(self):
        ret = collections.OrderedDict()

        unresolved_models = []
        for name, defn in self.def_map.items():
            if defn is None:
                unresolved_models.append(defn)
        if unresolved_models:
            raise ValueError('no definitions found for models: %r'
                             % unresolved_models)

        ret['swagger'] = '2.0'
        ret['host'] = self.host
        ret['basePath'] = self.base_path
        ret['schemes'] = self.schemes
        ret['consumes'] = self.consumes
        ret['produces'] = self.produces
        ret['info'] = {'version': self.api_version,
                       'title': self.title,
                       'description': self.description,
                       'contact': self.contact}
        ret['paths'] = self.path_map
        ret['definitions'] = self.def_map

        return ret

    def get_openapi_spec_yaml(self):
        return dump_yaml(self.get_openapi_spec_dict())

    def get_openapi_spec_json(self):
        return json.dumps(self.get_openapi_spec_dict(), indent=2)

# set up yaml pretty printing

_mapping_tag = yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG

def dict_representer(dumper, data):
    return dumper.represent_dict(data.iteritems())

def dict_constructor(loader, node):
    return collections.OrderedDict(loader.construct_pairs(node))

yaml.add_representer(collections.OrderedDict, dict_representer)
yaml.add_constructor(_mapping_tag, dict_constructor)

# disable reference/alias emission

class ExplicitDumper(yaml.Dumper):
    """
    A dumper that will never emit aliases.
    """
    def ignore_aliases(self, data):
        return True

def dump_yaml(*a, **kw):
    kw['Dumper'] = ExplicitDumper

    # always dump in characteristic yaml block style
    kw['default_flow_style'] = False
    return yaml.dump(*a, **kw)

# end yaml customization

if __name__ == '__main__':
    # attach_api_schema(get_admin_campaign)

    route = GET('/admin/campaign', get_admin_campaign)

    sb = APISpecBroker()

    sb.register_route(route)
    sb.resolve()

    print sb.get_openapi_spec_yaml()
    sb.get_openapi_spec_json()
<commit_msg>backend: quick flex add. this may be temporary, as i notice flex doesn't raise errors on missing models that are referenced in type fields. also, nearly forgot the response model loading.<commit_after>
import flex
from clastic.errors import Forbidden
from boltons.strutils import slugify

from rdb import CoordinatorDAO
from server import get_admin_round

# TODO: flex
# TODO: support "required"

# TODO: clastic add a bind-time middleware callback (application
# creation fails unless middleware signs off on success)

def get_admin_campaign(rdb_session, user, campaign_id):
    """
    Some non-API related facts.

    # API spec

    Summary: Get admin-level details for a campaign, identified by campaign ID.

    Request model:
        campaign_id:
            type: int64

    Response model name: CampaignDetails
    Response model:
        id:
            type: int64
        name:
            type: string
        rounds:
            type: array
            items:
                type: RoundDetails
        coordinators:
            type: array
            items:
                type: CoordDetails
        url_name:
            type: string

    Errors:
       403: User does not have permission to access requested campaign
       404: Campaign not found

    # End API spec

    More facts
    """
    coord_dao = CoordinatorDAO(rdb_session=rdb_session, user=user)
    campaign = coord_dao.get_campaign(campaign_id)
    if campaign is None:
        raise Forbidden('not a coordinator on this campaign')
    info = {'id': campaign.id,
            'name': campaign.name,
            'rounds': [],
            'coords': [u.username for u in campaign.coords]}
    for rnd in campaign.rounds:
        info['rounds'].append(get_admin_round(rdb_session, user, rnd.id))

    info['canonical_url_name'] = slugify(info['name'], '-')

    return info

models = """
"""

######

import re
import json
import yaml
import collections
from pprint import pprint

from clastic import GET
from boltons.strutils import under2camel
from boltons.iterutils import remap

_api_spec_start_re = re.compile('# API Spec', re.I)
_api_spec_end_re = re.compile('# End API Spec', re.I)

def extract_api_spec(func):
    parts = _api_spec_start_re.split(func.__doc__, maxsplit=1)
    if len(parts) == 1:
        # no match found, continuing
        return None
    elif len(parts) > 2:
        raise ValueError('expected only one API Spec section')

    spec_to_end = parts[1]

    spec_text = _api_spec_end_re.split(spec_to_end)[0]

    spec_dict = yaml.load(spec_text)

    def format_spec_key(path, key, value):
        return str(key).lower().replace(' ', '_'), value

    # should remap have a maxdepth? technically len(p) gives you the depth
    spec_dict = remap(spec_dict, format_spec_key)

    return spec_dict

def _pprint_od(od):
    ded = remap(od, lambda p, k, v: (k, dict(v) if isinstance(v, dict) else v))
    pprint(ded)

class APISpecMiddleware(object):
    pass

class APISpecBroker(object):
    def __init__(self, title='', description='', contact_name='',
                 extra_defs=None):
        self.api_version = '0.1'
        self.title = title
        self.description = description
        self.contact = {'name': contact_name}

        self.host = 'localhost'
        self.base_path = '/'
        self.schemes = ['http']
        self.consumes = ['application/json']
        self.produces = ['application/json']

        self.path_map = collections.OrderedDict()

        self.def_map = collections.OrderedDict()
        if extra_defs:
            if isinstance(extra_defs, basestring):
                extra_defs = yaml.load(extra_defs)
                self.def_map.update(extra_defs)

        # TODO: base defs for error model etc.
        return

    def register_route(self, route, autoskip=True):
        warnings = []  # TODO: better warning system
        if autoskip and not route.methods:
            warnings.append('skipping %r, no methods specified' % route)
            return
        endpoint_func = route.endpoint
        spec_dict = extract_api_spec(endpoint_func)
        if not spec_dict:
            return []  # TODO

        path = route.pattern  # TODO: curly-brace formatted
        op_id = route.endpoint.func_name
        cc_op_id = under2camel(op_id)

        _pprint_od(dict(spec_dict))

        param_list = []  # TODO: url path params

        req_def_name = spec_dict.get('request_model_name')
        if req_def_name:
            self.def_map[req_def_name] = None

        req_def = spec_dict.get('request_model')
        if req_def:
            default_req_def_name = '%sRequestModel' % (cc_op_id,)
            req_def_name = req_def_name or default_req_def_name
            req_param = {'name': op_id + '_request_message',
                         'in': 'body',
                         'description': 'JSON request message for %s' % op_id,
                         'required': True,
                         'schema': {'$ref': '#/definitions/' + req_def_name}}
            param_list.append(req_param)

            self.def_map[req_def_name] = req_def

        resp_def_name = spec_dict.get('response_model_name')
        if resp_def_name:
            self.def_map[resp_def_name] = None

        resp_def = spec_dict.get('response_model')

        if resp_def:
            default_resp_def_name = '%sResponseModel' % (cc_op_id,)
            resp_def_name = resp_def_name or default_resp_def_name
            resp_param = {'name': op_id + '_response_message',
                          'in': 'body',
                          'description': 'JSON response message for %s' % op_id,
                          'required': True,
                          'schema': {'$ref': '#/definitions/' + req_def_name}}
            param_list.append(resp_param)

            self.def_map[resp_def_name] = resp_def

        path_dict = {'description': spec_dict.get('summary', ''),
                     'operationId': op_id,
                     'produces': spec_dict.get('produces', self.produces),
                     'parameters': param_list}
        # TODO: errors

        self.path_map[path] = path_dict

        return []

    def register_app_routes(self, app, autoskip=True):
        warnings = []
        for rt in app.routes:
            ws = self.register_route(rt, autoskip=autoskip)
            warnings.extend(ws)
        return warnings

    def resolve(self):
        unresolved_models = []
        for name, defn in self.def_map.items():
            if defn is None:
                unresolved_models.append(defn)
        if unresolved_models:
            raise ValueError('no definitions found for models: %r'
                             % unresolved_models)
        return

    def get_openapi_spec_dict(self):
        ret = collections.OrderedDict()

        self.resolve()

        ret['swagger'] = '2.0'
        ret['host'] = self.host
        ret['basePath'] = self.base_path
        ret['schemes'] = self.schemes
        ret['consumes'] = self.consumes
        ret['produces'] = self.produces
        ret['info'] = {'version': self.api_version,
                       'title': self.title,
                       'description': self.description,
                       'contact': self.contact}
        ret['paths'] = self.path_map
        ret['definitions'] = self.def_map

        return ret

    def get_openapi_spec_yaml(self):
        return dump_yaml(self.get_openapi_spec_dict())

    def get_openapi_spec_json(self):
        return json.dumps(self.get_openapi_spec_dict(), indent=2)

# set up yaml pretty printing

_mapping_tag = yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG

def dict_representer(dumper, data):
    return dumper.represent_dict(data.iteritems())

def dict_constructor(loader, node):
    return collections.OrderedDict(loader.construct_pairs(node))

yaml.add_representer(collections.OrderedDict, dict_representer)
yaml.add_constructor(_mapping_tag, dict_constructor)

# disable reference/alias emission

class ExplicitDumper(yaml.Dumper):
    """
    A dumper that will never emit aliases.
    """
    def ignore_aliases(self, data):
        return True

def dump_yaml(*a, **kw):
    kw['Dumper'] = ExplicitDumper

    # always dump in characteristic yaml block style
    kw['default_flow_style'] = False
    return yaml.dump(*a, **kw)

# end yaml customization

if __name__ == '__main__':
    # attach_api_schema(get_admin_campaign)

    route = GET('/admin/campaign', get_admin_campaign)

    sb = APISpecBroker()

    sb.register_route(route)
    sb.resolve()

    print sb.get_openapi_spec_yaml()
    sb.get_openapi_spec_json()

    tmp = flex.load(sb.get_openapi_spec_yaml())

    import pdb;pdb.set_trace()
<|endoftext|>


<commit_before>#!/usr/bin/python
# -*- coding: utf-8  -*-
"""
An incomplete sample script.

This is not a complete bot; rather, it is a template from which simple
bots can be made. You can rename it to mybot.py, then edit it in
whatever way you want.

Use global -simulate option for test purposes. No changes to live wiki
will be done.

The following parameters are supported:

&params;

-always           If used, the bot won't ask if it should file the message
                  onto user talk page.

-text:            Use this text to be added; otherwise 'Test' is used

-replace:         Dont add text but replace it

-top              Place additional text on top of the page

-summary:         Set the action summary message for the edit.
"""
#
# (C) Pywikibot team, 2006-2016
#
# Distributed under the terms of the MIT license.
#
from __future__ import absolute_import, unicode_literals

__version__ = '$Id$'
#

import pywikibot
from pywikibot import pagegenerators

from pywikibot.bot import (
    SingleSiteBot, ExistingPageBot, NoRedirectPageBot, AutomaticTWSummaryBot)
from pywikibot.tools import issue_deprecation_warning

# This is required for the text that is shown when you run this script
# with the parameter -help.
docuReplacements = {
    '&params;': pagegenerators.parameterHelp
}

class BasicBot(
    # Refer pywikobot.bot for generic bot classes
    SingleSiteBot,  # A bot only working on one site
    # CurrentPageBot,  # Sets 'current_page'. Process it in treat_page method.
    #                  # Not needed here because we have subclasses
    ExistingPageBot,  # CurrentPageBot which only treats existing pages
    NoRedirectPageBot,  # CurrentPageBot which only treats non-redirects
    AutomaticTWSummaryBot,  # Automatically defines summary; needs summary_key
):

    """
    An incomplete sample bot.

    @ivar summary_key: Edit summary message key. The message that should be used
        is placed on /i18n subdirectory. The file containing these messages
        should have the same name as the caller script (i.e. basic.py in this
        case). Use summary_key to set a default edit summary message.
    @type summary_key: str
    """

    summary_key = 'basic-changing'

    def __init__(self, generator, **kwargs):
        """
        Constructor.

        @param generator: the page generator that determines on which pages
            to work
        @type generator: generator
        """
        # Add your own options to the bot and set their defaults
        # -always option is predefined by BaseBot class
        self.availableOptions.update({
            'replace': False,  # delete old text and write the new text
            'summary': None,  # your own bot summary
            'text': 'Test',  # add this text from option. 'Test' is default
            'top': False,  # append text on top of the page
        })

        # call constructor of the super class
        super(BasicBot, self).__init__(site=True, **kwargs)

        # handle old -dry paramter
        self._handle_dry_param(**kwargs)

        # assign the generator to the bot
        self.generator = generator

    def _handle_dry_param(self, **kwargs):
        """
        Read the dry parameter and set the simulate variable instead.

        This is a private method. It prints a deprecation warning for old
        -dry paramter and sets the global simulate variable and informs
        the user about this setting.

        The constuctor of the super class ignores it because it is not
        part of self.availableOptions.

        @note: You should ommit this method in your own application.

        @keyword dry: deprecated option to prevent changes on live wiki.
            Use -simulate instead.
        @type dry: bool
        """
        if 'dry' in kwargs:
            issue_deprecation_warning('dry argument',
                                      'pywikibot.config.simulate', 1)
            # use simulate variable instead
            pywikibot.config.simulate = True
            pywikibot.output('config.simulate was set to True')

    def treat_page(self):
        """Load the given page, do some changes, and save it."""
        text = self.current_page.text

        ################################################################
        # NOTE: Here you can modify the text in whatever way you want. #
        ################################################################

        # If you find out that you do not want to edit this page, just return.
        # Example: This puts Text on a page.

        # Retrieve your private option
        # Use your own text or use the default 'Test'
        text_to_add = self.getOption('text')

        if self.getOption('replace'):
            # replace the page text
            text = text_to_add

        elif self.getOption('top'):
            # put text on top
            text = text_to_add + text

        else:
            # put text on bottom
            text += text_to_add

        # if summary option is None, it takes the default i18n summary from
        # i18n subdirectory with summary_key as summary key.
        self.put_current(text, summary=self.getOption('summary'))

def main(*args):
    """
    Process command line arguments and invoke bot.

    If args is an empty list, sys.argv is used.

    @param args: command line arguments
    @type args: list of unicode
    """
    options = {}
    # Process global arguments to determine desired site
    local_args = pywikibot.handle_args(args)

    # This factory is responsible for processing command line arguments
    # that are also used by other scripts and that determine on which pages
    # to work on.
    genFactory = pagegenerators.GeneratorFactory()

    # Parse command line arguments
    for arg in local_args:

        # Catch the pagegenerators options
        if genFactory.handleArg(arg):
            continue  # nothing to do here

        # Now pick up your own options
        arg, sep, value = arg.partition(':')
        option = arg[1:]
        if option in ('summary', 'text'):
            if not value:
                pywikibot.input('Please enter a value for ' + arg)
            options[option] = value
        # take the remaining options as booleans.
        # You will get a hint if they aren't pre-definded in your bot class
        else:
            options[option] = True

    gen = genFactory.getCombinedGenerator()
    if gen:
        # The preloading generator is responsible for downloading multiple
        # pages from the wiki simultaneously.
        gen = pagegenerators.PreloadingGenerator(gen)
        # pass generator and private options to the bot
        bot = BasicBot(gen, **options)
        bot.run()  # guess what it does
        return True
    else:
        pywikibot.bot.suggest_help(missing_generator=True)
        return False

if __name__ == "__main__":
    main()
<commit_msg>cosmetic changes<commit_after>#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
An incomplete sample script.

This is not a complete bot; rather, it is a template from which simple
bots can be made. You can rename it to mybot.py, then edit it in
whatever way you want.

Use global -simulate option for test purposes. No changes to live wiki
will be done.

The following parameters are supported:

&params;

-always           If used, the bot won't ask if it should file the message
                  onto user talk page.

-text:            Use this text to be added; otherwise 'Test' is used

-replace:         Dont add text but replace it

-top              Place additional text on top of the page

-summary:         Set the action summary message for the edit.
"""
#
# (C) Pywikibot team, 2006-2016
#
# Distributed under the terms of the MIT license.
#
from __future__ import absolute_import, unicode_literals

__version__ = '$Id$'
#

import pywikibot
from pywikibot import pagegenerators

from pywikibot.bot import (
    SingleSiteBot, ExistingPageBot, NoRedirectPageBot, AutomaticTWSummaryBot)
from pywikibot.tools import issue_deprecation_warning

# This is required for the text that is shown when you run this script
# with the parameter -help.
docuReplacements = {
    '&params;': pagegenerators.parameterHelp
}

class BasicBot(
    # Refer pywikobot.bot for generic bot classes
    SingleSiteBot,  # A bot only working on one site
    # CurrentPageBot,  # Sets 'current_page'. Process it in treat_page method.
    #                  # Not needed here because we have subclasses
    ExistingPageBot,  # CurrentPageBot which only treats existing pages
    NoRedirectPageBot,  # CurrentPageBot which only treats non-redirects
    AutomaticTWSummaryBot,  # Automatically defines summary; needs summary_key
):

    """
    An incomplete sample bot.

    @ivar summary_key: Edit summary message key. The message that should be used
        is placed on /i18n subdirectory. The file containing these messages
        should have the same name as the caller script (i.e. basic.py in this
        case). Use summary_key to set a default edit summary message.
    @type summary_key: str
    """

    summary_key = 'basic-changing'

    def __init__(self, generator, **kwargs):
        """
        Constructor.

        @param generator: the page generator that determines on which pages
            to work
        @type generator: generator
        """
        # Add your own options to the bot and set their defaults
        # -always option is predefined by BaseBot class
        self.availableOptions.update({
            'replace': False,  # delete old text and write the new text
            'summary': None,  # your own bot summary
            'text': 'Test',  # add this text from option. 'Test' is default
            'top': False,  # append text on top of the page
        })

        # call constructor of the super class
        super(BasicBot, self).__init__(site=True, **kwargs)

        # handle old -dry paramter
        self._handle_dry_param(**kwargs)

        # assign the generator to the bot
        self.generator = generator

    def _handle_dry_param(self, **kwargs):
        """
        Read the dry parameter and set the simulate variable instead.

        This is a private method. It prints a deprecation warning for old
        -dry paramter and sets the global simulate variable and informs
        the user about this setting.

        The constuctor of the super class ignores it because it is not
        part of self.availableOptions.

        @note: You should ommit this method in your own application.

        @keyword dry: deprecated option to prevent changes on live wiki.
            Use -simulate instead.
        @type dry: bool
        """
        if 'dry' in kwargs:
            issue_deprecation_warning('dry argument',
                                      'pywikibot.config.simulate', 1)
            # use simulate variable instead
            pywikibot.config.simulate = True
            pywikibot.output('config.simulate was set to True')

    def treat_page(self):
        """Load the given page, do some changes, and save it."""
        text = self.current_page.text

        ################################################################
        # NOTE: Here you can modify the text in whatever way you want. #
        ################################################################

        # If you find out that you do not want to edit this page, just return.
        # Example: This puts Text on a page.

        # Retrieve your private option
        # Use your own text or use the default 'Test'
        text_to_add = self.getOption('text')

        if self.getOption('replace'):
            # replace the page text
            text = text_to_add

        elif self.getOption('top'):
            # put text on top
            text = text_to_add + text

        else:
            # put text on bottom
            text += text_to_add

        # if summary option is None, it takes the default i18n summary from
        # i18n subdirectory with summary_key as summary key.
        self.put_current(text, summary=self.getOption('summary'))

def main(*args):
    """
    Process command line arguments and invoke bot.

    If args is an empty list, sys.argv is used.

    @param args: command line arguments
    @type args: list of unicode
    """
    options = {}
    # Process global arguments to determine desired site
    local_args = pywikibot.handle_args(args)

    # This factory is responsible for processing command line arguments
    # that are also used by other scripts and that determine on which pages
    # to work on.
    genFactory = pagegenerators.GeneratorFactory()

    # Parse command line arguments
    for arg in local_args:

        # Catch the pagegenerators options
        if genFactory.handleArg(arg):
            continue  # nothing to do here

        # Now pick up your own options
        arg, sep, value = arg.partition(':')
        option = arg[1:]
        if option in ('summary', 'text'):
            if not value:
                pywikibot.input('Please enter a value for ' + arg)
            options[option] = value
        # take the remaining options as booleans.
        # You will get a hint if they aren't pre-definded in your bot class
        else:
            options[option] = True

    gen = genFactory.getCombinedGenerator()
    if gen:
        # The preloading generator is responsible for downloading multiple
        # pages from the wiki simultaneously.
        gen = pagegenerators.PreloadingGenerator(gen)
        # pass generator and private options to the bot
        bot = BasicBot(gen, **options)
        bot.run()  # guess what it does
        return True
    else:
        pywikibot.bot.suggest_help(missing_generator=True)
        return False

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


<commit_before>import functools
import random
import os.path
import time

from zstacklib.utils import shell
from zstacklib.utils import log
from zstacklib.utils import linux

logger = log.get_logger(__name__)
LV_RESERVED_SIZE = 1024*1024*4
LVM_CONFIG_PATH = "/etc/lvm"
LVM_CONFIG_BACKUP_PATH = "/etc/lvm/zstack-backup"

class LvmlockdLockType(object):
    NULL = 0
    SHARE = 1
    EXCLUSIVE = 2

    @staticmethod
    def from_abbr(abbr):
        if abbr == "sh":
            return LvmlockdLockType.SHARE
        elif abbr == "ex":
            return LvmlockdLockType.EXCLUSIVE
        elif abbr == "un":
            return LvmlockdLockType.NULL
        else:
            raise Exception("unknown lock type %s" % abbr)

    @staticmethod
    def from_str(string):
        if string == "NULL":
            return LvmlockdLockType.SHARE
        elif string == "SHARE":
            return LvmlockdLockType.EXCLUSIVE
        elif string == "EXCLUSIVE":
            return LvmlockdLockType.NULL
        else:
            raise Exception("unknown lock type %s" % string)

class RetryException(Exception):
    pass

def check_lvm_config_is_default():
    cmd = shell.ShellCmd("lvmconfig --type diff")
    cmd(is_exception=True)
    if cmd.stdout != "":
        return False
    else:
        return True

def backup_lvm_config():
    if not os.path.exists(LVM_CONFIG_PATH):
        logger.warn("can not find lvm config path: %s, backup failed" % LVM_CONFIG_PATH)
        return

    if not os.path.exists(LVM_CONFIG_BACKUP_PATH):
        os.makedirs(LVM_CONFIG_BACKUP_PATH)

    current_time = time.time()
    cmd = shell.ShellCmd("cp %s/lvm.conf %s/lvm-%s.conf; "
                         "cp %s/lvmlocal.conf %s/lvmlocal-%s.conf" %
                         (LVM_CONFIG_PATH, LVM_CONFIG_BACKUP_PATH, current_time,
                          LVM_CONFIG_PATH, LVM_CONFIG_BACKUP_PATH, current_time))
    cmd(is_exception=False)
    logger.debug("backup lvm config file success")

def reset_lvm_conf_default():
    if not os.path.exists(LVM_CONFIG_PATH):
        raise Exception("can not find lvm config path: %s, reset lvm config failed" % LVM_CONFIG_PATH)

    cmd = shell.ShellCmd("lvmconfig --type default > %s/lvm.conf; "
                         "lvmconfig --type default > %s/lvmlocal.conf" %
                         (LVM_CONFIG_PATH, LVM_CONFIG_PATH))
    cmd(is_exception=False)

def config_lvm_by_sed(keyword, entry, files):
    if not os.path.exists(LVM_CONFIG_PATH):
        raise Exception("can not find lvm config path: %s, config lvm failed" % LVM_CONFIG_PATH)

    for file in files:
        cmd = shell.ShellCmd("sed -i 's/.*%s.*/%s/g' %s/%s" %
                             (keyword, entry, LVM_CONFIG_PATH, file))
        cmd(is_exception=False)

def config_lvm_conf(node, value):
    cmd = shell.ShellCmd("lvmconfig --mergedconfig --config %s=%s -f /etc/lvm/lvm.conf" % (node, value))
    cmd(is_exception=True)

def config_lvmlocal_conf(node, value):
    cmd = shell.ShellCmd("lvmconfig --mergedconfig --config %s=%s -f /etc/lvm/lvmlocal.conf" % (node, value))
    cmd(is_exception=True)

def start_lvmlockd():
    for service in ["lvm2-lvmlockd", "wdmd", "sanlock"]:
        cmd = shell.ShellCmd("systemctl start %s" % service)
        cmd(is_exception=True)

def start_vg_lock(vgUuid):
    @linux.retry(times=20, sleep_time=random.uniform(1,10))
    def vg_lock_is_adding(vgUuid):
        # NOTE(weiw): this means vg locking is adding rather than complete
        cmd = shell.ShellCmd("sanlock client status | grep -E 's lvm_%s.*\\:0 ADD'" % vgUuid)
        cmd(is_exception=False)
        if cmd.return_code == 0:
            raise RetryException("vg %s lock space is starting" % vgUuid)
        return False

    @linux.retry(times=3, sleep_time=random.uniform(0.1, 1))
    def vg_lock_exists(vgUuid):
        cmd = shell.ShellCmd("lvmlockctl -i | grep %s" % vgUuid)
        cmd(is_exception=False)
        if cmd.return_code != 0:
            raise RetryException("can not find lock space for vg %s via lvmlockctl" % vgUuid)
        elif vg_lock_is_adding(vgUuid) is False:
            return True
        else:
            return False

    @linux.retry(times=15, sleep_time=random.uniform(0.1, 30))
    def start_lock(vgUuid):
        cmd = shell.ShellCmd("vgchange --lock-start %s" % vgUuid)
        cmd(is_exception=True)
        if cmd.return_code != 0:
            raise Exception("vgchange --lock-start failed")

        vg_lock_exists(vgUuid)

    try:
        vg_lock_exists(vgUuid)
    except RetryException:
        start_lock(vgUuid)
    except Exception as e:
        raise e

def get_vg_size(vgUuid):
    cmd = shell.ShellCmd("vgs --nolocking --readonly %s --noheadings --separator : --units b -o vg_size,vg_free" % vgUuid)
    cmd(is_exception=True)
    return cmd.stdout.strip().split(':')[0].strip("B"), cmd.stdout.strip().split(':')[1].strip("B")

def add_vg_tag(vgUuid, tag):
    cmd = shell.ShellCmd("vgchange --addtag %s %s" % (tag, vgUuid))
    cmd(is_exception=True)

def has_lv_tag(path, tag):
    o = shell.call("lvs -Stags={%s} %s --nolocking --noheadings --readonly 2>/dev/null | wc -l" % (tag, path))
    return o.strip() == '1'

def get_meta_lv_path(path):
    return path+"_meta"

def delete_image(path, tag):
    def activate_and_remove(f):
        lvm.active_lv(f, shared=False)
        backing = linux.qcow2_get_backing_file(f)
        shell.check_run("lvremove -y -Stags={%s} %s" % (tag, f))
        return f

    fpath = path
    while fpath:
        backing = activate_and_remove(fpath)
        activate_and_remove(get_meta_lv_path(fpath))
        fpath = backing

def clean_vg_exists_host_tags(vgUuid, hostUuid, tag):
    cmd = shell.ShellCmd("vgs %s -otags --nolocking --noheading | grep -Po '%s::%s::[\d.]*'" % (vgUuid, tag, hostUuid))
    cmd(is_exception=False)
    exists_tags = cmd.stdout.strip().split("\n")
    if len(exists_tags) == 0:
        return
    t = " --deltag " + " --deltag ".join(exists_tags)
    cmd = shell.ShellCmd("vgchange %s %s" % (t, vgUuid))
    cmd(is_exception=False)

def create_lv_from_absolute_path(path, size, tag="zs::sharedblock::volume"):
    vgName = path.split("/")[2]
    lvName = path.split("/")[3]

    cmd = shell.ShellCmd("lvcreate -an --addtag %s --size %sb --name %s %s" %
                         (tag, int(size) + LV_RESERVED_SIZE, lvName, vgName))
    cmd(is_exception=True)

def resize_lv(path, size):
    cmd = shell.ShellCmd("lvresize --size %sb %s" % (int(size) + LV_RESERVED_SIZE, path))
    cmd(is_exception=True)

def active_lv(path, shared=False):
    flag = "-ay"
    if shared:
        flag = "-asy"

    cmd = shell.ShellCmd("lvchange %s %s" % (flag, path))
    cmd(is_exception=True)

def deactive_lv(path, raise_exception=True):
    cmd = shell.ShellCmd("lvchange -an %s" % path)
    cmd(is_exception=raise_exception)

def delete_lv(path, raise_exception=True):
    cmd = shell.ShellCmd("lvremove -y %s" % path)
    cmd(is_exception=raise_exception)
    return cmd.return_code

def lv_exists(path):
    cmd = shell.ShellCmd("lvs --nolocking --readonly %s" % path)
    cmd(is_exception=False)
    return cmd.return_code == 0

def lv_uuid(path):
    cmd = shell.ShellCmd("lvs --nolocking --readonly --noheadings %s -ouuid" % path)
    cmd(is_exception=False)
    return cmd.stdout.strip()

def lv_active(path):
    cmd = shell.ShellCmd("lvs --nolocking --readonly --noheadings %s -oactive | grep active" % path)
    cmd(is_exception=False)
    return cmd.return_code == 0

def get_lv_locking_type(path):
    if not lv_active(path):
        return LvmlockdLockType.NULL
    cmd = shell.ShellCmd("lvmlockctl -i | grep %s | awk '{print $3}'" % lv_uuid(path))
    cmd(is_exception=True)
    return LvmlockdLockType.from_abbr(cmd.stdout.strip())

def lv_operate(abs_path, shared=False):
    def wrap(f):
        @functools.wraps(f)
        def inner(*args, **kwargs):
            with OperateLv(abs_path, shared):
                retval = f(*args, **kwargs)
            return retval
        return inner
    return wrap

def qcow2_lv_recursive_operate(abs_path, shared=False):
    def wrap(f):
        @functools.wraps(f)
        def inner(*args, **kwargs):
            with RecursiveOperateLv(abs_path, shared):
                retval = f(*args, **kwargs)
            return retval
        return inner
    return wrap

class OperateLv(object):
    def __init__(self, abs_path, shared=False):
        self.abs_path = abs_path
        self.shared = shared
        self.exists_lock = get_lv_locking_type(abs_path)
        self.target_lock = LvmlockdLockType.EXCLUSIVE if shared == False else LvmlockdLockType.SHARE

    def __enter__(self):
        if self.exists_lock < self.target_lock:
            active_lv(self.abs_path, self.shared)

    def __exit__(self, exc_type, exc_val, exc_tb):
        if self.exists_lock == LvmlockdLockType.NULL:
            deactive_lv(self.abs_path, raise_exception=False)
        else:
            active_lv(self.abs_path, self.exists_lock == LvmlockdLockType.SHARE)

class RecursiveOperateLv(object):
    def __init__(self, abs_path, shared=False):
        self.abs_path = abs_path
        self.shared = shared
        self.exists_lock = get_lv_locking_type(abs_path)
        self.target_lock = LvmlockdLockType.EXCLUSIVE if shared == False else LvmlockdLockType.SHARE
        self.backing = None

    def __enter__(self):
        if self.exists_lock < self.target_lock:
            active_lv(self.abs_path, self.shared)
        if linux.qcow2_get_backing_file(self.abs_path) != "":
            self.backing = RecursiveOperateLv(linux.qcow2_get_backing_file(self.abs_path), True)

        if self.backing is not None:
            self.backing.__enter__()

    def __exit__(self, exc_type, exc_val, exc_tb):
        if self.backing is not None:
            self.backing.__exit__(exc_type, exc_val, exc_tb)
        if self.exists_lock == LvmlockdLockType.NULL:
            deactive_lv(self.abs_path, raise_exception=False)
        else:
            active_lv(self.abs_path, self.exists_lock == LvmlockdLockType.SHARE)
<commit_msg>Remove inproper calling func with module name<commit_after>import functools
import random
import os.path
import time

from zstacklib.utils import shell
from zstacklib.utils import log
from zstacklib.utils import linux

logger = log.get_logger(__name__)
LV_RESERVED_SIZE = 1024*1024*4
LVM_CONFIG_PATH = "/etc/lvm"
LVM_CONFIG_BACKUP_PATH = "/etc/lvm/zstack-backup"

class LvmlockdLockType(object):
    NULL = 0
    SHARE = 1
    EXCLUSIVE = 2

    @staticmethod
    def from_abbr(abbr):
        if abbr == "sh":
            return LvmlockdLockType.SHARE
        elif abbr == "ex":
            return LvmlockdLockType.EXCLUSIVE
        elif abbr == "un":
            return LvmlockdLockType.NULL
        else:
            raise Exception("unknown lock type %s" % abbr)

    @staticmethod
    def from_str(string):
        if string == "NULL":
            return LvmlockdLockType.SHARE
        elif string == "SHARE":
            return LvmlockdLockType.EXCLUSIVE
        elif string == "EXCLUSIVE":
            return LvmlockdLockType.NULL
        else:
            raise Exception("unknown lock type %s" % string)

class RetryException(Exception):
    pass

def check_lvm_config_is_default():
    cmd = shell.ShellCmd("lvmconfig --type diff")
    cmd(is_exception=True)
    if cmd.stdout != "":
        return False
    else:
        return True

def backup_lvm_config():
    if not os.path.exists(LVM_CONFIG_PATH):
        logger.warn("can not find lvm config path: %s, backup failed" % LVM_CONFIG_PATH)
        return

    if not os.path.exists(LVM_CONFIG_BACKUP_PATH):
        os.makedirs(LVM_CONFIG_BACKUP_PATH)

    current_time = time.time()
    cmd = shell.ShellCmd("cp %s/lvm.conf %s/lvm-%s.conf; "
                         "cp %s/lvmlocal.conf %s/lvmlocal-%s.conf" %
                         (LVM_CONFIG_PATH, LVM_CONFIG_BACKUP_PATH, current_time,
                          LVM_CONFIG_PATH, LVM_CONFIG_BACKUP_PATH, current_time))
    cmd(is_exception=False)
    logger.debug("backup lvm config file success")

def reset_lvm_conf_default():
    if not os.path.exists(LVM_CONFIG_PATH):
        raise Exception("can not find lvm config path: %s, reset lvm config failed" % LVM_CONFIG_PATH)

    cmd = shell.ShellCmd("lvmconfig --type default > %s/lvm.conf; "
                         "lvmconfig --type default > %s/lvmlocal.conf" %
                         (LVM_CONFIG_PATH, LVM_CONFIG_PATH))
    cmd(is_exception=False)

def config_lvm_by_sed(keyword, entry, files):
    if not os.path.exists(LVM_CONFIG_PATH):
        raise Exception("can not find lvm config path: %s, config lvm failed" % LVM_CONFIG_PATH)

    for file in files:
        cmd = shell.ShellCmd("sed -i 's/.*%s.*/%s/g' %s/%s" %
                             (keyword, entry, LVM_CONFIG_PATH, file))
        cmd(is_exception=False)

def config_lvm_conf(node, value):
    cmd = shell.ShellCmd("lvmconfig --mergedconfig --config %s=%s -f /etc/lvm/lvm.conf" % (node, value))
    cmd(is_exception=True)

def config_lvmlocal_conf(node, value):
    cmd = shell.ShellCmd("lvmconfig --mergedconfig --config %s=%s -f /etc/lvm/lvmlocal.conf" % (node, value))
    cmd(is_exception=True)

def start_lvmlockd():
    for service in ["lvm2-lvmlockd", "wdmd", "sanlock"]:
        cmd = shell.ShellCmd("systemctl start %s" % service)
        cmd(is_exception=True)

def start_vg_lock(vgUuid):
    @linux.retry(times=20, sleep_time=random.uniform(1,10))
    def vg_lock_is_adding(vgUuid):
        # NOTE(weiw): this means vg locking is adding rather than complete
        cmd = shell.ShellCmd("sanlock client status | grep -E 's lvm_%s.*\\:0 ADD'" % vgUuid)
        cmd(is_exception=False)
        if cmd.return_code == 0:
            raise RetryException("vg %s lock space is starting" % vgUuid)
        return False

    @linux.retry(times=3, sleep_time=random.uniform(0.1, 1))
    def vg_lock_exists(vgUuid):
        cmd = shell.ShellCmd("lvmlockctl -i | grep %s" % vgUuid)
        cmd(is_exception=False)
        if cmd.return_code != 0:
            raise RetryException("can not find lock space for vg %s via lvmlockctl" % vgUuid)
        elif vg_lock_is_adding(vgUuid) is False:
            return True
        else:
            return False

    @linux.retry(times=15, sleep_time=random.uniform(0.1, 30))
    def start_lock(vgUuid):
        cmd = shell.ShellCmd("vgchange --lock-start %s" % vgUuid)
        cmd(is_exception=True)
        if cmd.return_code != 0:
            raise Exception("vgchange --lock-start failed")

        vg_lock_exists(vgUuid)

    try:
        vg_lock_exists(vgUuid)
    except RetryException:
        start_lock(vgUuid)
    except Exception as e:
        raise e

def get_vg_size(vgUuid):
    cmd = shell.ShellCmd("vgs --nolocking --readonly %s --noheadings --separator : --units b -o vg_size,vg_free" % vgUuid)
    cmd(is_exception=True)
    return cmd.stdout.strip().split(':')[0].strip("B"), cmd.stdout.strip().split(':')[1].strip("B")

def add_vg_tag(vgUuid, tag):
    cmd = shell.ShellCmd("vgchange --addtag %s %s" % (tag, vgUuid))
    cmd(is_exception=True)

def has_lv_tag(path, tag):
    o = shell.call("lvs -Stags={%s} %s --nolocking --noheadings --readonly 2>/dev/null | wc -l" % (tag, path))
    return o.strip() == '1'

def get_meta_lv_path(path):
    return path+"_meta"

def delete_image(path, tag):
    def activate_and_remove(f):
        active_lv(f, shared=False)
        backing = linux.qcow2_get_backing_file(f)
        shell.check_run("lvremove -y -Stags={%s} %s" % (tag, f))
        return f

    fpath = path
    while fpath:
        backing = activate_and_remove(fpath)
        activate_and_remove(get_meta_lv_path(fpath))
        fpath = backing

def clean_vg_exists_host_tags(vgUuid, hostUuid, tag):
    cmd = shell.ShellCmd("vgs %s -otags --nolocking --noheading | grep -Po '%s::%s::[\d.]*'" % (vgUuid, tag, hostUuid))
    cmd(is_exception=False)
    exists_tags = cmd.stdout.strip().split("\n")
    if len(exists_tags) == 0:
        return
    t = " --deltag " + " --deltag ".join(exists_tags)
    cmd = shell.ShellCmd("vgchange %s %s" % (t, vgUuid))
    cmd(is_exception=False)

def create_lv_from_absolute_path(path, size, tag="zs::sharedblock::volume"):
    vgName = path.split("/")[2]
    lvName = path.split("/")[3]

    cmd = shell.ShellCmd("lvcreate -an --addtag %s --size %sb --name %s %s" %
                         (tag, int(size) + LV_RESERVED_SIZE, lvName, vgName))
    cmd(is_exception=True)

def resize_lv(path, size):
    cmd = shell.ShellCmd("lvresize --size %sb %s" % (int(size) + LV_RESERVED_SIZE, path))
    cmd(is_exception=True)

def active_lv(path, shared=False):
    flag = "-ay"
    if shared:
        flag = "-asy"

    cmd = shell.ShellCmd("lvchange %s %s" % (flag, path))
    cmd(is_exception=True)

def deactive_lv(path, raise_exception=True):
    cmd = shell.ShellCmd("lvchange -an %s" % path)
    cmd(is_exception=raise_exception)

def delete_lv(path, raise_exception=True):
    cmd = shell.ShellCmd("lvremove -y %s" % path)
    cmd(is_exception=raise_exception)
    return cmd.return_code

def lv_exists(path):
    cmd = shell.ShellCmd("lvs --nolocking --readonly %s" % path)
    cmd(is_exception=False)
    return cmd.return_code == 0

def lv_uuid(path):
    cmd = shell.ShellCmd("lvs --nolocking --readonly --noheadings %s -ouuid" % path)
    cmd(is_exception=False)
    return cmd.stdout.strip()

def lv_active(path):
    cmd = shell.ShellCmd("lvs --nolocking --readonly --noheadings %s -oactive | grep active" % path)
    cmd(is_exception=False)
    return cmd.return_code == 0

def get_lv_locking_type(path):
    if not lv_active(path):
        return LvmlockdLockType.NULL
    cmd = shell.ShellCmd("lvmlockctl -i | grep %s | awk '{print $3}'" % lv_uuid(path))
    cmd(is_exception=True)
    return LvmlockdLockType.from_abbr(cmd.stdout.strip())

def lv_operate(abs_path, shared=False):
    def wrap(f):
        @functools.wraps(f)
        def inner(*args, **kwargs):
            with OperateLv(abs_path, shared):
                retval = f(*args, **kwargs)
            return retval
        return inner
    return wrap

def qcow2_lv_recursive_operate(abs_path, shared=False):
    def wrap(f):
        @functools.wraps(f)
        def inner(*args, **kwargs):
            with RecursiveOperateLv(abs_path, shared):
                retval = f(*args, **kwargs)
            return retval
        return inner
    return wrap

class OperateLv(object):
    def __init__(self, abs_path, shared=False):
        self.abs_path = abs_path
        self.shared = shared
        self.exists_lock = get_lv_locking_type(abs_path)
        self.target_lock = LvmlockdLockType.EXCLUSIVE if shared == False else LvmlockdLockType.SHARE

    def __enter__(self):
        if self.exists_lock < self.target_lock:
            active_lv(self.abs_path, self.shared)

    def __exit__(self, exc_type, exc_val, exc_tb):
        if self.exists_lock == LvmlockdLockType.NULL:
            deactive_lv(self.abs_path, raise_exception=False)
        else:
            active_lv(self.abs_path, self.exists_lock == LvmlockdLockType.SHARE)

class RecursiveOperateLv(object):
    def __init__(self, abs_path, shared=False):
        self.abs_path = abs_path
        self.shared = shared
        self.exists_lock = get_lv_locking_type(abs_path)
        self.target_lock = LvmlockdLockType.EXCLUSIVE if shared == False else LvmlockdLockType.SHARE
        self.backing = None

    def __enter__(self):
        if self.exists_lock < self.target_lock:
            active_lv(self.abs_path, self.shared)
        if linux.qcow2_get_backing_file(self.abs_path) != "":
            self.backing = RecursiveOperateLv(linux.qcow2_get_backing_file(self.abs_path), True)

        if self.backing is not None:
            self.backing.__enter__()

    def __exit__(self, exc_type, exc_val, exc_tb):
        if self.backing is not None:
            self.backing.__exit__(exc_type, exc_val, exc_tb)
        if self.exists_lock == LvmlockdLockType.NULL:
            deactive_lv(self.abs_path, raise_exception=False)
        else:
            active_lv(self.abs_path, self.exists_lock == LvmlockdLockType.SHARE)
<|endoftext|>


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

###############################################################################
# Copyright 2018 The Apollo Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
###############################################################################

import urllib
import os

URL_LIST = [
    "https://github.com/ApolloAuto/apollo/releases/download/v1.5.0/demo_1.5.bag",
    "https://github.com/ApolloAuto/apollo/releases/download/v2.0.0/demo_2.0.bag",
    "https://github.com/ApolloAuto/apollo/releases/download/v2.0.0/apollo_2.0_camera_sample.bag",
    "https://github.com/ApolloAuto/apollo/releases/download/v2.5.0/demo_2.5.bag",
    "https://github.com/ApolloAuto/apollo/releases/download/v1.0.0/demo_1.0.bag",
]

URL_DICT = {}
for link in URL_LIST:
    name = link.split("/")[-1]
    URL_DICT[name] = link

def retrieve_rosbag(bagname):
    if bagname not in URL_DICT:
        print(
            "bag[%s] is unknown, use one of the following rosbag names:\n%s" %
            (bagname, ", ".join([name for name in URL_DICT.keys()])))
        return False
    url = URL_DICT[bagname]
    print("Downloading from %s" % url)
    ret = os.system('wget %s -O %s' % (url, bagname))
    return ret == 0

if __name__ == "__main__":
    import argparse
    parser = argparse.ArgumentParser(
        description='retrieve demo rosbag file from remote')
    parser.add_argument(
        'name',
        type=str,
        help='rosbag names. You can choose one of [%s]' % ", ".join(
            [name for name in URL_DICT.keys()]))
    args = parser.parse_args()
    if retrieve_rosbag(args.name):
        print("Download %s success" % args.name)
    else:
        print("Download %s failed" % args.name)
<commit_msg>tools: fix rosbag_helper script executer<commit_after>#!/usr/bin/env python

###############################################################################
# Copyright 2018 The Apollo Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
###############################################################################

import urllib
import os

URL_LIST = [
    "https://github.com/ApolloAuto/apollo/releases/download/v1.5.0/demo_1.5.bag",
    "https://github.com/ApolloAuto/apollo/releases/download/v2.0.0/demo_2.0.bag",
    "https://github.com/ApolloAuto/apollo/releases/download/v2.0.0/apollo_2.0_camera_sample.bag",
    "https://github.com/ApolloAuto/apollo/releases/download/v2.5.0/demo_2.5.bag",
    "https://github.com/ApolloAuto/apollo/releases/download/v1.0.0/demo_1.0.bag",
]

URL_DICT = {}
for link in URL_LIST:
    name = link.split("/")[-1]
    URL_DICT[name] = link

def retrieve_rosbag(bagname):
    if bagname not in URL_DICT:
        print(
            "bag[%s] is unknown, use one of the following rosbag names:\n%s" %
            (bagname, ", ".join([name for name in URL_DICT.keys()])))
        return False
    url = URL_DICT[bagname]
    print("Downloading from %s" % url)
    ret = os.system('wget %s -O %s' % (url, bagname))
    return ret == 0

if __name__ == "__main__":
    import argparse
    parser = argparse.ArgumentParser(
        description='retrieve demo rosbag file from remote')
    parser.add_argument(
        'name',
        type=str,
        help='rosbag names. You can choose one of [%s]' % ", ".join(
            [name for name in URL_DICT.keys()]))
    args = parser.parse_args()
    if retrieve_rosbag(args.name):
        print("Download %s success" % args.name)
    else:
        print("Download %s failed" % args.name)
<|endoftext|>


<commit_before>"""
Tasks requiring asynchronous handling for course_duration_limits
"""

import datetime
import logging

import waffle
from celery import task
from celery_utils.logged_task import LoggedTask
from django.conf import settings
from django.contrib.auth.models import User
from django.contrib.sites.models import Site
from edx_ace import ace
from edx_ace.message import Message
from edx_ace.utils.date import deserialize, serialize
from edx_django_utils.monitoring import set_custom_metric
from openedx.core.djangoapps.schedules.tasks import (
    _annonate_send_task_for_monitoring,
    _track_message_sent
)
from openedx.core.djangoapps.schedules.resolvers import _get_datetime_beginning_of_day
from openedx.core.lib.celery.task_utils import emulate_http_request

from . import message_types, resolvers
from .models import CourseDurationLimitConfig

LOG = logging.getLogger(__name__)
ROUTING_KEY = getattr(settings, 'ACE_ROUTING_KEY', None)

class CourseDurationLimitMessageBaseTask(LoggedTask):
    """
    Base class for top-level Schedule tasks that create subtasks
    for each Bin.
    """
    ignore_result = True
    routing_key = ROUTING_KEY
    num_bins = resolvers.DEFAULT_NUM_BINS
    enqueue_config_var = None  # define in subclass
    log_prefix = None
    resolver = None  # define in subclass
    async_send_task = None  # define in subclass

    @classmethod
    def log_debug(cls, message, *args, **kwargs):
        """
        Wrapper around LOG.debug that prefixes the message.
        """
        LOG.debug(cls.log_prefix + ': ' + message, *args, **kwargs)

    @classmethod
    def log_info(cls, message, *args, **kwargs):
        """
        Wrapper around LOG.info that prefixes the message.
        """
        LOG.info(cls.log_prefix + ': ' + message, *args, **kwargs)

    @classmethod
    def enqueue(cls, site, current_date, day_offset, override_recipient_email=None):
        current_date = _get_datetime_beginning_of_day(current_date)

        # for course_key, config in CourseDurationLimitConfig.all_current_course_configs().items():
        for course_key, _ in CourseDurationLimitConfig.all_current_course_configs().items():
            # enqueue_enabled, _ = config[cls.enqueue_config_var]
            # TODO: Switch over to a model where enqueing is based in CourseDurationLimitConfig
            enqueue_enabled = waffle.switch_is_active('course_duration_limits.enqueue_enabled')

            if not enqueue_enabled:
                cls.log_info(u'Message queuing disabled for course_key %s', course_key)
                continue

            target_date = current_date + datetime.timedelta(days=day_offset)
            for bin_num in range(cls.num_bins):
                task_args = (
                    site.id,
                    course_key,
                    serialize(target_date),
                    day_offset,
                    bin_num,
                    override_recipient_email,
                )
                cls().apply_async(
                    task_args,
                    retry=False,
                )

    def run(  # pylint: disable=arguments-differ
        self, site_id, course_key, target_day_str, day_offset, bin_num, override_recipient_email=None,
    ):
        try:
            site = Site.objects.select_related('configuration').get(id=site_id)
            with emulate_http_request(site=site):
                msg_type = self.make_message_type(day_offset)
                _annotate_for_monitoring(msg_type, course_key, bin_num, target_day_str, day_offset)
                return self.resolver(  # pylint: disable=not-callable
                    self.async_send_task,
                    site,
                    course_key,
                    deserialize(target_day_str),
                    day_offset,
                    bin_num,
                    override_recipient_email=override_recipient_email,
                ).send(msg_type)
        except Exception:  # pylint: disable=broad-except
            LOG.exception("Task failed")

    def make_message_type(self, day_offset):
        raise NotImplementedError

@task(base=LoggedTask, ignore_result=True, routing_key=ROUTING_KEY)
def _expiry_reminder_schedule_send(site_id, msg_str):
    _schedule_send(
        msg_str,
        site_id,
        'deliver_expiry_reminder',
        resolvers.EXPIRY_REMINDER_LOG_PREFIX,
    )

class CourseDurationLimitExpiryReminder(CourseDurationLimitMessageBaseTask):
    """
    Task to send out a reminder that a users access to course content is expiring soon.
    """
    num_bins = resolvers.EXPIRY_REMINDER_NUM_BINS
    enqueue_config_var = 'enqueue_expiry_reminder'
    log_prefix = resolvers.EXPIRY_REMINDER_LOG_PREFIX
    resolver = resolvers.ExpiryReminderResolver
    async_send_task = _expiry_reminder_schedule_send

    def make_message_type(self, day_offset):
        return message_types.ExpiryReminder()

def _schedule_send(msg_str, site_id, delivery_config_var, log_prefix):
    site = Site.objects.select_related('configuration').get(pk=site_id)
    if _is_delivery_enabled(site, delivery_config_var, log_prefix):
        msg = Message.from_string(msg_str)

        user = User.objects.get(username=msg.recipient.username)  # pylint: disable=no-member
        with emulate_http_request(site=site, user=user):
            _annonate_send_task_for_monitoring(msg)
            LOG.debug(u'%s: Sending message = %s', log_prefix, msg_str)
            ace.send(msg)
            _track_message_sent(site, user, msg)

def _is_delivery_enabled(site, delivery_config_var, log_prefix):  # pylint: disable=unused-argument
    # Experiment TODO: when this is going to prod, switch over to a config-model backed solution
    #if getattr(CourseDurationLimitConfig.current(site=site), delivery_config_var, False):
    if waffle.switch_is_active('course_duration_limits.delivery_enabled'):
        return True
    else:
        LOG.info(u'%s: Message delivery disabled for site %s', log_prefix, site.domain)
        return False

def _annotate_for_monitoring(message_type, course_key, bin_num, target_day_str, day_offset):
    """
    Set custom metrics in monitoring to make it easier to identify what messages are being sent and why.
    """
    # This identifies the type of message being sent, for example: schedules.recurring_nudge3.
    set_custom_metric('message_name', '{0}.{1}'.format(message_type.app_label, message_type.name))
    # The domain name of the site we are sending the message for.
    set_custom_metric('course_key', course_key)
    # This is the "bin" of data being processed. We divide up the work into chunks so that we don't tie up celery
    # workers for too long. This could help us identify particular bins that are problematic.
    set_custom_metric('bin', bin_num)
    # The date we are processing data for.
    set_custom_metric('target_day', target_day_str)
    # The number of days relative to the current date to process data for.
    set_custom_metric('day_offset', day_offset)
    # A unique identifier for this batch of messages being sent.
    set_custom_metric('send_uuid', message_type.uuid)
<commit_msg>Don't send Access Expiry Emails to courses that don't have Course Duration Limits enabled<commit_after>"""
Tasks requiring asynchronous handling for course_duration_limits
"""

import datetime
import logging

import waffle
from celery import task
from celery_utils.logged_task import LoggedTask
from django.conf import settings
from django.contrib.auth.models import User
from django.contrib.sites.models import Site
from edx_ace import ace
from edx_ace.message import Message
from edx_ace.utils.date import deserialize, serialize
from edx_django_utils.monitoring import set_custom_metric
from openedx.core.djangoapps.schedules.tasks import (
    _annonate_send_task_for_monitoring,
    _track_message_sent
)
from openedx.core.djangoapps.schedules.resolvers import _get_datetime_beginning_of_day
from openedx.core.lib.celery.task_utils import emulate_http_request

from . import message_types, resolvers
from .models import CourseDurationLimitConfig

LOG = logging.getLogger(__name__)
ROUTING_KEY = getattr(settings, 'ACE_ROUTING_KEY', None)

class CourseDurationLimitMessageBaseTask(LoggedTask):
    """
    Base class for top-level Schedule tasks that create subtasks
    for each Bin.
    """
    ignore_result = True
    routing_key = ROUTING_KEY
    num_bins = resolvers.DEFAULT_NUM_BINS
    enqueue_config_var = None  # define in subclass
    log_prefix = None
    resolver = None  # define in subclass
    async_send_task = None  # define in subclass

    @classmethod
    def log_debug(cls, message, *args, **kwargs):
        """
        Wrapper around LOG.debug that prefixes the message.
        """
        LOG.debug(cls.log_prefix + ': ' + message, *args, **kwargs)

    @classmethod
    def log_info(cls, message, *args, **kwargs):
        """
        Wrapper around LOG.info that prefixes the message.
        """
        LOG.info(cls.log_prefix + ': ' + message, *args, **kwargs)

    @classmethod
    def enqueue(cls, site, current_date, day_offset, override_recipient_email=None):
        current_date = _get_datetime_beginning_of_day(current_date)

        for course_key, config in CourseDurationLimitConfig.all_current_course_configs().items():
            if not config['enabled'][0]:
                cls.log_info(u'Course duration limits disabled for course_key %s, skipping', course_key)
                continue

            # enqueue_enabled, _ = config[cls.enqueue_config_var]
            # TODO: Switch over to a model where enqueing is based in CourseDurationLimitConfig
            enqueue_enabled = waffle.switch_is_active('course_duration_limits.enqueue_enabled')

            if not enqueue_enabled:
                cls.log_info(u'Message queuing disabled for course_key %s', course_key)
                continue

            target_date = current_date + datetime.timedelta(days=day_offset)
            for bin_num in range(cls.num_bins):
                task_args = (
                    site.id,
                    course_key,
                    serialize(target_date),
                    day_offset,
                    bin_num,
                    override_recipient_email,
                )
                cls().apply_async(
                    task_args,
                    retry=False,
                )

    def run(  # pylint: disable=arguments-differ
        self, site_id, course_key, target_day_str, day_offset, bin_num, override_recipient_email=None,
    ):
        try:
            site = Site.objects.select_related('configuration').get(id=site_id)
            with emulate_http_request(site=site):
                msg_type = self.make_message_type(day_offset)
                _annotate_for_monitoring(msg_type, course_key, bin_num, target_day_str, day_offset)
                return self.resolver(  # pylint: disable=not-callable
                    self.async_send_task,
                    site,
                    course_key,
                    deserialize(target_day_str),
                    day_offset,
                    bin_num,
                    override_recipient_email=override_recipient_email,
                ).send(msg_type)
        except Exception:  # pylint: disable=broad-except
            LOG.exception("Task failed")

    def make_message_type(self, day_offset):
        raise NotImplementedError

@task(base=LoggedTask, ignore_result=True, routing_key=ROUTING_KEY)
def _expiry_reminder_schedule_send(site_id, msg_str):
    _schedule_send(
        msg_str,
        site_id,
        'deliver_expiry_reminder',
        resolvers.EXPIRY_REMINDER_LOG_PREFIX,
    )

class CourseDurationLimitExpiryReminder(CourseDurationLimitMessageBaseTask):
    """
    Task to send out a reminder that a users access to course content is expiring soon.
    """
    num_bins = resolvers.EXPIRY_REMINDER_NUM_BINS
    enqueue_config_var = 'enqueue_expiry_reminder'
    log_prefix = resolvers.EXPIRY_REMINDER_LOG_PREFIX
    resolver = resolvers.ExpiryReminderResolver
    async_send_task = _expiry_reminder_schedule_send

    def make_message_type(self, day_offset):
        return message_types.ExpiryReminder()

def _schedule_send(msg_str, site_id, delivery_config_var, log_prefix):
    site = Site.objects.select_related('configuration').get(pk=site_id)
    if _is_delivery_enabled(site, delivery_config_var, log_prefix):
        msg = Message.from_string(msg_str)

        user = User.objects.get(username=msg.recipient.username)  # pylint: disable=no-member
        with emulate_http_request(site=site, user=user):
            _annonate_send_task_for_monitoring(msg)
            LOG.debug(u'%s: Sending message = %s', log_prefix, msg_str)
            ace.send(msg)
            _track_message_sent(site, user, msg)

def _is_delivery_enabled(site, delivery_config_var, log_prefix):  # pylint: disable=unused-argument
    # Experiment TODO: when this is going to prod, switch over to a config-model backed solution
    #if getattr(CourseDurationLimitConfig.current(site=site), delivery_config_var, False):
    if waffle.switch_is_active('course_duration_limits.delivery_enabled'):
        return True
    else:
        LOG.info(u'%s: Message delivery disabled for site %s', log_prefix, site.domain)
        return False

def _annotate_for_monitoring(message_type, course_key, bin_num, target_day_str, day_offset):
    """
    Set custom metrics in monitoring to make it easier to identify what messages are being sent and why.
    """
    # This identifies the type of message being sent, for example: schedules.recurring_nudge3.
    set_custom_metric('message_name', '{0}.{1}'.format(message_type.app_label, message_type.name))
    # The domain name of the site we are sending the message for.
    set_custom_metric('course_key', course_key)
    # This is the "bin" of data being processed. We divide up the work into chunks so that we don't tie up celery
    # workers for too long. This could help us identify particular bins that are problematic.
    set_custom_metric('bin', bin_num)
    # The date we are processing data for.
    set_custom_metric('target_day', target_day_str)
    # The number of days relative to the current date to process data for.
    set_custom_metric('day_offset', day_offset)
    # A unique identifier for this batch of messages being sent.
    set_custom_metric('send_uuid', message_type.uuid)
<|endoftext|>


<commit_before><commit_msg>add scp mn image from wdpk node to ceph node<commit_after><|endoftext|>


<commit_before>#!/usr/bin/python
class Team:
	def __init__(self, name):
		self.name = name
		self.score = 0
		self.players = {}
		self.positions = []

class Player:
	def __init__(self, name, screenname, ip):
		self.name = name
		self.screenname = screenname
		self.ip = ip
		self.score = 0
		self.alive = False

class Zone:
	def __init__(self, grid, name, type, x, y, size, growth=0, xdir=0, ydir=0, interactive=None, r=None, g=None, b=None, target_size=None, rubber=None, player=None, owner=None, command=None):
		self.name = name
		self.type = type
		self.x = x
		self.y = y
		self.size = size
		self.growth = growth
		self.xdir = xdir
		self.ydir = ydir

		if interactive != None:
			self.interactive = interactive

		if r != None and g != None and b != None:
			self.r = r
			self.g = g
			self.b = b

		if target_size != None:
			self.target_size = target_size

		if type == "rubber":
			self.rubber = rubber

		if type == "zombie":
			self.player = player

		if type == "zombieOwner":
			self.player = player
			self.owner = owner

		if type == "target" and command != None:
			self.addCommand(command)

	def __del__(self):
		self.changeSize(0)

	def addCommand(self, command):
		if zone.type == "target":
			grid.sendCommand("SET_TARGET_COMMAND " + self.name + " " + command)

	def changeColor(self, r, g, b):
		self.r = r
		self.g = g
		self.b = b
		grid.sendCommand("SET_ZONE_COLOR " + self.name + " " + r + " " + g + " " + b)

	def changeExpansion(self, growth):
		self.growth = growth
		grid.sendCommand("SET_ZONE_EXPANSION " + self.name + " " + growth)

	def changePosition(self, x, y):
		self.x = x
		self.y = y
		grid.sendCommand("SET_ZONE_POSITION " + self.name + " " + x + " " + y)

	def changeSize(self, size, growth=None):
		self.size = size
		command = "SET_ZONE_RADIUS" + self.name + " " + size

		if growth != None:
			command += " " + growth

		grid.sendCommand(command)

	def changeSpeed(self, xdir, ydir):
		self.xdir = xdir
		self.ydir = ydir
		grid.sendCommand("SET_ZONE_SPEED " + self.name + " " + xdir + " " + ydir)
class Grid:
	def __init__(self, sendCommand):
		self.round = 0
		self.teams = {}
		self.num_players = 0
		self.players = {}
		self.zones = {}
		self.sendCommand = sendCommand

	def getTeam(self, name):
		if name in self.teams:
			return self.teams[name]

	def getPlayer(self, name):
		if name in self.players:
			return self.players[name]

	def getZone(self, name):
		if name in self.zones:
			return self.zones[name]

	def createZone(self, name, type, x, y, size, growth=0, xdir=0, ydir=0, interactive=None, r=None, g=None, b=None, target_size=None, rubber=None, player=None, owner=None, targetcommand=None):
		command = "SPAWN_ZONE n " + name + " " + type

		if type == "zombie":
			if player == None:
				return None
			command += " " + player

		if type == "zombieOwner":
			if player == None or owner == None:
				return None
			command += " " + player + " " + owner

		command += " " + x + " " + y + " " + size + " " + growth + " " + xdir + " " + ydir

		if type == "rubber":
			if rubber == None:
				return None
			command += rubber

		if interactive != None:
			command += " " + interactive

		if r != None and g != None and b != None:
			command += " " + r + " " + g+ " " + b

		if target_size != None:
			command += " " + target_size

		self.sendCommand(command)

		self.zones[name] = Zone(self, name, type, x, y, size, growth, xdir, ydir, interactive, r, g, b, target_size, rubber, player, owner, targetcommand)

		return self.zones[name]

	#Ladderlog commands

	def newRound(self, command):
		self.round += 1
		self.zones = {}

	def newMatch(self, command):
		self.round = 1
		for team in self.teams.values():
			team.score = 0
		for player in self.players.values():
			player.score = 0

	def roundScore(self, command):
		if command[2] in self.players:
			self.players[command[2]].score += command[1]

	def roundScoreTeam(self, command):
		if command[2] in self.teams:
			self.teams[command[2]].score += command[1]

	def teamCreated(self, command):
		self.teams[command[1]] = Team(command[1])

	def teamDestroyed(self, command):
		if command[1] in self.teams:
			del self.teams[command[1]]

	def teamRenamed(self, command):
		if command[1] in self.teams:
			self.teams[command[2]] = self.teams.pop(command[1])
			self.teams[command[2]].name = command[2]

	def teamPlayerAdded(self, command):
		if command[1] in self.teams and command[2] in self.players:
			self.teams[command[1]].players[command[2]] = self.players[command[2]]

	def teamPlayerRemoved(self, command):
		if command[1] in self.teams and command[2] in self.teams[command[1]].players:
			del self.teams[command[1]].players[command[2]]

	def playerEntered(self, command):
		self.players[command[1]] = Player(command[1], command[3], command[2])

	def playerLeft(self, command):
		if command[1] in self.players:
			del self.players[command[1]]

	def playerRenamed(self, command):
		if command[1] in self.players:
			if not command[2] in self.players:
				self.players[command[2]] = self.players.pop(command[1])
				self.players[command[2]].name = command[2]
			self.players[command[2]].screenname = command[5]

	def numHumans(self, command):
		self.num_players = command[1]

	def positions(self, command):
		if command[1] in self.teams:
			self.teams[command[1]].positions = []
			for i in range(2, len(command)):
				team.positions.append(getPlayer(command[i]))

	def zoneSpawned(self, command):
		if command[2] != "":
			self.zones[command[2]] = Zone(command[2], None, command[3], command[4], None)
		else:
			self.zones[command[1]] = Zone(command[1], None, command[3], command[4], None)

	def zoneCollapsed(self, command):
		if command[1] in self.zones:
			del self.zones[command[1]]
		elif command[2] in self.zones:
			del self.zones[command[2]]

	def reset(self, command):
		self.round = 0
		self.teams = {}
		self.num_players = 0
		self.players = {}
		self.zones = {}
<commit_msg>Bug fix<commit_after>#!/usr/bin/python
class Team:
	def __init__(self, name):
		self.name = name
		self.score = 0
		self.players = {}
		self.positions = []

class Player:
	def __init__(self, name, screenname, ip):
		self.name = name
		self.screenname = screenname
		self.ip = ip
		self.score = 0
		self.alive = False

class Zone:
	def __init__(self, grid, name, type, x, y, size, growth=0, xdir=0, ydir=0, interactive=None, r=None, g=None, b=None, target_size=None, rubber=None, player=None, owner=None, command=None):
		self.name = name
		self.type = type
		self.x = x
		self.y = y
		self.size = size
		self.growth = growth
		self.xdir = xdir
		self.ydir = ydir

		if interactive != None:
			self.interactive = interactive

		if r != None and g != None and b != None:
			self.r = r
			self.g = g
			self.b = b

		if target_size != None:
			self.target_size = target_size

		if type == "rubber":
			self.rubber = rubber

		if type == "zombie":
			self.player = player

		if type == "zombieOwner":
			self.player = player
			self.owner = owner

		if type == "target" and command != None:
			self.addCommand(command)

	def __del__(self):
		self.changeSize(0)

	def addCommand(self, command):
		if zone.type == "target":
			grid.sendCommand("SET_TARGET_COMMAND " + self.name + " " + command)

	def changeColor(self, r, g, b):
		self.r = r
		self.g = g
		self.b = b
		grid.sendCommand("SET_ZONE_COLOR " + self.name + " " + r + " " + g + " " + b)

	def changeExpansion(self, growth):
		self.growth = growth
		grid.sendCommand("SET_ZONE_EXPANSION " + self.name + " " + growth)

	def changePosition(self, x, y):
		self.x = x
		self.y = y
		grid.sendCommand("SET_ZONE_POSITION " + self.name + " " + x + " " + y)

	def changeSize(self, size, growth=None):
		self.size = size
		command = "SET_ZONE_RADIUS" + self.name + " " + size

		if growth != None:
			command += " " + growth

		grid.sendCommand(command)

	def changeSpeed(self, xdir, ydir):
		self.xdir = xdir
		self.ydir = ydir
		grid.sendCommand("SET_ZONE_SPEED " + self.name + " " + xdir + " " + ydir)
class Grid:
	def __init__(self, sendCommand):
		self.round = 0
		self.teams = {}
		self.num_players = 0
		self.players = {}
		self.zones = {}
		self.sendCommand = sendCommand

	def getTeam(self, name):
		if name in self.teams:
			return self.teams[name]

	def getPlayer(self, name):
		if name in self.players:
			return self.players[name]

	def getZone(self, name):
		if name in self.zones:
			return self.zones[name]

	def createZone(self, name, type, x, y, size, growth=0, xdir=0, ydir=0, interactive=None, r=None, g=None, b=None, target_size=None, rubber=None, player=None, owner=None, targetcommand=None):
		command = "SPAWN_ZONE n " + name + " " + type

		if type == "zombie":
			if player == None:
				return None
			command += " " + player

		if type == "zombieOwner":
			if player == None or owner == None:
				return None
			command += " " + player + " " + owner

		command += " " + x + " " + y + " " + size + " " + growth + " " + xdir + " " + ydir

		if type == "rubber":
			if rubber == None:
				return None
			command += rubber

		if interactive != None:
			command += " " + interactive

		if r != None and g != None and b != None:
			command += " " + r + " " + g+ " " + b

		if target_size != None:
			command += " " + target_size

		self.sendCommand(command)

		self.zones[name] = Zone(self, name, type, x, y, size, growth, xdir, ydir, interactive, r, g, b, target_size, rubber, player, owner, targetcommand)

		return self.zones[name]

	#Ladderlog commands

	def newRound(self, command):
		self.round += 1
		self.zones = {}

	def newMatch(self, command):
		self.round = 1
		for team in self.teams.values():
			team.score = 0
		for player in self.players.values():
			player.score = 0

	def roundScore(self, command):
		if command[2] in self.players:
			self.players[command[2]].score += command[1]

	def roundScoreTeam(self, command):
		if command[2] in self.teams:
			self.teams[command[2]].score += command[1]

	def teamCreated(self, command):
		self.teams[command[1]] = Team(command[1])

	def teamDestroyed(self, command):
		if command[1] in self.teams:
			del self.teams[command[1]]

	def teamRenamed(self, command):
		if command[1] in self.teams:
			self.teams[command[2]] = self.teams.pop(command[1])
			self.teams[command[2]].name = command[2]

	def teamPlayerAdded(self, command):
		if command[1] in self.teams and command[2] in self.players:
			self.teams[command[1]].players[command[2]] = self.players[command[2]]

	def teamPlayerRemoved(self, command):
		if command[1] in self.teams and command[2] in self.teams[command[1]].players:
			del self.teams[command[1]].players[command[2]]

	def playerEntered(self, command):
		self.players[command[1]] = Player(command[1], command[3], command[2])

	def playerLeft(self, command):
		if command[1] in self.players:
			del self.players[command[1]]

	def playerRenamed(self, command):
		if command[1] in self.players:
			if not command[2] in self.players:
				self.players[command[2]] = self.players.pop(command[1])
				self.players[command[2]].name = command[2]
			self.players[command[2]].screenname = command[5]

	def numHumans(self, command):
		self.num_players = command[1]

	def positions(self, command):
		if command[1] in self.teams:
			self.teams[command[1]].positions = []
			for i in range(2, len(command)):
				self.teams[command[1]].positions.append(getPlayer(command[i]))

	def zoneSpawned(self, command):
		if command[2] != "":
			self.zones[command[2]] = Zone(command[2], None, command[3], command[4], None)
		else:
			self.zones[command[1]] = Zone(command[1], None, command[3], command[4], None)

	def zoneCollapsed(self, command):
		if command[1] in self.zones:
			del self.zones[command[1]]
		elif command[2] in self.zones:
			del self.zones[command[2]]

	def reset(self, command):
		self.round = 0
		self.teams = {}
		self.num_players = 0
		self.players = {}
		self.zones = {}
<|endoftext|>


<commit_before>#!/usr/bin/python
class Team:
	def __init__(self, name):
		self.name = name
		self.score = 0
		self.players = {}
		self.positions = []

class Player:
	def __init__(self, name, screenname, ip):
		self.name = name
		self.screenname = screenname
		self.ip = ip
		self.score = 0
		self.alive = False

class Zone:
	def __init__(self, grid, name, type, x, y, size, growth=0, xdir=0, ydir=0, interactive=None, r=None, g=None, b=None, target_size=None, rubber=None, player=None, owner=None, command=None):
		self.name = name
		self.type = type
		self.x = x
		self.y = y
		self.size = size
		self.growth = growth
		self.xdir = xdir
		self.ydir = ydir

		if interactive != None:
			self.interactive = interactive

		if r != None and g != None and b != None:
			self.r = r
			self.g = g
			self.b = b

		if target_size != None:
			self.target_size = target_size

		if type == "rubber":
			self.rubber = rubber

		if type == "zombie":
			self.player = player

		if type == "zombieOwner":
			self.player = player
			self.owner = owner

		if type == "target" and command != None:
			self.addCommand(command)

	def __del__(self):
		self.changeSize(0)

	def addCommand(self, command):
		if zone.type == "target":
			grid.sendCommand("SET_TARGET_COMMAND " + self.name + " " + command)

	def changeColor(self, r, g, b):
		self.r = r
		self.g = g
		self.b = b
		grid.sendCommand("SET_ZONE_COLOR " + self.name + " " + r + " " + g + " " + b)

	def changeExpansion(self, growth):
		self.growth = growth
		grid.sendCommand("SET_ZONE_EXPANSION " + self.name + " " + growth)

	def changePosition(self, x, y):
		self.x = x
		self.y = y
		grid.sendCommand("SET_ZONE_POSITION " + self.name + " " + x + " " + y)

	def changeSize(self, size, growth=None):
		self.size = size
		command = "SET_ZONE_RADIUS" + self.name + " " + size

		if growth != None:
			command += " " + growth

		grid.sendCommand(command)

	def changeSpeed(self, xdir, ydir):
		self.xdir = xdir
		self.ydir = ydir
		grid.sendCommand("SET_ZONE_SPEED " + self.name + " " + xdir + " " + ydir)
class Grid:
	def __init__(self, sendCommand):
		self.reset(None)
		self.sendCommand = sendCommand

	def getTeam(self, name):
		if name in self.teams:
			return self.teams[name]

	def getPlayer(self, name):
		if name in self.players:
			return self.players[name]

	def getZone(self, name):
		if name in self.zones:
			return self.zones[name]

	def createZone(self, name, type, x, y, size, growth=0, xdir=0, ydir=0, interactive=None, r=None, g=None, b=None, target_size=None, rubber=None, player=None, owner=None, targetcommand=None):
		command = "SPAWN_ZONE n " + name + " " + type

		if type == "zombie":
			if player == None:
				return None
			command += " " + player

		if type == "zombieOwner":
			if player == None or owner == None:
				return None
			command += " " + player + " " + owner

		command += " " + x + " " + y + " " + size + " " + growth + " " + xdir + " " + ydir

		if type == "rubber":
			if rubber == None:
				return None
			command += rubber

		if interactive != None:
			command += " " + interactive

		if r != None and g != None and b != None:
			command += " " + r + " " + g+ " " + b

		if target_size != None:
			command += " " + target_size

		self.sendCommand(command)

		self.zones[name] = Zone(self, name, type, x, y, size, growth, xdir, ydir, interactive, r, g, b, target_size, rubber, player, owner, targetcommand)

		return self.zones[name]

	#Ladderlog commands

	def newRound(self, command):
		self.round += 1
		self.zones = {}

	def newMatch(self, command):
		self.round = 1
		for team in self.teams.values():
			team.score = 0
		for player in self.players.values():
			player.score = 0

	def roundScore(self, command):
		if command[2] in self.players:
			self.players[command[2]].score += command[1]

	def roundScoreTeam(self, command):
		if command[2] in self.teams:
			self.teams[command[2]].score += command[1]

	def teamCreated(self, command):
		self.teams[command[1]] = Team(command[1])

	def teamDestroyed(self, command):
		if command[1] in self.teams:
			del self.teams[command[1]]

	def teamRenamed(self, command):
		if command[1] in self.teams:
			self.teams[command[2]] = self.teams.pop(command[1])
			self.teams[command[2]].name = command[2]

	def teamPlayerAdded(self, command):
		if command[1] in self.teams and command[2] in self.players:
			self.teams[command[1]].players[command[2]] = self.players[command[2]]

	def teamPlayerRemoved(self, command):
		if command[1] in self.teams and command[2] in self.teams[command[1]].players:
			del self.teams[command[1]].players[command[2]]

	def playerEntered(self, command):
		self.players[command[1]] = Player(command[1], command[3], command[2])

	def playerLeft(self, command):
		if command[1] in self.players:
			del self.players[command[1]]

	def playerRenamed(self, command):
		if command[1] in self.players:
			if not command[2] in self.players:
				self.players[command[2]] = self.players.pop(command[1])
				self.players[command[2]].name = command[2]
			self.players[command[2]].screenname = command[5]

	def numHumans(self, command):
		self.num_players = command[1]

	def positions(self, command):
		if command[1] in self.teams:
			self.teams[command[1]].positions = []
			for i in range(2, len(command)):
				self.teams[command[1]].positions.append(getPlayer(command[i]))

	def zoneSpawned(self, command):
		if command[2] != "":
			self.zones[command[2]] = Zone(command[2], None, command[3], command[4], None)
		else:
			self.zones[command[1]] = Zone(command[1], None, command[3], command[4], None)

	def zoneCollapsed(self, command):
		if command[1] in self.zones:
			del self.zones[command[1]]
		elif command[2] in self.zones:
			del self.zones[command[2]]

	def reset(self, command):
		self.round = 0
		self.teams = {}
		self.num_players = 0
		self.players = {}
		self.zones = {}
<commit_msg>Fixed score being parsed as string<commit_after>#!/usr/bin/python
class Team:
	def __init__(self, name):
		self.name = name
		self.score = 0
		self.players = {}
		self.positions = []

class Player:
	def __init__(self, name, screenname, ip):
		self.name = name
		self.screenname = screenname
		self.ip = ip
		self.score = 0
		self.alive = False

class Zone:
	def __init__(self, grid, name, type, x, y, size, growth=0, xdir=0, ydir=0, interactive=None, r=None, g=None, b=None, target_size=None, rubber=None, player=None, owner=None, command=None):
		self.name = name
		self.type = type
		self.x = x
		self.y = y
		self.size = size
		self.growth = growth
		self.xdir = xdir
		self.ydir = ydir

		if interactive != None:
			self.interactive = interactive

		if r != None and g != None and b != None:
			self.r = r
			self.g = g
			self.b = b

		if target_size != None:
			self.target_size = target_size

		if type == "rubber":
			self.rubber = rubber

		if type == "zombie":
			self.player = player

		if type == "zombieOwner":
			self.player = player
			self.owner = owner

		if type == "target" and command != None:
			self.addCommand(command)

	def __del__(self):
		self.changeSize(0)

	def addCommand(self, command):
		if zone.type == "target":
			grid.sendCommand("SET_TARGET_COMMAND " + self.name + " " + command)

	def changeColor(self, r, g, b):
		self.r = r
		self.g = g
		self.b = b
		grid.sendCommand("SET_ZONE_COLOR " + self.name + " " + r + " " + g + " " + b)

	def changeExpansion(self, growth):
		self.growth = growth
		grid.sendCommand("SET_ZONE_EXPANSION " + self.name + " " + growth)

	def changePosition(self, x, y):
		self.x = x
		self.y = y
		grid.sendCommand("SET_ZONE_POSITION " + self.name + " " + x + " " + y)

	def changeSize(self, size, growth=None):
		self.size = size
		command = "SET_ZONE_RADIUS" + self.name + " " + size

		if growth != None:
			command += " " + growth

		grid.sendCommand(command)

	def changeSpeed(self, xdir, ydir):
		self.xdir = xdir
		self.ydir = ydir
		grid.sendCommand("SET_ZONE_SPEED " + self.name + " " + xdir + " " + ydir)
class Grid:
	def __init__(self, sendCommand):
		self.reset(None)
		self.sendCommand = sendCommand

	def getTeam(self, name):
		if name in self.teams:
			return self.teams[name]

	def getPlayer(self, name):
		if name in self.players:
			return self.players[name]

	def getZone(self, name):
		if name in self.zones:
			return self.zones[name]

	def createZone(self, name, type, x, y, size, growth=0, xdir=0, ydir=0, interactive=None, r=None, g=None, b=None, target_size=None, rubber=None, player=None, owner=None, targetcommand=None):
		command = "SPAWN_ZONE n " + name + " " + type

		if type == "zombie":
			if player == None:
				return None
			command += " " + player

		if type == "zombieOwner":
			if player == None or owner == None:
				return None
			command += " " + player + " " + owner

		command += " " + x + " " + y + " " + size + " " + growth + " " + xdir + " " + ydir

		if type == "rubber":
			if rubber == None:
				return None
			command += rubber

		if interactive != None:
			command += " " + interactive

		if r != None and g != None and b != None:
			command += " " + r + " " + g+ " " + b

		if target_size != None:
			command += " " + target_size

		self.sendCommand(command)

		self.zones[name] = Zone(self, name, type, x, y, size, growth, xdir, ydir, interactive, r, g, b, target_size, rubber, player, owner, targetcommand)

		return self.zones[name]

	#Ladderlog commands

	def newRound(self, command):
		self.round += 1
		self.zones = {}

	def newMatch(self, command):
		self.round = 1
		for team in self.teams.values():
			team.score = 0
		for player in self.players.values():
			player.score = 0

	def roundScore(self, command):
		if command[2] in self.players:
			self.players[command[2]].score += int(command[1])

	def roundScoreTeam(self, command):
		if command[2] in self.teams:
			self.teams[command[2]].score += int(command[1])

	def teamCreated(self, command):
		self.teams[command[1]] = Team(command[1])

	def teamDestroyed(self, command):
		if command[1] in self.teams:
			del self.teams[command[1]]

	def teamRenamed(self, command):
		if command[1] in self.teams:
			self.teams[command[2]] = self.teams.pop(command[1])
			self.teams[command[2]].name = command[2]

	def teamPlayerAdded(self, command):
		if command[1] in self.teams and command[2] in self.players:
			self.teams[command[1]].players[command[2]] = self.players[command[2]]

	def teamPlayerRemoved(self, command):
		if command[1] in self.teams and command[2] in self.teams[command[1]].players:
			del self.teams[command[1]].players[command[2]]

	def playerEntered(self, command):
		self.players[command[1]] = Player(command[1], command[3], command[2])

	def playerLeft(self, command):
		if command[1] in self.players:
			del self.players[command[1]]

	def playerRenamed(self, command):
		if command[1] in self.players:
			if not command[2] in self.players:
				self.players[command[2]] = self.players.pop(command[1])
				self.players[command[2]].name = command[2]
			self.players[command[2]].screenname = command[5]

	def numHumans(self, command):
		self.num_players = command[1]

	def positions(self, command):
		if command[1] in self.teams:
			self.teams[command[1]].positions = []
			for i in range(2, len(command)):
				self.teams[command[1]].positions.append(getPlayer(command[i]))

	def zoneSpawned(self, command):
		if command[2] != "":
			self.zones[command[2]] = Zone(command[2], None, command[3], command[4], None)
		else:
			self.zones[command[1]] = Zone(command[1], None, command[3], command[4], None)

	def zoneCollapsed(self, command):
		if command[1] in self.zones:
			del self.zones[command[1]]
		elif command[2] in self.zones:
			del self.zones[command[2]]

	def reset(self, command):
		self.round = 0
		self.teams = {}
		self.num_players = 0
		self.players = {}
		self.zones = {}
<|endoftext|>