<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def preview(self, path=None, extra_context=None, publish=False):
 """ Serve up a project path """

        try:
            self.call_hook("preview", self)

            if path is None:
                path = 'index.html'

            # Detect files
            filepath, mimetype = self._resolve_path(path)

            # Serve dynamic
            if filepath and mimetype and mimetype in self.project.TEMPLATE_TYPES:
                context = self.get_context(publish)
                context.update({
                    "PATH": path,
                    "PREVIEW_SERVER": not publish,
                    "TIMESTAMP": int(time.time()),
                })
                if extra_context:
                    context.update(extra_context)

                rendered = render_template(path, **context)
                return Response(rendered, mimetype=mimetype)

            # Serve static
            if filepath:
                dir, filename = os.path.split(filepath)
                return send_from_directory(dir, filename)

        except Exception as e:
            ex_type, ex, tb = sys.exc_info()
            try:
                # Find template with name of error
                cls = e.__class__
                ex_type, ex, tb = sys.exc_info()

                context = self.project.DEFAULT_CONTEXT
                context.update({
                    'PATH': path,
                    'traceback': traceback.format_exception(ex_type, ex, tb),
                    'e': e,
                })
                if extra_context:
                    context.update(extra_context)

                try:
                    error_path = '_{0}.{1}.html'.format(cls.__module__, cls.__name__)
                    rendered = render_template(error_path, **context)
                except TemplateNotFound:
                    # Find template without underscore prefix, @TODO remove in v1.1
                    error_path = '{0}.{1}.html'.format(cls.__module__, cls.__name__)
                    rendered = render_template(error_path, **context)

                return Response(rendered, mimetype="text/html")
            except TemplateNotFound:
                # Otherwise raise old error
                reraise(ex_type, ex, tb)

        # Last ditch effort -- see if path has "index.html" underneath it
        if not path.endswith("index.html"):
            if not path.endswith("/"):
                path = "{0}/".format(path)
            path = "{0}{1}".format(path, "index.html")
            return self.preview(path)

        # It's a 404
        if path.endswith('/index.html'):
            path = path[:-11]
        rendered = render_template("404.html", PATH=path)
        return Response(rendered, status=404)