Example #1
0
class ScreenshotsInit(Component):
    """
       Init component initialises database and environment for screenshots
       plugin.
    """
    implements(IEnvironmentSetupParticipant)

    # Configuration options.
    path = PathOption('screenshots', 'path', '../screenshots',
      doc = _("Path where to store uploaded screenshots."))

    # IEnvironmentSetupParticipanttr
    def environment_created(self):
        pass

    def environment_needs_upgrade(self, db):
        cursor = db.cursor()

        # Is database up to date?
        return (self._get_db_version(cursor) != last_db_version) or not \
          os.path.isdir(self.path)

    def upgrade_environment(self, db):
        cursor = db.cursor()

        # Create screenshots directory if not exists.
        if not os.path.isdir(self.path):
            os.mkdir(os.path.normpath(self.path))

        # Get current database schema version
        db_version = self._get_db_version(cursor)

        # Is this clean installation?
        if db_version == 0:
            # Perform single upgrade.
            module = __import__('tracscreenshots.db.db%s' % (last_db_version),
              globals(), locals(), ['do_upgrade'])
            module.do_upgrade(self.env, cursor, False)
        else:
            # Perform incremental upgrades
            for I in range(db_version + 1, last_db_version + 1):
                script_name  = 'db%i' % (I)
                module = __import__('tracscreenshots.db.%s' % (script_name),
                  globals(), locals(), ['do_upgrade'])
                module.do_upgrade(self.env, cursor, True)

    def _get_db_version(self, cursor):
        try:
            sql = ("""SELECT value
                      FROM system
                      WHERE name='screenshots_version'""")
            self.log.debug(sql)
            cursor.execute(sql)
            for row in cursor:
                return int(row[0])
            return 0
        except:
            return 0
Example #2
0
 def get_screenshots_view(req):
     yield ('matrix', _("Matrix View"))
Example #3
0
 def get_timeline_filters(self, req):
     if 'SCREENSHOTS_VIEW' in req.perm:
         yield ('screenshots', _("Screenshots changes"))
