Example #1
0
 def clear_ticket_system_field_cache(self):
     # In Trac 0.12, fields will be cached by new functionality and this
     # cache will be initialized before our custom field configuration was
     # read so we need to force a reload
     ticket_system = AgiloTicketSystem(self.env)
     if not ticket_system.is_trac_012():
         return
     del ticket_system.fields
     del ticket_system.custom_fields
Example #2
0
 def clear_ticket_system_field_cache(self):
     # In Trac 0.12, fields will be cached by new functionality and this
     # cache will be initialized before our custom field configuration was
     # read so we need to force a reload
     ticket_system = AgiloTicketSystem(self.env)
     if not ticket_system.is_trac_012():
         return
     del ticket_system.fields
     del ticket_system.custom_fields
Example #3
0
    def create_field(self, field_name, field_type, **field_options):
        config = AgiloConfig(self.env)
        ticket_custom = config.get_section('ticket-custom')
        ticket_custom.change_option(field_name, field_type)
        for (option_name, option_value) in field_options.items():
            key = '%s.%s' % (field_name, option_name)
            ticket_custom.change_option(key, option_value)
        config.save()

        ticket_system = AgiloTicketSystem(self.env)
        all_known_fields = ticket_system.fieldnames(ticket_system.get_ticket_fields())
        assert_contains(field_name, all_known_fields)
Example #4
0
 def _get_field_names(self, backlog):
     """Return an ordered collection of all field names which appear in one 
     of the tickets for this backlog."""
     ticket_types = set()
     for bi in backlog:
         ticket_types.add(bi[Key.TYPE])
     
     field_names = set()
     ats = AgiloTicketSystem(self.env)
     for ticket_type in ticket_types:
         for field in ats.get_ticket_fields(ticket_type):
             field_names.add(field[Key.NAME])
     return list(field_names)
Example #5
0
    def create_field(self, field_name, field_type, **field_options):
        config = AgiloConfig(self.env)
        ticket_custom = config.get_section('ticket-custom')
        ticket_custom.change_option(field_name, field_type)
        for (option_name, option_value) in field_options.items():
            key = '%s.%s' % (field_name, option_name)
            ticket_custom.change_option(key, option_value)
        config.save()

        ticket_system = AgiloTicketSystem(self.env)
        all_known_fields = ticket_system.fieldnames(
            ticket_system.get_ticket_fields())
        assert_contains(field_name, all_known_fields)
Example #6
0
    def convert_owner_field_to_select_if_needed(self, field_dict, backlog):
        if not AgiloTicketSystem(self.env).restrict_owner:
            return

        owner_properties = field_dict.get(Key.OWNER)
        if owner_properties is None:
            return

        sprint_name = None
        if backlog.is_sprint_backlog():
            sprint_name = backlog.sprint().name

        AgiloTicketSystem(self.env).eventually_restrict_owner(
            owner_properties, sprint_name=sprint_name)
Example #7
0
    def reset_db(self, default_data=None):
        from agilo.test.functional.api import EnvironmentBuilder
        env = EnvironmentBuilder.get_testenv(self.env_key)
        from trac.db.api import _parse_db_str
        scheme, db_prop = _parse_db_str(env.get_db_url())

        if scheme != 'sqlite' and not default_data:
            return super(BetterEnvironmentStub, self).reset_db(default_data)

        env_for_transaction = env.get_trac_environment()
        if AgiloTicketSystem.is_trac_1_0():
            env_for_transaction = env

        tables = []
        if scheme != 'sqlite':
            db = self.get_db_cnx()
            @with_transaction(env_for_transaction, db)
            def implementation(db):
                cursor = db.cursor()
                cursor.execute("update system set value='9999' WHERE name='database_version'")
                db.commit()

            tables = super(BetterEnvironmentStub, self).reset_db(default_data)
        else:
            from trac import db_default
            from trac.db_default import schema
            from trac.db.sqlite_backend import _to_sql

            # our 'destroy_db'
            db = self.get_db_cnx()
            @with_transaction(env_for_transaction, db)
            def implementation(db):
                cursor = db.cursor()
                cursor.execute("SELECT name FROM sqlite_master WHERE type='table'")
                tables = cursor.fetchall()
                for table in tables:
                    cursor.execute("DROP TABLE %s" % table)

                # part of sqlite_backend's init_db
                for table in schema:
                    for stmt in _to_sql(table):
                        cursor.execute(stmt)

                # part of reset_db
                for table, cols, vals in db_default.get_data(db):
                    cursor.executemany("INSERT INTO %s (%s) VALUES (%s)"
                                       % (table, ','.join(cols),
                                          ','.join(['%s' for c in cols])),
                        vals)
                db.commit()

        if env.tester.testcase.testtype != 'unittest':
            try:
                env._upgrade_environment()
                env._setup_users_and_permissions()
            except:
                # it's possible that this has already happened
                print "Warning: Exception on post-reset_db tasks"

        return tables
