Changeset 4364

Show
Ignore:
Timestamp:
10/01/08 06:42:41 (3 months ago)
Author:
Blackhex
Message:

ScreenshotsPlugin:

  • Zip archive upload support.
  • Fixed bug that first screenshot was not displayed.
Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • screenshotsplugin/0.11/tracscreenshots/api.py

    r4344 r4364  
    100100          components) and ' OR c.component IS NULL) ' or ') ') + 'ORDER BY ' + \ 
    101101            orders_str 
    102         self.log.debug(versions + components) 
    103102        self.log.debug(sql % tuple(versions + components)) 
    104103        context.cursor.execute(sql, versions + components) 
  • screenshotsplugin/0.11/tracscreenshots/core.py

    r4359 r4364  
    33import sets, re, os, os.path, shutil, mimetypes, unicodedata, Image, ImageOps 
    44from datetime import * 
     5from zipfile import * 
     6from StringIO import * 
    57 
    68from trac.core import * 
     
    265267                file, filename = self._get_file_from_req(context.req) 
    266268                name, ext = os.path.splitext(filename) 
    267                 filename = name + ext.lower() 
    268  
    269                 # Create image object. 
    270                 image = Image.open(file) 
    271  
    272                 # Construct screenshot dictionary from form values. 
    273                 screenshot = {'name' :  context.req.args.get('name'), 
    274                               'description' : context.req.args.get('description'), 
    275                               'time' : to_timestamp(datetime.now(utc)), 
    276                               'author' : context.req.authname, 
    277                               'tags' : context.req.args.get('tags'), 
    278                               'file' : filename, 
    279                               'width' : image.size[0], 
    280                               'height' : image.size[1], 
    281                               'priority' : int(context.req.args.get('priority') 
    282                                 or '0')} 
    283  
    284                 # Add new screenshot. 
    285                 api.add_screenshot(context, screenshot) 
    286  
    287                 # Get inserted screenshot to with new id. 
    288                 screenshot = api.get_screenshot_by_time(context, 
    289                    screenshot['time']) 
    290  
    291                 # Add components to screenshot. 
    292                 components = context.req.args.get('components') or [] 
    293                 if not isinstance(components, list): 
    294                     components = [components] 
    295                 for component in components: 
    296                     component = {'screenshot' : screenshot['id'], 
    297                                  'component' : component} 
    298                     api.add_component(context, component) 
    299                 screenshot['components'] = components 
    300  
    301                 # Add versions to screenshots 
    302                 versions = context.req.args.get('versions') or [] 
    303                 if not isinstance(versions, list): 
    304                     versions = [versions] 
    305                 for version in versions: 
    306                     version = {'screenshot' : screenshot['id'], 
    307                                'version' : version} 
    308                     api.add_version(context, version) 
    309                 screenshot['versions'] = versions 
    310  
    311                 self.log.debug('screenshot: %s' % (screenshot,)) 
    312  
    313                 # Prepare file paths 
    314                 name, ext = os.path.splitext(screenshot['file']) 
    315                 path = os.path.join(self.path, unicode(screenshot['id'])) 
    316                 filepath = os.path.join(path, '%s-%ix%i%s' % (name, 
    317                   screenshot['width'], screenshot['height'], ext)) 
    318                 path = os.path.normpath(path) 
    319                 filepath = os.path.normpath(filepath) 
    320  
    321                 self.log.debug('path: %s' % (path,)) 
    322                 self.log.debug('filename: %s' % (filepath,)) 
    323  
    324                 # Store uploaded image. 
    325                 try: 
    326                     os.mkdir(path) 
    327                     out_file = open(filepath, 'wb+')  
    328                     file.seek(0) 
    329                     shutil.copyfileobj(file, out_file) 
    330                     out_file.close() 
    331                 except Exception, error: 
    332                     api.delete_screenshot(context, screenshot['id']) 
    333                     try: 
    334                         os.remove(filename) 
    335                     except: 
    336                         pass 
    337                     try: 
    338                         os.rmdir(path) 
    339                     except: 
    340                         pass 
    341                     raise TracError('Error storing file. Is directory' \ 
    342                       ' specified in path config option in [screenshots]' \ 
    343                       ' section of trac.ini existing? Original message was: %s' \ 
    344                       % (to_unicode(error),)) 
    345  
    346                 # Notify change listeners. 
    347                 for listener in self.change_listeners: 
    348                     listener.screenshot_created(context.req, screenshot) 
     269                ext = ext.lower() 
     270                filename = name + ext 
     271 
     272                # Is uploaded file archive or single image? 
     273                if ext == '.zip': 
     274                    # Get global timestamp for all files in archive. 
     275                    timestamp = to_timestamp(datetime.now(utc)) 
     276 
     277                    # List files in archive. 
     278                    zip_file = ZipFile(file) 
     279                    for filename in zip_file.namelist(): 
     280                        # Test file extensions for supported type. 
     281                        name, ext = os.path.splitext(filename) 
     282                        tmp_ext = ext.lower()[1:] 
     283                        if tmp_ext in self.ext and tmp_ext != 'zip': 
     284                            # Decompress image file 
     285                            data = zip_file.read(filename) 
     286                            file = StringIO(data) 
     287                            filename = to_unicode(os.path.basename(filename)) 
     288 
     289                            # Screenshots must be identified by timestamp. 
     290                            timestamp += 1 
     291 
     292                            # Save screenshot file and add DB entry. 
     293                            self._add_screenshot(context, api, file, filename, 
     294                              timestamp) 
     295 
     296                    zip_file.close() 
     297                else: 
     298                    # Add single image. 
     299                    self._add_screenshot(context, api, file, filename, 
     300                      to_timestamp(datetime.now(utc))) 
    349301 
    350302                # Clear ID to prevent display of edit and delete button. 
     
    482434                path = os.path.join(self.path, to_unicode(screenshot['id'])) 
    483435                path = os.path.normpath(path) 
    484  
    485436                self.log.debug('path: %s' % (path,)) 
    486437 
     
    491442                        os.remove(file) 
    492443                    os.rmdir(path) 
    493                 except Exception, error: 
    494                     raise TracError('Error deleting screenshot. Original' \ 
    495                       ' message was: %s' % (to_unicode(error),)) 
     444                except: 
     445                    pass 
    496446 
    497447                # Notify change listeners. 
     
    572522                screenshots = api.get_filtered_screenshots(context, 
    573523                  enabled_components, enabled_versions, relation, orders) 
     524                self.log.debug('screenshots: %s' % (screenshots,)) 
    574525 
    575526                # Convert enabled components and versions to dictionary. 
     
    604555                screenshot = api.get_screenshot(context, self.id) 
    605556                self.log.debug('screenshot: %s' % (screenshot,)) 
     557 
     558    def _add_screenshot(self, context, api, file, filename, time): 
     559        # Create image object. 
     560        image = Image.open(file) 
     561 
     562        # Construct screenshot dictionary from form values. 
     563        screenshot = {'name' :  context.req.args.get('name'), 
     564                      'description' : context.req.args.get('description'), 
     565                      'time' : time, 
     566                      'author' : context.req.authname, 
     567                      'tags' : context.req.args.get('tags'), 
     568                      'file' : filename, 
     569                      'width' : image.size[0], 
     570                      'height' : image.size[1], 
     571                      'priority' : int(context.req.args.get('priority') 
     572                        or '0')} 
     573 
     574        # Add new screenshot. 
     575        api.add_screenshot(context, screenshot) 
     576 
     577        # Get inserted screenshot to with new id. 
     578        screenshot = api.get_screenshot_by_time(context, screenshot['time']) 
     579 
     580        # Add components to screenshot. 
     581        components = context.req.args.get('components') or [] 
     582        if not isinstance(components, list): 
     583            components = [components] 
     584        for component in components: 
     585            component = {'screenshot' : screenshot['id'], 
     586                         'component' : component} 
     587            api.add_component(context, component) 
     588        screenshot['components'] = components 
     589 
     590        # Add versions to screenshots 
     591        versions = context.req.args.get('versions') or [] 
     592        if not isinstance(versions, list): 
     593            versions = [versions] 
     594        for version in versions: 
     595            version = {'screenshot' : screenshot['id'], 
     596                       'version' : version} 
     597            api.add_version(context, version) 
     598        screenshot['versions'] = versions 
     599 
     600        self.log.debug('screenshot: %s' % (screenshot,)) 
     601 
     602        # Prepare file paths 
     603        name, ext = os.path.splitext(screenshot['file']) 
     604        path = os.path.join(self.path, unicode(screenshot['id'])) 
     605        filepath = os.path.join(path, '%s-%ix%i%s' % (name, screenshot['width'], 
     606          screenshot['height'], ext)) 
     607        path = os.path.normpath(path) 
     608        filepath = os.path.normpath(filepath) 
     609 
     610        self.log.debug('path: %s' % (path,)) 
     611        self.log.debug('filename: %s' % (filepath,)) 
     612 
     613        # Store uploaded image. 
     614        try: 
     615            os.mkdir(path) 
     616            out_file = open(filepath, 'wb+')  
     617            file.seek(0) 
     618            shutil.copyfileobj(file, out_file) 
     619            out_file.close() 
     620        except Exception, error: 
     621            api.delete_screenshot(context, screenshot['id']) 
     622            try: 
     623                os.remove(filename) 
     624            except: 
     625                pass 
     626            try: 
     627                os.rmdir(path) 
     628            except: 
     629                pass 
     630            raise TracError('Error storing file. Is directory specified in path' \ 
     631              ' config option in [screenshots] section of trac.ini existing?' \ 
     632              ' Original message was: %s' % (to_unicode(error),)) 
     633 
     634        # Notify change listeners. 
     635        for listener in self.change_listeners: 
     636            listener.screenshot_created(context.req, screenshot) 
    606637 
    607638    def _create_image(self, orig_name, path, name, ext, width, height): 
  • screenshotsplugin/0.11/tracscreenshots/matrix_view.py

    r4359 r4364  
    8181        data['next_index'] = next_index 
    8282        data['screenshot_count'] = len(data['screenshots']) 
    83  
    8483        return ('screenshots-matrix-view.html', None) 
    8584 
     
    9998        for I in xrange(count): 
    10099            # Add screenshot. 
    101             if ((index + I) < len(screenshots)) and ((index + I) > 0): 
     100            if ((index + I) < len(screenshots)) and ((index + I) >= 0): 
    102101                row.append(screenshots[index + I]) 
    103102            else: