Changeset 231:e43a99828990
- Timestamp:
- 2007-08-11 17:40:33
(1 year ago)
- Author:
- Stefan Schwarzer <sschwarzer@sschwarzer.net>
- branch:
- default
- Message:
Handle frames more intelligently. Details:
- If the user types a directory URL into the browser's address line,
it's automatically opened in frames. The advantage is that the user
has neither to enter the special /_WEBSOURCERBROSER_/frames URL nor
has he/she to click "Reset view".
- If a directory link in the directory display (left pane) is clicked,
it opens in a new frameset. This makes it possible to open a
directory link in a new window and have the appropriate frameset
constructed automatically.
- The "frames" builtin is no longer needed and its support has
therefore been removed.
- The code in `browser.py` and `converter.py` has become more
complex/nested, though. Perhaps I can clean that a bit up.
-
Files:
-
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
| r228 |
r231 |
|
| 84 | 84 | content_type="text/css", |
|---|
| 85 | 85 | mtime=os.path.getmtime(actual_css_path())) |
|---|
| 86 | | elif builtin == "frames": |
|---|
| 87 | | self.send_response(httplib.OK) |
|---|
| 88 | | header_content_type = "text/html; charset=%s" % \ |
|---|
| 89 | | coding.DEFAULT_ENCODING |
|---|
| 90 | | self.send_header("Content-type", header_content_type) |
|---|
| 91 | | self.end_headers() |
|---|
| 92 | | self.wfile.write(coding.encode(template.FRAMESET) % { |
|---|
| 93 | | 'dir_target': config.DIR_WINDOW_TARGET, |
|---|
| 94 | | 'source_target': config.SOURCE_WINDOW_TARGET, |
|---|
| 95 | | 'host': config.http_host, 'port': config.http_port}) |
|---|
| 96 | 86 | elif builtin == "help": |
|---|
| 97 | 87 | self.emit_data(template.HELP, title=u"Websourcebrowser help", |
|---|
| … | … | |
| 121 | 111 | def emit_data(self, data=u"", title=u"", content_type="text/html", |
|---|
| 122 | 112 | h1_class="Path", http_status=httplib.OK, mtime=None, |
|---|
| 123 | | refresh_html=u""): |
|---|
| | 113 | refresh_html=u"", use_header_and_footer=True): |
|---|
| 124 | 114 | """ |
|---|
| 125 | 115 | Emit the `data` on the HTTP output stream with a content type |
|---|
| … | … | |
| 129 | 119 | 200 (OK). If `mtime` is set, it's taken as a floating point |
|---|
| 130 | 120 | value like from `time.time()` to set a Last-Modified header. |
|---|
| | 121 | If `use_header_and_footer` is true (the default), |
|---|
| | 122 | prepend/append the header and footer templates from the |
|---|
| | 123 | `template` module. |
|---|
| 131 | 124 | """ |
|---|
| 132 | 125 | self.send_response(http_status) |
|---|
| … | … | |
| 147 | 140 | h1_class = "Error" |
|---|
| 148 | 141 | title = httplib.responses[http_status] |
|---|
| 149 | | self.wfile.write(coding.encode(template.HEADER % { |
|---|
| 150 | | 'title': cgi.escape(title), |
|---|
| 151 | | 'project_title': cgi.escape(config.project_title), |
|---|
| 152 | | 'h1_class': h1_class, |
|---|
| 153 | | 'special_dir': config.SPECIAL_DIR, |
|---|
| 154 | | 'refresh_html': refresh_html})) |
|---|
| | 142 | if use_header_and_footer: |
|---|
| | 143 | self.wfile.write(coding.encode(template.HEADER % { |
|---|
| | 144 | 'title': cgi.escape(title), |
|---|
| | 145 | 'project_title': cgi.escape(config.project_title), |
|---|
| | 146 | 'h1_class': h1_class, |
|---|
| | 147 | 'special_dir': config.SPECIAL_DIR, |
|---|
| | 148 | 'refresh_html': refresh_html})) |
|---|
| 155 | 149 | if content_type.startswith("text/"): |
|---|
| 156 | 150 | self.wfile.write(coding.encode(data)) |
|---|
| 157 | 151 | else: |
|---|
| 158 | 152 | self.wfile.write(data) |
|---|
| 159 | | if content_type == "text/html": |
|---|
| | 153 | if content_type == "text/html" and use_header_and_footer: |
|---|
| 160 | 154 | self.wfile.write(coding.encode(template.FOOTER)) |
|---|
| 161 | 155 | |
|---|
| 162 | | def _path_and_params(self, url): |
|---|
| | 156 | def _url_and_params(self, url): |
|---|
| 163 | 157 | """ |
|---|
| 164 | 158 | Return a tuple, splitting the URL `url` into an URL without |
|---|
| … | … | |
| 177 | 171 | self.handle_builtin(self.path) |
|---|
| 178 | 172 | return |
|---|
| 179 | | # separate path and query parameters |
|---|
| 180 | | url, params = self._path_and_params(self.path) |
|---|
| | 173 | # separate URL and query parameters |
|---|
| | 174 | url, params = self._url_and_params(self.path) |
|---|
| 181 | 175 | try: |
|---|
| 182 | 176 | path = urlpath.to_file_system(config.root, url) |
|---|
| … | … | |
| 185 | 179 | # avoiding information disclosure (double dot attack) |
|---|
| 186 | 180 | self.emit_data(http_status=httplib.BAD_REQUEST) |
|---|
| | 181 | use_header_and_footer = True |
|---|
| 187 | 182 | if not os.path.exists(path): |
|---|
| 188 | 183 | self.emit_data(http_status=httplib.NOT_FOUND) |
|---|
| 189 | 184 | else: |
|---|
| 190 | 185 | if os.path.isdir(path): |
|---|
| 191 | | # extract `dir_levels` parameter |
|---|
| 192 | | html = converter.dir_to_html(path, params) |
|---|
| | 186 | use_frames = (params.get('frames', "yes") == "yes") |
|---|
| | 187 | if use_frames: |
|---|
| | 188 | params['frames'] = "no" |
|---|
| | 189 | dir_url = session.default_session.add_to_url(url, params) |
|---|
| | 190 | html = template.FRAMESET % { |
|---|
| | 191 | 'dir_url': dir_url, |
|---|
| | 192 | 'dir_target': config.DIR_WINDOW_TARGET, |
|---|
| | 193 | 'source_target': config.SOURCE_WINDOW_TARGET, |
|---|
| | 194 | 'host': config.http_host, 'port': config.http_port} |
|---|
| | 195 | use_header_and_footer = False |
|---|
| | 196 | else: |
|---|
| | 197 | html = converter.dir_to_html(path, params) |
|---|
| 193 | 198 | elif self.is_image_path(path): |
|---|
| 194 | 199 | html = converter.image_to_html(url) |
|---|
| … | … | |
| 205 | 210 | title = coding.decode(url[1:]) or u"." |
|---|
| 206 | 211 | title = urllib.unquote(title) |
|---|
| 207 | | self.emit_data(html, title=title, mtime=os.path.getmtime(path)) |
|---|
| | 212 | self.emit_data(html, title=title, mtime=os.path.getmtime(path), |
|---|
| | 213 | use_header_and_footer=use_header_and_footer) |
|---|
| 208 | 214 | |
|---|
| 209 | 215 | # |
|---|
| r226 |
r231 |
|
| 126 | 126 | # show horizontal menu of directory levels |
|---|
| 127 | 127 | add_html('<p class="Options">') |
|---|
| 128 | | add_html('<a href="/%s/frames" target="_top">Reset view</a>' % |
|---|
| 129 | | config.SPECIAL_DIR) |
|---|
| | 128 | add_html('<a href="/" target="_top">Reset view</a>') |
|---|
| 130 | 129 | add_html(' ') |
|---|
| 131 | 130 | add_html('<a href="/%s/help" target="%s">Help</a>' % |
|---|
| … | … | |
| 197 | 196 | if path != config.root: |
|---|
| 198 | 197 | parent_url = urlpath.to_url(config.root, path) + "/.." |
|---|
| | 198 | params['frames'] = "yes" |
|---|
| 199 | 199 | parent_url = session.default_session.add_to_url(parent_url, params) |
|---|
| 200 | 200 | add_html(u'<tr><td><span class="Options">' |
|---|
| 201 | | u'<a href="%s">up</a></span></td></tr>' % parent_url) |
|---|
| | 201 | u'<a href="%s" target="_top">up</a></span></td></tr>' % parent_url) |
|---|
| 202 | 202 | for item in itertools.ifilterfalse(_ignore_item, |
|---|
| 203 | 203 | walk(path, params['dir_levels'])): |
|---|
| 204 | | # if the item is a directory, append a slash |
|---|
| 205 | 204 | if os.path.isdir(item): |
|---|
| 206 | | target_attribute = u"" |
|---|
| 207 | 205 | suffix = u" /" |
|---|
| | 206 | target_attribute = u' target="_top"' |
|---|
| | 207 | params['frames'] = "yes" |
|---|
| 208 | 208 | else: |
|---|
| 209 | 209 | suffix = "" |
|---|
| 210 | 210 | target_attribute = u' target="%s"' % config.SOURCE_WINDOW_TARGET |
|---|
| | 211 | params['frames'] = "no" |
|---|
| 211 | 212 | spacing = (u'<span class="Indent">' + |
|---|
| 212 | 213 | (u'>' + (config.dir_indent-1) * u' ') * \ |
|---|
| r225 |
r231 |
|
| 108 | 108 | class DefaultSession(Session): |
|---|
| 109 | 109 | def __init__(self): |
|---|
| 110 | | super(DefaultSession, self).__init__(['dir_levels']) |
|---|
| | 110 | super(DefaultSession, self).__init__(['dir_levels', 'frames']) |
|---|
| 111 | 111 | |
|---|
| 112 | 112 | def get_from_url(self, url): |
|---|
| r161 |
r231 |
|
| 60 | 60 | </head> |
|---|
| 61 | 61 | <frameset cols="30%%,70%%"> |
|---|
| 62 | | <frame name="%(dir_target)s" src="http://%(host)s:%(port)s/" /> |
|---|
| | 62 | <frame name="%(dir_target)s" src="http://%(host)s:%(port)s%(dir_url)s" /> |
|---|
| 63 | 63 | <frame name="%(source_target)s" /> |
|---|
| 64 | 64 | <noframes> |
|---|