Example #4
0
class ScreenshotsWiki(Component):
    """
        The wiki module implements macro for screenshots referencing.
    """
    implements(IWikiSyntaxProvider, IWikiMacroProvider)

    # Configuration options.
    default_description = Option(
        'screenshots',
        'default_description',
        '$description',
        doc=_("Template for embended image description."))
    default_list_item = Option(
        'screenshots',
        'default_list_item', '$id - '
        '$name - $description',
        doc=_("Default format of list item "
              "description of ![[ScreenshotsList()]] macro."))

    def __init__(self):
        self.screenshot_macro_doc = _("""Allows embed screenshot image in
wiki page. First mandatory argument is ID of the screenshot. Number or
image attributes can be specified next:

 * {{{align}}} - Specifies image alignment in wiki page. Possible values are:
   {{{left}}}, {{{right}}} and {{{center}}}.
 * {{{alt}}} - Alternative description of image.
 * {{{border}}} - Sets image border of specified width in pixels.
 * {{{class}}} - Class of image for CSS styling.
 * {{{description}}} - Brief description under the image. Accepts several
   variables (see bellow).
 * {{{format}}} - Format of returned image or screenshot behind link.
 * {{{height}}} - Height of image. Set to 0 if you want original image height.
 * {{{id}}} - ID of image for CSS styling.
 * {{{longdesc}}} - Detailed description of image.
 * {{{title}}} - Title of image.
 * {{{usemap}}} - Image map for clickable images.
 * {{{width}}} - Width of image. Set to 0 if you want original image width.

Attribute {{{description}}} displays several variables:

 * {{{$id}}} - ID of image.
 * {{{$name}}} - Name of image.
 * {{{$author}}} - User name who uploaded image.
 * {{{$time}}} - Time when image was uploaded.
 * {{{$file}}} - File name of image.
 * {{{$description}}} - Detailed description of image.
 * {{{$width}}} - Original width of image.
 * {{{$height}}} - Original height of image.
 * {{{$tags}}} - Comma separated list of screenshot tags.
 * {{{$components}}} - Comma separated list of screenshot components.
 * {{{$versions}}} - Comma separated list of screenshot versions.

Example:

{{{
 [[Screenshot(2,width=400,height=300,description=The $name by $author: $description,align=left)]]
}}}""")

        self.screenshots_list_macro_doc = _("""Displays list of all available
screenshots on wiki page. Accepts one argument which is template for
list items formatting. Possible variables in this template are:

 * {{{$id}}} - ID of image.
 * {{{$name}}} - Name of image.
 * {{{$author}}} - User name who uploaded image.
 * {{{$time}}} - Time when image was uploaded.
 * {{{$file}}} - File name of image.
 * {{{$description}}} - Detailed description of image.
 * {{{$width}}} - Original width of image.
 * {{{$height}}} - Original height of image.
 * {{{$tags}}} - Comma separated list of screenshot tags.
 * {{{$components}}} - Comma separated list of screenshot components.
 * {{{$versions}}} - Comma separated list of screenshot versions.

Example:

{{{
 [[ScreenshotsList($name - $description ($widthx$height))]]
}}}""")

        # [screenshot:<id>] macro id regular expression.
        self.id_re = re.compile('^(\d+)($|.+$)')

        # [[Screenshot()]] macro attributes regular expression.
        self.attributes_re = re.compile(
            '(align|alt|border|class|description|'
            'format|height|id|longdesc|title|usemap|width)=(.*)')

    # IWikiSyntaxProvider

    def get_link_resolvers(self):
        yield ('screenshot', self._screenshot_link)

    def get_wiki_syntax(self):
        return []

    # IWikiMacroProvider

    def get_macros(self):
        yield 'Screenshot'
        yield 'ScreenshotsList'

    def get_macro_description(self, name):
        if name == 'Screenshot':
            return self.screenshot_macro_doc
        elif name == 'ScreenshotsList':
            return self.screenshots_list_macro_doc

    def expand_macro(self, formatter, name, content):

        # Create request context.
        context = Context.from_request(formatter.req)('screenshots-wiki')

        # Get database access.
        db = self.env.get_db_cnx()
        context.cursor = db.cursor()

        # Get API component.
        api = self.env[ScreenshotsApi]

        if name == 'Screenshot':
            # Check permission.
            if not formatter.req.perm.has_permission('SCREENSHOTS_VIEW'):
                return html.div(_("No permissions to see screenshots."),
                                class_='system-message')

            # Get macro arguments.
            arguments = content.split(',')

            # Get screenshot ID.
            try:
                screenshot_id = int(arguments[0])
            except:
                raise TracError(_("Missing screenshot ID in macro arguments."))

            # Try to get screenshots of that ID.
            screenshot = api.get_screenshot(context, screenshot_id)

            # Build and return macro content.
            if screenshot:
                # Set default values of image attributes.
                attributes = {
                    'align': 'none',
                    'border': '1',
                    'format': 'raw',
                    'alt': screenshot['description'],
                    'description': self.default_description
                }

                # Fill attributes from macro arguments.
                for argument in arguments[1:]:
                    argument = argument.strip()
                    match = self.attributes_re.match(argument)
                    if match:
                        attributes[str(match.group(1))] = match.group(2)

                # Zero width or height means keep original.
                if attributes.has_key('width'):
                    if attributes['width'] == 0:
                        attributes['width'] = screenshot['width']
                if attributes.has_key('height'):
                    if attributes['height'] == 0:
                        attributes['height'] = screenshot['height']

                # If one dimension is missing compute second to keep aspect.
                if not attributes.has_key('width') and \
                  attributes.has_key('height'):
                    attributes['width'] = int(
                        int(attributes['height']) *
                        (float(screenshot['width']) /
                         float(screenshot['height'])) + 0.5)
                if not attributes.has_key('height') and \
                  attributes.has_key('width'):
                    attributes['height'] = int(
                        int(attributes['width']) *
                        (float(screenshot['height']) /
                         float(screenshot['width'])) + 0.5)

                # If both dimensions are missing keep original.
                if not attributes.has_key('width') and not \
                  attributes.has_key('height'):
                    attributes['width'] = screenshot['width']
                    attributes['height'] = screenshot['height']

                self.log.debug('attributes: %s' % (attributes, ))

                # Format screenshot description from template.
                attributes['description'] = self._format_description(
                    context, attributes['description'], screenshot)

                # Make copy of attributes for image tag.
                img_attributes = {}
                for attribute in attributes.keys():
                    if attribute not in ('align', 'border', 'description',
                                         'format', 'width', 'height'):
                        img_attributes[attribute] = attributes[attribute]

                # Add CSS for image.
                add_stylesheet(formatter.req,
                               'screenshots/css/screenshots.css')

                # Build screenshot image and/or screenshot link.
                image = html.img(src=formatter.req.href.screenshots(
                    screenshot['id'],
                    format='raw',
                    width=attributes['width'],
                    height=attributes['height']),
                                 **img_attributes)
                link = html.a(image,
                              href=formatter.req.href.screenshots(
                                  screenshot['id'],
                                  format=attributes['format']),
                              title=screenshot['description'],
                              style='border-width: %spx;' %
                              (attributes['border'], ))
                width_and_border = int(attributes['width']) + 2 * \
                  int(attributes['border'])
                description = html.span(attributes['description'],
                                        class_='description',
                                        style="width: %spx;" %
                                        (width_and_border, ))
                auxilary = html.span(link,
                                     description,
                                     class_='aux',
                                     style="width: %spx;" %
                                     (width_and_border, ))
                thumbnail_class = 'thumbnail' + (
                    (attributes['align'] == 'left') and '-left' or
                    (attributes['align'] == 'right') and '-right' or '')
                thumbnail = html.span(auxilary, class_=thumbnail_class)
                return thumbnail
            else:
                return html.a(screenshot_id,
                              href=formatter.req.href.screenshots(),
                              title=content,
                              class_='missing')

        elif name == 'ScreenshotsList':
            # Check permission.
            if not formatter.req.perm.has_permission('SCREENSHOTS_VIEW'):
                return html.div(_("No permissions to see screenshots."),
                                class_='system-message')

            # Get desired list item description
            list_item_description = content or self.default_list_item

            # Get all screenshots.
            screenshots = api.get_screenshots_complete(context)

            # Create and return HTML list of screenshots.
            list_items = []
            for screenshot in screenshots:
                list_item = self._format_description(context,
                                                     list_item_description,
                                                     screenshot)
                list_items.append(
                    html.li(
                        html.a(list_item,
                               href=formatter.req.href.screenshots(
                                   screenshot['id']))))
            return html.ul(list_items)

    # Internal functions

    def _screenshot_link(self, formatter, ns, params, label):
        if ns == 'screenshot':
            # Get screenshot ID and link arguments from macro.
            match = self.id_re.match(params)
            if match:
                screenshot_id = int(match.group(1))
                arguments = match.group(2)
            else:
                # Bad format of link.
                return html.a(label,
                              href=formatter.href.screenshots(),
                              title=params,
                              class_='missing')

            # Create request context.
            context = Context.from_request(formatter.req)('screenshots-wiki')

            # Get database access.
            db = self.env.get_db_cnx()
            context.cursor = db.cursor()

            # Get API component.
            api = self.env[ScreenshotsApi]

            # Try to get screenshots of that ID.
            screenshot = api.get_screenshot(context, screenshot_id)

            # Return macro content
            if screenshot:
                return html.a(
                    label,
                    href=formatter.href.screenshots(screenshot['id']) +
                    arguments,
                    title=screenshot['description'])
            else:
                return html.a(screenshot_id,
                              href=formatter.href.screenshots(),
                              title=params,
                              class_='missing')

    def _format_description(self, context, template, screenshot):
        description = template.replace('$id', to_unicode(screenshot['id']))
        description = description.replace('$name', screenshot['name'])
        description = description.replace('$file',
                                          to_unicode(screenshot['file']))
        description = description.replace(
            '$time', format_datetime(to_datetime(screenshot['time'], utc)))
        description = description.replace('$author', screenshot['author'])
        description = description.replace('$description',
                                          screenshot['description'])
        description = description.replace('$width',
                                          to_unicode(screenshot['width']))
        description = description.replace('$height',
                                          to_unicode(screenshot['height']))
        description = description.replace('$tags',
                                          to_unicode(screenshot['tags']))
        description = description.replace('$components',
                                          ', '.join(screenshot['components']))
        description = description.replace('$versions',
                                          ', '.join(screenshot['versions']))

        return format_to_oneliner(self.env, context, description)
