def import_version_data(self, template_path):
        """
        Import system version data from the info.json file. Note that only white 
        listed data will not be imported, but that the entire system table is 
        exported for traceability."""

        template_name = os.path.basename(os.path.normpath(template_path))
        template_info = ProjectTemplateAPI(self.env).get_template_information(template_name)

        # some old test/staging templates won't have version data
        version_data = template_info.get('versions')
        system_verson_to_import = dict((n, v) for n, v in version_data.iteritems() 
                                        if n in self.system_version_white_list)

        @self.env.with_transaction()
        def update_system_table(db):
            """
            No Trac API for this, so we have to use raw SQL queries."""

            self.log.info("Inserting template version data into system table")
            cursor = db.cursor()
            for name, value in system_verson_to_import.iteritems():
                cursor.execute("""UPDATE system SET value = %s 
                                  WHERE name = %s""", (value, name))

        json_version = version_data.get('json_latest_version')
        type_config_version = version_data.get('type_config_version')

        if json_version and type_config_version:
            # we also need to update the config file to ensure the necessary 
            # upgrade scripts will then be executed to transform the data
            self.env.config.set("logica workflows", "json_version", json_version)
            self.env.config.set("logica workflows", "type_config_version",
                            type_config_version)
            self.env.config.save()
    def filter_stream(self, req, method, filename, stream, data):
        """This is a filter stream for the project request ticket type 
        on the dashboard project. 

        We examine the filter stream and look to find the Project Template
        text input markup. We then replace this with a select list, and generate
        the values using the API get_all_templates() method. 

        We don't have these options in the trac.ini file as they are dynamic, 
        and don't use a select list by default as this will cause validation
        issues."""

        try:
            ticket_type = data['ticket']['type']
        except KeyError:
            ticket_type = None

        if (filename == 'ticket.html' 
            and ticket_type == 'projectrequest'
            and self.env.is_component_enabled('define.dashboard.DashboardDisplayModule')):

            # get a list of available templates
            templates = ProjectTemplateAPI(self.env).get_all_templates()
            # we need a None option for the default
            templates.insert(0, 'None')

            # generate the select list markup
            select = tag.select(name='field_template')
            for template in templates:
                if template == 'None':
                    select.append(tag.option(template, value=template, selected='selected'))
                else:
                    select.append(tag.option(template, value=template))

            # replace the text input with a select list
            stream = stream | Transformer("//*[@id='field-template']").replace(select)

        return stream
    def render_admin_panel(self, req, category, page, path_info):
        if page == 'create_template':

            # we always need to load JS regardless of POST or GET
            add_script(req, 'createtemplate/js/create_template_admin.js')

            # we also need to let JS know what templates currently exist
            # so we can validate client side
            template_api = ProjectTemplateAPI(self.env)
            all_templates = template_api.get_all_templates()
            add_script_data(req, { 'usedNames':all_templates })

            # find templates for this project and place them into data dict
            # as a list of dicts so we can display on page
            templates = []
            for template in all_templates:
                template_data = template_api.get_template_information(template)
                if template_data.get('project') == self.env.project_name:
                    templates.append(template_data)

            # sort template order based on created date
            templates = sorted(templates, key=itemgetter('created'))

            data = {
                    'name': self.env.project_name, 
                    'templates': templates
                    }

            # Send all available options to the template
            data['tpl_components'] = (("wiki", "Wiki pages and attachments"),
                                      ("ticket", "Ticket types, workflows, "
                                                 "custom fields, components, "
                                                 "priorities and versions"),
                                      ("archive", "Archive folder structure"),
                                      ("milestone", "Milestones"),
                                      ("list", "Mailing lists"),
                                      ("group", "Groups and permissions"))

            if req.method == 'POST':

                template_name = req.args.get('template_name')

                # server side check that there is a template name
                # there is jquery validation server side too
                if not template_name:
                    add_notice(req, "Please enter a template name")
                    return 'template_admin.html', data

                # check the template name input so its alphanumeric seperated by hyphens
                # we don't allow special characters etc
                complied_regex = re.compile(RemoteTicketSystem.PROJECTID_RE)
                if not complied_regex.match(template_name):
                    add_warning(req, "Please enter a different template name. "
                                "It should only include alphanumeric characters "
                                "and hypens. Special characters and spaces are "
                                "not allowed.")
                    return 'template_admin.html', data

                # if there is already a template with the same name we prompt user for an alternative
                # we can catch this on client side with JS too
                template_path = os.path.join(self.template_dir_path, template_name)
                try:
                    os.mkdir(template_path)
                    self.log.debug("Created directory for project template at", template_path)
                except OSError as exception:
                    if exception.errno == errno.EEXIST:
                        data.update({'failure':True,
                                     'template_name':template_name,
                                    })
                        return 'template_admin.html', data
                    raise

                # so far so good
                # we now call functions which create the XML template files
                # and append that data to a data dict we return to the template
                if 'template_components' in req.args:
                    options = req.args['template_components']

                    if 'wiki' in options:
                        data['wiki_pages'] = self.export_wiki_pages(template_path)
                        data['attachments'] = self.export_wiki_attachments(req, template_name)
                    if 'ticket' in options:
                        data['ticket_types'] = self.export_ticket_types(template_path)
                        data['workflows'] = self.export_workflows(req, template_path)
                        # we export priority, version and components if we export tickets
                        data['priority'] = self.export_priorites(template_path)
                        data['versions'] = self.export_versions(template_path)
                        data['components'] = self.export_components(template_path)
                    if 'archive' in options:
                        data['repos'] = self.export_file_archive(req, os.path.join(template_path, template_name + '.dump.gz'))
                    if 'group' in options:
                        # we import the group perms as part of the group export
                        data['groups'] = self.export_groups_and_permissions(template_path)
                    if 'list' in options:
                        data['lists'] = self.export_mailinglists(template_path)
                    if 'milestone' in options:
                        data['milestones'] = self.export_milestones(template_path)

                # create an info file to store the exact time of template
                # creation, username of template creator etc.
                self.create_template_info_file(req, template_name, template_path)

                data.update({'success':True,
                             'template_name':template_name,
                             })

                # we also need to add the new template to the list 
                # of templates we have for this project
                templates.append(template_api.get_template_information(template_name))

            return 'template_admin.html', data