def __init__(self):
     MigrateBase.__init__(self)
     self.id = __name__.split('.')[-1]
     self.description = self.__doc__
     self.icon_dir = conf.get('multiproject-projects', 'icon_dir')
     self.projects_dir = conf.get('multiproject', 'sys_projects_root')
     self.content_types = {
         'image/png': 'png',
         'image/x-png': 'png',
         'image/bmp': 'bmp',
         'image/tiff': 'tiff',
         'image/pjpeg': 'jpeg',
         'image/jpeg': 'jpeg',
         'image/jpg': 'jpeg',
         'image/gif': 'gif',
         'image/xml+svg': 'svg',
         'image/svg+xml': 'svg',
         'image/x-icon': 'ico',
         'application/octet-stream': 'ext'
     }
     # Parse option value using custom Trac option: DimensionOption
     value = conf.get('multiproject-projects', 'icon_size', '64x64')
     # TODO: Find proper way to read config values outside of component
     self.icon_size = DimensionOption(
         section='multiproject-projects',
         name='icon_size')._parse_dimension(value)
Example #2
0
    def icon_url(self):
        """
        Returns the URL path to project icon, or default if not set
        :return: Path of the icon URL
        """
        # Load default icon URL from configuration
        icon_url = conf.get('multiproject-projects', 'icon_default_url', '')

        # If project has icon set, show it instead
        if self.icon_name:
            icon_url = Href(conf.get('multiproject-projects', 'icon_url', ''))(self.icon_name)

        return icon_url