Example #5
0
    def __init__(self):
        self.screenshot_macro_doc = _("""Allows embed screenshot image in
wiki page. First mandatory argument is ID of the screenshot. Number or
image attributes can be specified next:

 * {{{align}}} - Specifies image alignment in wiki page. Possible values are:
   {{{left}}}, {{{right}}} and {{{center}}}.
 * {{{alt}}} - Alternative description of image.
 * {{{border}}} - Sets image border of specified width in pixels.
 * {{{class}}} - Class of image for CSS styling.
 * {{{description}}} - Brief description under the image. Accepts several
   variables (see bellow).
 * {{{format}}} - Format of returned image or screenshot behind link.
 * {{{height}}} - Height of image. Set to 0 if you want original image height.
 * {{{id}}} - ID of image for CSS styling.
 * {{{longdesc}}} - Detailed description of image.
 * {{{title}}} - Title of image.
 * {{{usemap}}} - Image map for clickable images.
 * {{{width}}} - Width of image. Set to 0 if you want original image width.

Attribute {{{description}}} displays several variables:

 * {{{$id}}} - ID of image.
 * {{{$name}}} - Name of image.
 * {{{$author}}} - User name who uploaded image.
 * {{{$time}}} - Time when image was uploaded.
 * {{{$file}}} - File name of image.
 * {{{$description}}} - Detailed description of image.
 * {{{$width}}} - Original width of image.
 * {{{$height}}} - Original height of image.
 * {{{$tags}}} - Comma separated list of screenshot tags.
 * {{{$components}}} - Comma separated list of screenshot components.
 * {{{$versions}}} - Comma separated list of screenshot versions.

Example:

{{{
 [[Screenshot(2,width=400,height=300,description=The $name by $author: $description,align=left)]]
}}}""")

        self.screenshots_list_macro_doc = _("""Displays list of all available
screenshots on wiki page. Accepts one argument which is template for
list items formatting. Possible variables in this template are:

 * {{{$id}}} - ID of image.
 * {{{$name}}} - Name of image.
 * {{{$author}}} - User name who uploaded image.
 * {{{$time}}} - Time when image was uploaded.
 * {{{$file}}} - File name of image.
 * {{{$description}}} - Detailed description of image.
 * {{{$width}}} - Original width of image.
 * {{{$height}}} - Original height of image.
 * {{{$tags}}} - Comma separated list of screenshot tags.
 * {{{$components}}} - Comma separated list of screenshot components.
 * {{{$versions}}} - Comma separated list of screenshot versions.

Example:

{{{
 [[ScreenshotsList($name - $description ($widthx$height))]]
}}}""")

        # [screenshot:<id>] macro id regular expression.
        self.id_re = re.compile('^(\d+)($|.+$)')

        # [[Screenshot()]] macro attributes regular expression.
        self.attributes_re = re.compile(
            '(align|alt|border|class|description|'
            'format|height|id|longdesc|title|usemap|width)=(.*)')
