Revision 1b295402
Added by dsorber over 11 years ago
| software/bookmark_library/bmklib/web/base_controller.py | ||
|---|---|---|
|
TEMPLATE_PATH = os.path.join(BASE_PATH, 'bmklib', 'web', 'templates')
|
||
|
|
||
|
# Someday this should go into some sort of configuration
|
||
|
MAX_PER_PAGE = 20
|
||
|
MAX_PER_PAGE = 30
|
||
|
|
||
|
class BaseHTMLController(object):
|
||
|
|
||
| software/bookmark_library/bmklib/web/bmklib.wsgi | ||
|---|---|---|
|
from bmklib.web.controllers.bookmark import BookmarkPageController
|
||
|
import re
|
||
|
|
||
|
from bmklib.web.controllers.all_bookmarks import AllBookmarksPageController
|
||
|
from bmklib.web.controllers.main import MainPageController
|
||
|
|
||
|
# It accepts two arguments:
|
||
| ... | ... | |
|
# start_response is a callback function supplied by the server
|
||
|
# which will be used to send the HTTP status and headers to the server
|
||
|
def application(environ, start_response):
|
||
|
|
||
|
path = environ['PATH_INFO']
|
||
|
|
||
|
if not environ['PATH_INFO'] or environ['PATH_INFO'] == '/':
|
||
|
if not path or path == '/':
|
||
|
|
||
|
controller = MainPageController(environ)
|
||
|
response_headers, response_body = controller.generate_response()
|
||
|
|
||
|
elif environ['PATH_INFO'].startswith('/bookmark'):
|
||
|
elif re.search('^/bookmarks$', path) or re.search('^/bookmarks/', path):
|
||
|
|
||
|
controller = BookmarkPageController(environ)
|
||
|
controller = AllBookmarksPageController(environ)
|
||
|
response_headers, response_body = controller.generate_response()
|
||
|
|
||
|
else:
|
||
|
# User supplied an invalid URL
|
||
|
response_body = 'Invalid URL "%s"' % environ['PATH_INFO']
|
||
| software/bookmark_library/bmklib/web/controllers/all_bookmarks.py | ||
|---|---|---|
|
import math
|
||
|
import os.path
|
||
|
|
||
|
import sqlite3
|
||
|
|
||
|
from bmklib.lib.bookmark import Bookmark
|
||
|
from bmklib.web.base_controller import BaseHTMLController, DB_PATH, MAX_PER_PAGE
|
||
|
|
||
|
class AllBookmarksPageController(BaseHTMLController):
|
||
|
|
||
|
def __init__(self, environ, template_name='all_bookmarks.html'):
|
||
|
super(AllBookmarksPageController, self).__init__(environ, template_name)
|
||
|
|
||
|
def build_content(self):
|
||
|
|
||
|
# Split the path so we can parse it below
|
||
|
path = self.environ['PATH_INFO'][1:]
|
||
|
path_parts = path.split('/')
|
||
|
|
||
|
conn = sqlite3.connect(DB_PATH)
|
||
|
db = conn.cursor()
|
||
|
|
||
|
db = conn.cursor()
|
||
|
db.execute("SELECT COUNT(*) FROM bookmarks")
|
||
|
total_bmks = int(db.fetchone()[0])
|
||
|
self.content['total_num_bmks'] = total_bmks
|
||
|
self.content['max_page_idx'] = math.ceil(float(total_bmks) / MAX_PER_PAGE)
|
||
|
|
||
|
page_idx = 1
|
||
|
|
||
|
# Parse the path and modify the query as needed
|
||
|
if len(path_parts) == 2:
|
||
|
if path_parts[1] == 'all':
|
||
|
db.execute("SELECT id FROM bookmarks WHERE deleted=0")
|
||
|
else:
|
||
|
# Attempt to grab a new query index from the URL
|
||
|
try:
|
||
|
page_idx = int(path_parts[1])
|
||
|
except ValueError:
|
||
|
pass
|
||
|
|
||
|
if page_idx < 1:
|
||
|
page_idx = 1
|
||
|
|
||
|
query = "SELECT id FROM bookmarks WHERE deleted=0 LIMIT {:d}"\
|
||
|
" OFFSET {:d}".format(MAX_PER_PAGE, (page_idx - 1) * MAX_PER_PAGE)
|
||
|
db.execute(query)
|
||
|
else:
|
||
|
db.execute("SELECT id FROM bookmarks WHERE deleted=0 LIMIT {:d}".format(MAX_PER_PAGE))
|
||
|
|
||
|
self.content['page_idx'] = page_idx
|
||
|
|
||
|
# Build Bookmark objects for all of the returned results
|
||
|
bookmarks = [Bookmark(conn, id=row[0]) for row in db.fetchall()]
|
||
|
|
||
|
self.content['bookmarks'] = bookmarks
|
||
|
self.content['path_parts'] = len(path_parts)
|
||
|
|
||
|
# Set previous link to control pagination in the template
|
||
|
if page_idx == 1:
|
||
|
self.content['previous'] = None
|
||
|
else:
|
||
|
prev_idx = page_idx - 1
|
||
|
prev_path = ['..'] * len(path_parts)
|
||
|
prev_path.extend(['bookmarks', str(prev_idx)])
|
||
|
self.content['previous'] = os.path.join(*prev_path)
|
||
|
|
||
|
# Set the next link to control pagination in the template
|
||
|
next_idx = page_idx + 1
|
||
|
if next_idx > self.content['max_page_idx']:
|
||
|
self.content['next'] = None
|
||
|
else:
|
||
|
next_path = ['..'] * len(path_parts)
|
||
|
next_path.extend(['bookmarks', str(next_idx)])
|
||
|
self.content['next'] = os.path.join(*next_path)
|
||
| software/bookmark_library/bmklib/web/controllers/bookmark.py | ||
|---|---|---|
|
import sqlite3
|
||
|
|
||
|
from bmklib.lib.bookmark import Bookmark
|
||
|
from bmklib.web.base_controller import BaseHTMLController, DB_PATH, MAX_PER_PAGE
|
||
|
|
||
|
class BookmarkPageController(BaseHTMLController):
|
||
|
|
||
|
def __init__(self, environ, template_name='bookmark.html'):
|
||
|
super(BookmarkPageController, self).__init__(environ, template_name)
|
||
|
|
||
|
def build_content(self):
|
||
|
|
||
|
# Split the path so we can parse it below
|
||
|
path = self.environ['PATH_INFO'][1:]
|
||
|
path_parts = path.split('/')
|
||
|
|
||
|
conn = sqlite3.connect(DB_PATH)
|
||
|
db = conn.cursor()
|
||
|
|
||
|
page_idx = 0
|
||
|
|
||
|
# Parse the path and modify the query as needed
|
||
|
if len(path_parts) == 2:
|
||
|
if path_parts[1] == 'all':
|
||
|
db.execute("SELECT id FROM bookmarks WHERE deleted=0")
|
||
|
else:
|
||
|
# Attempt to grab a new query index from the URL
|
||
|
try:
|
||
|
page_idx = int(path_parts[1])
|
||
|
except ValueError:
|
||
|
pass
|
||
|
|
||
|
query = "SELECT id FROM bookmarks WHERE deleted=0 LIMIT {:d}"\
|
||
|
" OFFSET {:d}".format(MAX_PER_PAGE, page_idx * MAX_PER_PAGE)
|
||
|
db.execute(query)
|
||
|
else:
|
||
|
db.execute("SELECT id FROM bookmarks WHERE deleted=0 LIMIT {:d}".format(MAX_PER_PAGE))
|
||
|
|
||
|
# Build Bookmark objects for all of the returned results
|
||
|
bookmarks = [Bookmark(conn, id=row[0]) for row in db.fetchall()]
|
||
|
|
||
|
self.content['bookmarks'] = bookmarks
|
||
|
self.content['path_parts'] = len(path_parts)
|
||
|
|
||
|
# Set previous and next to control pagination in the template
|
||
|
if page_idx == 0:
|
||
|
self.content['previous'] = None
|
||
|
else:
|
||
|
prev_idx = page_idx - 1
|
||
|
if len(path_parts) == 2:
|
||
|
self.content['previous'] = '../../bookmark/{:d}'.format(prev_idx)
|
||
|
else:
|
||
|
self.content['previous'] = '../bookmark/{:d}'.format(prev_idx)
|
||
|
|
||
|
next_idx = page_idx + 1
|
||
|
if len(path_parts) == 2:
|
||
|
self.content['next'] = '../../bookmark/{:d}'.format(next_idx)
|
||
|
else:
|
||
|
self.content['next'] = '../bookmark/{:d}'.format(next_idx)
|
||
| software/bookmark_library/bmklib/web/controllers/main.py | ||
|---|---|---|
|
import os.path
|
||
|
|
||
|
import sqlite3
|
||
|
|
||
|
from bmklib.web.base_controller import BaseHTMLController, DB_PATH
|
||
| ... | ... | |
|
|
||
|
def __init__(self, environ, template_name='main.html'):
|
||
|
super(MainPageController, self).__init__(environ, template_name)
|
||
|
|
||
|
def build_link(self, link):
|
||
|
# Create links based on the PATH_INFO
|
||
|
prefix = []
|
||
|
if not self.environ['PATH_INFO']:
|
||
|
prefix = ['/', 'bmk']
|
||
|
|
||
|
prefix.append(link)
|
||
|
return os.path.join(*prefix)
|
||
|
|
||
|
def build_content(self):
|
||
|
conn = sqlite3.connect(DB_PATH)
|
||
|
|
||
|
|
||
|
# Grab the total number of bookmarks
|
||
|
db = conn.cursor()
|
||
|
db.execute("SELECT COUNT(*) FROM bookmarks")
|
||
|
row = db.fetchone()
|
||
|
self.content['total_num_bmks'] = db.fetchone()[0]
|
||
|
|
||
|
|
||
|
links = {'All Bookmarks': self.build_link('bookmarks'),
|
||
|
'All Tags': self.build_link('tags')}
|
||
|
|
||
|
self.content['total_num_bmks'] = row[0]
|
||
|
self.content['links'] = links
|
||
| software/bookmark_library/bmklib/web/templates/all_bookmarks.html | ||
|---|---|---|
|
<html xmlns="http://www.w3.org/1999/xhtml"
|
||
|
xmlns:py="http://genshi.edgewall.org/">
|
||
|
<head>
|
||
|
<title>Bookmark Library</title>
|
||
|
<link rel="stylesheet" type="text/css" href="http://127.0.0.1/htdocs/css/bmk_main.css"></link>
|
||
|
</head>
|
||
|
|
||
|
<body>
|
||
|
<h1>All Bookmarks</h1>
|
||
|
<p>${page_idx} of ${max_page_idx}</p>
|
||
|
<table>
|
||
|
<tr py:for="idx, bookmark in enumerate(bookmarks)" class="${idx % 2 == 1 and 'odd' or 'even'}">
|
||
|
<td>${bookmark.id}</td>
|
||
|
<td><a href="${bookmark.url}">${bookmark.title and bookmark.title or 'no title'}</a></td>
|
||
|
<td><py:for each="tag in bookmark.category_tags"><span class="tag">${tag.value}</span></py:for></td>
|
||
|
<td><py:for each="tag in bookmark.description_tags"><span class="tag">${tag.value}</span></py:for></td>
|
||
|
</tr>
|
||
|
</table>
|
||
|
|
||
|
<py:if test="previous is not None"><a href="bookmark/${previous}">Previous</a></py:if>
|
||
|
|
||
|
<py:if test="next is not None"><a href="bookmark/${next}">Next</a></py:if>
|
||
|
</body>
|
||
|
</html>
|
||
| software/bookmark_library/bmklib/web/templates/bookmark.html | ||
|---|---|---|
|
<html xmlns="http://www.w3.org/1999/xhtml"
|
||
|
xmlns:py="http://genshi.edgewall.org/">
|
||
|
<head>
|
||
|
<title>Bookmark Library</title>
|
||
|
<link rel="stylesheet" type="text/css" href="http://127.0.0.1/htdocs/css/bmk_main.css"></link>
|
||
|
</head>
|
||
|
|
||
|
<body>
|
||
|
<h1>Bookmarks</h1>
|
||
|
|
||
|
<p>${path_parts}</p>
|
||
|
|
||
|
<table>
|
||
|
<tr py:for="idx, bookmark in enumerate(bookmarks)" class="${idx % 2 == 1 and 'odd' or 'even'}">
|
||
|
<td>${bookmark.id}</td>
|
||
|
<td><a href="${bookmark.url}">${bookmark.title and bookmark.title or 'no title'}</a></td>
|
||
|
<td><py:for each="tag in bookmark.category_tags"><span class="tag">${tag.value}</span></py:for></td>
|
||
|
<td><py:for each="tag in bookmark.description_tags"><span class="tag">${tag.value}</span></py:for></td>
|
||
|
</tr>
|
||
|
</table>
|
||
|
|
||
|
<py:if test="previous is not None"><a href="bookmark/${previous}">Previous</a></py:if>
|
||
|
|
||
|
<py:if test="next is not None"><a href="bookmark/${next}">Next</a></py:if>
|
||
|
</body>
|
||
|
</html>
|
||
| software/bookmark_library/bmklib/web/templates/main.html | ||
|---|---|---|
|
<body>
|
||
|
<h1>Bookmark Library</h1>
|
||
|
|
||
|
There are currently ${total_num_bmks} bookmarks in the library.
|
||
|
<p>There are currently ${total_num_bmks} bookmarks in the library.</p>
|
||
|
|
||
|
<ul>
|
||
|
<li><a href="bmk/bookmark">All bookmarks</a></li>
|
||
|
<li>All tags</li>
|
||
|
<li py:for="title, link in links.items()"><a href="${link}">${title}</a></li>
|
||
|
</ul>
|
||
|
</body>
|
||
|
</html>
|
||
I haven't really don't anything yet other than cleanup some of the messiness that I left behind. I fixed pagination and renamed a few things to make them more clear.