Example #3
0
    def icon_url(self):
        """
        Returns the URL path to project icon, or default if not set
        :return: Path of the icon URL
        """
        # Load default icon URL from configuration
        icon_url = conf.get('multiproject-projects', 'icon_default_url', '')

        # If project has icon set, show it instead
        if self.icon_name:
            icon_url = Href(conf.get('multiproject-projects', 'icon_url',
                                     ''))(self.icon_name)

        return icon_url
 def __init__(self):
     MigrateBase.__init__(self)
     self.id = __name__.split(".")[-1]
     self.description = self.__doc__
     self.icon_dir = conf.get("multiproject-projects", "icon_dir")
     self.projects_dir = conf.get("multiproject", "sys_projects_root")
     self.content_types = {
         "image/png": "png",
         "image/x-png": "png",
         "image/bmp": "bmp",
         "image/tiff": "tiff",
         "image/pjpeg": "jpeg",
         "image/jpeg": "jpeg",
         "image/jpg": "jpeg",
         "image/gif": "gif",
         "image/xml+svg": "svg",
         "image/svg+xml": "svg",
         "image/x-icon": "ico",
         "application/octet-stream": "ext",
     }
     # Parse option value using custom Trac option: DimensionOption
     value = conf.get("multiproject-projects", "icon_size", "64x64")
     # TODO: Find proper way to read config values outside of component
     self.icon_size = DimensionOption(section="multiproject-projects", name="icon_size")._parse_dimension(value)
    def upgrade(self):
        """
        Run DB upgrade steps
        """
        if self.applied():
            return True

        if self.icon_dir:
            # Create if not existing
            if not os.path.exists(self.icon_dir):
                try:
                    os.makedirs(self.icon_dir)
                except EnvironmentError:
                    self.printerr('Failed to create directory %s, giving up' %
                                  self.icon_dir)
                    return

            # Check writable
            if not os.access(self.icon_dir, os.W_OK):
                self.printerr('Cannot write to directory %s, giving up' %
                              self.icon_dir)
                return

        # Load default icon
        sql_default_icon = 'SELECT icon_data, content_type FROM project_icon WHERE icon_id = %s'
        with admin_query(cursors.DictCursor) as cursor:
            default_icon_id = conf.get('multiproject', 'default_icon_id', '0')
            cursor.execute(sql_default_icon, int(default_icon_id))
            row = cursor.fetchone()
            if row:
                image_path = os.path.join(
                    self.icon_dir or '/tmp',
                    'default.%s' % self.content_types[row['content_type']])
                self._save_image(row['icon_data'], image_path)
                self.printout('Saved default image: %s' % image_path)
                self.printwarn('Set icon_default_url = <url> in configuration',
                               'TODO')

        # Load each project icon data and dump them to filesystem
        sql_projects = '''
        SELECT p.project_id AS id, p.icon_id, i.icon_data, i.content_type, te.identifier
        FROM projects AS p
        LEFT JOIN project_icon AS i ON i.icon_id = p.icon_id
        LEFT JOIN trac_environment AS te ON te.environment_id = p.trac_environment_key
        WHERE i.icon_id IS NOT NULL
        '''
        project_icons = {}

        with admin_query(cursors.DictCursor) as cursor:
            cursor.execute(sql_projects)
            for row in cursor.fetchall():
                try:
                    hash = md5()
                    hash.update(row['icon_data'])
                    image_name = '%s-%s.%s' % (row['id'], hash.hexdigest(
                    ), self.content_types[row['content_type']])
                    image_path = os.path.join(self.projects_dir,
                                              row['identifier'], 'htdocs',
                                              image_name)

                    # Use custom icon dir if set
                    if self.icon_dir:
                        image_path = os.path.join(self.icon_dir, image_name)

                    try:
                        self._save_image(row['icon_data'], image_path)
                        self.printout('Save project image: %s' % image_path)
                    except IOError, err:
                        self.printwarn(
                            'Failed to save image: %s. Dumping the file as is: %s'
                            % (err, image_path))

                        with open(image_path, 'w+b') as fd:
                            try:
                                fd.write(row['icon_data'])
                            except IOError:
                                self.printerr(
                                    'Failed to write the file: %s. Please fix before continue'
                                    % image_path)
                                return

                    project_icons[row['id']] = image_name

                except KeyError:
                    self.printerr(
                        'Unsupported image format: %s. Please fix before continue'
                        % row['content_type'])
                    return
    def upgrade(self):
        """
        Run DB upgrade steps
        """
        if self.applied():
            return True

        if self.icon_dir:
            # Create if not existing
            if not os.path.exists(self.icon_dir):
                try:
                    os.makedirs(self.icon_dir)
                except EnvironmentError:
                    self.printerr("Failed to create directory %s, giving up" % self.icon_dir)
                    return

            # Check writable
            if not os.access(self.icon_dir, os.W_OK):
                self.printerr("Cannot write to directory %s, giving up" % self.icon_dir)
                return

        # Load default icon
        sql_default_icon = "SELECT icon_data, content_type FROM project_icon WHERE icon_id = %s"
        with admin_query(cursors.DictCursor) as cursor:
            default_icon_id = conf.get("multiproject", "default_icon_id", "0")
            cursor.execute(sql_default_icon, int(default_icon_id))
            row = cursor.fetchone()
            if row:
                image_path = os.path.join(
                    self.icon_dir or "/tmp", "default.%s" % self.content_types[row["content_type"]]
                )
                self._save_image(row["icon_data"], image_path)
                self.printout("Saved default image: %s" % image_path)
                self.printwarn("Set icon_default_url = <url> in configuration", "TODO")

        # Load each project icon data and dump them to filesystem
        sql_projects = """
        SELECT p.project_id AS id, p.icon_id, i.icon_data, i.content_type, te.identifier
        FROM projects AS p
        LEFT JOIN project_icon AS i ON i.icon_id = p.icon_id
        LEFT JOIN trac_environment AS te ON te.environment_id = p.trac_environment_key
        WHERE i.icon_id IS NOT NULL
        """
        project_icons = {}

        with admin_query(cursors.DictCursor) as cursor:
            cursor.execute(sql_projects)
            for row in cursor.fetchall():
                try:
                    hash = md5()
                    hash.update(row["icon_data"])
                    image_name = "%s-%s.%s" % (row["id"], hash.hexdigest(), self.content_types[row["content_type"]])
                    image_path = os.path.join(self.projects_dir, row["identifier"], "htdocs", image_name)

                    # Use custom icon dir if set
                    if self.icon_dir:
                        image_path = os.path.join(self.icon_dir, image_name)

                    try:
                        self._save_image(row["icon_data"], image_path)
                        self.printout("Save project image: %s" % image_path)
                    except IOError, err:
                        self.printwarn("Failed to save image: %s. Dumping the file as is: %s" % (err, image_path))

                        with open(image_path, "w+b") as fd:
                            try:
                                fd.write(row["icon_data"])
                            except IOError:
                                self.printerr("Failed to write the file: %s. Please fix before continue" % image_path)
                                return

                    project_icons[row["id"]] = image_name

                except KeyError:
                    self.printerr("Unsupported image format: %s. Please fix before continue" % row["content_type"])
                    return