Example #6
0
 def get_timeline_filters(self, req):
     if 'SCREENSHOTS_VIEW' in req.perm:
         yield ('screenshots', _("Screenshots changes"))
Example #7
0
    def expand_macro(self, formatter, name, content):

        # Create request context.
        context = Context.from_request(formatter.req)('screenshots-wiki')

        # Get database access.
        db = self.env.get_db_cnx()
        context.cursor = db.cursor()

        # Get API component.
        api = self.env[ScreenshotsApi]

        if name == 'Screenshot':
            # Check permission.
            if not formatter.req.perm.has_permission('SCREENSHOTS_VIEW'):
                return html.div(_("No permissions to see screenshots."),
                                class_='system-message')

            # Get macro arguments.
            arguments = content.split(',')

            # Get screenshot ID.
            try:
                screenshot_id = int(arguments[0])
            except:
                raise TracError(_("Missing screenshot ID in macro arguments."))

            # Try to get screenshots of that ID.
            screenshot = api.get_screenshot(context, screenshot_id)

            # Build and return macro content.
            if screenshot:
                # Set default values of image attributes.
                attributes = {
                    'align': 'none',
                    'border': '1',
                    'format': 'raw',
                    'alt': screenshot['description'],
                    'description': self.default_description
                }

                # Fill attributes from macro arguments.
                for argument in arguments[1:]:
                    argument = argument.strip()
                    match = self.attributes_re.match(argument)
                    if match:
                        attributes[str(match.group(1))] = match.group(2)

                # Zero width or height means keep original.
                if attributes.has_key('width'):
                    if attributes['width'] == 0:
                        attributes['width'] = screenshot['width']
                if attributes.has_key('height'):
                    if attributes['height'] == 0:
                        attributes['height'] = screenshot['height']

                # If one dimension is missing compute second to keep aspect.
                if not attributes.has_key('width') and \
                  attributes.has_key('height'):
                    attributes['width'] = int(
                        int(attributes['height']) *
                        (float(screenshot['width']) /
                         float(screenshot['height'])) + 0.5)
                if not attributes.has_key('height') and \
                  attributes.has_key('width'):
                    attributes['height'] = int(
                        int(attributes['width']) *
                        (float(screenshot['height']) /
                         float(screenshot['width'])) + 0.5)

                # If both dimensions are missing keep original.
                if not attributes.has_key('width') and not \
                  attributes.has_key('height'):
                    attributes['width'] = screenshot['width']
                    attributes['height'] = screenshot['height']

                self.log.debug('attributes: %s' % (attributes, ))

                # Format screenshot description from template.
                attributes['description'] = self._format_description(
                    context, attributes['description'], screenshot)

                # Make copy of attributes for image tag.
                img_attributes = {}
                for attribute in attributes.keys():
                    if attribute not in ('align', 'border', 'description',
                                         'format', 'width', 'height'):
                        img_attributes[attribute] = attributes[attribute]

                # Add CSS for image.
                add_stylesheet(formatter.req,
                               'screenshots/css/screenshots.css')

                # Build screenshot image and/or screenshot link.
                image = html.img(src=formatter.req.href.screenshots(
                    screenshot['id'],
                    format='raw',
                    width=attributes['width'],
                    height=attributes['height']),
                                 **img_attributes)
                link = html.a(image,
                              href=formatter.req.href.screenshots(
                                  screenshot['id'],
                                  format=attributes['format']),
                              title=screenshot['description'],
                              style='border-width: %spx;' %
                              (attributes['border'], ))
                width_and_border = int(attributes['width']) + 2 * \
                  int(attributes['border'])
                description = html.span(attributes['description'],
                                        class_='description',
                                        style="width: %spx;" %
                                        (width_and_border, ))
                auxilary = html.span(link,
                                     description,
                                     class_='aux',
                                     style="width: %spx;" %
                                     (width_and_border, ))
                thumbnail_class = 'thumbnail' + (
                    (attributes['align'] == 'left') and '-left' or
                    (attributes['align'] == 'right') and '-right' or '')
                thumbnail = html.span(auxilary, class_=thumbnail_class)
                return thumbnail
            else:
                return html.a(screenshot_id,
                              href=formatter.req.href.screenshots(),
                              title=content,
                              class_='missing')

        elif name == 'ScreenshotsList':
            # Check permission.
            if not formatter.req.perm.has_permission('SCREENSHOTS_VIEW'):
                return html.div(_("No permissions to see screenshots."),
                                class_='system-message')

            # Get desired list item description
            list_item_description = content or self.default_list_item

            # Get all screenshots.
            screenshots = api.get_screenshots_complete(context)

            # Create and return HTML list of screenshots.
            list_items = []
            for screenshot in screenshots:
                list_item = self._format_description(context,
                                                     list_item_description,
                                                     screenshot)
                list_items.append(
                    html.li(
                        html.a(list_item,
                               href=formatter.req.href.screenshots(
                                   screenshot['id']))))
            return html.ul(list_items)