Example #8
0
 def wait_if_last_change_was_within_this_second(self, req, ticket_id, args):
     if AgiloTicketSystem(self.env).is_trac_012():
         return
     # Trac can't save two ticket changes within one second
     last_changetime = self.get_last_changetime(
         self.get_ticket_as_json(req, ticket_id))
     if last_changetime == self.get_last_changetime(args):
         time.sleep(1)
Example #9
0
 def get_enabled_components(self):
     components = self.super()
     from agilo.ticket import AgiloTicketSystem
     if AgiloTicketSystem.is_trac_1_0():
         components += ['agilo.*', 'webadmin.*', 'acct_mgr.*', 'tracopt.versioncontrol.svn.*']
     else:
         components += ['agilo.*', 'webadmin.*', 'acct_mgr.*']
     return components
Example #10
0
 def runTest(self):
     self.tester.login_as(Usernames.team_member)
     task_id = self.tester.create_new_agilo_task('Foo')
     
     last_change = self.tester.get_time_of_last_change(task_id)
     from agilo.ticket import AgiloTicketSystem
     if AgiloTicketSystem.is_trac_1_0():
         self.tester.edit_ticket(task_id, summary='fnord', view_time='12')
     else:
         self.tester.edit_ticket(task_id, summary='fnord', ts='12')
     tc.find('This ticket has been modified by someone else since you started')
     
     if AgiloTicketSystem.is_trac_1_0():
         self.tester.edit_ticket(task_id, summary='fnord', view_time=str(last_change))
     else:
         self.tester.edit_ticket(task_id, summary='fnord', ts=str(last_change))
     tc.notfind('This ticket has been modified by someone else since you started')
     tc.find('fnord')
Example #11
0
    def has_permission(self, username, action):
        # DefaultPermissionPolicy will cache permissions for 5 seconds so we
        # need to reset the cache
        DefaultPermissionPolicy(self.env).permission_cache = {}

        if AgiloTicketSystem.is_trac_1_0():
            del PermissionSystem(self.env).store._all_permissions

        return PermissionSystem(self.env).check_permission(action, username)
Example #12
0
    def __init__(self, env, req, ticket):
        self.ats = AgiloTicketSystem(env)
        self.req = req
        self.ticket = ticket

        self._old_status_stack = []
        self._status_stack = []
        self.candidate_queue = None
        self.checked_status = None
Example #13
0
    def has_permission(self, username, action):
        # DefaultPermissionPolicy will cache permissions for 5 seconds so we
        # need to reset the cache
        DefaultPermissionPolicy(self.env).permission_cache = {}

        if AgiloTicketSystem.is_trac_1_0():
            del PermissionSystem(self.env).store._all_permissions

        return PermissionSystem(self.env).check_permission(action, username)
Example #14
0
 def rename_fields(self, req, ticket_type=None):
     fields = AgiloTicketSystem(self.env).get_ticket_fields(ticket_type)
     for field in fields:
         name = field[Key.NAME]
         if name in req.args:
             value = req.args[name]
             if not isinstance(value, basestring):
                 value = str(value)
             del req.args[name]
             req.args['field_' + name] = value
    def update_contains_can_edit(self, args):
        json = self.ticket_as_json(self.task)
        json.update(args)
        from agilo.ticket import AgiloTicketSystem
        if AgiloTicketSystem.is_trac_1_0():
            from trac.util.datefmt import to_utimestamp
            json.update(dict(view_time=str(to_utimestamp(self.task.time_changed)), submit=True))

        view = TicketUpdateView(self.env)
        result = view.do_post(self.req, json)
        return result['can_edit']
