Пример #1
0
    def post_process_request(self, req, template, data, content_type):
        if data is None:
            return template, data, content_type

        if req.path_info.startswith('/changeset') and \
                data.get('changeset') is not False and \
                'CODEREVIEWER_MODIFY' in req.perm:
            changeset = data['changeset']
            repos = changeset.repos
            reponame, rev = repos.reponame, repos.db_rev(changeset.rev)
            review = CodeReview(self.env, reponame, rev)
            tickets = req.args.getlist('tickets')
            if req.method == 'POST':
                status_changed = \
                    review.encode(req.args['status']) != review.status
                if review.save(req.authname, req.args['status'],
                               req.args['summary']):
                    self._update_tickets(changeset, review, status_changed)
                    tickets = review.tickets
                req.redirect(req.href(req.path_info, tickets=tickets))
            ctx = web_context(req)
            format_summary = functools.partial(format_to_html,
                                               self.env,
                                               ctx,
                                               escape_newlines=True)
            format_time = functools.partial(user_time, req, format_datetime)

            add_stylesheet(req, 'coderev/coderev.css')
            add_script(req, 'coderev/coderev.js')
            add_script_data(
                req, {
                    'review': {
                        'status':
                        review.status,
                        'encoded_status':
                        review.encode(review.status),
                        'summaries': [
                            dict([
                                ('html_summary', format_summary(r['summary'])),
                                ('pretty_when', format_time(r['when'])),
                                ('pretty_timedelta', pretty_timedelta(
                                    r['when'])), ('reviewer', r['reviewer']),
                                ('status', r['status'])
                            ])
                            for r in CodeReview.select(self.env, reponame, rev)
                        ],
                    },
                    'tickets': tickets,
                    'statuses': self.statuses,
                    'form_token': req.form_token,
                })
            req.send_header('Cache-Control', 'no-cache')
        elif req.path_info.startswith('/ticket/'):
            add_stylesheet(req, 'coderev/coderev.css')
        return template, data, content_type