Example #8
0
class ScreenshotsTags(Component):
    """
        The tags module implements plugin's ability to create tags related
        to screenshots.
    """
    implements(IScreenshotChangeListener)

    # Configuration options.
    additional_tags = ListOption(
        'screenshots',
        'additional_tags',
        'author,components,versions,name',
        doc=_(
            "Additional tags that will be "
            "created for submitted screenshots. Possible values are: author, "
            "components, versions, name, description."))

    # IScreenshotChangeListener methods.

    def screenshot_created(self, req, screenshot):
        # Create temporary resource.
        resource = Resource('screenshots', to_unicode(screenshot['id']))

        # Delete tags of screenshot with same ID for sure.
        tag_system = TagSystem(self.env)
        tag_system.delete_tags(req, resource)

        # Add tags of new screenshot.
        new_tags = self._get_tags(screenshot)
        tag_system.add_tags(req, resource, new_tags)

    def screenshot_changed(self, req, screenshot, old_screenshot):
        # Update old screenshot with new values.
        old_screenshot.update(screenshot)

        # Create temporary resource.
        resource = Resource('screenshots', to_unicode(old_screenshot['id']))

        # Delete old tags.
        tag_system = TagSystem(self.env)
        tag_system.delete_tags(req, resource)

        # Add new ones.
        new_tags = self._get_tags(old_screenshot)
        tag_system.add_tags(req, resource, new_tags)

    def screenshot_deleted(self, req, screenshot):
        # Create temporary resource.
        resource = Resource('screenshots', to_unicode(screenshot['id']))

        # Delete tags of screenshot.
        tag_system = TagSystem(self.env)
        tag_system.delete_tags(req, resource)

    def _get_tags(self, screenshot):
        # Prepare tag names.
        self.log.debug("additional_tags: %s" % (self.additional_tags, ))
        tags = []
        if 'author' in self.additional_tags:
            tags = [screenshot['author']]
        if 'components' in self.additional_tags and screenshot['components']:
            tags += [component for component in screenshot['components']]
        if 'versions' in self.additional_tags and screenshot['versions']:
            tags += [version for version in screenshot['versions']]
        if 'name' in self.additional_tags and screenshot['name']:
            tags += [screenshot['name']]
        if 'description' in self.additional_tags and screenshot['description']:
            tags += [screenshot['description']]
        if screenshot['tags']:
            tags += screenshot['tags'].split()
        return sorted(tags)

    def _get_stored_tags(self, req, screenshot_id):
        tag_system = TagSystem(self.env)
        resource = Resource('screenshots', to_unicode(screenshot_id))
        tags = tag_system.get_tags(req, resource)
        return sorted(tags)