Example #16
0
 def get_enabled_components(self):
     components = self.super()
     from agilo.ticket import AgiloTicketSystem
     if AgiloTicketSystem.is_trac_1_0():
         components += [
             'agilo.*', 'webadmin.*', 'acct_mgr.*',
             'tracopt.versioncontrol.svn.*'
         ]
     else:
         components += ['agilo.*', 'webadmin.*', 'acct_mgr.*']
     return components
Example #17
0
    def _get_action_controllers_for_action(self, action):
        def _get_actions_for(controller):
            weighted_actions = controller.get_ticket_actions(
                self.req, self.ticket)
            actions = [action for (weight, action) in weighted_actions]
            return actions

        controllers = []
        ats = AgiloTicketSystem(self.env)
        for controller in ats.action_controllers:
            if action in _get_actions_for(controller):
                controllers.append(controller)
        return controllers
    def update_contains_can_edit(self, args):
        json = self.ticket_as_json(self.task)
        json.update(args)
        from agilo.ticket import AgiloTicketSystem
        if AgiloTicketSystem.is_trac_1_0():
            from trac.util.datefmt import to_utimestamp
            json.update(
                dict(view_time=str(to_utimestamp(self.task.time_changed)),
                     submit=True))

        view = TicketUpdateView(self.env)
        result = view.do_post(self.req, json)
        return result['can_edit']
Example #19
0
 def runTest(self):
     self.tester.go_to_product_backlog()
     story_as_dict = self.story.as_dict()
     from agilo.ticket import AgiloTicketSystem
     if AgiloTicketSystem.is_trac_1_0():
         from trac.util.datefmt import to_utimestamp
         story_as_dict.update({'view_time': str(to_utimestamp(self.story.time_changed))})
     if story_as_dict.has_key('description'):
         del story_as_dict['description']
     data = json.dumps(story_as_dict)
     import trac.util
     escaped_data = trac.util.escape(data)
     page = tc.get_browser().get_html()
     self.assert_(str(escaped_data) in page, "Metadata error")
Example #20
0
 def __init__(self, project, rev, reponame=None, env=None):
     """Initialize the class with the project path and the revision"""
     try:
         self.env = env or Environment(project)
         self.tm = AgiloTicketModelManager(self.env)
         if AgiloTicketSystem(self.env).is_trac_011():
             repos = self.env.get_repository()
         else:
             repos = self.env.get_repository(reponame=reponame)
         repos.sync()
     except Exception, e:
         print >> sys.stderr, "An Error occurred while opening Trac project: %s => %s" % (
             project, to_unicode(e))
         sys.exit(1)
Example #21
0
 def runTest(self):
     self.tester.go_to_product_backlog()
     story_as_dict = self.story.as_dict()
     from agilo.ticket import AgiloTicketSystem
     if AgiloTicketSystem.is_trac_1_0():
         from trac.util.datefmt import to_utimestamp
         story_as_dict.update(
             {'view_time': str(to_utimestamp(self.story.time_changed))})
     if story_as_dict.has_key('description'):
         del story_as_dict['description']
     data = json.dumps(story_as_dict)
     import trac.util
     escaped_data = trac.util.escape(data)
     page = tc.get_browser().get_html()
     self.assert_(str(escaped_data) in page, "Metadata error")
Example #22
0
    def do_put(self, req, args):
        trac_type = AgiloTicketSystem(self.env).normalize_type(
            args.get(Key.TYPE))
        if trac_type is None:
            self.error_response(req, {}, ['Must specify a type.'])

        success, ticket_id, errors = self._create_ticket(req, args)
        if not success:
            self.error_response(req, {}, errors)

        ticket_resource = Resource('ticket')(id=ticket_id)
        if not req.perm.has_permission(Action.TICKET_VIEW, ticket_resource):
            self.error_response(req, {},
                                ['No permission to see ticket %d' % ticket_id])
        return self.get_ticket_as_json(req, ticket_id)
