Changeset 3313
- Timestamp:
- 03/05/08 06:26:47 (9 months ago)
- Files:
-
- screenshotsplugin/0.10/tracscreenshots/api.py (modified) (3 diffs)
- screenshotsplugin/0.10/tracscreenshots/core.py (modified) (4 diffs)
- screenshotsplugin/0.10/tracscreenshots/htdocs/css/screenshots.css (modified) (3 diffs)
- screenshotsplugin/0.10/tracscreenshots/wiki.py (modified) (4 diffs)
- screenshotsplugin/0.11/tracscreenshots/core.py (modified) (7 diffs)
- screenshotsplugin/0.11/tracscreenshots/htdocs/css/screenshots.css (modified) (1 diff)
- screenshotsplugin/0.11/tracscreenshots/wiki.py (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
screenshotsplugin/0.10/tracscreenshots/api.py
r3161 r3313 103 103 return row 104 104 105 def _format_screenshot(self, screenshot):106 #screenshot['author'] = wiki_to_oneliner(screenshot['author'], self.env)107 #screenshot['name'] = wiki_to_oneliner(screenshot['name'], self.env)108 #screenshot['description'] = wiki_to_oneliner(screenshot['description'],109 # self.env)110 screenshot['width'] = int(screenshot['width'])111 screenshot['height'] = int(screenshot['height'])112 screenshot['time'] = pretty_timedelta(screenshot['time'])113 return screenshot114 115 105 def get_screenshot(self, cursor, id): 116 106 # Get screenshot from database. … … 125 115 screenshot['versions'] = self.get_screenshot_versions(cursor, 126 116 screenshot['id']) 127 return s elf._format_screenshot(screenshot)117 return screenshot 128 118 else: 129 119 return None … … 136 126 137 127 # Append components and versions. 138 screenshot['components'] = self.get_screenshot_components(cursor, 139 screenshot['id']) 140 screenshot['versions'] = self.get_screenshot_versions(cursor, 141 screenshot['id']) 142 return self._format_screenshot(screenshot) 128 if screenshot: 129 screenshot['components'] = self.get_screenshot_components(cursor, 130 screenshot['id']) 131 screenshot['versions'] = self.get_screenshot_versions(cursor, 132 screenshot['id']) 133 return screenshot 134 else: 135 return None 143 136 144 137 def get_screenshot_components(self, cursor, id): screenshotsplugin/0.10/tracscreenshots/core.py
r3304 r3313 8 8 from trac.web.chrome import Chrome, add_stylesheet, add_script 9 9 from trac.web.clearsilver import HDFWrapper 10 from trac.util import Markup, format_datetime, TracError10 from trac.util import format_datetime, pretty_timedelta, TracError 11 11 from trac.util.html import html 12 12 … … 120 120 req.hdf['screenshots.has_tags'] = self.env.is_component_enabled( 121 121 'tracscreenshots.tags.ScreenshotsTags') 122 #req.hdf['screenshots.has_tags'] = self.config.get('components',123 # 'tracscreenshots.tags.screenshotstags') == 'enabled'124 122 return template, content_type 125 123 … … 167 165 height = int(req.args.get('height') or 0) 168 166 169 self.log.debug(self.formats)170 171 167 # Check if requested format is allowed. 172 168 if not format in self.formats: … … 183 179 184 180 if format == 'html': 181 # Format screenshot attributes. 182 screenshot['time'] = pretty_timedelta(screenshot['time']) 183 185 184 #Â Prepare data dictionary. 186 185 data['screenshot'] = screenshot screenshotsplugin/0.10/tracscreenshots/htdocs/css/screenshots.css
r3309 r3313 50 50 display: inline-block; 51 51 margin: 1em; 52 margin-top: 0.5em; 52 53 padding: 0em; 53 54 font-size: 75%; … … 58 59 span.thumbnail-left 59 60 { 61 margin-left : 0em; 60 62 float: left; 61 63 } … … 63 65 span.thumbnail-right 64 66 { 67 margin-right: 0em; 65 68 float: right; 66 69 } screenshotsplugin/0.10/tracscreenshots/wiki.py
r3309 r3313 9 9 from trac.util.html import html 10 10 from trac.util.text import to_unicode 11 from trac.util.datefmt import format_datetime 11 12 12 13 from trac.wiki import IWikiSyntaxProvider, IWikiMacroProvider … … 16 17 class ScreenshotsWiki(Component): 17 18 18 screenshot_macro_doc = "" 19 screenshot_macro_doc = """Allows embed screenshot image in wiki page. 20 First mandatory argument is ID of the screenshot. Number or image attributes 21 can be specified next: 22 23 * {{{align}}} - Specifies image alignment in wiki page. Possible values are: 24 {{{left}}}, {{{right}}} and {{{center}}}. 25 * {{{alt}}} - Alternative description of image. 26 * {{{border}}} - Sets image border of specified width in pixels. 27 * {{{class}}} - Class of image for CSS styling. 28 * {{{description}}} - Brief description under the image. Accepts several 29 variables (see bellow). 30 * {{{format}}} - Format of returned image or screenshot behind link. 31 * {{{height}}} - Height of image. Set to 0 if you want original image height. 32 * {{{id}}} - ID of image for CSS styling. 33 * {{{longdesc}}} - Detailed description of image. 34 * {{{title}}} - Title of image. 35 * {{{usemap}}} - Image map for clickable images. 36 * {{{width}}} - Width of image. Set to 0 if you want original image width. 37 38 Attribute {{{description}}} displays several variables: 39 40 * {{{$id}}} - ID of image. 41 * {{{$name}}} - Name of image. 42 * {{{$author}}} - User name who uploaded image. 43 * {{{$time}}} - Time when image was uploaded. 44 * {{{$file}}} - File name of image. 45 * {{{$description}}} - Detailed description of image. 46 * {{{$width}}} - Original width of image. 47 * {{{$height}}} - Original height of image. 48 49 Example: 50 51 {{{ 52 [[Screenshot(2,width=400,height=300,description=The $name by $author: $description,align=left)]] 53 }}}""" 19 54 20 55 """ … … 53 88 def render_macro(self, req, name, content): 54 89 if name == 'Screenshot': 90 # Check permission. 91 if not req.perm.has_permission('SCREENSHOTS_VIEW'): 92 return html.div('No permissions to see screenshots.', 93 class_ = 'system-message') 94 55 95 # Get database access. 56 96 db = self.env.get_db_cnx() … … 165 205 description = description.replace('$file', 166 206 to_unicode(screenshot['file'])) 167 description = description.replace('$time', screenshot['time']) 207 description = description.replace('$time', format_datetime( 208 screenshot['time'])) 168 209 description = description.replace('$author', screenshot['author']) 169 210 description = description.replace('$description', screenshotsplugin/0.11/tracscreenshots/core.py
r3271 r3313 6 6 from trac.core import * 7 7 from trac.mimeview import Context 8 from trac.config import Option 9 from trac.web.chrome import add_stylesheet, add_script 8 from trac.config import Option, ListOption 9 from trac.web.chrome import add_stylesheet, add_script, format_to_oneliner, \ 10 pretty_timedelta 10 11 from trac.util.html import html 11 12 from trac.util.text import to_unicode … … 42 43 #Â Configuration options. 43 44 mainnav_title = Option('screenshots', 'mainnav_title', 'Screenshots', 44 'Main navigation bar button title.')45 doc = 'Main navigation bar button title.') 45 46 metanav_title = Option('screenshots', 'metanav_title', '', 46 'Meta navigation bar link title.')47 doc = 'Meta navigation bar link title.') 47 48 path = Option('screenshots', 'path', '/var/lib/trac/screenshots', 48 'Path where to store uploaded screenshots.')49 ext = Option('screenshots', 'ext', 'jpgpng',50 'List of screenshot file extensions that can be uploaded. Must be'49 doc = 'Path where to store uploaded screenshots.') 50 ext = ListOption('screenshots', 'ext', 'jpg,png', 51 doc = 'List of screenshot file extensions that can be uploaded. Must be' 51 52 ' supported by PIL.') 52 formats = Option('screenshots', 'formats', 'raw html jpgpng',53 'List of allowed formats for screenshot download.')53 formats = ListOption('screenshots', 'formats', 'raw,html,jpg,png', 54 doc = 'List of allowed formats for screenshot download.') 54 55 default_format = Option('screenshots', 'default_format', 'html', 55 'Default format for screenshot download links.')56 default_components = Option('screenshots', 'default_components', 'none',57 'List of components enabled by default.')58 default_versions = Option('screenshots', 'default_versions', 'none',59 'List of versions enabled by default.')56 doc = 'Default format for screenshot download links.') 57 default_components = ListOption('screenshots', 'default_components', 'none', 58 doc = 'List of components enabled by default.') 59 default_versions = ListOption('screenshots', 'default_versions', 'none', 60 doc = 'List of versions enabled by default.') 60 61 61 62 # IPermissionRequestor methods. 62 63 63 64 def get_permission_actions(self): 64 return ['SCREENSHOTS_VIEW', 'SCREENSHOTS_FILTER', 'SCREENSHOTS_ADMIN'] 65 view = 'SCREENSHOTS_VIEW' 66 filter = ('SCREENSHOTS_FILTER', ['SCREENSHOTS_VIEW']) 67 admin = ('SCREENSHOTS_ADMIN', ['SCREENSHOTS_FILTER', 68 'SCREENSHOTS_VIEW']) 69 return [view, filter, admin] 65 70 66 71 # ITemplateProvider methods. … … 167 172 168 173 # Check if requested format is allowed. 169 if not format in self.formats .split():174 if not format in self.formats: 170 175 raise TracError('Requested screenshot format that is not' 171 176 ' allowed.', 'Requested format not allowed.') … … 247 252 result = reg.match(filename) 248 253 if result: 249 if not result.group(2).lower() in self.ext .split():254 if not result.group(2).lower() in self.ext: 250 255 raise TracError('Unsupported uploaded file type.') 251 256 else: … … 448 453 ' at least one.', 'No screenshots renderer enabled') 449 454 455 #Â Get all available components and versions. 456 components = [self.none_component] + api.get_components( 457 context.cursor) 458 versions = [self.none_version] + api.get_versions( 459 context.cursor) 460 450 461 # Get enabled components and versions from request or session. 451 462 enabled_components = self._get_enabled_components(context.req) 452 463 enabled_versions = self._get_enabled_versions(context.req) 464 if 'all' in enabled_components: 465 enabled_components = [component['name'] for component in 466 components] 467 if 'all' in enabled_versions: 468 enabled_versions = [version['name'] for version in 469 versions] 470 471 self.log.debug(enabled_components) 472 473 # Filter screenshots. 453 474 screenshots = api.get_filtered_screenshots(context, 454 475 enabled_components, enabled_versions) … … 462 483 # Fill data dictionary. 463 484 self.data['id'] = screenshot_id 464 self.data['components'] = [self.none_component] + \ 465 api.get_components(context) 466 self.data['versions'] = [self.none_version] + \ 467 api.get_versions(context) 485 self.data['components'] = components 486 self.data['versions'] = versions 468 487 self.data['screenshots'] = screenshots 469 488 self.data['href'] = context.req.href.screenshots() … … 509 528 510 529 def _get_enabled_components(self, req): 511 #Â Check if session is initialized. 512 if not req.session.has_key('enabled_components'): 513 req.session['enabled_components'] = str(self.default_components \ 514 .split()) 515 516 #Â Return enabled components from session. 517 return eval(req.session.get('enabled_components')) 530 if req.perm.has_permission('SCREENSHOTS_FILTER'): 531 #Â Return existing filter from session or create default. 532 if req.session.has_key('enabled_components'): 533 components = eval(req.session.get('enabled_components')) 534 else: 535 components = self.default_components 536 req.session['enabled_components'] = str(components) 537 else: 538 # Users without SCREENSHOTS_FILTER permission uses 539 # 'default_components' configuration option. 540 components = self.default_components 541 self.log.debug('enabled_components: %s' % (components,)) 542 return components 518 543 519 544 def _get_enabled_versions(self, req): 520 #Â Check if session is initialized. 521 if not req.session.has_key('enabled_versions'): 522 req.session['enabled_versions'] = str(self.default_versions \ 523 .split()) 524 525 #Â Return enabled versions from session. 526 return eval(req.session.get('enabled_versions')) 545 if req.perm.has_permission('SCREENSHOTS_FILTER'): 546 #Â Return existing filter from session or create default. 547 if req.session.has_key('enabled_versions'): 548 versions = eval(req.session.get('enabled_versions')) 549 else: 550 versions = self.default_versions 551 req.session['enabled_versions'] = str(versions) 552 else: 553 # Users without SCREENSHOTS_FILTER permission uses 554 # 'default_versions' configuration option. 555 versions = self.default_versions 556 self.log.debug('enabled_versions: %s' % (versions,)) 557 return versions screenshotsplugin/0.11/tracscreenshots/htdocs/css/screenshots.css
r3140 r3313 21 21 display: inline; 22 22 } 23 24 /* Wiki [[Screenshot()]] macro styles. */ 25 span.thumbnail > a > img 26 { 27 display: inline; 28 border-color: #b00; 29 border-style: solid; 30 margin: 0em; 31 padding: 0em; 32 } 33 34 span.thumbnail > a 35 { 36 display: inline-block; 37 border: 0px none; 38 margin: 0.2em; 39 padding: 0em; 40 } 41 42 span.thumbnail > span.description 43 { 44 display: inline-block; 45 } 46 47 span.thumbnail, span.thumbnail-left, span.thumbnail-right 48 { 49 display: inline-block; 50 margin: 1em; 51 margin-top: 0.5em; 52 padding: 0em; 53 font-size: 75%; 54 text-align: center; 55 vertical-align: middle; 56 } 57 58 span.thumbnail-left 59 { 60 margin-left: 0em; 61 float: left; 62 } 63 64 span.thumbnail-right 65 { 66 margin-right: 0em; 67 float: right; 68 } screenshotsplugin/0.11/tracscreenshots/wiki.py
r3140 r3313 4 4 5 5 from trac.core import * 6 from trac.config import Option 7 from trac.wiki.formatter import format_to_html, format_to_oneliner 8 from trac.web.chrome import add_stylesheet, add_script, format_datetime 6 9 from trac.util.html import html 7 8 from trac.wiki import IWikiSyntaxProvider 10 from trac.util.text import to_unicode 11 12 from trac.wiki import IWikiSyntaxProvider, IWikiMacroProvider 9 13 10 14 from tracscreenshots.api import * 11 15 12 16 class ScreenshotsWiki(Component): 17 18 screenshot_macro_doc = """Allows embed screenshot image in wiki page. 19 First mandatory argument is ID of the screenshot. Number or image attributes 20 can be specified next: 21 22 * {{{align}}} - Specifies image alignment in wiki page. Possible values are: 23 {{{left}}}, {{{right}}} and {{{center}}}. 24 * {{{alt}}} - Alternative description of image. 25 * {{{border}}} - Sets image border of specified width in pixels. 26 * {{{class}}} - Class of image for CSS styling. 27 * {{{description}}} - Brief description under the image. Accepts several 28 variables (see bellow). 29 * {{{format}}} - Format of returned image or screenshot behind link. 30 * {{{height}}} - Height of image. Set to 0 if you want original image height. 31 * {{{id}}} - ID of image for CSS styling. 32 * {{{longdesc}}} - Detailed description of image. 33 * {{{title}}} - Title of image. 34 * {{{usemap}}} - Image map for clickable images. 35 * {{{width}}} - Width of image. Set to 0 if you want original image width. 36 37 Attribute {{{description}}} displays several variables: 38 39 * {{{$id}}} - ID of image. 40 * {{{$name}}} - Name of image. 41 * {{{$author}}} - User name who uploaded image. 42 * {{{$time}}} - Time when image was uploaded. 43 * {{{$file}}} - File name of image. 44 * {{{$description}}} - Detailed description of image. 45 * {{{$width}}} - Original width of image. 46 * {{{$height}}} - Original height of image. 47 48 Example: 49 50 {{{ 51 [[Screenshot(2,width=400,height=300,description=The $name by $author: $description,align=left)]] 52 }}}""" 53 13 54 """ 14 55 The wiki module implements macro for screenshots referencing. 15 56 """ 16 implements(IWikiSyntaxProvider) 17 18 #Â [screenshot] macro attributes regular expression. 19 attributes_re = re.compile('(align|border|width|height|alt|title|longdesc|' 20 'class|id|usemap|format)=(.+)') 57 implements(IWikiSyntaxProvider, IWikiMacroProvider) 58 59 # [screenshot] macro id regular expression. 60 id_re = re.compile('^(\d+)($|.+$)') 61 62 #Â [[Screenshot()]] macro attributes regular expression. 63 attributes_re = re.compile('(align|alt|border|class|description|format|' \ 64 'height|id|longdesc|title|usemap|width)=(.*)') 65 66 #Â Configuration options. 67 default_description = Option('screenshots', 'default_description', 68 '$description', 'Template for embended image description.') 21 69 22 70 # IWikiSyntaxProvider 71 23 72 def get_link_resolvers(self): 24 73 yield ('screenshot', self._screenshot_link) … … 27 76 return [] 28 77 29 # Internal functions 30 31 def _screenshot_link(self, formatter, ns, params, label): 32 if ns == 'screenshot': 78 # IWikiMacroProvider 79 80 def get_macros(self): 81 yield 'Screenshot' 82 83 def get_macro_description(self, name): 84 if name == 'Screenshot': 85 return self.screenshot_macro_doc 86 87 def expand_macro(self, formatter, name, content): 88 if name == 'Screenshot': 89 # Check permission. 90 if not formatter.req.perm.has_permission('SCREENSHOTS_VIEW'): 91 return html.div('No permissions to see screenshots.', 92 class_ = 'system-message') 93 33 94 # Create request context. 34 95 context = Context.from_request(formatter.req)('screenshots-wiki') … … 41 102 api = self.env[ScreenshotsApi] 42 103 43 # Get macro arguments and screenshot. 44 arguments = params.split(',') 45 screenshot_id = int(arguments[0]) 104 #Â Get macro arguments. 105 arguments = content.split(',') 106 107 # Get screenshot ID. 108 try: 109 screenshot_id = int(arguments[0]) 110 except: 111 raise TracError("Missing screenshot ID in macro arguments.") 112 113 # Try to get screenshots of that ID. 46 114 screenshot = api.get_screenshot(context, screenshot_id) 47 115 48 # Return macro content116 #Â Build and return macro content. 49 117 if screenshot: 50 118 #Â Set default values of image attributes. 51 attributes = {'alt' : screenshot['description'], 52 'format' : 'html'} 119 attributes = {'align' : 'none', 120 'border' : '1', 121 'format' : 'raw', 122 'width' : screenshot['width'], 123 'height' : screenshot['height'], 124 'alt' : screenshot['description'], 125 'description' : self.default_description} 53 126 54 127 # Fill attributes from macro arguments. … … 58 131 if match: 59 132 attributes[str(match.group(1))] = match.group(2) 60 if attributes.has_key('width'):61 if attributes['width'] == '0':62 attributes['width'] = screenshot['width']63 if attributes.has_key('height'):64 if attributes['height'] == '0':65 attributes['height'] = screenshot['height']66 133 self.log.debug('attributes: %s' % (attributes,)) 67 134 135 # Format screenshot description from template. 136 attributes['description'] = self._format_description(context, 137 attributes['description'], screenshot) 138 139 # Make copy of attributes for image tag. 140 img_attributes = {'align' : 'center', 141 'style' : 'border-width: %spx;' % ( 142 attributes['border'],)} 143 for attribute in attributes.keys(): 144 if attribute not in ('align', 'border', 'description', 145 'format'): 146 img_attributes[attribute] = attributes[attribute] 147 148 # Add CSS for image. 149 add_stylesheet(formatter.req, 'screenshots/css/screenshots.css') 150 68 151 # Build screenshot image and/or screenshot link. 69 screenshot_href = formatter.href.screenshots(screenshot['id']) \ 70 + '?format=%s' % (attributes['format'],) 71 if attributes.has_key('width') and attributes.has_key('height'): 72 image = html.img(src = formatter.href.screenshots( 73 screenshot['id'], width = attributes['width'], height = 74 attributes['height'], format = 'raw'), **attributes) 75 return html.a(image, href = screenshot_href, title = 76 screenshot['description']) 77 else: 78 return html.a(label, href = screenshot_href, title = 79 screenshot['description']) 152 image = html.img(src = formatter.req.href.screenshots( 153 screenshot['id'], width = attributes['width'], height = 154 attributes['height'], format = 'raw'), **img_attributes) 155 link = html.a(image, href = formatter.req.href.screenshots( 156 screenshot['id'], format = attributes['format']), title = 157 screenshot['description']) 158 description = html.span(attributes['description'], class_ = 159 'description') 160 thumbnail_class = 'thumbnail' + ((attributes['align'] == 'left') 161 and '-left' or (attributes['align'] == 'right') and '-right' 162 or '') 163 thumbnail = html.span(link, ' ', description, class_ = 164 thumbnail_class, style = "width: %spx;" % ( 165 int(attributes['width']) + 2 * int(attributes['border'],))) 166 return thumbnail 167 else: 168 return html.a(screenshot_id, href = 169 formatter.req.href.screenshots(), title = content, 170 class_ = 'missing') 171 172 # Internal functions 173 174 def _screenshot_link(self, formatter, ns, params, label): 175 if ns == 'screenshot': 176 # Get screenshot ID and link arguments from macro. 177 match = self.id_re.match(params) 178 if match: 179 screenshot_id = int(match.group(1)) 180 arguments = match.group(2) 181 else: 182 # Bad format of link. 183 return html.a(label, href = formatter.href.screenshots(), 184 title = params, class_ = 'missing') 185 186 # Create request context. 187 context = Context.from_request(formatter.req)('screenshots-wiki') 188 189 # Get database access. 190 db = self.env.get_db_cnx() 191 context.cursor = db.cursor() 192 193 # Get API component. 194 api = self.env[ScreenshotsApi] 195 196 # Try to get screenshots of that ID. 197 screenshot = api.get_screenshot(context, screenshot_id) 198 199 # Return macro content 200 if screenshot: 201 return html.a(label, href = formatter.href.screenshots( 202 screenshot['id']) + arguments, title = 203 screenshot['description']) 80 204 else: 81 205 return html.a(arguments[0], href = formatter.href.screenshots(), 82 206 title = params, class_ = 'missing') 207 208 def _format_description(self, context, template, screenshot): 209 description = template.replace('$id', to_unicode(screenshot['id'])) 210 description = description.replace('$name', screenshot['name']) 211 description = description.replace('$file', 212 to_unicode(screenshot['file'])) 213 description = description.replace('$time', format_datetime(to_datetime( 214 screenshot['time'], utc))) 215 description = description.replace('$author', screenshot['author']) 216 description = description.replace('$description', 217 screenshot['description']) 218 description = description.replace('$width', to_unicode( 219 screenshot['width'])) 220 description = description.replace('$height', to_unicode( 221 screenshot['height'])) 222 self.log.debug(description) 223 return format_to_oneliner(self.env, context, description) 224