Example #9
0
    def __init__(self):
        self.screenshot_macro_doc = _("""Allows embed screenshot image in
wiki page. First mandatory argument is ID of the screenshot. Number or
image attributes can be specified next:

 * {{{align}}} - Specifies image alignment in wiki page. Possible values are:
   {{{left}}}, {{{right}}} and {{{center}}}.
 * {{{alt}}} - Alternative description of image.
 * {{{border}}} - Sets image border of specified width in pixels.
 * {{{class}}} - Class of image for CSS styling.
 * {{{description}}} - Brief description under the image. Accepts several
   variables (see bellow).
 * {{{format}}} - Format of returned image or screenshot behind link.
 * {{{height}}} - Height of image. Set to 0 if you want original image height.
 * {{{id}}} - ID of image for CSS styling.
 * {{{longdesc}}} - Detailed description of image.
 * {{{title}}} - Title of image.
 * {{{usemap}}} - Image map for clickable images.
 * {{{width}}} - Width of image. Set to 0 if you want original image width.

Attribute {{{description}}} displays several variables:

 * {{{$id}}} - ID of image.
 * {{{$name}}} - Name of image.
 * {{{$author}}} - User name who uploaded image.
 * {{{$time}}} - Time when image was uploaded.
 * {{{$file}}} - File name of image.
 * {{{$description}}} - Detailed description of image.
 * {{{$width}}} - Original width of image.
 * {{{$height}}} - Original height of image.
 * {{{$tags}}} - Comma separated list of screenshot tags.
 * {{{$components}}} - Comma separated list of screenshot components.
 * {{{$versions}}} - Comma separated list of screenshot versions.

Example:

{{{
 [[Screenshot(2,width=400,height=300,description=The $name by $author: $description,align=left)]]
}}}""")

        self.screenshots_list_macro_doc = _("""Displays list of all available
screenshots on wiki page. Accepts one argument which is template for
list items formatting. Possible variables in this template are:

 * {{{$id}}} - ID of image.
 * {{{$name}}} - Name of image.
 * {{{$author}}} - User name who uploaded image.
 * {{{$time}}} - Time when image was uploaded.
 * {{{$file}}} - File name of image.
 * {{{$description}}} - Detailed description of image.
 * {{{$width}}} - Original width of image.
 * {{{$height}}} - Original height of image.
 * {{{$tags}}} - Comma separated list of screenshot tags.
 * {{{$components}}} - Comma separated list of screenshot components.
 * {{{$versions}}} - Comma separated list of screenshot versions.

Example:

{{{
 [[ScreenshotsList($name - $description ($widthx$height))]]
}}}""")

        # [screenshot:<id>] macro id regular expression.
        self.id_re = re.compile('^(\d+)($|.+$)')

        # [[Screenshot()]] macro attributes regular expression.
        self.attributes_re = re.compile('(align|alt|border|class|description|'
          'format|height|id|longdesc|title|usemap|width)=(.*)')