Example #23
0
 def edit_ticket(self, ticket_id, **kwargs):
     if 'time_of_last_change' not in kwargs:
         ticket = AgiloTicket(self.env, ticket_id)
         kwargs['time_of_last_change'] = to_timestamp(ticket.time_changed)
     if 'ts' not in kwargs:
         ticket = AgiloTicket(self.env, ticket_id)
         kwargs['ts'] = str(ticket.time_changed)
     from agilo.ticket import AgiloTicketSystem
     if AgiloTicketSystem.is_trac_1_0():
         from trac.util.datefmt import to_utimestamp
         if 'view_time' not in kwargs:
             ticket = AgiloTicket(self.env, ticket_id)
             kwargs['view_time'] = str(to_utimestamp(ticket.time_changed))
         if 'submit' not in kwargs:
             kwargs['submit'] = True
     return self.server.json.tickets[ticket_id].post(**kwargs)
Example #24
0
 def edit_ticket(self, ticket_id, **kwargs):
     if 'time_of_last_change' not in kwargs:
         ticket = AgiloTicket(self.env, ticket_id)
         kwargs['time_of_last_change'] = to_timestamp(ticket.time_changed)
     if 'ts' not in kwargs:
         ticket = AgiloTicket(self.env, ticket_id)
         kwargs['ts'] = str(ticket.time_changed)
     from agilo.ticket import AgiloTicketSystem
     if AgiloTicketSystem.is_trac_1_0():
         from trac.util.datefmt import to_utimestamp
         if 'view_time' not in kwargs:
             ticket = AgiloTicket(self.env, ticket_id)
             kwargs['view_time'] = str(to_utimestamp(ticket.time_changed))
         if 'submit' not in kwargs:
             kwargs['submit'] = True
     return self.server.json.tickets[ticket_id].post(**kwargs)
Example #25
0
    def allow_link_from_to(self, from_type, to_type, save=None):
        # All tickets instantiated before this call will have a copy
        # of their allowed links, so for this call to have an effect,
        # the objects have to be dropped and recreated.
        config = AgiloConfig(self.env)
        assert from_type in config.get_available_types()
        assert to_type in config.get_available_types()
        section = config.get_section(AgiloConfig.AGILO_LINKS)
        allowed_links = section.get_list('allow')
        allowed_links.append('%s-%s' % (from_type, to_type))
        section.change_option('allow', ', '.join(allowed_links), save=save)

        # Recreate all the worst caches
        links_configuration = LinksConfiguration(self.env)
        links_configuration._initialized = False
        links_configuration.initialize()
        AgiloTicketSystem(self.env).clear_cached_information()
    def _request_for_ticket_change(self, username, **kwargs):
        # We need to load the ticket again to get the correct time of last 
        # change - otherwise trac will reject the edit...
        task = AgiloTicket(self.env, self.task.id)
        args = dict(
            ticket_id=task.id,
            time_of_last_change=to_timestamp(task.time_changed),
            ts=str(task.time_changed),
        )

        from agilo.ticket import AgiloTicketSystem
        if AgiloTicketSystem.is_trac_1_0():
            from trac.util.datefmt import to_utimestamp
            args.update({'view_time':str(to_utimestamp(task.time_changed)),'submit':True})

        args.update(kwargs)
        req = self.teh.mock_request(username, method='POST')
        req.args = args
        return req
    def _request_for_ticket_change(self, username, **kwargs):
        # We need to load the ticket again to get the correct time of last
        # change - otherwise trac will reject the edit...
        task = AgiloTicket(self.env, self.task.id)
        args = dict(
            ticket_id=task.id,
            time_of_last_change=to_timestamp(task.time_changed),
            ts=str(task.time_changed),
        )

        from agilo.ticket import AgiloTicketSystem
        if AgiloTicketSystem.is_trac_1_0():
            from trac.util.datefmt import to_utimestamp
            args.update({
                'view_time': str(to_utimestamp(task.time_changed)),
                'submit': True
            })

        args.update(kwargs)
        req = self.teh.mock_request(username, method='POST')
        req.args = args
        return req
Example #28
0
 def should_be_skipped(self):
     return (not AgiloTicketSystem.is_trac_1_0()) or (self.super())