Пример #2
0
    def _do_actions(self, context, actions):
        # Get API component.
        api = self.env[ScreenshotsApi]

        for action in actions:
            if action == 'get-file':
                context.req.perm.assert_permission('SCREENSHOTS_VIEW')

                # Get request arguments.
                screenshot_id = int(context.req.args.get('id') or 0)
                format = context.req.args.get('format') or self.default_format
                width = int(context.req.args.get('width') or 0)
                height =  int(context.req.args.get('height') or 0)

                # Check if requested format is allowed.
                if not format in self.formats:
                    raise TracError(_("Requested screenshot format that is not "
                      "allowed."), _("Requested format not allowed."))

                # Get screenshot.
                screenshot = api.get_screenshot(context, screenshot_id)

                # Check if requested screenshot exists.
                if not screenshot:
                    if context.req.perm.has_permission('SCREENSHOTS_ADD'):
                        context.req.redirect(context.req.href.screenshots(
                          action = 'add'))
                    else:
                        raise TracError(_("Screenshot not found."))

                # Set missing dimensions.
                width = width or screenshot['width']
                height = height or screenshot['height']

                if format == 'html':
                    # Format screenshot for presentation.
                    screenshot['author'] = format_to_oneliner(self.env, context,
                      screenshot['author'])
                    screenshot['name'] = format_to_oneliner(self.env, context,
                      screenshot['name'])
                    screenshot['description'] = format_to_oneliner(self.env,
                      context, screenshot['description'])
                    screenshot['time'] = pretty_timedelta(to_datetime(
                      screenshot['time'], utc))

                    # For HTML preview format return template.
                    context.req.data['screenshot'] = screenshot
                    return ('screenshot', None)
                else:
                    # Prepare screenshot filename.
                    name, ext = os.path.splitext(screenshot['file'])
                    format = (format == 'raw') and ext or '.' + format
                    path = os.path.normpath(os.path.join(self.path, to_unicode(
                      screenshot['id'])))
                    filename = os.path.normpath(os.path.join(path, '%s-%sx%s%s'
                      % (name, width, height, format)))
                    orig_name = os.path.normpath(os.path.join(path, '%s-%sx%s%s'
                      % (name, screenshot['width'], screenshot['height'], ext)))
                    base_name = os.path.normpath(os.path.basename(filename))

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

                    # Create requested file from original if not exists.
                    if not os.path.isfile(filename.encode('utf-8')):
                        self._create_image(orig_name, path, name, format,
                          width, height)

                    # Guess mime type.
                    file = open(filename.encode('utf-8'), "r")
                    file_data = file.read(1000)
                    file.close()
                    mimeview = Mimeview(self.env)
                    mime_type = mimeview.get_mimetype(filename, file_data)
                    if not mime_type:
                        mime_type = 'application/octet-stream'
                    if 'charset=' not in mime_type:
                        charset = mimeview.get_charset(file_data, mime_type)
                        mime_type = mime_type + '; charset=' + charset

                    # Send file to request.
                    context.req.send_header('Content-Disposition',
                      'attachment;filename="%s"' % (base_name))
                    context.req.send_header('Content-Description',
                      screenshot['description'])
                    context.req.send_file(filename.encode('utf-8'), mime_type)

            elif action == 'add':
                context.req.perm.assert_permission('SCREENSHOTS_ADD')

                # Get request arguments.
                index = int(context.req.args.get('index') or 0)

                # Fill data dictionary.
                context.req.data['index'] = index
                context.req.data['versions'] = api.get_versions(context)
                context.req.data['components'] = api.get_components(context)

                # Return template with add screenshot form.
                return ('screenshot-add', None)

            elif action == 'post-add':
                context.req.perm.assert_permission('SCREENSHOTS_ADD')

                # Get image file from request.
                file, filename = self._get_file_from_req(context.req)
                name, ext = os.path.splitext(filename)
                ext = ext.lower()
                filename = name + ext

                # Is uploaded file archive or single image?
                if ext == '.zip':
                    # Get global timestamp for all files in archive.
                    timestamp = to_timestamp(datetime.now(utc))

                    # List files in archive.
                    zip_file = ZipFile(file)
                    for filename in zip_file.namelist():
                        # Test file extensions for supported type.
                        name, ext = os.path.splitext(filename)
                        tmp_ext = ext.lower()[1:]
                        if tmp_ext in self.ext and tmp_ext != 'zip':
                            # Decompress image file
                            data = zip_file.read(filename)
                            file = StringIO(data)
                            filename = to_unicode(os.path.basename(filename))

                            # Screenshots must be identified by timestamp.
                            timestamp += 1

                            # Create image object.
                            image = Image.open(file)

                            # Construct screenshot dictionary from form values.
                            screenshot = {'name' :  context.req.args.get('name'),
                              'description' : context.req.args.get('description'),
                              'time' : timestamp,
                              'author' : context.req.authname,
                              'tags' : context.req.args.get('tags'),
                              'file' : filename,
                              'width' : image.size[0],
                              'height' : image.size[1],
                              'priority' : int(context.req.args.get('priority')
                              or '0')}
                            self.log.debug('screenshot: %s' % (screenshot,))

                            # Save screenshot file and add DB entry.
                            self._add_screenshot(context, api, screenshot, file)

                    zip_file.close()
                else:
                    # Create image object.
                    image = Image.open(file)

                    # Construct screenshot dictionary from form values.
                    screenshot = {'name' :  context.req.args.get('name'),
                      'description' : context.req.args.get('description'),
                      'time' : to_timestamp(datetime.now(utc)),
                      'author' : context.req.authname,
                      'tags' : context.req.args.get('tags'),
                      'file' : filename,
                      'width' : image.size[0],
                      'height' : image.size[1],
                      'priority' : int(context.req.args.get('priority')
                      or '0')}
                    self.log.debug('screenshot: %s' % (screenshot,))

                    # Add single image.
                    self._add_screenshot(context, api, screenshot, file)

                # Close input file.
                file.close()

                # Clear ID to prevent display of edit and delete button.
                context.req.args['id'] = None

            elif action == 'edit':
                context.req.perm.assert_permission('SCREENSHOTS_EDIT')

                # Get request arguments.
                screenshot_id = context.req.args.get('id')

                # Prepare data dictionary.
                context.req.data['screenshot'] = api.get_screenshot(context,
                  screenshot_id)

            elif action == 'post-edit':
                context.req.perm.assert_permission('SCREENSHOTS_EDIT')

                # Get screenshot arguments.
                screenshot_id = int(context.req.args.get('id') or 0)

                # Get old screenshot
                old_screenshot = api.get_screenshot(context, screenshot_id)

                # Check if requested screenshot exits.
                if not old_screenshot:
                    raise TracError(_("Edited screenshot not found."),
                      _("Screenshot not found."))

                # Get image file from request.
                image = context.req.args['image']
                if hasattr(image, 'filename') and image.filename:
                    in_file, filename = self._get_file_from_req(context.req)
                    name, ext = os.path.splitext(filename)
                    filename = name + ext.lower()
                else:
                    filename = None

                # Construct screenshot dictionary from form values.
                screenshot = {'name' :  context.req.args.get('name'),
                  'description' : context.req.args.get('description'),
                  'author' : context.req.authname,
                  'tags' : context.req.args.get('tags'),
                  'components' : context.req.args.get('components') or [],
                  'versions' : context.req.args.get('versions') or [],
                  'priority' : int(context.req.args.get('priority') or '0')}

                # Update dimensions and filename if image file is updated.
                if filename:
                    image = Image.open(in_file)
                    screenshot['file'] = filename
                    screenshot['width'] = image.size[0]
                    screenshot['height'] = image.size[1]

                # Convert components and versions to list if only one item is
                # selected.
                if not isinstance(screenshot['components'], list):
                     screenshot['components'] = [screenshot['components']]
                if not isinstance(screenshot['versions'], list):
                     screenshot['versions'] = [screenshot['versions']]

                self.log.debug('screenshot: %s' % (screenshot))

                # Edit screenshot.
                api.edit_screenshot(context, screenshot_id, screenshot)

                # Prepare file paths.
                if filename:
                    name, ext = os.path.splitext(screenshot['file'])
                    path = os.path.normpath(os.path.join(self.path, to_unicode(
                      screenshot_id)))
                    filepath = os.path.normpath(os.path.join(path, '%s-%ix%i%s'
                      % (name, screenshot['width'], screenshot['height'], ext)))

                    self.log.debug('path: %s' % (path,))
                    self.log.debug('filepath: %s' % (filepath,))

                    # Delete present images.
                    try:
                        for file in os.listdir(path):
                            file = os.path.normpath(os.path.join(path,
                              to_unicode(file)))
                            os.remove(file.encode('utf-8'))
                    except Exception, error:
                        raise TracError(_("Error deleting screenshot. Original "
                          "error message was: %s""") % (to_unicode(error),))

                    # Store uploaded image.
                    try:
                        out_file = open(filepath.encode('utf-8'), 'wb+') 
                        in_file.seek(0)
                        shutil.copyfileobj(in_file, out_file)
                        out_file.close()
                    except Exception, error:
                        try:
                            os.remove(filepath.encode('utf-8'))
                        except:
                            pass
                        raise TracError(_("Error storing file. Is directory "
                          "specified in path config option in [screenshots] "
                          "section of trac.ini existing? Original error "
                          "message was: %s") % (to_unicode(error),))

                # Notify change listeners.
                for listener in self.change_listeners:
                    listener.screenshot_changed(context.req, screenshot,
                      old_screenshot)

                # Clear ID to prevent display of edit and delete button.
                context.req.args['id'] = None