Example #10
0
    def expand_macro(self, formatter, name, content):

        # Create request context.
        context = Context.from_request(formatter.req)('screenshots-wiki')

        # Get database access.
        db = self.env.get_db_cnx()
        context.cursor = db.cursor()

        # Get API component.
        api = self.env[ScreenshotsApi]

        if name == 'Screenshot':
            # Check permission.
            if not formatter.req.perm.has_permission('SCREENSHOTS_VIEW'):
               return html.div(_("No permissions to see screenshots."),
               class_ = 'system-message')

            # Get macro arguments.
            arguments = content.split(',')

            # Get screenshot ID.
            try:
               screenshot_id = int(arguments[0])
            except:
                 raise TracError(_("Missing screenshot ID in macro arguments."))

            # Try to get screenshots of that ID.
            screenshot = api.get_screenshot(context, screenshot_id)

            # Build and return macro content.
            if screenshot:
                # Set default values of image attributes.
                attributes = {'align' : 'none',
                              'border' : '1',
                              'format' : 'raw',
                              'alt' : screenshot['description'],
                              'description' : self.default_description}

                # Fill attributes from macro arguments.
                for argument in arguments[1:]:
                    argument = argument.strip()
                    match = self.attributes_re.match(argument)
                    if match:
                        attributes[str(match.group(1))] = match.group(2)

                # Zero width or height means keep original.
                if attributes.has_key('width'):
                    if attributes['width'] == 0:
                        attributes['width'] = screenshot['width']
                if attributes.has_key('height'):
                    if attributes['height'] == 0:
                        attributes['height'] = screenshot['height']

                # If one dimension is missing compute second to keep aspect.
                if not attributes.has_key('width') and \
                  attributes.has_key('height'):
                    attributes['width'] = int(int(attributes['height']) * (
                      float(screenshot['width']) / float(screenshot['height']))
                      + 0.5)
                if not attributes.has_key('height') and \
                  attributes.has_key('width'):
                    attributes['height'] = int(int(attributes['width']) * (
                      float(screenshot['height']) / float(screenshot['width']))
                      + 0.5)

                # If both dimensions are missing keep original.
                if not attributes.has_key('width') and not \
                  attributes.has_key('height'):
                    attributes['width'] = screenshot['width']
                    attributes['height'] = screenshot['height']

                self.log.debug('attributes: %s' % (attributes,))

                # Format screenshot description from template.
                attributes['description'] = self._format_description(context,
                  attributes['description'], screenshot)

                # Make copy of attributes for image tag.
                img_attributes = {}
                for attribute in attributes.keys():
                    if attribute not in ('align', 'border', 'description',
                      'format', 'width', 'height'):
                        img_attributes[attribute] = attributes[attribute]

                # Add CSS for image.
                add_stylesheet(formatter.req, 'screenshots/css/screenshots.css')

                # Build screenshot image and/or screenshot link.
                image = html.img(src = formatter.req.href.screenshots(
                  screenshot['id'], format = 'raw', width = attributes['width'],
                  height = attributes['height']), **img_attributes)
                link = html.a(image, href = formatter.req.href.screenshots(
                  screenshot['id'], format = attributes['format']), title =
                  screenshot['description'], style = 'border-width: %spx;' % (
                  attributes['border'],))
                width_and_border = int(attributes['width']) + 2 * \
                  int(attributes['border'])
                description = html.span(attributes['description'], class_ =
                  'description', style = "width: %spx;" % (width_and_border,))
                auxilary = html.span(link, description, class_ = 'aux',
                  style = "width: %spx;" % (width_and_border,))
                thumbnail_class = 'thumbnail' + ((attributes['align'] == 'left')
                  and '-left' or (attributes['align'] == 'right') and '-right'
                  or '')
                thumbnail = html.span(auxilary, class_ = thumbnail_class)
                return thumbnail
            else:
                return html.a(screenshot_id, href =
                  formatter.req.href.screenshots(), title = content,
                  class_ = 'missing')

        elif name == 'ScreenshotsList':
            # Check permission.
            if not formatter.req.perm.has_permission('SCREENSHOTS_VIEW'):
               return html.div(_("No permissions to see screenshots."),
               class_ = 'system-message')

            # Get desired list item description
            list_item_description = content or self.default_list_item

            # Get all screenshots.
            screenshots = api.get_screenshots_complete(context)

            # Create and return HTML list of screenshots.
            list_items = []
            for screenshot in screenshots:
                list_item = self._format_description(context,
                  list_item_description, screenshot)
                list_items.append(html.li(html.a(list_item, href =
                  formatter.req.href.screenshots(screenshot['id']))))
            return html.ul(list_items)