Example #29
0
 def should_be_skipped(self):
     return (not AgiloTicketSystem.is_trac_1_0()) or (self.super())
Example #30
0
    def reset_db(self, default_data=None):
        from agilo.test.functional.api import EnvironmentBuilder
        env = EnvironmentBuilder.get_testenv(self.env_key)
        from trac.db.api import _parse_db_str
        scheme, db_prop = _parse_db_str(env.get_db_url())

        if scheme != 'sqlite' and not default_data:
            return super(BetterEnvironmentStub, self).reset_db(default_data)

        env_for_transaction = env.get_trac_environment()
        if AgiloTicketSystem.is_trac_1_0():
            env_for_transaction = env

        tables = []
        if scheme != 'sqlite':
            db = self.get_db_cnx()

            @with_transaction(env_for_transaction, db)
            def implementation(db):
                cursor = db.cursor()
                cursor.execute(
                    "update system set value='9999' WHERE name='database_version'"
                )
                db.commit()

            tables = super(BetterEnvironmentStub, self).reset_db(default_data)
        else:
            from trac import db_default
            from trac.db_default import schema
            from trac.db.sqlite_backend import _to_sql

            # our 'destroy_db'
            db = self.get_db_cnx()

            @with_transaction(env_for_transaction, db)
            def implementation(db):
                cursor = db.cursor()
                cursor.execute(
                    "SELECT name FROM sqlite_master WHERE type='table'")
                tables = cursor.fetchall()
                for table in tables:
                    cursor.execute("DROP TABLE %s" % table)

                # part of sqlite_backend's init_db
                for table in schema:
                    for stmt in _to_sql(table):
                        cursor.execute(stmt)

                # part of reset_db
                for table, cols, vals in db_default.get_data(db):
                    cursor.executemany(
                        "INSERT INTO %s (%s) VALUES (%s)" %
                        (table, ','.join(cols), ','.join(['%s'
                                                          for c in cols])),
                        vals)
                db.commit()

        if env.tester.testcase.testtype != 'unittest':
            try:
                env._upgrade_environment()
                env._setup_users_and_permissions()
            except:
                # it's possible that this has already happened
                print "Warning: Exception on post-reset_db tasks"

        return tables
Example #31
0

test.get_dburi = custom_get_dburi


def custom_get_db_cnx(self, destroying=False):
    dbenv = EnvironmentStub.dbenv
    if not dbenv:
        dbenv = EnvironmentStub.dbenv = EnvironmentStub()
        dbenv.config.set('trac', 'database', self.dburi)
        if not destroying:
            self.reset_db()  # make sure we get rid of previous garbage
    return DatabaseManager(dbenv).get_connection()


if not AgiloTicketSystem.is_trac_1_0():
    EnvironmentStub.get_db_cnx = custom_get_db_cnx


def suppressed__del__(self):
    try:
        self.close()
    except:
        # if we got here, it's because the poolable connection was
        # garbage collected from a thread other than the one where it
        # was opened.  this is not trac's fault, but it should handle
        # the situation better
        pass


from trac.db.pool import PooledConnection
Example #32
0
 def is_unknown_status(self, status):
     known_statuses = AgiloTicketSystem(self.env).valid_ticket_statuses()
     known_statuses = known_statuses + TicketStatusManipulator.DEFAULT_SIMPLE_STATUSES
     return not status in known_statuses
Example #33
0
        return original_get_dburi()
    testenv = EnvironmentBuilder.get_testenv(LAST_ENV_KEY)
    return testenv.get_db_url()

test.get_dburi = custom_get_dburi

def custom_get_db_cnx(self, destroying=False):
    dbenv = EnvironmentStub.dbenv
    if not dbenv:
        dbenv = EnvironmentStub.dbenv = EnvironmentStub()
        dbenv.config.set('trac', 'database', self.dburi)
        if not destroying:
            self.reset_db() # make sure we get rid of previous garbage
    return DatabaseManager(dbenv).get_connection()

if not AgiloTicketSystem.is_trac_1_0():
    EnvironmentStub.get_db_cnx = custom_get_db_cnx

def suppressed__del__(self):
    try:
        self.close()
    except:
        # if we got here, it's because the poolable connection was 
        # garbage collected from a thread other than the one where it
        # was opened.  this is not trac's fault, but it should handle
        # the situation better
        pass
    
from trac.db.pool import PooledConnection
PooledConnection.__del__ = suppressed__del__
Example #34
0
    def _append_backlog_item_html_to_string(self,
                                            file_str,
                                            item,
                                            level=1,
                                            parent=None):
        item_id = item.ticket.id
        item_html_id = str(item_id)
        ticket_type = item.ticket.get_type()
        status = item.ticket.values['status']
        owner = item.ticket.values['owner']
        is_container = self.ticket_is_container(item.ticket)
        has_multiple_parents = self.ticket_has_multiple_parents(item.ticket)
        if has_multiple_parents:
            if item_id in self.tickets_with_multiple_parents:
                if parent is not None and self.backlog_values_as_dict.has_key(
                        parent.ticket.id):
                    item_html_id += "-" + str(parent.ticket.id)
            else:
                self.tickets_with_multiple_parents.append(item_id)

        if is_container and level > 1:
            file_str.write('<dd class="childcontainer">')
        if is_container:
            file_str.write('<dl>')
            file_str.write('<dt class="container ')
        else:
            file_str.write('<dd class="leaf ')
        if has_multiple_parents:
            file_str.write('multi-linked-item ')

        html_text = 'handle level-$level ' +\
                       'tickettype-$type '+\
                       'ticketstatus-$status" '+\
                       'id="ticketID-$html_id" '+\
                       'data=\"$data\">'

        html_template = string.Template(html_text)
        data_dict = item.ticket.as_dict()
        if data_dict.has_key('description'):
            del data_dict['description']
        from agilo.ticket import AgiloTicketSystem
        if AgiloTicketSystem.is_trac_1_0():
            from trac.util.datefmt import to_utimestamp
            data_dict.update(
                {'view_time': str(to_utimestamp(item.ticket.time_changed))})

        data_dump = json.dumps(data_dict)

        import trac.util

        file_str.write(
            html_template.substitute({
                'level': level,
                'type': ticket_type,
                'status': status,
                'id': item_id,
                'html_id': item_html_id,
                'owner': owner,
                'ts': str(item.ticket.time_changed),
                'data': trac.util.escape(data_dump)
            }))

        for field in self.column_names:
            if field == 'id':
                ticket_url = ""
                if self.base_url != "" and self.base_url != "/":
                    ticket_url = self.base_url + ticket_url
                ticket_url = ticket_url + "/ticket/%s" % item_id
                file_str.write(
                    '<span class="%s numeric" data="{field:\'%s\'}"><a href="%s">%s</a></span>'
                    % (field, field, ticket_url, item_id))
            else:
                actual_field = field
                if isinstance(field, list):
                    actual_field = field[0]
                    for alternative in field:
                        if alternative in item.fields_for_type or alternative in item.ticket.get_calculated_fields_names(
                        ):
                            actual_field = alternative
                data_field = actual_field
                if actual_field not in item.fields_for_type:
                    data_field = ''
                css_class = actual_field
                if actual_field in item.ticket.get_calculated_fields_names():
                    css_class += " numeric"

                value = item.get(actual_field)

                if value is None:
                    value = ""
                try:
                    file_str.write(
                        '<span class="%s" data="{field:\'%s\'}">%g</span>' %
                        (css_class, data_field, value))
                except TypeError:
                    file_str.write(
                        '<span class="%s" data="{field:\'%s\'}">%s</span>' %
                        (css_class, data_field, value))
        if is_container:
            file_str.write('</dt>')
        else:
            file_str.write('</dd>')
        children = item.ticket.get_outgoing()

        def index_for_item(item):
            if self.backlog_values_as_dict.has_key(item.id):
                return self.backlog_values.index(item)
            else:
                return None

        sorted_children = sorted(children,
                                 key=lambda item: index_for_item(item))

        for child in sorted_children:
            if self.backlog_values_as_dict.has_key(child.id):
                self._append_backlog_item_html_to_string(
                    file_str,
                    self.backlog_values_as_dict[child.id],
                    level=level + 1,
                    parent=item)
        if is_container:
            file_str.write('</dl>')
        if is_container and level > 1:
            file_str.write('</dt>')