Example #11
0
class ScreenshotsMatrixView(Component):

    implements(ITemplateProvider, IScreenshotsRenderer)

    # Configuration options.
    rows = IntOption('screenshots-matrix',
                     'rows',
                     3,
                     doc=_("Number of screenshot preview rows."))
    columns = IntOption('screenshots-matrix',
                        'columns',
                        3,
                        doc=_("Number of screenshot columns."))
    width = IntOption('screenshots-matrix',
                      'width',
                      160,
                      doc=_("Width of screenshot preview."))
    height = IntOption('screenshots-matrix',
                       'height',
                       120,
                       doc=_("Height of screenshot preview."))

    def __init__(self):
        # Items for not specified screenshot.
        self.null_screenshot = {'id': -1, 'name': '', 'description': ''}

    # ITemplateProvider methods.

    def get_htdocs_dirs(self):
        from pkg_resources import resource_filename
        return [('screenshots', resource_filename(__name__, 'htdocs'))]

    def get_templates_dirs(self):
        from pkg_resources import resource_filename
        return [resource_filename(__name__, 'templates')]

    # IScreenshotsRenderer methods.

    def render_screenshots(self, req):
        # Add CSS style and JavaScript scripts.
        add_stylesheet(req, 'screenshots/css/matrix-view.css')

        # Get custom request arguments.
        index = int(req.args.get('index') or -1)
        page = int(req.args.get('page') or -1)

        self.log.debug('index: %s' % (index))
        self.log.debug('page: %s' % (page))

        # Count index or page depending on user input.
        count = len(req.data['screenshots'])
        count_on_page = self.rows * self.columns
        if index != -1:
            page = (index / count_on_page) + 1
        elif page != -1:
            index = (page - 1) * count_on_page
        else:
            index = 0
            page = 1

        self.log.debug('index: %s' % (index))
        self.log.debug('page: %s' % (page))

        # Compute page count, next and previous page id.
        page_cout = (count + (count_on_page - 1)) / count_on_page
        prev_index = (index - count_on_page)
        next_index = (index + count_on_page)
        max_index = page_cout * count_on_page - 1
        if prev_index < 0:
            prev_index = -1
        if next_index > max_index:
            next_index = -1

        # Fill data dictionary.
        req.data['rows'] = self.rows
        req.data['columns'] = self.columns
        req.data['width'] = self.width
        req.data['height'] = self.height
        req.data['matrix'] = self._build_matrix(index, req.data['screenshots'])
        req.data['index'] = index
        req.data['page'] = page
        req.data['page_count'] = page_cout
        req.data['prev_index'] = prev_index
        req.data['next_index'] = next_index
        req.data['screenshot_count'] = len(req.data['screenshots'])
        return ('screenshots-matrix-view.html', None)

    def get_screenshots_view(req):
        yield ('matrix', _("Matrix View"))

    # Private methods.

    def _build_matrix(self, index, screenshots):
        # Determine index of first screenshot.
        count = self.rows * self.columns
        index = index - (index % count)

        # Construct rows x columns matrix.
        row = []
        matrix = []
        for I in xrange(count):
            # Add screenshot.
            if ((index + I) < len(screenshots)) and ((index + I) >= 0):
                row.append(screenshots[index + I])
            else:
                row.append(self.null_screenshot)

            # Move to next row.
            if ((I + 1) % self.columns) == 0:
                matrix.append(row)
                row = []

        return matrix
Example #12
0
 def get_screenshots_view(req):
     yield ('matrix', _("Matrix View"))