Example #35
0
    def _append_backlog_item_html_to_string(self, file_str, item, level=1, parent=None):
        item_id = item.ticket.id
        item_html_id = str(item_id)
        ticket_type = item.ticket.get_type()
        status = item.ticket.values['status']
        owner = item.ticket.values['owner']
        is_container = self.ticket_is_container(item.ticket)
        has_multiple_parents = self.ticket_has_multiple_parents(item.ticket)
        if has_multiple_parents:
            if item_id in self.tickets_with_multiple_parents:
                if parent is not None and self.backlog_values_as_dict.has_key(parent.ticket.id):
                    item_html_id += "-" + str(parent.ticket.id)
            else:
                self.tickets_with_multiple_parents.append(item_id)

        if is_container and level > 1:
            file_str.write('<dd class="childcontainer">')
        if is_container:
            file_str.write('<dl>')
            file_str.write('<dt class="container ')
        else:
            file_str.write('<dd class="leaf ')
        if has_multiple_parents:
            file_str.write('multi-linked-item ')

        html_text = 'handle level-$level ' +\
                       'tickettype-$type '+\
                       'ticketstatus-$status" '+\
                       'id="ticketID-$html_id" '+\
                       'data=\"$data\">'
                            
        html_template = string.Template(html_text)
        data_dict = item.ticket.as_dict()
        if data_dict.has_key('description'):
            del data_dict['description']
        from agilo.ticket import AgiloTicketSystem
        if AgiloTicketSystem.is_trac_1_0():
            from trac.util.datefmt import to_utimestamp
            data_dict.update({'view_time': str(to_utimestamp(item.ticket.time_changed))})

        data_dump = json.dumps(data_dict)

        import trac.util

        file_str.write(html_template.substitute({'level': level,
                                                  'type': ticket_type,
                                                  'status': status,
                                                  'id': item_id,
                                                  'html_id': item_html_id,
                                                  'owner': owner,
                                                  'ts': str(item.ticket.time_changed),
                                                  'data': trac.util.escape(data_dump)
                                                  }))
        
        for field in self.column_names:
            if field == 'id':
                ticket_url = ""
                if self.base_url != "" and self.base_url != "/":
                    ticket_url = self.base_url + ticket_url 
                ticket_url = ticket_url + "/ticket/%s" % item_id
                file_str.write('<span class="%s numeric" data="{field:\'%s\'}"><a href="%s">%s</a></span>' %(field, field, ticket_url, item_id))
            else:
                actual_field = field
                if isinstance(field, list):
                    actual_field = field[0]
                    for alternative in field:
                        if alternative in item.fields_for_type or alternative in item.ticket.get_calculated_fields_names():
                            actual_field = alternative
                data_field = actual_field
                if actual_field not in item.fields_for_type:
                    data_field = ''
                css_class = actual_field
                if actual_field in item.ticket.get_calculated_fields_names():
                    css_class += " numeric"
                
                value = item.get(actual_field)
                        
                if value is None:
                    value = ""
                try:
                    file_str.write('<span class="%s" data="{field:\'%s\'}">%g</span>' %(css_class, data_field, value))
                except TypeError:
                    file_str.write('<span class="%s" data="{field:\'%s\'}">%s</span>' %(css_class, data_field, value))
        if is_container:
            file_str.write('</dt>')
        else:
            file_str.write('</dd>')
        children = item.ticket.get_outgoing()
        
        def index_for_item(item):
            if self.backlog_values_as_dict.has_key(item.id):
                return self.backlog_values.index(item)
            else:
                return None
            
        sorted_children = sorted(children, key=lambda item: index_for_item(item))
        
        for child in sorted_children:
            if self.backlog_values_as_dict.has_key(child.id):
                self._append_backlog_item_html_to_string(file_str, self.backlog_values_as_dict[child.id], level = level+1, parent=item)
        if is_container:
            file_str.write('</dl>')
        if is_container and level > 1:
            file_str.write('</dt>')
Example #36
0
 def _configured_fields(self):
     for field in AgiloTicketSystem(self.env).get_ticket_fields():
         field_name = field['name']
         del field['name']
         yield field_name, field