leonardo-0.6.0/0000755000076500007650000000000010247462064014451 5ustar jtauberjtauber00000000000000leonardo-0.6.0/bin/0000755000076500007650000000000010247462064015221 5ustar jtauberjtauber00000000000000leonardo-0.6.0/bin/convert_lfs.py0000644000076500007650000000502010247461761020117 0ustar jtauberjtauber00000000000000#!/usr/bin/env python # # Copyright (C) 2003-2005 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # """ This script converts .ldv bundles by moving the following to the property db: - title in __content__ - mtime (last modified time) Previous __content__ files are backed up as content.bak """ import os import sys import re import shutil # adjust accordingly if need be sys.path.append("../lib/") import filesystem def usage(): print 'Usage:', sys.argv[0], '' sys.exit(0) if len(sys.argv) != 2: usage() lfs_root = sys.argv[1] lfs = filesystem.LeonardoFileSystem(lfs_root) def convert(lfs, key=""): directories, files = lfs.get_children(key) for filename in files: f = lfs.get(key + "/" + filename) print f.key content = f.get_content() content_type = f.get_content_type() files = f.get_content_files_() ST_MTIME = 8 if files: last_mod = os.stat(files[0])[ST_MTIME] else: last_mod = None if content_type in ["wiki04", "wikiBNL"]: m = re.match(r'==([^=]+)==', content) if m: title = m.group(1) rest = content[m.end(1)+2:] print "TITLE:", title shutil.copy2(f.get_content_filename_(content_type), f.get_directory_() + "content.bak") f.set_content(rest, content_type) print "SET NEW CONTENT" f.set_property("page_title", title) print "SET PAGE TITLE" else: print "NO TITLE" else: print "NOT WIKI", content_type if last_mod: f.set_property("last_modified", last_mod) print "SET LAST MODIFIED PROPERTY" for directory in directories: convert(lfs, key + "/" + directory) convert(lfs)leonardo-0.6.0/bin/convert_static.py0000644000076500007650000000356610247461761020637 0ustar jtauberjtauber00000000000000#!/usr/bin/env python # # Copyright (C) 2003-2004 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # """ This script converts the files in the static directory to .ldv bundles in the Leonardo File System. """ # based on Min Sik Kim's earlier leonconv-04.py for converting 0.3 to 0.4 LFS. import os import sys import shutil from stat import ST_MODE, S_IXUSR, S_IXGRP, S_IXOTH def usage(): print 'Usage:', sys.argv[0], ' ' sys.exit(0) if len(sys.argv) != 3: usage() src_root, dst_root = sys.argv[1], sys.argv[2] if not os.path.exists(src_root): sys.stderr.write('Error: cannot find %s\n' % srcdir) sys.exit(1) for root, dirs, files in os.walk(src_root): for name in files: src = os.path.join(root, name) ext = name.split(".")[-1] dst = os.path.join(root.replace(src_root, dst_root), name + '.ldv', '__content__.' + ext) dstdir = os.path.dirname(dst) if not os.path.exists(dstdir): os.makedirs(dstdir) shutil.copy2(src, dst) shutil.copystat(src, dstdir) os.chmod(dstdir, os.stat(dstdir)[ST_MODE] | S_IXUSR | S_IXGRP | S_IXOTH) leonardo-0.6.0/bin/create_user.py0000755000076500007650000000320210247461761020077 0ustar jtauberjtauber00000000000000#!/usr/bin/env python # # Copyright (C) 2003-2004 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # """ This script is used for creating or modifying users in the user database. """ USER_DB = "../data/user_db" def create_user(name, email, password): """ Creates (or overwrites) a new user entry in the user database. """ import anydbm, sha user_db = anydbm.open(USER_DB, "c") user_db[email] = "%s|%s|%s" % (email, name, sha.sha(password).hexdigest()) from getpass import getpass if __name__ == "__main__": name = raw_input("User's Full Name: ") email = raw_input("User's Email Address (used as user id): ") while True: password = getpass("User's Password: ") password_confirm = getpass("Confirm Password: ") if password == password_confirm: break print "Passwords didn't match." print "Creating account...", create_user(name, email, password) print "done." leonardo-0.6.0/bin/regen_index.py0000644000076500007650000000333710247461761020073 0ustar jtauberjtauber00000000000000#!/usr/bin/env python # # Copyright (C) 2003-2005 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # """ This script regenerates the property index. """ import sys import os import os.path # adjust accordingly if need be sys.path.append("../lib/") import filesystem def usage(): print 'Usage:', sys.argv[0], '' sys.exit(0) if len(sys.argv) != 2: usage() lfs_root = sys.argv[1] lfs = filesystem.LeonardoFileSystem(lfs_root) index_filename = os.path.join(lfs_root, "property_index") if os.access(index_filename, os.F_OK): os.remove(index_filename) def reindex(lfs, key=""): directories, files = lfs.get_children(key) for filename in files: f = lfs.get(key + "/" + filename) print f.key for name in f.get_properties(): value = f.get_property(name) if value != None: print "\t", name, value lfs.add_property(f.key, name, value) for directory in directories: reindex(lfs, key + "/" + directory) reindex(lfs)leonardo-0.6.0/cgi-bin/0000755000076500007650000000000010247462064015761 5ustar jtauberjtauber00000000000000leonardo-0.6.0/cgi-bin/leonardo.config0000644000076500007650000000205710247461761020762 0ustar jtauberjtauber00000000000000## Configuration file for Leonardo # # You will almost certainly want to change the settings under [page], [blog] # and [atom] # # For actual deployment you will likely want to change data_dir as well. # Without a ScriptAlias, you will probably also need to change cgi-root. [page] site_title : Leonardo site_sub_title : sample site copyright_holder : James Tauber [blog] blog_title : Leonardo Sample Blog site_url : http://localhost:8000/ [atom] blog_author : James Tauber [DEFAULT] # location of data directory # uncomment and change value if data_dir not parallel to lib # note: must end with a slash # data_dir : # location of lfs directory # uncomment and change value if not under data_dir # note: must end with a slash # lfs_root : # http path to the cgi-bin script cgi_root : / # usually blank path_prefix : # http path to the home page # must end with a slash when expanded home_href : %(cgi_root)s%(path_prefix)s leonardo-0.6.0/cgi-bin/leonardo.py0000755000076500007650000000257010247461761020150 0ustar jtauberjtauber00000000000000#!/usr/bin/env python # # Copyright (C) 2003-2005 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # ## Leonardo main CGI script import cgitb; cgitb.enable() from os.path import join, dirname, abspath # location of leonardo modules (full path to leonardo lib directory) # the following is just to get you started - you'll probably want to change it # to the literal path leonardo_lib = abspath(join(dirname(__file__), "../lib")) # location of main configuration file for this instance main_config = join(dirname(__file__), "leonardo.config") import sys; sys.path.append(leonardo_lib) import config import core leonardo = core.Leonardo(config.Configurator(main_config)) leonardo.dispatch()leonardo-0.6.0/CREDITS0000644000076500007650000000030510247461761015472 0ustar jtauberjtauber00000000000000Principal Developer James Tauber Developers Bryan Lawrence Contributors Peter Sefton Min Sik Kim C. J. Wagenius Grigory Bakunov Dave Warnock Xavier Verges leonardo-0.6.0/data/0000755000076500007650000000000010247462064015362 5ustar jtauberjtauber00000000000000leonardo-0.6.0/data/lfs/0000755000076500007650000000000010247462064016146 5ustar jtauberjtauber00000000000000leonardo-0.6.0/data/lfs/__home__.ldv/0000755000076500007650000000000010247462064020456 5ustar jtauberjtauber00000000000000leonardo-0.6.0/data/lfs/__home__.ldv/__content__.wiki040000644000076500007650000000526310247461761023766 0ustar jtauberjtauber00000000000000It is recommended you read this page to get started. Further enquires should be directed to the [http://mail.pyworks.org/listinfo/leonardo Leonardo Mailing List]. ===Users and Login=== To be able to edit pages or create new ones, you will need to first of all create a user account by running create_user.py in the Leonardo bin directory. You will then be able to log in via the Login link at the bottom of the menu to the left. ===Editing Existing Pages=== To edit an existing page, click on the Edit Page link at the bottom of the menu. You can find out more about the wiki formatting used in the [Wiki Formatting Guide]. ===Creating a New Page=== A page may be created one of two ways. If you go to a non-existent page while logged in, you can click on Edit Page to create the page directly. Alternatively, you can use the draft facility. Click on Drafts at the bottom of the menu (while logged in) and you can create a draft page. Once you have created a draft page, you can promote it to a real page (which includes as a blog entry). ===Blog Entries=== A blog entry is simply a page under blog////. Entries here will show up in daily, monthly, yearly and overall blog lists as well as in the Atom feed. ===Atom Feeds=== A titles-only atom feed is available at /atom and a full-entry atom feed at /atom/full. Note that these paths can be changed by overriding the relevant atom provider settings in your leonardo.config file. ===Comments and Trackbacks=== When you create or edit a page, you will have the option to turn on comments and/or trackbacks. ===Categories=== When you create or edit a page, you can specify a list of categories separated by whitespace. Categories in Leonardo are just page names. For example, a category "python" corresponds to page "python". If you would like a list of all the pages in category foo, insert "category/foo". See the [Wiki Formatting Guide] for how to insert. ===Non-Wiki Files=== Non-wiki files such as images or code can be uploaded using the "Upload File" page linked from the bottom of the menu when logged in. It is also possible to edit such files if they are text. An example is at [:/static/sample]. ===Customization=== Customisation can be done in a number of places: * the leonardo.config file in cgi-bin * the menu (see below) * the css stylesheet (see below) * individual templates under the lib/providers packages ===Editing the Menu=== To change the menu to the left, go to [:edit?resource=__menu__ /edit?resource=__menu__] while logged. ===Editing the CSS=== To make a change to the CSS stylesheet, go to [:edit?resource=css /edit?resource=css] while logged in.���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������leonardo-0.6.0/data/lfs/__home__.ldv/property_db����������������������������������������������������0000644�0000765�0000765�00000030000�10247461761�022726� 0����������������������������������������������������������������������������������������������������ustar �jtauber�������������������������jtauber�������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������a������������������������������� ��5������������������������^h������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������F1116979561.845598 .last_modifiedS'Welcome to Leonardo!' p1 .page_titleS'NO' p1 .allow_comments������������������������������������������ ��5������������������������^h����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������S'NO' p1 .allow_trackbacksleonardo-0.6.0/data/lfs/__menu__.ldv/���������������������������������������������������������������0000755�0000765�0000765�00000000000�10247462064�020472� 5����������������������������������������������������������������������������������������������������ustar �jtauber�������������������������jtauber�������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������leonardo-0.6.0/data/lfs/__menu__.ldv/__content__.wiki04���������������������������������������������0000644�0000765�0000765�00000000413�10247461761�023772� 0����������������������������������������������������������������������������������������������������ustar �jtauber�������������������������jtauber�������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������===General=== [http://jtauber.com/leonardo Leonardo Home Page] [Wiki Formatting Guide] [Wiki Formatting Guide 2] ===[Blog]=== [insert:calendar] [:/atom/ title-only atom feed] [:/atom/full/ full-entry atom feed] [:/blog/all/ all blog entries]�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������leonardo-0.6.0/data/lfs/blog/�����������������������������������������������������������������������0000755�0000765�0000765�00000000000�10247462064�017071� 5����������������������������������������������������������������������������������������������������ustar �jtauber�������������������������jtauber�������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������leonardo-0.6.0/data/lfs/blog/2004/������������������������������������������������������������������0000755�0000765�0000765�00000000000�10247462064�017456� 5����������������������������������������������������������������������������������������������������ustar �jtauber�������������������������jtauber�������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������leonardo-0.6.0/data/lfs/blog/2004/12/���������������������������������������������������������������0000755�0000765�0000765�00000000000�10247462064�017700� 5����������������������������������������������������������������������������������������������������ustar �jtauber�������������������������jtauber�������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������leonardo-0.6.0/data/lfs/blog/2004/12/16/������������������������������������������������������������0000755�0000765�0000765�00000000000�10247462064�020126� 5����������������������������������������������������������������������������������������������������ustar �jtauber�������������������������jtauber�������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������leonardo-0.6.0/data/lfs/blog/2004/12/16/my_first_blog_entry.ldv/������������������������������������0000755�0000765�0000765�00000000000�10247462064�024772� 5����������������������������������������������������������������������������������������������������ustar �jtauber�������������������������jtauber�������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������leonardo-0.6.0/data/lfs/blog/2004/12/16/my_first_blog_entry.ldv/__content__.wiki04������������������0000644�0000765�0000765�00000000034�10247461761�030271� 0����������������������������������������������������������������������������������������������������ustar �jtauber�������������������������jtauber�������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������This is my first blog entry.����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������leonardo-0.6.0/data/lfs/blog/2004/12/16/my_first_blog_entry.ldv/property_db�������������������������0000644�0000765�0000765�00000030000�10247461761�027242� 0����������������������������������������������������������������������������������������������������ustar �jtauber�������������������������jtauber�������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������a������������������������������� ��;u������������������������^h�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������S'My First Blog Entry' p1 .page_titleS'NO' p1 .allow_comments������������������������������������������ ��;u������������������������^h����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������S'NO' p1 .allow_trackbacksleonardo-0.6.0/data/lfs/blog.ldv/�������������������������������������������������������������������0000755�0000765�0000765�00000000000�10247462064�017655� 5����������������������������������������������������������������������������������������������������ustar �jtauber�������������������������jtauber�������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������leonardo-0.6.0/data/lfs/blog.ldv/__content__.wiki04�������������������������������������������������0000644�0000765�0000765�00000000022�10247461761�023151� 0����������������������������������������������������������������������������������������������������ustar �jtauber�������������������������jtauber�������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������This is your blog!��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������leonardo-0.6.0/data/lfs/blog.ldv/property_db��������������������������������������������������������0000644�0000765�0000765�00000030000�10247461761�022125� 0����������������������������������������������������������������������������������������������������ustar �jtauber�������������������������jtauber�������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������a������������������������������� ��2������������������������^h���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������S'Your Blog' p1 .page_titleS'NO' p1 .allow_comments������������������������������������������ ��2������������������������^h����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������S'NO' p1 .allow_trackbacksleonardo-0.6.0/data/lfs/css.ldv/��������������������������������������������������������������������0000755�0000765�0000765�00000000000�10247462064�017522� 5����������������������������������������������������������������������������������������������������ustar �jtauber�������������������������jtauber�������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������leonardo-0.6.0/data/lfs/css.ldv/__content__.css�����������������������������������������������������0000644�0000765�0000765�00000006462�10247461761�022515� 0����������������������������������������������������������������������������������������������������ustar �jtauber�������������������������jtauber�������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������body { color : #333; background-color : #FFF; font-family : verdana, arial, helvetica, sans-serif; font-size : 0.8em; margin : 0px; } div#top { margin : 0px; padding-top : 5px; padding-bottom : 5px; background-color : #454; color : #996; } div#top h1 { font : 2.56em "trebuchet ms", verdana, arial, helvetica, sans-serif; padding-left : 15px; margin-top : 8px; margin-bottom : 8px; text-shadow: 3px 3px 3px #000; } div#top h2 { font : 1.6em "trebuchet ms", verdana, arial, helvetica, sans-serif; padding-left : 20px; margin-bottom : 8px; margin-top : 0px; font-style : italic; text-shadow: 3px 3px 3px #000; } div#main { margin-left : 22%; margin-right : 10%; margin-top : 0px; padding-top : 20px; padding-left : 10px; padding-bottom : 20px; } div#main h2 { margin-top : 0px; margin-bottom : 5px; padding : 0px; font : 1.92em "trebuchet ms", verdana, arial, helvetica, sans-serif; } div#main h3 { margin-top : 0px; margin-bottom : 5px; padding : 0px; font : 1.5em arial, helvetica, sans-serif; } div#main h4 { margin-top : 20px; margin-bottom : 0px; padding : 0px; border-bottom : 1px solid #444; font : bold 1.2em arial, helvetica, sans-serif; } div#main p { margin-top : 0px; margin-bottom : 10px; padding : 0px; } div#menu { float : left; width : 20%; margin-top : 0px; margin-right : 0px; padding-left : 15px; padding-top : 20px; padding-right : 10px; padding-bottom : 20px; border-right : 1px solid #ddd; } div#menu h3 { margin-bottom : 3px; padding-top : 0px; margin-top : 5px; border-bottom : 1px solid #ccc; font : bold 1em verdana, arial, helvetica, sans-serif; } div#menu p { margin-top : 0px; margin-bottom : 0px; font : 0.9em "trebuchet ms", verdana, arial, helvetica, sans-serif; line-height : 1.1em; } a:link, a:visited, a:active { color : #996; text-decoration : none; background-color : transparent; } a:hover { text-decoration : underline; background-color : transparent; } a.external { font-style : italic; } img { border : 0px; } div#bottom { clear : left; font-size : 0.8em; border-top : 1px solid #DDD; margin-top : 0px; padding-bottom : 5px; text-align : right; padding-right : 15px; color : #AAA; } .debug { font-size : 0.8em; color : #AAA; } tt { font-size : 1.21em; } p.blog_date { font-size : 0.8em; color : #666; } div.comment, div.trackback { border-top: 1px solid #999; margin: 10px 5px 5px 5px; padding: 3px; } p.comment_citation, p.trackback_citation { font-size : 0.8em; font-style: italic; } .footnotes { font-size : smaller; border-top : 1px solid #DDD; padding-top : 10px; } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������leonardo-0.6.0/data/lfs/draft/����������������������������������������������������������������������0000755�0000765�0000765�00000000000�10247462064�017246� 5����������������������������������������������������������������������������������������������������ustar �jtauber�������������������������jtauber�������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������leonardo-0.6.0/data/lfs/draft/my_first_blog_entry.ldv/����������������������������������������������0000755�0000765�0000765�00000000000�10247462064�024112� 5����������������������������������������������������������������������������������������������������ustar �jtauber�������������������������jtauber�������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������leonardo-0.6.0/data/lfs/draft/my_first_blog_entry.ldv/__content__.wiki04����������������������������0000644�0000765�0000765�00000000047�10247461761�027415� 0����������������������������������������������������������������������������������������������������ustar �jtauber�������������������������jtauber�������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������This is a draft of my first blog entry.�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������leonardo-0.6.0/data/lfs/draft/my_first_blog_entry.ldv/property_db�����������������������������������0000644�0000765�0000765�00000030000�10247461761�026362� 0����������������������������������������������������������������������������������������������������ustar �jtauber�������������������������jtauber�������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������a��������������������������������� >��ʂ��3����������������������^h�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������S'My First Blog Entry' p1 .page_titleS'NO' p1 .allow_comments������������������������������������������ >��ʂ��3����������������������^h����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������S'NO' p1 .allow_trackbacksleonardo-0.6.0/data/lfs/property_index��������������������������������������������������������������0000644�0000765�0000765�00000030000�10247461761�021140� 0����������������������������������������������������������������������������������������������������ustar �jtauber�������������������������jtauber�������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������a������������������������������� ��SA������������������������^h��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� � n ` �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������(dp1 F1116979561.845598 (lp2 S'__home__' p3 asF1116979362.5375631 (lp4 sF1116979500.352155 (lp5 s.last_modified(dp1 S'None' p2 (lp3 S'blog' p4 asS'My Blog' p5 (lp6 S'blog' p7 asS'My First Blog Entry' p8 (lp9 S'blog/2004/12/16/my_first_blog_entry' p10 aS'draft/my_first_blog_entry' p11 asS'Wiki Formatting Guide (wikiBNL)' p12 (lp13 S'wiki_formatting_guide_2' p14 asS'Your Blog' p15 (lp16 S'blog' p17 asS'Welcome to Leonardo!' p18 (lp19 S'__home__' p20 asS'Wiki Formatting Guide (wiki04)' p21 (lp22 S'wiki_formatting_guide' p23 as.page_title(dp1 S'NO' p2 (lp3 S'blog' p4 aS'blog/2004/12/16/my_first_blog_entry' p5 aS'blog' p6 aS'blog' p7 aS'draft/my_first_blog_entry' p8 aS'wiki_formatting_guide' p9 aS'wiki_formatting_guide_2' p10 aS'__home__' p11 as.allow_comments������������������������������������������ ��SA������������������������^h�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������(dp1 S'NO' p2 (lp3 S'blog' p4 aS'blog/2004/12/16/my_first_blog_entry' p5 aS'blog' p6 aS'blog' p7 aS'draft/my_first_blog_entry' p8 aS'wiki_formatting_guide' p9 aS'wiki_formatting_guide_2' p10 aS'__home__' p11 as.allow_trackbacksleonardo-0.6.0/data/lfs/static/���������������������������������������������������������������������0000755�0000765�0000765�00000000000�10247462064�017435� 5����������������������������������������������������������������������������������������������������ustar �jtauber�������������������������jtauber�������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������leonardo-0.6.0/data/lfs/static/sample.ldv/����������������������������������������������������������0000755�0000765�0000765�00000000000�10247462064�021502� 5����������������������������������������������������������������������������������������������������ustar �jtauber�������������������������jtauber�������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������leonardo-0.6.0/data/lfs/static/sample.ldv/__content__.txt�������������������������������������������0000644�0000765�0000765�00000000060�10247461761�024510� 0����������������������������������������������������������������������������������������������������ustar �jtauber�������������������������jtauber�������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������This is an example of a statically served file. ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������leonardo-0.6.0/data/lfs/wiki_formatting_guide.ldv/��������������������������������������������������0000755�0000765�0000765�00000000000�10247462064�023304� 5����������������������������������������������������������������������������������������������������ustar �jtauber�������������������������jtauber�������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������leonardo-0.6.0/data/lfs/wiki_formatting_guide.ldv/__content__.wiki04��������������������������������0000644�0000765�0000765�00000002424�10247461761�026610� 0����������������������������������������������������������������������������������������������������ustar �jtauber�������������������������jtauber�������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������===Headings=== ==Second Level Heading== ===Third Level Heading=== ====Fourth Level Heading==== ===Lists=== asterix at the start of a line give you * this ===Blocks=== : a colon and a space at the start of a line for block quotes Four spaces at start of line for pre Empty lines mark paragraph boundaries ===Character Formatting=== Surround with asterixes for *blog* and two single quotes for ''italic'' Three dashes --- for emdash. ===Links=== Internal wiki links are surround by square brackets, e.g. [wiki formatting guide]. External links are surrounded by squared brackets and begin with the URI followed by a space followed by a title, e.g. [http://jtauber.com/leonardo Leonardo Home Page]. Internal links that involve / or need to be titled differently are surround by [: and ] with the path followed by a space followed by the title to use, e.g. [:blog/2004 the 2004 blog]. Books can be linked via ISBN to amazon using [amazon:<isbn>]. ===Insertions=== Images can be inserted using [image: and ] surrounding the image path followed by a space followed by the alt text. Other wiki pages can be inserted by using prefixing the wiki link with insert: as demonstrated below: [insert:blog/2004/12/16/my_first_blog_entry]��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������leonardo-0.6.0/data/lfs/wiki_formatting_guide.ldv/property_db���������������������������������������0000644�0000765�0000765�00000030000�10247461761�025554� 0����������������������������������������������������������������������������������������������������ustar �jtauber�������������������������jtauber�������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������a������������������������������� K����D����������������������^h������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������S'Wiki Formatting Guide (wiki04)' p1 .page_titleS'NO' p1 .allow_comments������������������������������������������ K����D����������������������^h����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������S'NO' p1 .allow_trackbacksleonardo-0.6.0/data/lfs/wiki_formatting_guide_2.ldv/������������������������������������������������0000755�0000765�0000765�00000000000�10247462064�023525� 5����������������������������������������������������������������������������������������������������ustar �jtauber�������������������������jtauber�������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������leonardo-0.6.0/data/lfs/wiki_formatting_guide_2.ldv/__content__.wikiBNL�����������������������������0000644�0000765�0000765�00000007551�10247461761�027227� 0����������������������������������������������������������������������������������������������������ustar �jtauber�������������������������jtauber�������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������This is a guide to Bryan Lawrence's modified wiki format designated "wikiBNL". Syntax supported includes: * Links (local, and external, labelled or otherwise, including images) * Lists (obviously), including bulleted and enumerated (to four deep) * Tables * Highlighting, Italics, Math mode (simple and latex if available) * Code Higlighting (where source-highlight is also available) * Preformatted Text and Blockquoting * Footnotes are supported too [fn: All you need do is wrap the footnote text in between square brackets with fn following the first one, e.g.\[fn: text\]]. Note that both \[ and \* can be escaped by using a \ before the \[ or \*. (Sometimes you'll also need to escape the return ],e.g. in a footnote), but generally not). Paragraphs are delineated by a blank line. === Links === * Simple local links are done with \[WikiFormat] to give you [WikiFormat]. * Local links can be renamed using \[:WikiFormat local wiki instructions] to give [:WikiFormat local wiki instructions]. * Remote Links are simply \[http:blah] or \[http:blah with local label]. * Images are included by using [image: linktoimage] === Bold and Italic Text === You can easily produce *bold* and ''italic'' text using \*bold\* and a pair of single quotes either side of the required text, e.g. [pre You can easily produce *bold* and ''italic'' pre] === Preformatted Text and Blockquotes === For preformatted text, simply surround your material with [pre and pre] each on their own lines, without following spaces befor the carriage returns, to get [pre exactly \[&<what you typed pre] For Blockquotes, begin the material with a colon in the first column, followed by a space, to get : Something someone else said. === Tables === | one |2 two | | 1 | 2 | 3 | came from [pre | one |2 two | | 1 | 2 | 3 | pre] === Lists === * lists ** can *** go **** four deep [pre * lists ** can *** go **** four deep pre] Numbered too! 0 something 00 can 000 be numbered 0000 four deep, and even include preformatted material: [pre 0 something 00 can 000 be numbered 0000 four deep pre] === Image Support === Syntax for adding images is: [pre [image: static/flag.gif] pre] resulting in [image: static/flag.gif] [image: static/another.gif] Or alternatively [pre [image: static/NotHereYet.jpg picture] pre] produces [image: static/NotHereYet.jpg picture] === Maths Mode === There are two forms of math mode supported, simple, for inline greek and super and subscripts (e.g. [m: \alpha^2 = \beta^3 _2], or CO[m _2]). This is done using a simple \[m: \alpha^2 = \beta^3 _2] syntax. More complicated expressions can be constructed using the latex syntax if latex is available on your server. The following syntax: [pre [embed latex \int \frac{\partial y}{\partial x}\,\partial z = b*C\frac{1}{2} embed] pre] results in [embed latex \int\frac{\partial y}{\partial x}\,\partial z = b*C\frac{1}{2} embed] === Embedding Code === Code can be highlighted and optionally numbered, using the source-highlight software if that is available on your server. [embed code python def example(argument): ''' commment string ''' r=remote(argument) if r: return 'string' return 'another string' embed] was done with [pre [embed code python ... embed] pre] You can access the source-highlight command line to number lines in python too with [pre [embed code python -n ... embed] pre] to get this sort of thing: [embed code python -n def routine: ''' starting comment ''' pass embed] === Misc. === You can access the DOI redirect system with [pre [doi:10.1038/news050124-10 nature] pre] to get, for example, a link to a [doi:10.1038/news050124-10 nature] paper �������������������������������������������������������������������������������������������������������������������������������������������������������leonardo-0.6.0/data/lfs/wiki_formatting_guide_2.ldv/__embedded__1/����������������������������������0000755�0000765�0000765�00000000000�10247462064�026133� 5����������������������������������������������������������������������������������������������������ustar �jtauber�������������������������jtauber�������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������leonardo-0.6.0/data/lfs/wiki_formatting_guide_2.ldv/__embedded__1/__content__.png�������������������0000644�0000765�0000765�00000003304�10247461761�031112� 0����������������������������������������������������������������������������������������������������ustar �jtauber�������������������������jtauber�������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG  ��� IHDR������&��EI���PLTEǿ~~~{{{wwwsssooolllhhheeebbb^^^[[[XXXUUURRROOOLLLIIIFFFDDDAAA>>><<<999666444111///,,,***'''%%%###  ���M.���@tRNS� -8@HOU[`fkotx|D���bKGD�H���tIME-:4���tEXtSoftware�dvi2bitmap 0.13b2m���-tEXtComment�Converted from DVI file tmpzJfMiu.dvi���DtEXtComment�See http://www.astro.gla.ac.uk/users/norman/star/dvi2bitmap/(��IDATXWv:DPZ >b/ZmZ Ww{zZL&dfO��PjͯL[pS rM)mn+غZњ.lk{rV 蠦g'0Vv?Y_O|fQ[(�~�(vmY =ÊeYpƹ?=b3>SD\6S8 g$mQ*A ʎچ|sg_b =~ǰ ?كKKraHZK^"O$Rϒ&qpJ7USְt@O]IY!&Ử ,X7<%x3,zb:3W qmY ry~q2}0r/]S :2@_]]eL`tC LBUV+ʒԍμPN"hAU8! ՒvB \#70gy 9l5~Z lI@E4U0JWGj~Z ieZAo]Sq0b|rFH40$GGOff͎jԥ_/i` ǔ"[yrϸNy7k&Jg˜eaggFݼ}_u9rRcķm6Byw޶uIo SP4 *#?-Sjުubd>llO0-C5(-b!%zɃ-t1r1뤷#NNJ3abo-Qd:߇b9 k@4 %TYwdQ2.cli^;Jέ<'G>3DU:_'jTX OOqNh7Aߦr7NC dGKۉ]\OD2+ bi;ǯtLy:j(h~,M+AU!fvz|0/4Q#:[l; Լ%Fvۑ]-t e|g?"g5_hd!x2~*~yӁa3jgaSã}8~+=Pþ /.|Ţ!|f6$__9/la7n����IENDB`����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������leonardo-0.6.0/data/lfs/wiki_formatting_guide_2.ldv/__embedded__2/����������������������������������0000755�0000765�0000765�00000000000�10247462064�026134� 5����������������������������������������������������������������������������������������������������ustar �jtauber�������������������������jtauber�������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������leonardo-0.6.0/data/lfs/wiki_formatting_guide_2.ldv/__embedded__2/__content__.png�������������������0000644�0000765�0000765�00000002554�10247461761�031121� 0����������������������������������������������������������������������������������������������������ustar �jtauber�������������������������jtauber�������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG  ��� IHDR�����������PLTEǿ~~~{{{wwwsssooolllhhheeebbb^^^[[[XXXUUURRROOOLLLIIIFFFDDDAAA>>><<<999666444111///,,,***'''%%%###  ���M.���@tRNS� -8@HOU[`fkotx|D���bKGD�H���tIME7F���tEXtSoftware�dvi2bitmap 0.13b2m���-tEXtComment�Converted from DVI file tmpKrkoSk.dviJ4J���DtEXtComment�See http://www.astro.gla.ac.uk/users/norman/star/dvi2bitmap/(��LIDATHUr0]@,^jt(JnBhTu8ٳe&o؂IAjy `+wXhukxҌeX{ciH[ENȲ!avf1"�R29wG[t2B&JH^o{EZqu ;YHiB<1kTpqD`_e2!Z9^"m kc϶e%G3&6*>w4|˫)kђJ3+ pw@2;mT,ZdR^) ȥ`MO-Cڵ\N=*Jo.'cH(7*n48^5`dq3_x1iF/7V2o Jęeta Tpo^Υť[@u#Atj*~ERیR.0)s)V2=4?j17lvӓi?~lԊv. k9 ̸ymxK1'Ia-ޣy2A^RΦŬX(]LܤvQ&0t/IX[Ʒ:D _WSEnicd0Vu}0fH5 #'ݡrW<aU 'USvqg(Bk ۑp]bF_mIWm%IygwD{S Y2%2):ގ/%wz2&㛭힇$4nDXɽQ{=Ϲ9&Ѥ̮H_Z;����IENDB`����������������������������������������������������������������������������������������������������������������������������������������������������leonardo-0.6.0/data/lfs/wiki_formatting_guide_2.ldv/property_db�������������������������������������0000644�0000765�0000765�00000030000�10247461761�025775� 0����������������������������������������������������������������������������������������������������ustar �jtauber�������������������������jtauber�������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������a��������������������������������� N��$��L����������������������^h�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������S'Wiki Formatting Guide (wikiBNL)' p1 .page_titleS'NO' p1 .allow_comments������������������������������������������ N��$��L����������������������^h����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������S'NO' p1 .allow_trackbacksleonardo-0.6.0/EXTRAS�������������������������������������������������������������������������������0000644�0000765�0000765�00000001645�10247461761�015413� 0����������������������������������������������������������������������������������������������������ustar �jtauber�������������������������jtauber�������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ By default, Leonardo uses a wiki format referred to as wiki04. From 0.5 onwards, Leonardo also comes with a more advanced format contributed by Bryan Lawrence referred to as wikiBNL. It is possible for wiki04 and wikiBNL files to co-exist in a single Leonardo wiki. By default, newly created pages are interpreted as wiki04. To change this, edit leonardo.config and add overrides for draft_type_default in the [draft] section and editform_default_type in the [editform] section. wikiBNL supports embedded latex equations. For this to work both latex and dvi2bitmap must be on the path. dvi2bitmap is available from http://www.astro.gla.ac.uk/users/norman/star/dvi2bitmap/ wikiBNL also supports code highlighting. For this to work, source-highlight must be on the path. source-highlight is available from http://www.gnu.org/software/src-highlite/source-highlight.html Feel free to ask the Leonardo mailing list for any help.�������������������������������������������������������������������������������������������leonardo-0.6.0/GPL����������������������������������������������������������������������������������0000644�0000765�0000765�00000043131�10247461761�015023� 0����������������������������������������������������������������������������������������������������ustar �jtauber�������������������������jtauber�������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. <one line to give the program's name and a brief idea of what it does.> Copyright (C) <year> <name of author> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. <signature of Ty Coon>, 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������leonardo-0.6.0/lib/���������������������������������������������������������������������������������0000755�0000765�0000765�00000000000�10247462063�015216� 5����������������������������������������������������������������������������������������������������ustar �jtauber�������������������������jtauber�������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������leonardo-0.6.0/lib/auth.py��������������������������������������������������������������������������0000755�0000765�0000765�00000011420�10247461761�016536� 0����������������������������������������������������������������������������������������������������ustar �jtauber�������������������������jtauber�������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# # Copyright (C) 2003-2004 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # """ This module deals with session and user management. """ # session status codes OK = "ok" WRONG_IP = "different ip address" UNKNOWN_SID = "unknown sid" NO_SID = "no sid in cookie" NO_COOKIE = "no cookie" class SessionManager: def __init__(self, request, data_dir): self.request = request self.data_dir = data_dir self.session_db = None def check_session(self): """Returns the current session status as triple: code, user_id, session_id""" if self.request.cookie: import Cookie ip_address = self.request.remote_address cookie = Cookie.SimpleCookie(self.request.cookie) if "session_id" in cookie: sid = cookie["session_id"].value if self.has_session(sid): session_uid, session_ip_address = self.get_session(sid) if ip_address == session_ip_address: return OK, session_uid, sid else: # spoof return WRONG_IP, None, sid else: # unknown session ID return UNKNOWN_SID, None, sid else: # no session ID in cookie return NO_SID, None, None else: # no cookie return NO_COOKIE, None, None def get_sessions(self): """Get the session database, loading from disk if necessary""" if not self.session_db: import anydbm self.session_db = anydbm.open(self.data_dir + "sessions_db", "c") return self.session_db def create_session(self, uid, ip_address): """Create a new session for the given user at the given IP address""" sid = generate_id(uid, ip_address) self.get_sessions()[sid] = " ".join((uid, ip_address)) if hasattr(self.get_sessions(), "sync"): self.get_sessions().sync() return sid def get_session(self, sid): """Get the session info for the given session ID. Returned as pair: user_id, ip_address""" return self.get_sessions()[sid].split(" ") def has_session(self, sid): """Does the given session ID exist?""" return self.get_sessions().has_key(sid) def delete_session(self, sid): """Delete the session with the given ID. Has effect of logging user out""" del self.get_sessions()[sid] if hasattr(self.get_sessions(), "sync"): self.get_sessions().sync() def generate_id(uid, ip_address): """Generate a new session ID""" import md5, time, base64 m = md5.new() m.update('this is just a fun little sentence to get things started') m.update(str(time.time())) m.update(uid) m.update(ip_address) return base64.encodestring(m.digest())[:-3].replace("/", "$") class UserManager: def __init__(self, request, data_dir): self.request = request self.user_db = None self.data_dir = data_dir def get_users(self): """Get the user database, loading from disk if necessary""" if not self.user_db: import anydbm self.user_db = anydbm.open(self.data_dir + "user_db", "c") return self.user_db def known_user(self, user_id): """Is the given user known?""" return self.get_users().has_key(user_id) def get_password(self, user_id): """Get the (hashed) password for given user""" return self.get_userinfo(user_id)[2] def get_userinfo(self, user_id): """Get info for the given user. Returned as triple: user_id, name, (hashed) password""" return self.get_users()[user_id].split("|") def correct_password(self, user_id, passwd): """Is the given password correct for the given user?""" import sha return (self.known_user(user_id) and self.get_password(user_id) == sha.sha(passwd).hexdigest()) ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������leonardo-0.6.0/lib/config.py������������������������������������������������������������������������0000644�0000765�0000765�00000002713�10247461761�017044� 0����������������������������������������������������������������������������������������������������ustar �jtauber�������������������������jtauber�������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ import ConfigParser import os import os.path class Configurator: def __init__(self, main_file): self.config = ConfigParser.ConfigParser() self.main_file = main_file def add(self, package_name): package = __import__(package_name) components = package_name.split('.') for comp in components[1:]: package = getattr(package, comp) package_paths = package.__path__ module_name = package_name.split('.')[-1] for package_path in package_paths: config_filename = os.path.join(package_path, module_name + ".config") self.config.read(config_filename) def read_main(self): self.config.read(self.main_file) # default data_dir for quick start if not self.config.has_option("DEFAULT", "data_dir"): this_directory = os.path.dirname(__file__) abs_path = os.path.abspath(os.path.join(this_directory, "../data")) self.config.set("DEFAULT", "data_dir", abs_path + os.sep) # default lfs_root if not self.config.has_option("DEFAULT", "lfs_root"): data_dir = self.config.get("DEFAULT", "data_dir") self.config.set("DEFAULT", "lfs_root", os.path.join(data_dir, "lfs") + os.sep) def get(self, section, key): return self.config.get(section, key) def getint(self, section, key): return self.config.getint(section, key) �����������������������������������������������������leonardo-0.6.0/lib/core.py��������������������������������������������������������������������������0000755�0000765�0000765�00000003377�10247461761�016541� 0����������������������������������������������������������������������������������������������������ustar �jtauber�������������������������jtauber�������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# # Copyright (C) 2003-2005 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # import sys import request_response import filesystem from providers.manager import ProviderManager class Leonardo: def __init__(self, configurator): self.configurator = configurator self.resource_manager = ProviderManager(self.configurator) def dispatch(self): request = request_response.Request(self.configurator) resource_id = request.relative_path if request.method == "GET": resource = self.resource_manager.get(resource_id, request, None) elif request.method == "POST": resource = self.resource_manager.post(resource_id, request, None) else: # @@@ need better error handling resource = None if request.not_modified(resource): response = request_response.Response(status="304 Not Modified") else: response = request_response.Response(resource) response.send(sys.stdout) �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������leonardo-0.6.0/lib/filesystem.py��������������������������������������������������������������������0000644�0000765�0000765�00000022726�10247461761�017771� 0����������������������������������������������������������������������������������������������������ustar �jtauber�������������������������jtauber�������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# # Copyright (C) 2003-2005 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # """ This module abstracts the access to file contents and file attributes. Alternative backend data stores such as databases or version control systems could be implemented by implementing an identical interface. This implementation works by storing each "file" as a directory with the extension ".ldv". The directory may then contain not only the content (potentially in multiple forms) but additional metadata, annotations, etc. @@@ document enclosures @@@ document property indicies """ import os import re import shelve import time class LeonardoFileSystem: def __init__(self, root): self.root = root # check access to filesystem root if not os.access(self.root, os.R_OK): # @@@ improve response to user raise "can't access filesystem root" self.property_index_db = None def get(self, key): if self.valid(key): return LeonardoFile(self, key) else: raise ValueError def valid(self, key): root = os.path.abspath(self.root) path = os.path.abspath(os.path.normpath(self.root + "/" + key)) return path.startswith(root) def get_children(self, key): """ Returns a tuple of: - list of directories that are children of the key - list of leonardo pages that are children of the key A ValueError is raised if the key is invalid. """ if not self.valid(key): raise ValueError directories = [] files = [] # @@@ factor out commonalities with LeonardoFile d = self.root + key.strip("/") if os.path.isdir(d) and not d.endswith(".ldv"): for f in os.listdir(d): # @@@ factor out ignore list if os.path.isdir(d + "/" + f) and f not in [".svn"]: if f.endswith(".ldv"): # @@@ change to creation time sort_key = os.path.getmtime(os.path.join(d, f)) files.append((sort_key, f[:-4])) else: directories.append(f) directories.sort() directories.reverse() files.sort() files.reverse() files = [c[1] for c in files] return directories, files def get_property_index_(self): """Get the property index, loading from disk if necessary""" if not self.property_index_db: self.property_index_db = shelve.open(self.root + "property_index") return self.property_index_db def find_property(self, property_name): """find a property in the index""" return self.get_property_index_().get(property_name, {}) def list_properties(self): """list the properties in the index""" return self.get_property_index_().keys() def add_property(self, key, name, value): """add a property to the index""" x = self.get_property_index_().get(name, {}) if type(value) == list: for item in value: x.setdefault(item, []).append(key) else: x.setdefault(value, []).append(key) self.get_property_index_()[name] = x if hasattr(self.property_index_db, "sync"): self.property_index_db.sync() def remove_property(self, key, name): """remove a property from the index""" x = self.get_property_index_().get(name, {}) for value in x: y = x[value] if key in y: y.remove(key) self.get_property_index_()[name] = x if hasattr(self.property_index_db, "sync"): self.property_index_db.sync() class Bundle: def __init__(self): self.property_db = None def get_content_filename_(self, content_type): return self.get_directory_() + "__content__." + content_type def get_content_filename_glob_(self): return self.get_content_filename_("*") def get_content_files_(self): import glob return glob.glob(self.get_content_filename_glob_()) def exists(self): files = self.get_content_files_() if files: return True else: return False def load_content_(self): files = self.get_content_files_() if files: f = file(files[0]) s = f.read() f.close() self.content = s def load_content_type_(self): files = self.get_content_files_() if files: self.content_type = files[0].split(".")[-1] else: self.content_type = None def get_content(self): if not self.content: self.load_content_() return self.content def get_content_type(self): if not self.content_type: self.load_content_type_() return self.content_type def get_lastmod(self): lastmod = self.get_property("last_modified", -1) if lastmod == -1: files = self.get_content_files_() ST_MTIME = 8 if files: lastmod = os.stat(files[0])[ST_MTIME] else: lastmod = -1 return lastmod def get_creation_time(self): t = self.get_property("creation_time", "-1") return int(t) def set_content(self, content, content_type): self.make_bundle_() self.content = content self.content_type = content_type path = self.get_content_filename_(content_type) f = file(path, "w") f.write(content) f.close() self.set_property("last_modified", time.time()) def delete(self): from os.path import join for root, dirs, files in os.walk(self.get_directory_(), topdown=False): for name in files: os.remove(join(root, name)) for name in dirs: os.rmdir(join(root, name)) os.rmdir(self.get_directory_()) def make_bundle_(self): directory = self.get_directory_() if not os.access(directory, os.F_OK): os.makedirs(directory) self.set_property("creation_time", time.time()) def get_property_db_(self): """Get the property db, loading from disk if necessary""" if not self.property_db: self.property_db = shelve.open(self.get_directory_() + "property_db") return self.property_db def get_property(self, name, default=None): if self.exists(): return self.get_property_db_().get(name, default) else: return default def get_properties(self): """Get a list of the properties (i.e. property names) on this file""" if self.exists(): return self.get_property_db_().keys() else: return [] def set_property(self, name, value): self.make_bundle_() self.get_property_db_()[name] = value if hasattr(self.property_db, "sync"): self.property_db.sync() class LeonardoFile(Bundle): def __init__(self, filesystem, key): Bundle.__init__(self) self.filesystem = filesystem self.key = key self.content = None self.content_type = None def get_directory_(self): return self.filesystem.root + self.key.strip("/") + ".ldv/" def set_property(self, name, value): Bundle.set_property(self, name, value) self.filesystem.remove_property(self.key, name) self.filesystem.add_property(self.key, name, value) def delete(self): for name in self.get_properties(): self.filesystem.remove_property(self.key, name) Bundle.delete(self) def enclosure(self, enctype, index): return Enclosure(self, enctype, index) def enclosures(self, enctype): enc_list = [] for d in os.listdir(self.get_directory_()): match = re.match("__(\w+)__(\d+)", d) if match and enctype == match.group(1): index = match.group(2) enc_list.append(self.enclosure(enctype, index)) return enc_list class Enclosure(Bundle): def __init__(self, parent, enctype, index): Bundle.__init__(self) self.parent = parent self.enctype = enctype self.index = index self.content = None self.content_type = None def get_directory_(self): return self.parent.filesystem.root + self.parent.key.strip("/") + ".ldv/" + "__" + self.enctype + "__" + str(self.index) + "/" ������������������������������������������leonardo-0.6.0/lib/formatters/����������������������������������������������������������������������0000755�0000765�0000765�00000000000�10247462063�017404� 5����������������������������������������������������������������������������������������������������ustar �jtauber�������������������������jtauber�������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������leonardo-0.6.0/lib/formatters/__init__.py�����������������������������������������������������������0000644�0000765�0000765�00000001474�10247461761�021527� 0����������������������������������������������������������������������������������������������������ustar �jtauber�������������������������jtauber�������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# # Copyright (C) 2003-2005 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # """ Package for Leonardo wiki formatters. """����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������leonardo-0.6.0/lib/formatters/manager.py������������������������������������������������������������0000755�0000765�0000765�00000003535�10247461761�021405� 0����������������������������������������������������������������������������������������������������ustar �jtauber�������������������������jtauber�������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# # Copyright (C) 2003-2005 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # import re import wiki04.formatter as wiki04 import wikiBNL.formatter as wikiBNL import xhtml.formatter as xhtml class FormatterManager: def __init__(self, config): home_href = config.get("DEFAULT", "home_href") self.formatters = { "wiki04": wiki04.WikiFormatter(home_href), "wikiBNL": wikiBNL.WikiFormatter(home_href), "xhtml": xhtml.XHTMLFormatter(home_href), } self.default_formatter = DefaultFormatter() def known(self, content_type): return content_type in self.formatters def format(self, content, content_type, leofile, resource_getter): formatter = self.formatters.get(content_type, self.default_formatter) return formatter.format(content, leofile, resource_getter) class DefaultFormatter: def format(self, content, leofile, resource_getter): if content: content = re.sub("&", "&", content) content = re.sub("<", "<", content) else: content = "" return content �������������������������������������������������������������������������������������������������������������������������������������������������������������������leonardo-0.6.0/lib/formatters/wiki04/���������������������������������������������������������������0000755�0000765�0000765�00000000000�10247462063�020513� 5����������������������������������������������������������������������������������������������������ustar �jtauber�������������������������jtauber�������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������leonardo-0.6.0/lib/formatters/wiki04/__init__.py����������������������������������������������������0000644�0000765�0000765�00000001457�10247461761�022637� 0����������������������������������������������������������������������������������������������������ustar �jtauber�������������������������jtauber�������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# # Copyright (C) 2003-2005 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # """ wiki04 formatter plugin. """�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������leonardo-0.6.0/lib/formatters/wiki04/formatter.py���������������������������������������������������0000755�0000765�0000765�00000012202�10247461761�023074� 0����������������������������������������������������������������������������������������������������ustar �jtauber�������������������������jtauber�������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# # Copyright (C) 2003-2005 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # import re class WikiFormatter: def __init__(self, link_prefix): self.link_prefix = link_prefix def __sub_link(self, matchobj): wiki_word = matchobj.group(1) wiki_word = re.sub(r'\\(.)', '\\1', wiki_word) link = self.link_prefix + re.sub(' ', '_', wiki_word).lower() return """<a href="%s">%s</a>""" % (link, wiki_word) def extract_title(self, page_content): m = re.match(r'(?m)^==([^=]+)==', page_content) if m: return m.group(1) else: return None def __insert(self, resource_id, resource_getter): resource = resource_getter(resource_id) if resource.exists(): if hasattr(resource, "get_html"): return resource.get_html() else: return """<p class="debug">invalid insert : %s</p>""" % resource_id else: return """<p class="debug">unknown insert : %s</p>""" % resource_id # @@@ templatize def format(self, page_content, leo_file=None, resource_getter=None): s = page_content s = re.sub(r'&', '&', s) s = re.sub(r'<', '<', s) s = re.sub(r'>', '>', s) s = re.sub(r'"', '"', s) # ==...== to h2 s = re.sub(r'(?m)^==([^=]+)==', '<h2>\\1</h2>', s) # ===...=== to h3 s = re.sub(r'(?m)^===([^=]+)===', '<h3>\\1</h3>', s) # ====...==== to h4 s = re.sub(r'(?m)^====([^=]+)====', '<h4>\\1</h4>', s) # * ... to list s = re.sub(r'(?m)^\* (.+)$', '<li>\\1</li>', s) # ": " at start of line to blockquote s = re.sub(r'(?m)^: (.+)$', '<blockquote>\\1</blockquote>', s) s = re.sub(r'</blockquote>(\s*)<blockquote>', '\\1', s) # four spaces at start of line to pre s = re.sub(r'(?m)^ (.+)$', '<pre>\\1</pre>', s) s = re.sub(r'</pre>(\s*)<pre>', '\\1', s) # *...* bold s = re.sub(r'\*([^\*]+)\*', '<b>\\1</b>', s) # ''...'' italic s = re.sub(r"''([^']+)''", '<i>\\1</i>', s) # --- to emdash s = re.sub(r'---', '—', s) # empty lines -> paragraph boundaries s = re.sub(r'(?m)^\s*$', '</p>\n<p>', s) s = "<p>" + s + "</p>" s = re.sub(r'<p>\s*<li>', '<ul><li>', s) s = re.sub(r'</li>\s*</p>', '</li></ul>', s) s = re.sub(r'<p>\s*<h2>', '<h2>', s) s = re.sub(r'</h2>\s*</p>', '</h2>', s) s = re.sub(r'<p>\s*<h3>', '<h3>', s) s = re.sub(r'</h3>\s*</p>', '</h3>', s) s = re.sub(r'<p>\s*<h4>', '<h4>', s) s = re.sub(r'</h4>\s*</p>', '</h4>', s) s = re.sub(r'<p></p>', '', s) URL = r'((?:ftp|http):[^ \]]+)' # [http:..] to external link s = re.sub(r'\['+URL+r'\]', '<a class="external" href="\\1">\\1</a>', s) # [http:... ...] to titled and entitled external link s = re.sub(r'\['+URL+r' "([^"]+)" ([^\]]+)\]', '<a class="external" title="\\2" href="\\1">\\3</a>', s) # [http:... ...] to titled external link s = re.sub(r'\['+URL+r' ([^\]]+)\]', '<a class="external" href="\\1">\\2</a>', s) # [:...] to local link s = re.sub(r'\[:/([^ \]]+)\]', '<a href="%s\\1">%s\\1</a>' % (self.link_prefix, self.link_prefix), s) s = re.sub(r'\[:([^ \]]+)\]', '<a href="\\1">\\1</a>', s) # [:... ...] to titled local link s = re.sub(r'\[:/([^ \]]+) ([^\]]+)\]', '<a href="%s\\1">\\2</a>' % self.link_prefix, s) s = re.sub(r'\[:([^ \]]+) ([^\]]+)\]', '<a href="\\1">\\2</a>', s) # [image:... ...] to local image s = re.sub('\[image:/([^ \]]+) ([^\]]+)\]', '<img src="%s\\1" alt="\\2"/>' % self.link_prefix, s) s = re.sub('\[image:([^ \]]+) ([^\]]+)\]', '<img src="\\1" alt="\\2"/>', s) # [insert:...] to insert a resource s = re.sub(r'\[insert:([^\]]+)\]', lambda x: self.__insert(x.group(1), resource_getter), s) # [amazon:... ...] to link to Amazon using ISBN and link title s = re.sub(r'\[amazon:([0-9X]+) ([^\]]+)\]', '<a href="http://www.amazon.com/exec/obidos/tg/detail/-/\\1">\\2</a>', s) # [..] to wiki link s = re.sub(r'(?<!\\)\[(([^\\\]]|(\\\])|(\\(?!\])))+)\]', self.__sub_link, s) return s ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������leonardo-0.6.0/lib/formatters/wikiBNL/��������������������������������������������������������������0000755�0000765�0000765�00000000000�10247462063�020703� 5����������������������������������������������������������������������������������������������������ustar �jtauber�������������������������jtauber�������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������leonardo-0.6.0/lib/formatters/wikiBNL/__init__.py���������������������������������������������������0000644�0000765�0000765�00000001460�10247461761�023021� 0����������������������������������������������������������������������������������������������������ustar �jtauber�������������������������jtauber�������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# # Copyright (C) 2003-2005 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # """ wikiBNL formatter plugin. """����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������leonardo-0.6.0/lib/formatters/wikiBNL/embedhandler.py�����������������������������������������������0000644�0000765�0000765�00000020444�10247461761�023677� 0����������������������������������������������������������������������������������������������������ustar �jtauber�������������������������jtauber�������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# # Copyright Bryan Lawrence and James Tauber, 2004/05 # Gnu Public License # Wiki Latex Embed Handler # # V0.1 January 2, 2005 # V0.2 January 6, 2005; standalone ready # respect last modification time and speed up # V0.3 January 17,2005: add code highlighting support # V0.31 January 18, 2005: better errors # V0.32 January 20, 2005: handling code strings better ... (avoids hangup) # V0.4 Feburary 11, 2005: Using a scratch directory # Fixing the error handling # V0.41 Feburary 13, 2005: Support location of external binaries # V0.42 February 22, 2005: Default scratch dir in /tmp # V0.43 Feburary 25, 2005: remove <center> for xhtml1.1 # V0.44 March 25, 2005: Add support for access to source-highlight command line # Changes default to not support numbering ... # import os, tempfile, popen2, glob from xml.dom import minidom class embedhandler: def __init__(self, link_prefix, embed_prefix='/__embedded__', workingpath='/tmp/leoscratch',binarypath='/usr/local/bin'): ''' Input arguments include link_prefix necessary to find the location of the html file and any embedded inclusions embed_prefix used to indicate any further additions to the URI for the path to the inclusions workingpath is a directory location for temporary files binarypath is an additional directory for embeddding binaries like source-highlight and/or dvi2bitmap ''' self.link_prefix = link_prefix self.embed_prefix = embed_prefix self.item=0 # # check and see if binarypath is in path, if not add it # path=os.environ['PATH'] pathdirs=path.split(':') if binarypath not in pathdirs: os.environ['PATH']+=':'+binarypath # self.workingpath=workingpath if not os.path.exists(workingpath): os.mkdir(workingpath) # # we care about the current directory for use when standalone ... self.currentdir=os.getcwd() def execmd(self,command): ''' wraps up subprocess error handling''' # has to be linuxacious because process handling is uncool in python #V0.33 and earlier: try: r=popen2.Popen3(command +' >& /dev/null ') res=r.wait() return res except: return 1 def latex(self,payload,tmpfilebase): ''' Given a latex payload, and base path for tmpfiles, produce a png file which is the output of dvi2bitmap and then return the content of that file for inclusion in the "official" output file ''' latex=r'''\documentclass{article} \usepackage{amssymb,amsmath,amscd,concmath} \pagestyle{empty} \begin{document} \begin{equation*}%s\end{equation*} \end{document} ''' % payload tmplatex=tmpfilebase+'.tex' tmpdvi=tmpfilebase+'.dvi' tmppng=tmpfilebase+'.png' t=file(tmplatex,"w") t.write(latex) t.close() if self.execmd('latex --interaction=batchmode '+tmplatex): return self.preformat(payload,'Latex Error ') cmd=''.join(["dvi2bitmap ",tmpfilebase, " --magnification=2 " "--scale=6 --font-mode=nechi --resolution=360 ", "--process=blur,crop,transparent ", "--output=",tmppng]) if self.execmd(cmd): return self.preformat(payload,'dvi2bitmap error ') try: f=open(tmppng,'rb') content=f.read() self.cleanup() return content except: return self.preformat(payload,'Unable to find '+tmppng) def codehighlight(self,payload,language,tmpfilebase): ''' takes a set of code lines, and a language definition, and uses the external source-highlight code operating on temporary files to produce some highlighted code ''' # March 25, we expect the 'language' string to look like either # python # python -n (and any other source-highlight command except # the -f and --src-lang ) # so the default is now no numbering tmpcode=tmpfilebase+'.code' tmpout=tmpcode+'.html' t=file(tmpcode,'w') t.write(payload) t.close() # access source-highlight args from language variable blank=language.find(' ') if blank!=-1: args=language[blank+1:] language=language[0:blank] else: args='' if self.execmd('source-highlight '+args+' -f xhtml --src-lang=' +language+' '+tmpcode+' >& /dev/null'): self.preformat(payload,'highlight error ') try: t=file(tmpout,'r') content=t.read() t.close() self.cleanup() return content except: return self.preformat(payload,'highlight file error') def embed(self,xmlstring,leofile=''): ''' Take an xml document consisting of a script command and a payload to be executed by the script (if necessary) and if necessary, embed the output in leofile. Outside the context of leonardo, leofile is not necessary ''' os.chdir(self.workingpath) doc=minidom.parseString(xmlstring) command=doc.getElementsByTagName('script')[0].firstChild.data payload=doc.getElementsByTagName('payload')[0].firstChild.data # two cases, return html pointing to an image, or return html rimage={'late':1,'code':0}[command[0:4]] firstchild,parent=-1,0 # hack for comparisons if rimage: self.item+=1 if leofile=='': key='' leo=0 else: leo=1 self.leofile=leofile key=self.leofile.key.strip('/') embedded_uri=''.join([self.link_prefix,key, self.embed_prefix,str(self.item)]) if leo: # we can evaluate whether we need to do anything or not parent=self.leofile.get_lastmod() firstchild=self.leofile.enclosure('embedded', self.item).get_lastmod() if firstchild<=parent: tmpfilebase=tempfile.mktemp() tmpfilebase=os.path.basename(tmpfilebase) self.tmpfilebase=tmpfilebase if leofile is None: return self.preformat(payload,' Leofile is None ') if command[0:5]=='latex': content=self.latex(payload,tmpfilebase) if content[0:5]=='<pre>': rimage=0 elif command[0:4]=='code': content=self.codehighlight(payload,command[5:].rstrip(),tmpfilebase) else: return self.preformat(payload,'Unknown command '+command) #would prefer not to copy it ... could do directly ... but if the lfs isn't a #"real" file system then we probably have to do it this way ... perhaps better #for lfs to return a "file-type" object ... but difficult to see how #we could use it in external scripts ... if rimage: if leo: self.leofile.enclosure('embedded', self.item).set_content(content, 'png') else: os.chdir(self.currentdir) ff=embedded_uri fo=open(ff,'w') fo.write(content) fo.close() if rimage: wrap=('<table><tr><td>','</td></tr></table>') html=''.join([wrap[0],'<img src="',embedded_uri, '" alt="Latex Embedded Image"></img>',wrap[1]]) else: html=content os.chdir(self.currentdir) return html def preformat(self,payload,message): self.cleanup() html=''.join(['<pre>',payload,'\n***\n',message,'\n***\n','</pre>']) return html def cleanup(self): files=glob.glob(self.tmpfilebase+'*') for file in files: os.remove(file) ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������leonardo-0.6.0/lib/formatters/wikiBNL/formatter.py��������������������������������������������������0000644�0000765�0000765�00000046015�10247461761�023272� 0����������������������������������������������������������������������������������������������������ustar �jtauber�������������������������jtauber�������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Copyright Bryan Lawrence and James Tauber, 2004 # Covered by the GPL since based on GPL code. # # eventually make all this xml compliant ... but not now ... # V0.1 (Dec 17, 2004) - for Leonardo 0.4rc1 (v67) # V0.2 (Jan 06, 2005) - more exact backwards compatiability with JT code # - simple greek inserts # - for Leonardo v111 up # V0.3 (Jan 10, 2005) - inline math mode ... # V0.4 (Jan 11, 2005) - stricter XHTML # V0.41 (Jan 12, 2005) - verbatim/preformat handled using [pre: pre] # V0.42 (Jan 17, 2005) - working source highlighter # V0.50 (Jan 18, 2005) - Modify to James' new insert syntax # V0.51 (Jan 24, 2005) - tiny change to support for _ in URL's .. # V0.52 (Jan 28, 2005) - support doi redirects # V0.53 (Feb 07, 2005) - Minor bug fix for preformat and embed in column 1 # Also sort out break on table close ... # V0.54 (Feb 14, 2005) - Minor bug in [:... ...] syntax # Actually, this was less a bug, more a difference # of opinion about how this should work. An ongoing # issue. Currently this formatter does not support # "local" links. # V0.55 (Feb 19, 2005) - Support rooted links, ie [:/blah xx] (but assume # this is still the same as [:blah xx] for now. # - Fix bug in [asdf] syntax, so that a space cannot # occur within a hyperlink. (Broke some inline maths) # V0.56 (Feb 22, 2005) - Pass embed scratch dir # V0.57 (Feb 25, 2005) - More modifications for strict XHTML1.1 # <p> within blockquote, <img .../>, # (nb can't use this at xhthml1.1): <center><table> -> <table align=center> # V0.59 Feb 26, ugly hack for images xhtml ...means that for now, images # can only occur in paragraph mode ... this doesn't seem to matter. # V0.591, Mar 08, support for https links # V0.592, Mar 24, somehow had missed delta!! # V0.593, Mar 25, escaping [ and * # V0.60, Mar 26, Adding support for footnotes # V0.61, Mar 26, Also allow math mode to start with [m: for consistency # May 22, JKT - made scratchdir changes submitted by Xavier Verges import re import tempfile import os.path from MultiSplit import MultiSplit embedscratchdir = os.path.join(tempfile.gettempdir(), 'leoscratch') class WikiFormatter: ''' Provides wiki page formatting to produce XHTML output ''' def __init__(self, link_prefix, external_embedhandler=None, embedscratchdir=embedscratchdir): ''' On instantiation provide any external link prefixes, something to get the contents of external page inserts, and an external embedhandler if required (it shouldnt be) ''' self.link_prefix = link_prefix if external_embedhandler is None: from embedhandler import embedhandler self.embedhandler=embedhandler(link_prefix, workingpath=embedscratchdir) else: self.embedhandler=external_embedhandler def __sub_link(self, matchobj): wiki_word = matchobj.group(1) link = self.link_prefix + re.sub(' ', '_', wiki_word).lower() return """<a href="%s">%s</a>""" % (link, wiki_word) def __insert(self, matchobj): ''' need to handle inserting resources via this to ensure that we flag to the formatter that this must be a new piece of block level html ''' # self.resource_getter set in formatter wiki_word = matchobj.group(1) stuff=self.resource_getter(wiki_word).get_html() return '<skip>'+stuff+'</skip>' def __embedder(self,matchobj): ''' takes the embedded text and sends off to the embedhandler and replaces with simple html expressions ''' #self.leofile set in formatter s=''.join(['<embed><script>',matchobj.group(1), '</script><payload>', matchobj.group(2),'</payload></embed>']) s='<skip>'+self.embedhandler.embed(s,self.leofile)+'</skip>' return s def __footnoter(self,matchobj): ''' takes some maaterial and adds it to the footnote list and returns appropriate html for a marker ''' fnumber=len(self.footnotelist)+1 sfnum=str(fnumber) address1='fn'+sfnum address2=address1+'call' html=''.join(['<a id="',address2,'">', '</a><sup><a href="#',address1,'">',sfnum,'</a></sup>']) text=''.join(['<div class="footnoteitem">','<a id="',address1, '">',sfnum,'</a>: ',matchobj.group(1), ' <a href="#',address2,'">(ret)</a>.</div>\n']) self.footnotelist.append(text) return html def extract_title(self, page_content): m = re.match(r'(?m)^==([^=]+)==', page_content) if m: return m.group(1) else: return None def escapewikimarkup(self,s): ## bnl this is where I put the escaped wiki markup characters s = re.sub(r'\\\[','<wikiLB>',s) s = re.sub(r'\\\]','<wikiRB>',s) s = re.sub(r'\\\*','<wikiAst>',s) ## and these are undone after formatting is complete return s def escapereturn(self,s): s=re.sub(r'<wikiLB>',r'[',s) s=re.sub(r'<wikiRB>',r']',s) s=re.sub(r'<wikiAst>','*',s) return s def htmlspecial(self,s): ''' replace html special characters ''' # Why don't I do this in stateless format? In case we need these # characters to go into a latex preparser ... s = re.sub(r'&', '&', s) s = re.sub(r'<', '<', s) s = re.sub(r'>', '>', s) return s def htmlgreek(self,matchobj): ''' takes a string and inserts into it based on "latex-like" escaped greek (e.g \alpha) the xhtml code for the required symbol ''' s=matchobj.group(1) # handle super/sub scripts sup,sub=r'\^(\S+)',r'_(\S+)' s=re.sub(sup,'<sup>\\1</sup>',s) s=re.sub(sub,'<sub>\\1</sub>',s) # can't imagine doing it more inefficiently than this ... lexicon = ('alpha','beta','gamma','delta','epsilon','zeta', 'eta','theta','iota','kappa','lambda','mu', 'nu','xi','omicron','pi','rho','sigma','tau', 'upsilon','phi','chi','psi','omega', 'Alpha','Beta','Gamma','Delta','Epsilon','Zeta', 'Eta','Theta','Iota','Kappa','Lambda','Mu', 'Nu','Xi','Omicron','Pi','Rho','Sigma','Tau', 'Upsilon','Phi','Chi','Psi','Omega') for item in lexicon: target='\\'+item replacement='&'+item+';' s=s.replace(target,replacement) #should add a regular expression to make normal letters italics return s def statelessformat(self, s): ''' This method simply parses s and does the substitutions that do not have any state carried to subsequent lines ''' # ==...== to h2 s = re.sub(r'(?m)^==([^=]+)==', '<h2>\\1</h2>', s) # ===...=== to h3 s = re.sub(r'(?m)^===([^=]+)===', '<h3>\\1</h3>', s) # ====...==== to h4 s = re.sub(r'(?m)^====([^=]+)====', '<h4>\\1</h4>', s) # --- to emdash s = re.sub(r'---', '—', s) # [..] to wiki link s = re.sub(r'\[([\._A-Za-z0-9]+)\]',self.__sub_link, s) URL = r'((?:ftp|http|https):[^ \]]+)' # [http:..] to external link s = re.sub(r'\['+URL+r'\]', '<a class="external" href="\\1">\\1</a>', s) # [http:... ...] to titled and entitled external link s = re.sub(r'\['+URL+r' "([^"]+)" ([^\]]+)\]', '<a class="external" title="\\2" href="\\1">\\3</a>', s) # [http:... ...] to titled external link s = re.sub(r'\['+URL+r' ([^\]]+)\]', '<a class="external" href="\\1">\\2</a>', s) # [:... ...] to titled local link s = re.sub(r'\[:/([^ \]]+) ([^\]]+)\]', '<a href="%s\\1">\\2</a>' % self.link_prefix, s) s = re.sub(r'\[:([^ \]]+) ([^\]]+)\]', '<a href="%s\\1">\\2</a>' % self.link_prefix, s) #s = re.sub(r'\[:([^\]]+)\]', '<a href="\\1">\\1</a>', s) image=r'image: ([^ \]]+)' # [image: filename] insert an image from the static directory wrapper=('</p><table><tr><td>','</td></tr></table><p>') s=re.sub(r'\['+image+r'\]',wrapper[0]+ '<img src="%s\\1" alt="Image: \\1"/>'%self.link_prefix+wrapper[1],s) # [image: filename alternate] insert an image with user alternate s=re.sub(r'\['+image+r' ([^\]]+)\]',wrapper[0]+ '<img src="%s\\1" alt="\\2"/>'%self.link_prefix+wrapper[1],s) # [amazon:... ...] to link to Amazon using ISBN and link title s = re.sub(r'\[amazon:(\d+) ([^\]]+)\]', '<a href="http://www.amazon.com/exec/obidos/tg/detail/-/\\1">\\2</a>', s) # [doi:doistring title] pop in the dx.doi.org redirect, can't rely on #browsers. s = re.sub(r'\[doi:(\S+) ([^\]]+)\]', '<a href="http://dx.doi.org/\\1">\\2</a>',s) # handle simple inline mathematics (greek, super, subscripts) s=re.sub(r'\[m ([^\]]+)\]',self.htmlgreek,s) s=re.sub(r'\[m: ([^\]]+)\]',self.htmlgreek,s) # do bold and italic # actually italics don't really work properly ... s=re.sub(r'\*(?! )([^\*]+)\*', '<b>\\1</b>', s) s=re.sub(r"''([^']+)''", '<i>\\1</i>',s) # last, but not least, now do the footnotes ... s = re.sub(r'\[fn: ([^\]]+)\]',self.__footnoter,s) return s def statefulformat(self,para,reset=0): # * 0 ... to list and | tables # the members of the key of the following dictionary when present # at the beginning of a line represent a state change # the tuple has the state start and close html # current state is carried between verbatim and embedding incidents, # but not between paragraph incidents ... # variables holding state between invocations include: # self.current_state # self.NewPara # self.ListOpen - terminated unless we continue list tokens={'* ':('<ul>','</li></ul>\n'), '** ':('<ul>','</li></ul>\n'), '*** ':('<ul>','</li></ul>\n'), '**** ':('<ul>','</li></ul>\n'), '0 ':('<ol style="list-style-type:decimal">','</li></ol>\n'), '00 ':('<ol style="list-style-type:lower-alpha">', '</li></ol>\n'), '000 ':('<ol style="list-style-type:lower-roman">', '</li></ol>\n'), '0000 ':('<ol style="list-style-type:lower-greek">', '</li></ol>\n'), '|':('\n<table border="1" rules="all">', '</table><br/>\n'), ': ':('<blockquote><p>','</p></blockquote>\n')} current_state=self.current_state p='' if self.NewPara or reset: #we may need to close some lists or tables if len(current_state)>1: while len(current_state)>1: type=current_state.pop() p+=tokens[type][1] current_state=[[0]] # implies no current state self.NewPara=0 self.ListOpen=0 if reset: return p states=['\n'+x for x in tokens.keys()] tokeniser=MultiSplit(para,states) for state in tokeniser: if state[0] not in states: # make sure that it's not a heading ... if state[1].find('<h')==-1: # this is a standard paragraph p+='<p>'+state[1] self.ParaClose=1 else: p+=state[1] self.ParaClose=0 else: if self.ParaClose: p+='</p>' self.ParaClose=0 statetype=state[0][1:] if '*' in statetype or '0' in statetype: #it's a list if statetype != current_state[-1]: #incrementing or decrementing level nl=len(statetype)-len(current_state) if nl>0: current_state.append(statetype) p+=tokens[statetype][0] else: #close previous ones for i in range(-nl): type=current_state.pop() p+=tokens[type][1] p+='</li>' # and close the last one else: p+='</li>' p+='%s%s'%('<li>',state[1]) #needed to ensure that orphans are not created within lists if '*' in current_state[-1] or '0' in current_state[-1]: self.ListOpen=1 elif statetype == '|': # Handle tables, assume never part of lists! # We assume that tables continue until the end # of the paragraph, and that new rows start when # there is a | in column 1 ... a space in column # 1 indicates a continuation from previous row. # not that i've tested this properly yet if current_state[-1] not in [[0],'|']: p+=''' <i> Tables cannot be part of a paragraph or list (It is too hard to ensure xhtml compliance in a wiki). Please leave a blank line before tables </i>''' if current_state[-1]!='|': current_state.append('|') p+=tokens[statetype][0] # No default for colspan line=re.sub(r'\| ',r'|1',statetype+state[1]) line='<tr>'+re.sub(r'^\|(\d)', r'<td align="center" colspan="\1">  ',line) line=re.sub( r'\|(\d)', r'  </td><td align="center" colspan="\1">  ',line) # need two for offline and online, why? # emacs shows lines ending in ^M ... which the second # one catches ... line=re.sub(r'\|$',' </td></tr>\n',line) line=re.sub(r'\|\s',' </td></tr>\n',line) p+=line elif statetype ==': ': # handle block quotes p+=tokens[': '][0]+state[1]+tokens[': '][1] self.current_state=current_state if self.ParaClose: p+='</p>' self.ParaClose=0 return p def format(self, page_content, leofile=None, resource_getter=None ): ''' Parse page_content and produced xhtml formatted output ''' self.leofile=leofile self.resource_getter=resource_getter self.footnotelist = [] # We'll build a list of useful words for a later searching as well # but it is not yet implemented ... because it will have to wait # until we have page formatting on submission not on extraction self.searchable=[] # Bryan knows we can improve much of this with regular expressions, # but not right now ... s = page_content s = self.htmlspecial(s) # # general structure # # preformatted text # embedded material external html # parsed and formatted wiki instructions # # concept then is three passes through the material, rather # than event driven parsing. # first pass gets preformatted text # second finds embedded material # third does any wiki formatting # First we need to identify the preformatted text, and ensure that # no tokenising is done on that ... # Note that preformatted text cannot be part of an html <p>, # but it can be part of lists etc, so we can't treat # preformatted items as new paragraphs. s = re.sub(r'[\n$]\[pre[\n\r\f\v]([\s\S]+?)[\n\r]pre\]', '<pre>\\1</pre>',s) s = re.sub(r'</pre>(\s*)</pre>', '\\1', s) # # then get the other chunks that will be preformatted # preblocks=MultiSplit(s,['<pre>','</pre>']) news='' for block in preblocks: news+=block[0] if block[0]<>'<pre>': s=block[1] # Now find anything for embedding and get it done s=re.sub(r'\[embed\s(.+)\s([\s\S]+?)[\n]embed\]', self.__embedder,s) # [insert:...] to insert a resource s = re.sub(r'\[insert:([^\]]+)\]',self.__insert, s) news+=s else: news+=block[1] # # now we can do the wiki formatting proper # #yes we could avoid doing this twice, but it's simple blocks=MultiSplit(news,['<skip>','<pre>','</pre>','</skip>']) self.NewPara=1 self.current_state=[[0]] new='' for block in blocks: if block[0] not in ('<pre>','<skip>'): ss='' s=block[1] # empty lines -> paragraph boundaries s = re.sub(r'(?m)^\s*$', '<pb>', s) subblocks=MultiSplit(s,['<pb>']) for sub in subblocks: s=sub[1] if s<>'': if sub[0]=='<pb>': self.NewPara=1 s=self.escapewikimarkup(s) s=self.statelessformat(s) s=self.statefulformat(s) s=self.escapereturn(s) ss+=s block=[{'</pre>':'</pre>','</skip>':'','':''}[block[0]],ss] elif block[0]=='<skip>': block[0]='' elif block[0]=='<pre>': pass new+=block[0]+block[1] new+=self.statefulformat('',1) # close any environments # now add any footnotes if len(self.footnotelist)!=0: new+='<div class="footnotes">' for item in self.footnotelist:new+=self.escapereturn(item) new+='</div>' return new �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������leonardo-0.6.0/lib/formatters/wikiBNL/MultiSplit.py�������������������������������������������������0000644�0000765�0000765�00000003234�10247461761�023371� 0����������������������������������������������������������������������������������������������������ustar �jtauber�������������������������jtauber�������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Version 0.1 BNL, December 2, 2004 # This code is in the public domain, no warranty etc, use it at your own risk from UserList import UserList class MultiSplit(UserList): ''' Take a string,s, and a list containing items to split on, and when instantiated, return a list of lists identifying substrings and what precedes it.''' def __init__(self,s,listofsplitters): slist=[x for x in listofsplitters] UserList.__init__(self) result=[(None,s)] while len(slist) > 0: results=[] item=slist.pop() for edge,substring in result: #if substring != '': splitted=substring.split(item) if len(splitted)<>1: results.append([edge,splitted[0]]) for word in splitted[1:]: results.append([item,word]) else: results.append([edge,substring]) #else: # results.append(edge,substring) result=results #get rid of meaningless first term if result[0][0]==None: result[0]=['',results[0][1]] if result[0]==['',''] and len(result)>1: result=result[1:] self.data=result def join(self): ''' Return version of self as a concatenated string ''' result='' for item in self.data: result='%s%s%s'% (result,item[0],item[1]) return result if __name__=='__main__': # test it input = 'abcn def 12 ghin xy adsf' result=MultiSplit(input,['n','12','xy']) print result print result.join() input = '12341231' x=MultiSplit(input,['1','4']) print x print x.join() print MultiSplit('',['1']) ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������leonardo-0.6.0/lib/formatters/xhtml/����������������������������������������������������������������0000755�0000765�0000765�00000000000�10247462063�020540� 5����������������������������������������������������������������������������������������������������ustar �jtauber�������������������������jtauber�������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������leonardo-0.6.0/lib/formatters/xhtml/__init__.py�����������������������������������������������������0000644�0000765�0000765�00000001456�10247461761�022663� 0����������������������������������������������������������������������������������������������������ustar �jtauber�������������������������jtauber�������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# # Copyright (C) 2003-2005 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # """ xhtml formatter plugin. """������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������leonardo-0.6.0/lib/formatters/xhtml/formatter.py����������������������������������������������������0000755�0000765�0000765�00000002276�10247461761�023133� 0����������������������������������������������������������������������������������������������������ustar �jtauber�������������������������jtauber�������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# # Copyright (C) 2003-2005 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # import re class XHTMLFormatter: def __init__(self, link_prefix): self.link_prefix = link_prefix def extract_title(self, page_content): m = re.match(r'(?m)^<h2>([^<]+)</h2>', page_content) if m: return m.group(1) else: return None def format(self, page_content, leo_file=None, resource_getter=None): return page_content ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������leonardo-0.6.0/lib/providers/�����������������������������������������������������������������������0000755�0000765�0000765�00000000000�10247462064�017234� 5����������������������������������������������������������������������������������������������������ustar �jtauber�������������������������jtauber�������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������leonardo-0.6.0/lib/providers/__init__.py������������������������������������������������������������0000644�0000765�0000765�00000001477�10247461761�021361� 0����������������������������������������������������������������������������������������������������ustar �jtauber�������������������������jtauber�������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# # Copyright (C) 2003-2004 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # """ Package for Leonardo resource providers. """�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������leonardo-0.6.0/lib/providers/atom/������������������������������������������������������������������0000755�0000765�0000765�00000000000�10247462064�020174� 5����������������������������������������������������������������������������������������������������ustar �jtauber�������������������������jtauber�������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������leonardo-0.6.0/lib/providers/atom/__init__.py�������������������������������������������������������0000644�0000765�0000765�00000001454�10247461761�022314� 0����������������������������������������������������������������������������������������������������ustar �jtauber�������������������������jtauber�������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# # Copyright (C) 2003-2004 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # """ Atom provider plugin. """��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������leonardo-0.6.0/lib/providers/atom/atom.config�������������������������������������������������������0000644�0000765�0000765�00000000506�10247461761�022327� 0����������������������������������������������������������������������������������������������������ustar �jtauber�������������������������jtauber�������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# Configuration file for atom provider # Note that blog_author always comes from main configuration file. [atom] atom_path : %(path_prefix)satom full_atom_path : %(path_prefix)satom/full atom_all_path : %(path_prefix)satom/all full_atom_all_path : %(path_prefix)satom/all/full atom_recent_count : 10 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������leonardo-0.6.0/lib/providers/atom/atom_provider.py��������������������������������������������������0000755�0000765�0000765�00000014076�10247461761�023436� 0����������������������������������������������������������������������������������������������������ustar �jtauber�������������������������jtauber�������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# # Copyright (C) 2003-2005 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # __provider__ = "AtomProvider" __contributions__ = {"head_links": "head_link"} import time import urllib from web_resource import TopLevelResource from providers.blog.blog_provider import Walker, ALL import templates def head_link(request, resource, main_resource, config): # @@@ this should probably only be added on certain pages atom_href = config.get("DEFAULT", "home_href") + config.get("atom", "full_atom_path") blog_title = config.get("blog", "blog_title") return templates.auto_discovery_link % locals() class AtomProvider: def __init__(self, resource_manager, lfs, config): self.resource_manager = resource_manager self.lfs = lfs self.config = config self.atom_path = config.get("atom", "atom_path") self.full_atom_path = config.get("atom", "full_atom_path") self.atom_all_path = config.get("atom", "atom_all_path") self.full_atom_all_path = config.get("atom", "full_atom_all_path") self.atom_recent_count = config.getint("atom", "atom_recent_count") def get(self, resource_id, request, main_resource): if resource_id == self.atom_path: return AtomResource(resource_id, self.resource_manager, self.lfs, request, self.config, full=False, number=self.atom_recent_count) elif resource_id == self.full_atom_path: return AtomResource(resource_id, self.resource_manager, self.lfs, request, self.config, full=True, number=self.atom_recent_count) elif resource_id == self.atom_all_path: return AtomResource(resource_id, self.resource_manager, self.lfs, request, self.config, full=False, number=ALL) elif resource_id == self.full_atom_all_path: return AtomResource(resource_id, self.resource_manager, self.lfs, request, self.config, full=True, number=ALL) else: return None def post(self, resource_id, request, main_resource): return None class AtomResource(TopLevelResource): def __init__(self, resource_id, resource_manager, lfs, request, config, full, number): TopLevelResource.__init__(self, resource_id, "text/xml; charset=utf-8") if full: formatter = FullAtomFormatter(resource_manager, config) else: formatter = AtomFormatter(resource_manager, config) walker = Walker(formatter, config.get("blog", "blog_path"), lfs) if number == ALL: self.content = walker.all(request, self) else: self.content = walker.recent(request, self, number) def get_content(self): return self.content class AtomFormatter: def __init__(self, resource_manager, config): self.resource_manager = resource_manager self.atom_path = config.get("atom", "atom_path") self.site_url = config.get("blog", "site_url") self.blog_title = config.get("blog", "blog_title") self.blog_path = config.get("blog", "blog_path") self.blog_author = config.get("atom", "blog_author") self.shown_modified = False def header(self): blog_title = self.blog_title blog_url = self.site_url + self.blog_path blog_author = self.blog_author return templates.atom_header % locals() def footer(self): return templates.atom_footer % locals() def no_entries(self): return templates.atom_no_entries % locals() def entry(self, year, month, day, entry, request, main_resource): page_key = "%s/%s/%s/%s/%s" % (self.blog_path, year, month, day, entry) page = self.resource_manager.get(page_key, request, main_resource) iso_time = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime(page.get_lastmod())) title = page.get_title() html_link = self.site_url + urllib.quote(page_key) if not self.shown_modified: self.shown_modified = True s = templates.atom_modified % locals() # this is the overall feed lastmod, so tell the main resource main_resource.lastmod = time.gmtime(page.get_lastmod()) else: s = "" modified = iso_time issued = iso_time s += templates.atom_entry % locals() return s class FullAtomFormatter(AtomFormatter): def entry(self, year, month, day, entry, request, main_resource): page_key = "%s/%s/%s/%s/%s" % (self.blog_path, year, month, day, entry) page = self.resource_manager.get(page_key, request, main_resource) iso_time = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime(page.get_lastmod())) title = page.get_title() html_link = self.site_url + urllib.quote(page_key) if not self.shown_modified: self.shown_modified = True s = templates.atom_modified % locals() # this is the overall feed lastmod, so tell the main resource main_resource.lastmod = time.gmtime(page.get_lastmod()) else: s = "" modified = iso_time issued = iso_time content = page.get_html() s += templates.atom_full_entry % locals() return s ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������leonardo-0.6.0/lib/providers/atom/templates.py������������������������������������������������������0000644�0000765�0000765�00000003401�10247461761�022545� 0����������������������������������������������������������������������������������������������������ustar �jtauber�������������������������jtauber�������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# # Copyright (C) 2003-2004 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # auto_discovery_link = """\ <link rel="alternate" type="application/atom+xml" title="%(blog_title)s" href="%(atom_href)s" /> """ atom_header = """\ <?xml version="1.0" encoding="utf-8"?> <feed version="0.3" xmlns="http://purl.org/atom/ns#" xml:lang="en"> <title>%(blog_title)s %(blog_author)s """ atom_footer = """ """ atom_no_entries = "" atom_modified = """ %(iso_time)s """ atom_entry = """ %(title)s %(modified)s %(issued)s %(html_link)s """ atom_full_entry = """ %(title)s %(modified)s %(issued)s %(html_link)s """ leonardo-0.6.0/lib/providers/blog/0000755000076500007650000000000010247462063020156 5ustar jtauberjtauber00000000000000leonardo-0.6.0/lib/providers/blog/__init__.py0000644000076500007650000000145410247461761022277 0ustar jtauberjtauber00000000000000# # Copyright (C) 2003-2004 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # """ Blog provider plugin. """leonardo-0.6.0/lib/providers/blog/blog.config0000644000076500007650000000035210247461761022274 0ustar jtauberjtauber00000000000000# Configuration file for blog provider # Note that blog_title and site_url always come from main configuration file. [blog] blog_path : %(path_prefix)sblog all_blog_path : %(path_prefix)sblog/all blog_recent_count : 10 leonardo-0.6.0/lib/providers/blog/blog_provider.py0000755000076500007650000002253210247461761023400 0ustar jtauberjtauber00000000000000# # Copyright (C) 2003-2005 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # __provider__ = "BlogProvider" __contributions__ = {} from web_resource import PagePart from providers.page.page_provider import HTMLPage, HTMLPage404 import templates ALL = "all" YEARS = ["2004", "2005"] MONTHS = ["01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12"] DAYS = [ "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31"] class BlogProvider: def __init__(self, resource_manager, lfs, config): self.resource_manager = resource_manager self.lfs = lfs self.config = config self.blog_path = config.get("blog", "blog_path") self.all_blog_path = config.get("blog", "all_blog_path") self.site_url = config.get("blog", "site_url") self.blog_recent_count = config.getint("blog", "blog_recent_count") def get(self, resource_id, request, main_resource): if resource_id == self.all_blog_path: page_part = BlogPagePart(resource_id, self.resource_manager, request, self.lfs, self.config, number=ALL) return HTMLPage(resource_id, page_part, self.resource_manager, request, main_resource, self.config) if not resource_id.startswith(self.blog_path): return None blog_path = resource_id[len(self.blog_path):] year, month, day, entry = None, None, None, None path_components = blog_path.split("/") if len(path_components) == 1: pass elif len(path_components) == 2: year = path_components[1] elif len(path_components) == 3: year, month = path_components[1:] elif len(path_components) == 4: year, month, day = path_components[1:] elif len(path_components) == 5: year, month, day, entry = path_components[1:] else: return HTMLPage404(resource_id, self.resource_manager, request, main_resource, self.config) if year and year not in YEARS: return HTMLPage404(resource_id, self.resource_manager, request, main_resource, self.config) if month and month not in MONTHS: return HTMLPage404(resource_id, self.resource_manager, request, main_resource, self.config) if day and day not in DAYS: return HTMLPage404(resource_id, self.resource_manager, request, main_resource, self.config) if entry: return None # we don't need to handle it @@@ although we could to add date/permalink else: if year: page_part = BlogPagePart(resource_id, self.resource_manager, request, self.lfs, self.config, year, month, day) else: if main_resource != None: # if not a top-level request, return None # don't handle it here page_part = TopBlogPagePart(resource_id, self.resource_manager, request, self.lfs, self.config, number=self.blog_recent_count) return HTMLPage(resource_id, page_part, self.resource_manager, request, main_resource, self.config) def post(self, resource_id, resource, main_resource): return None class BlogPagePart(PagePart): def __init__(self, resource_id, resource_manager, request, lfs, config, year=None, month=None, day=None, number=None): PagePart.__init__(self, resource_id) formatter = HTMLFormatter(resource_manager, config) walker = Walker(formatter, config.get("blog", "blog_path"), lfs) blog_title = config.get("blog", "blog_title") if day: title = templates.blog_title_day % locals() content = walker.day(year, month, day, request, self) elif month: title = templates.blog_title_month % locals() content = walker.month(year, month, request, self) elif year: title = templates.blog_title_year % locals() content = walker.year(year, request, self) elif number == ALL: title = templates.blog_title_all % locals() content = walker.all(request, self) else: # latest n title = templates.blog_title_latest % locals() content = walker.recent(request, self, number) self.title = title self.html = content class TopBlogPagePart(BlogPagePart): def __init__(self, resource_id, resource_manager, request, lfs, config, year=None, month=None, day=None, number=None): BlogPagePart.__init__(self, resource_id, resource_manager, request, lfs, config, year, month, day, number) page_part = resource_manager.get(resource_id, request, self) if page_part.exists(): self.html = page_part.get_html() + self.html def is_read_only(self): return False class HTMLFormatter: def __init__(self, resource_manager, config): self.resource_manager = resource_manager self.site_url = config.get("blog", "site_url") self.blog_path = config.get("blog", "blog_path") self.config = config def header(self): return "" def footer(self): return "" def no_entries(self): return templates.blog_no_entries % locals() def entry(self, year, month, day, entry, request, main_resource): page_key = "%s/%s/%s/%s/%s" % (self.blog_path, year, month, day, entry) page = self.resource_manager.get(page_key, request, main_resource) body = page.get_html() title = page.get_title() date = "%s/%s/%s" % (year, month, day) html_link = self.site_url + page_key blog_footer_extras = "" for provider in self.resource_manager.get_contributors("blog_entry_footer"): blog_footer_extras += provider(request, page, main_resource, self.config) return templates.blog_entry % locals() class Walker: def __init__(self, formatter, blog_path, lfs): self.formatter = formatter self.blog_path = blog_path self.lfs = lfs def all(self, request, main_resource): return \ self.formatter.header() + \ self.descend(self.blog_path, lambda year: self.year(year, request, main_resource)) + \ self.formatter.footer() # contributed by Min Sik Kim # @@@ could be merged with descend with an extra parameter def recent(self, request, main_resource, num): import os content = "" years = self.lfs.get_children(self.blog_path)[0] for year in years: year_dir = os.path.join(self.blog_path, year) months = self.lfs.get_children(year_dir)[0] for month in months: month_dir = os.path.join(year_dir, month) days = self.lfs.get_children(month_dir)[0] for day in days: day_dir = os.path.join(month_dir, day) entries = self.lfs.get_children(day_dir)[1] for entry in entries: content += self.entry(year, month, day, entry, request, main_resource) num -= 1 if num == 0: break if num == 0: break if num == 0: break if num == 0: break return self.formatter.header() + content + self.formatter.footer() def year(self, year, request, main_resource): return self.descend(self.blog_path + "/" + year, lambda month: self.month(year, month, request, main_resource)) def month(self, year, month, request, main_resource): return self.descend("%s/%s/%s" % (self.blog_path, year, month), lambda day: self.day(year, month, day, request, main_resource)) def day(self, year, month, day, request, main_resource): return self.descend("%s/%s/%s/%s" % (self.blog_path, year, month, day), lambda entry: self.entry(year, month, day, entry, request, main_resource)) def entry(self, year, month, day, entry, request, main_resource): return self.formatter.entry(year, month, day, entry, request, main_resource) def descend(self, key, func): directories, files = self.lfs.get_children(key) children = directories + files content = "" if children: for child in children: content += func(child) else: content = self.formatter.no_entries() return content leonardo-0.6.0/lib/providers/blog/templates.py0000644000076500007650000000227210247461761022535 0ustar jtauberjtauber00000000000000# # Copyright (C) 2003-2005 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # blog_title_day = "%(blog_title)s %(year)s/%(month)s/%(day)s" blog_title_month = "%(blog_title)s %(year)s/%(month)s" blog_title_year = "%(blog_title)s %(year)s" blog_title_latest = "%(blog_title)s" blog_title_all = "%(blog_title)s" blog_no_entries = """

No Entries.

""" blog_entry = """

%(title)s

%(body)s

%(date)s %(blog_footer_extras)s (permalink)

""" leonardo-0.6.0/lib/providers/blogcalendar/0000755000076500007650000000000010247462064021651 5ustar jtauberjtauber00000000000000leonardo-0.6.0/lib/providers/blogcalendar/__init__.py0000644000076500007650000000147710247461761023776 0ustar jtauberjtauber00000000000000# # Copyright (C) 2003-2004 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # """ Package for Leonardo resource providers. """leonardo-0.6.0/lib/providers/blogcalendar/blogcalendar.config0000644000076500007650000000014610247461761025461 0ustar jtauberjtauber00000000000000# Configuration file for blogcalendar provider [blogcalendar] calendar_key : %(path_prefix)scalendar leonardo-0.6.0/lib/providers/blogcalendar/blogcalendar_provider.py0000644000076500007650000001513010247461761026555 0ustar jtauberjtauber00000000000000# # Version 0.1 of a blog calendar for leonardo > 0.4 # BNL, December 05, 2004 # Modification History # (BNL) to Leonardo provider, December 12 # (BNL) for rc1, December 17, 22 # (BNL) 01/1 bug fix (from james), 23rd # (BNL) 01/01 bug fix, 4th Jan (should have got that the first time) # (JKT) 16th Jan to take advantage of new [insert:...] # (BNL) Feb 25, true XHTML # (JKT) Mar 5, new provider framework __provider__ = "CalendarProvider" __contributions__ = {} import os, os.path, time class CalendarProvider: def __init__(self, resource_manager, lfs, config): self.config=config self.calendar_key = config.get("blogcalendar", "calendar_key") def get(self, resource_id, request, main_resource): if resource_id == self.calendar_key: return blogcalendar(request, self.config) else: return None def post(self, resource_id, request, main_resource): return None # @@@ should subclass class blogcalendar: def __init__(self,request,config): ''' this is called by the menu but we get the context from the request itself ''' self.relative_path = request.relative_path path=self.relative_path self.site_url = config.get("blog", "site_url") self.blog_path = config.get("blog", "blog_path") self.lfs_root = config.get("DEFAULT", "lfs_root") # five cases: # blog: - serve up latest month # blog/year - serve up Jan # blog/year/month - serve up year/month # blog/year/month/day - serve up year/month # anything else - serve up latest month # where of course blog is the config blog prefix ... bl=len(self.blog_path) if path[0:bl]!=self.blog_path or path[bl:bl+1]!='/': #serve up latest month y,m=time.gmtime()[0:2] else: lookingfor=path[bl+1:] slash=lookingfor.find('/') try: if slash==-1: y=int(lookingfor) m=1 else: y=int(lookingfor[0:4]) m=int(lookingfor[5:7]) except ValueError: y,m=time.gmtime()[0:2] year,last,this,next=self.title_links(y,m) #don't create a blog calendar instance unless we are going to use it #if config.blog_calendar=='T': # chtml=HtmlCalendar(y,m,self.day_links(y,m),(last,next),this,year) # self.html=chtml #elif config.blog_calendar=='B': self.html = HtmlCalendar(y,m,self.day_links(y,m),(last,next),this,year) def get_mime_type(self): return 'text/html' def get_html(self): return self.html def get_content(self): return self.html def exists(self): return True def day_links(self,y,m): # Jump directly down to the month ... #self.fd=open('debuglinks','a') links={} tail = ''.join([self.blog_path,'/',str(y),'/','%2.2i'%m]) monthdir=self.lfs_root+tail base=self.site_url+tail #self.fd.write(monthdir+'\n') try: if os.path.isdir(monthdir): blogs=os.listdir(monthdir) for blog in blogs: if blog[0:1]!='.':links[int(blog)]=base+'/'+blog except "nothing": #let it die for now and see why pass # in case something nasty ended up in the dir tree #self.fd.write(str(links)+'\n') #self.fd.close() return links def title_links(self,y,m): def yeartitle(y): return ''.join([self.site_url,self.blog_path,'/',str(y)]) def increment(y,m,i): mm=m+i yy=y if mm>12: mm,yy=mm%12,y+mm/12 elif mm < 1: mm,yy=12+mm,y-1 return yy,mm plus=increment(y,m,1) minus=increment(y,m,-1) year=yeartitle(y) this='%s%s%2.2i'%(year,'/',m) next='%s%s%2.2i'%(yeartitle(plus[0]),'/',plus[1]) last='%s%s%2.2i'%(yeartitle(minus[0]),'/',minus[1]) return year,last,this,next def HtmlCalendar(year,month,links={},arrows=None,monthlink=None,yearlink=None): ''' Produces an html table representation of the month. If the links argument is passed then it should consist of a set of links keyed by day of the month. If the arrows argument is passed, then it should consist of a two member tuple which has the links to the previous and next month. If the monthlink argument is passed, then it should be used as a link from the month title, if the yearlink argument is passed it can be used as the yearlink title. ''' months=('January ','February ','March ','April ','May ','June ', 'July ','August ','September ','October ','November ','December ') # Ok, I know I should be able to find someone elses code to do this, # but it'll take longer to find it than write it import calendar def makelink(target,link): return ''.join(['',link,'']) def monthtitle(m,link,short=0): title=months[m-1] if short: title=title[0:3] if link is None: return title else: return makelink(link,title) tr=('','') td=('','') if yearlink==None: yeartitle=str(year) else: yeartitle=makelink(yearlink,str(year)) if arrows==None: template=''.join(['']) else: template=''.join(['
', monthtitle(month,monthlink),yeartitle,'
',td[0],makelink(arrows[0],'<<'), td[1],'',td[0], makelink(arrows[1],'>>'),td[1],tr[1]]) template+=tr[0] for day in ('Mo','Tu','We','Th','Fr','Sa','Su'): template+=''.join([td[0],day,td[1]]) template+=tr[1] matrix=calendar.monthcalendar(year,month) for week in matrix: row=tr[0] for day in week: if day!=0: if day not in links.keys(): row+=''.join([td[0],str(day),td[1]]) else: row+=''.join([td[0],makelink(links[day],str(day)),td[1]]) else: row+=''.join(td) row+=tr[1] template+=row template+='
', monthtitle(month,monthlink,short=1),' ', yeartitle,'
' return template leonardo-0.6.0/lib/providers/category/0000755000076500007650000000000010247462064021051 5ustar jtauberjtauber00000000000000leonardo-0.6.0/lib/providers/category/__init__.py0000644000076500007650000000146010247461761023166 0ustar jtauberjtauber00000000000000# # Copyright (C) 2003-2004 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # """ Category provider plugin. """leonardo-0.6.0/lib/providers/category/category_provider.py0000644000076500007650000001250010247461761025153 0ustar jtauberjtauber00000000000000# # Copyright (C) 2003-2005 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # __provider__ = "CategoryProvider" __contributions__ = {"edit_form": "category_edit_form", "draft_hidden": "category_draft_hidden", "page_end": "category_page_end", "blog_entry_footer": "category_blog_entry_footer", "post_processing": "category_post_processing"} from web_resource import PagePart from providers.page.page_provider import HTMLPage, ForbiddenPage def category_edit_form(request, resource, main_resource, config): if resource: categories = " ".join(resource.get_property("categories", [])) else: categories = "" # @@@ templatize return """ Categories
""" % locals() def category_draft_hidden(request, resource, main_resource, config): if resource: categories = " ".join(resource.get_property("categories", [])) else: categories = "" # @@@ templatize return """ """ % locals() # @@@ templatize def category_blog_entry_footer(request, resource, main_resource, config): s = "" prefix = config.get("DEFAULT", "home_href") for category in resource.get_property("categories", []): href = prefix + category s += """ %(category)s""" % locals() if s: s = ": Categories " + s return s # @@@ templatize def category_page_end(request, resource, main_resource, config): if main_resource == None: s = "" categories = "" prefix = config.get("DEFAULT", "home_href") for category in resource.get_property("categories", []): href = prefix + category categories += """ %(category)s""" % locals() if categories: s += "

Categories: %(categories)s

" % locals() return s else: return "" def category_post_processing(request, resource, main_resource, config): categories = request.fields.getvalue("categories", "").split() if categories and request.logged_in(): resource.set_property("categories", categories) return "" class CategoryProvider: def __init__(self, resource_manager, lfs, config): self.resource_manager = resource_manager self.lfs = lfs self.config = config def get(self, resource_id, request, main_resource): if not resource_id.startswith("category"): return None page_part = CategoryPagePart(resource_id, self.lfs, request, self.resource_manager, self.config) return page_part def post(self, resource_id, request, main_resource): return None class CategoryPagePart(PagePart): def __init__(self, resource_id, lfs, request, resource_manager, config): PagePart.__init__(self, resource_id) parts = resource_id.split("/") prefix = config.get("DEFAULT", "home_href") draft_prefix = config.get("draft", "draft_prefix") self.html = "
    " if len(parts) != 2: self.title = "Categories" for value, resources in lfs.find_property("categories").items(): self.html += "
  • %(value)s
      " % locals() for resource in resources: if resource.startswith(draft_prefix): # @@@ continue href = prefix + resource page = resource_manager.get(resource, request, "hack") if page: title = page.get_property("page_title") or resource else: title = resource self.html += """
    • %(title)s
    • """ % locals() self.html += "
  • " else: category = parts[1] self.title = "Category '%(category)s'" % locals() for resource in lfs.find_property("categories").get(category, []): if resource.startswith(draft_prefix): # @@@ continue href = prefix + resource page = resource_manager.get(resource, request, "hack") if page: title = page.get_property("page_title") or resource else: title = resource self.html += """
  • %(title)s
  • """ % locals() self.html += "
" leonardo-0.6.0/lib/providers/comment/0000755000076500007650000000000010247462064020676 5ustar jtauberjtauber00000000000000leonardo-0.6.0/lib/providers/comment/__init__.py0000644000076500007650000000145710247461761023021 0ustar jtauberjtauber00000000000000# # Copyright (C) 2003-2004 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # """ Comment provider plugin. """leonardo-0.6.0/lib/providers/comment/comment_provider.py0000644000076500007650000001702510247461761024634 0ustar jtauberjtauber00000000000000# # Copyright (C) 2003-2005 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # __provider__ = "CommentProvider" __contributions__ = {"edit_form": "comments_allowed_edit_form", "draft_hidden": "comments_allowed_draft_hidden", "page_end" : "comment_page_end", "blog_entry_footer" : "comment_blog_entry_footer", "post_processing": "comments_post_processing"} import urllib import re from web_resource import PagePart from providers.page.page_provider import HTMLPage, ForbiddenPage import templates def comments_allowed_edit_form(request, resource, main_resource, config): # @@@ templatize if resource: allow_comments = resource.get_property("allow_comments") else: allow_comments = "" s = """ Allow Comments?
""" return s def comments_allowed_draft_hidden(request, resource, main_resource, config): # @@@ templatize if resource: allow_comments = resource.get_property("allow_comments") else: allow_comments = "" s = """ """ % locals() return s # @@@ templatize def comment_blog_entry_footer(request, resource, main_resource, config): if resource.get_property("allow_comments", "NO") != "NO": comment_count = len(resource.enclosures("comment")) if comment_count == 1: s = " : 1 comment" else: s = " : %s comments" % comment_count else: s = "" return s # @@@ templatize def comment_page_end(request, resource, main_resource, config): if main_resource == None and resource.get_property("allow_comments", "NO") != "NO": enclosures = resource.enclosures("comment") html = """

Comments (%s)

""" % len(enclosures) for comment in enclosures: author_name = comment.get_property("author_name") or "unknown" author_link = comment.get_property("author_link") content = comment.get_content() # @@@ utility function author_name = re.sub(r'&', '&', author_name) author_name = re.sub(r'<', '<', author_name) author_name = re.sub(r'>', '>', author_name) if author_link: author_link = re.sub(r'&', '&', author_link) author_link = re.sub(r'<', '<', author_link) author_link = re.sub(r'>', '>', author_link) author_link = re.sub(r'"', '"', author_link) content = re.sub(r'&', '&', content) content = re.sub(r'<', '<', content) content = re.sub(r'>', '>', content) lastmod = comment.get_lastmod() if lastmod: import time lastmod_display = time.strftime("%A %d %B, %Y", time.gmtime(lastmod)) else: lastmod_display = "" if author_link: citation = """%(author_name)s""" % locals() else: citation = author_name html += """

%(citation)s on %(lastmod_display)s:

%(content)s
""" % locals() if resource.get_property("allow_comments", "NO") == "YES": html += """

Add a Comment

Name
URI
Comment
""" else: html += """

Comments presently read-only.

""" else: html = "" return html def comments_post_processing(request, resource, main_resource, config): allow_comments = request.fields.getvalue("allow_comments") if allow_comments and request.logged_in(): resource.set_property("allow_comments", allow_comments) if resource.get_property("allow_comments", "NO") != "YES": return None comment_content = request.fields.getvalue("comment_content", None) if comment_content: return add_comment(resource, request, main_resource) else: return None def add_comment(resource, request, main_resource): comment_content = request.fields.getvalue("comment_content", None) author_name = request.fields.getvalue("author_name", None) author_link = request.fields.getvalue("author_link", None) inner_resource = resource # @@@ could create comment object for this that wraps enclosure existing_comments = inner_resource.enclosures("comment") next_index = 0 for comment in existing_comments: if int(comment.index) > next_index: next_index = int(comment.index) next_index += 1 new_comment = inner_resource.enclosure("comment", next_index) new_comment.set_content(comment_content, "txt") if author_name: new_comment.set_property("author_name", author_name) if author_link: new_comment.set_property("author_link", author_link) class CommentProvider: def __init__(self, resource_manager, lfs, config): self.resource_manager = resource_manager self.lfs = lfs self.config = config def get(self, resource_id, request, main_resource): return None def post(self, resource_id, request, main_resource): pass leonardo-0.6.0/lib/providers/comment/templates.py0000644000076500007650000000370110247461761023252 0ustar jtauberjtauber00000000000000# # Copyright (C) 2003-2005 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # toggle_comments_confirm_title = "%(site_title)s : toggle comments on %(resource_to_toggle)s?" toggle_comments_confirm_form = """

Toggle Comments on %(resource_to_toggle)s?

Cancel """ #toggle_comments_menu = """ #

toggle_comments Page

#""" toggle_comments_missing_id_title = "Missing Resource ID" toggle_comments_missing_id_content = "Missing Resource ID." toggle_comments_page_not_exist_title = "%(site_title)s : %(resource_to_toggle)s does not exist" toggle_comments_page_not_exist_content = "%(resource_to_toggle)s does not exist." toggle_comments_read_only_title = "Can't toggle comments on a read-only resource" toggle_comments_read_only_content = "Can't toggle comments on a read-only resource." toggle_comments_done_title = "%(site_title)s: %(resource_to_toggle)s comments toggled" toggle_comments_done_content = """%(resource_to_toggle)s comments toggled to %(new_value)s."""leonardo-0.6.0/lib/providers/css/0000755000076500007650000000000010247462063020023 5ustar jtauberjtauber00000000000000leonardo-0.6.0/lib/providers/css/__init__.py0000644000076500007650000000147710247461761022151 0ustar jtauberjtauber00000000000000# # Copyright (C) 2003-2004 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # """ Package for Leonardo resource providers. """leonardo-0.6.0/lib/providers/css/css.config0000644000076500007650000000015510247461761022007 0ustar jtauberjtauber00000000000000# Configuration file for css provider [CSS] css_id : %(path_prefix)scss css_href : %(cgi_root)s%(css_id)s leonardo-0.6.0/lib/providers/css/css_provider.py0000755000076500007650000000204510247461761023107 0ustar jtauberjtauber00000000000000# # Copyright (C) 2003-2005 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # __provider__ = None __contributions__ = {"head_links": "head_link"} def head_link(request, resource, main_resource, config): css_href = config.get("CSS", "css_href") return """""" % locals() leonardo-0.6.0/lib/providers/delete/0000755000076500007650000000000010247462064020476 5ustar jtauberjtauber00000000000000leonardo-0.6.0/lib/providers/delete/__init__.py0000644000076500007650000000145610247461761022620 0ustar jtauberjtauber00000000000000# # Copyright (C) 2003-2004 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # """ Delete provider plugin. """leonardo-0.6.0/lib/providers/delete/delete.config0000644000076500007650000000026610247461761023136 0ustar jtauberjtauber00000000000000# Configuration file for delete provider [delete] delete_path : %(path_prefix)sdelete delete_href : %(cgi_root)s%(delete_path)s delete_resource_field : resource leonardo-0.6.0/lib/providers/delete/delete_provider.py0000755000076500007650000001251710247461761024240 0ustar jtauberjtauber00000000000000# # Copyright (C) 2003-2004 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # """ GETing the 'delete' resource confirms deletion of a resource. POSTing to the 'delete' resource is intended as an alternative to DELETEing a resource in cases like HTML forms where you can't directly DELETE. """ __provider__ = "DeleteProvider" __contributions__ = {"menu": "delete_menu_part"} import urllib from web_resource import PagePart from providers.page.page_provider import HTMLPage, ForbiddenPage import templates def delete_menu_part(request, resource, main_resource, config): if request.logged_in() and not resource.is_read_only(): delete_page_href = config.get("delete", "delete_href") + "?" + config.get("delete", "delete_resource_field") + "=" + urllib.quote(resource.get_id()) menu_part = templates.delete_menu % locals() else: menu_part = "" return menu_part class DeleteProvider: def __init__(self, resource_manager, lfs, config): self.resource_manager = resource_manager self.lfs = lfs self.config = config self.delete_path = config.get("delete", "delete_path") self.resource_name = config.get("delete", "delete_resource_field") def get(self, resource_id, request, main_resource): if resource_id != self.delete_path: return None if not request.logged_in(): return ForbiddenPage(resource_id, self.resource_manager, request, main_resource, self.config) resource_to_delete = request.fields.getvalue(self.resource_name) page_part = GetDeletePagePart(resource_id, resource_to_delete, self.resource_manager, request, self.config) return HTMLPage(resource_id, page_part, self.resource_manager, request, main_resource, self.config) def post(self, resource_id, request, main_resource): if resource_id != self.delete_path: return None if not request.logged_in(): return ForbiddenPage(resource_id, self.resource_manager, request, main_resource, self.config) resource_to_delete = request.fields.getvalue(self.resource_name) page_part = PostDeletePagePart(resource_id, resource_to_delete, self.resource_manager, request, self.config) return HTMLPage(resource_id, page_part, self.resource_manager, request, main_resource, self.config) class GetDeletePagePart(PagePart): def __init__(self, resource_id, resource_to_delete, resource_manager, request, config): PagePart.__init__(self, resource_id) site_title = config.get("page", "site_title") post_action = config.get("delete", "delete_href") resource_name = config.get("delete", "delete_resource_field") cancel_action = urllib.quote(resource_to_delete) if resource_to_delete: page = resource_manager.get(resource_to_delete, request, self) if not page.exists(): self.title = templates.delete_page_not_exist_title % locals() self.html = templates.delete_page_not_exist_content % locals() elif page.is_read_only(): self.title = templates.delete_read_only_title % locals() self.html = templates.delete_read_only_content % locals() else: self.title = templates.delete_confirm_title % locals() self.html = templates.delete_confirm_form % locals() else: self.title = templates.delete_missing_id_title % locals() self.html = templates.delete_missing_id_content % locals() class PostDeletePagePart(PagePart): def __init__(self, resource_id, resource_to_delete, resource_manager, request, config): PagePart.__init__(self, resource_id) site_title = config.get("page", "site_title") if resource_to_delete: page = resource_manager.get(resource_to_delete, request, self) if not page.exists(): self.title = templates.delete_page_not_exist_title % locals() self.html = templates.delete_page_not_exist_content % locals() elif page.is_read_only(): self.title = templates.delete_read_only_title % locals() self.html = templates.delete_read_only_content % locals() else: page.delete() self.title = templates.delete_done_title % locals() self.html = templates.delete_done_content % locals() else: self.title = templates.delete_missing_id_title % locals() self.html = templates.delete_missing_id_form % locals() leonardo-0.6.0/lib/providers/delete/templates.py0000644000076500007650000000330610247461761023053 0ustar jtauberjtauber00000000000000# # Copyright (C) 2003-2004 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # delete_confirm_title = "%(site_title)s : DELETE %(resource_to_delete)s?" delete_confirm_form = """

Delete %(resource_to_delete)s?

Cancel """ delete_menu = """

Delete Page

""" delete_missing_id_title = "Missing Resource ID" delete_missing_id_content = "Missing Resource ID." delete_page_not_exist_title = "%(site_title)s : %(resource_to_delete)s does not exist" delete_page_not_exist_content = "%(resource_to_delete)s does not exist." delete_read_only_title = "Can't delete read-only resource" delete_read_only_content = "Can't delete read-only resource."# delete_done_title = "%(site_title)s: %(resource_to_delete)s DELETED" delete_done_content = "%(resource_to_delete)s DELETED."leonardo-0.6.0/lib/providers/draft/0000755000076500007650000000000010247462064020334 5ustar jtauberjtauber00000000000000leonardo-0.6.0/lib/providers/draft/__init__.py0000644000076500007650000000145510247461761022455 0ustar jtauberjtauber00000000000000# # Copyright (C) 2003-2004 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # """ Draft provider plugin. """leonardo-0.6.0/lib/providers/draft/draft.config0000644000076500007650000000025110247461761022624 0ustar jtauberjtauber00000000000000# Configuration file for draft provider [draft] draft_prefix : %(path_prefix)sdraft draft_href : %(cgi_root)s%(draft_prefix)s draft_type_default : wiki04 leonardo-0.6.0/lib/providers/draft/draft_provider.py0000755000076500007650000001753410247461761023740 0ustar jtauberjtauber00000000000000# # Copyright (C) 2003-2005 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # __provider__ = "DraftProvider" __contributions__ = {"menu": "draft_menu_part"} import re import time import urllib from formatters.manager import FormatterManager from web_resource import PagePart from providers.page.page_provider import HTMLPage, ForbiddenPage import templates def draft_menu_part(request, resource, main_resource, config): if request.logged_in(): draft_href = config.get("draft", "draft_href") menu_part = templates.draft_menu % locals() else: menu_part = "" return menu_part # form field names page_id_name = "page_id" page_title_name = "page_title" page_content_name = "page_content" page_content_type_name = "page_content_type" # requires 'editform', 'blog' and 'put' modules # @@@ perhaps this could delegate more to the editform provider class DraftProvider: def __init__(self, resource_manager, lfs, config): self.resource_manager = resource_manager self.lfs = lfs self.config = config self.draft_prefix = config.get("draft", "draft_prefix") self.formatter_manager = FormatterManager(config) def get(self, resource_id, request, main_resource): return self.handle(resource_id, request, main_resource) def post(self, resource_id, request, main_resource): return self.handle(resource_id, request, main_resource) def handle(self, resource_id, request, main_resource): """ handle both GET and POST. """ if not resource_id.startswith(self.draft_prefix): return None if not request.logged_in(): return ForbiddenPage(resource_id, self.resource_manager, request, main_resource, self.config) draft_path = resource_id[len(self.draft_prefix):].strip("/") if draft_path == "": # top level page_part = DraftListPagePart(resource_id, self.resource_manager, request, self.lfs, self.config, self.formatter_manager) return HTMLPage(resource_id, page_part, self.resource_manager, request, main_resource, self.config) else: # individual draft page if main_resource != None: # if not a top-level request, return None # don't handle it here outer_page_part = DraftPagePart(resource_id, self.resource_manager, request, self.config) return HTMLPage(resource_id, outer_page_part, self.resource_manager, request, main_resource, self.config) class DraftListPagePart(PagePart): def __init__(self, resource_id, resource_manager, request, lfs, config, formatter_manager): PagePart.__init__(self, resource_id) status = "" # @@@ how can this be avoided? page_content_name = globals()["page_content_name"] page_content_type_name = globals()["page_content_type_name"] page_title_name = globals()["page_title_name"] form_extras = "" for provider in resource_manager.get_contributors("edit_form"): form_extras += provider(request, None, None, config) form_content = templates.draft_initial_form_content % locals() # @@@ posting should really be done as a separate method if request.method == "POST": page_content = request.fields.getvalue(page_content_name, "") page_content_type = request.fields.getvalue(page_content_type_name, "") page_title = request.fields.getvalue(page_title_name, None) if page_title: draft_resource_id = config.get("draft", "draft_prefix") + "/" + re.sub(' ', '_', page_title.lower()) page = resource_manager.get(draft_resource_id, request, self) if page.exists(): status = templates.draft_existing_title % locals() form_content = page_content else: page.set_content(page_content, page_content_type) page.set_property("page_title", page_title) for provider in resource_manager.get_contributors("post_processing"): provider(request, page, None, config) status = templates.draft_success % locals() else: status = templates.draft_no_title % locals() form_content = page_content title = templates.draft_title # get list of drafts drafts = lfs.get_children(config.get("draft", "draft_prefix"))[1] if drafts: draft_items = "" for draft_title in drafts: draft_link = config.get("draft", "draft_href") + "/" + urllib.quote(draft_title) draft_items += templates.draft_item % locals() draft_list = templates.draft_list % locals() else: draft_list = templates.empty_draft_list % locals() action = config.get("draft", "draft_href") page_content_type = config.get("draft", "draft_type_default") content = templates.draft_page % locals() self.title = title self.html = content class DraftPagePart(PagePart): def __init__(self, resource_id, resource_manager, request, config): PagePart.__init__(self, resource_id) page_part = resource_manager.get(resource_id, request, self) if page_part.exists(): page_title = page_part.get_title() content = page_part.get_html() page_content = page_part.get_content() page_content_type = page_part.get_content_type() page_content = re.sub(r'&', '&', page_content) page_content = re.sub(r'<', '<', page_content) page_content = re.sub(r'>', '>', page_content) page_content = re.sub(r'"', '"', page_content) draft_path = resource_id[len(config.get("draft", "draft_prefix")):].strip("/") post_action = config.get("put", "put_href") resource_name = config.get("put", "put_resource_field") page_content_name = config.get("put", "put_content_field") page_content_type_name = config.get("put", "put_content_type_field") # @@@ should be in put config, not editform page_title_name = config.get("editform", "edit_title_field") resource_id_to_put = config.get("blog", "blog_path") + "/%04d/%02d/%02d/" % tuple(time.localtime()[:3]) + draft_path form_extras = "" for provider in resource_manager.get_contributors("draft_hidden"): form_extras += provider(request, page_part, None, config) content = templates.draft_put_form % locals() + content self.title = page_title self.html = content else: # @@@ really should return a 404 self.title = "Non-existent draft" # @@@ templatize self.html = "

Non-existent draft.

" # @@@ templatize def is_read_only(self): return False leonardo-0.6.0/lib/providers/draft/templates.py0000644000076500007650000000433610247461761022715 0ustar jtauberjtauber00000000000000# # Copyright (C) 2003-2005 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # draft_initial_form_content = "Type content here." draft_existing_title = "Page with that title already exists in drafts." draft_no_title = "Please provide a title." draft_success = "Successfully created '%(draft_resource_id)s'." draft_title = "Drafts" draft_item = """
  • %(draft_title)s
  • """ draft_list = """
      %(draft_items)s
    """ empty_draft_list = """

    No drafts.

    """ draft_page = """

    %(status)s

    Existing

    %(draft_list)s

    New Draft Page

    Title:

    %(form_extras)s
    as
    Cancel """ draft_menu = """

    Drafts

    """ draft_put_form = """

    to as

    %(form_extras)s
    """leonardo-0.6.0/lib/providers/editform/0000755000076500007650000000000010247462064021045 5ustar jtauberjtauber00000000000000leonardo-0.6.0/lib/providers/editform/__init__.py0000644000076500007650000000146010247461761023162 0ustar jtauberjtauber00000000000000# # Copyright (C) 2003-2004 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # """ Editform provider plugin. """leonardo-0.6.0/lib/providers/editform/editform.config0000644000076500007650000000037010247461761024050 0ustar jtauberjtauber00000000000000# Configuration file for editform provider [editform] edit_path : %(path_prefix)sedit edit_href : %(cgi_root)s%(edit_path)s edit_resource_field : resource edit_title_field : title editform_default_type : wiki04 leonardo-0.6.0/lib/providers/editform/editform_provider.py0000755000076500007650000001112010247461761025143 0ustar jtauberjtauber00000000000000# # Copyright (C) 2003-2005 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # __provider__ = "EditFormProvider" __contributions__ = {"menu": "edit_menu_part"} import urllib from web_resource import PagePart from providers.page.page_provider import HTMLPage, ForbiddenPage import templates def edit_menu_part(request, resource, main_resource, config): if request.logged_in() and not resource.is_read_only(): edit_page_href = config.get("editform", "edit_href") + "?" + config.get("editform", "edit_resource_field") + "=" + urllib.quote(resource.get_id()) menu_part = templates.edit_menu % locals() else: menu_part = "" return menu_part class EditFormProvider: def __init__(self, resource_manager, lfs, config): self.resource_manager = resource_manager self.lfs = lfs self.config = config self.edit_path = config.get("editform", "edit_path") self.resource_name = config.get("editform", "edit_resource_field") def get(self, resource_id, request, main_resource): if resource_id != self.edit_path: return None if not request.logged_in(): return ForbiddenPage(resource_id, self.resource_manager, request, main_resource, self.config) resource_to_edit = request.fields.getvalue(self.resource_name) outer_page_part = EditFormPagePart(resource_id, resource_to_edit, self.resource_manager, request, self.config) html_page = HTMLPage(resource_id, outer_page_part, self.resource_manager, request, main_resource, self.config) html_page.expiry = 0 return html_page def post(self, resource_id, request, main_resource): return None class EditFormPagePart(PagePart): def __init__(self, resource_id, resource_to_edit, resource_manager, request, config): PagePart.__init__(self, resource_id) post_action = config.get("put", "put_href") page_content_name = config.get("put", "put_content_field") page_content_type_name = config.get("put", "put_content_type_field") resource_name = config.get("put", "put_resource_field") title_name = config.get("editform", "edit_title_field") if resource_to_edit: cancel_action = urllib.quote(resource_to_edit) page = resource_manager.get(resource_to_edit, request, self) if page.is_read_only(): self.title = templates.edit_read_only_title % locals() self.html = templates.edit_read_only_title % locals() else: time = None site_title = config.get("page", "site_title") if page.exists(): page_title = page.get_title() title = templates.page_title % locals() page_content = page.get_content() page_content_type = page.get_content_type() time = page.get_lastmod() else: # new wiki word page_title = resource_to_edit title = templates.new_page_title % locals() page_content = templates.new_page_content % locals() page_content_type = config.get("editform", "editform_default_type") form_extras = "" for provider in resource_manager.get_contributors("edit_form"): form_extras += provider(request, page, None, config) content = templates.edit_form % locals() self.title = title self.html = content else: self.title = templates.edit_missing_id_title % locals() self.html = templates.edit_missing_id_content % locals() leonardo-0.6.0/lib/providers/editform/templates.py0000644000076500007650000000325310247461761023423 0ustar jtauberjtauber00000000000000# # Copyright (C) 2003-2005 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # page_title = "Edit %(page_title)s" new_page_title = "New Page" new_page_content = "Type content here." edit_form = """
    Title:

    %(form_extras)s as
    Cancel """ edit_menu = """

    Edit Page

    """ edit_missing_id_title = "Missing Resource ID" edit_missing_id_content = "Missing Resource ID." edit_read_only_title = "Can't edit read-only resource" edit_read_only_content = "Can't edit read-only resource."leonardo-0.6.0/lib/providers/enclosure/0000755000076500007650000000000010247462064021233 5ustar jtauberjtauber00000000000000leonardo-0.6.0/lib/providers/enclosure/__init__.py0000644000076500007650000000145110247461761023350 0ustar jtauberjtauber00000000000000# # Copyright (C) 2003-2004 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # """ Enclosures plugin. """leonardo-0.6.0/lib/providers/enclosure/enclosure_provider.py0000755000076500007650000000652610247461761025535 0ustar jtauberjtauber00000000000000# # Copyright (C) 2003-2005 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # __provider__ = "EnclosureProvider" __contributions__ = {} import re import mimetypes from formatters.manager import FormatterManager from web_resource import TopLevelResource, FileObjectResource from providers.page.page_provider import NonWikiPage, WikiPagePart, HTMLPage, HTMLPage404 # @@@ this is now too much like PageProvider not to be refactored class EnclosureProvider: def __init__(self, resource_manager, lfs, config): self.resource_manager = resource_manager self.lfs = lfs self.config = config self.formatter_manager = FormatterManager(config) def get(self, resource_id, request, main_resource): match = re.match("(.*)/__(\w+)__(\d+)", resource_id) if not match: return None base = match.group(1) enctype = match.group(2) index = match.group(3) key = resource_id enclosure = self.lfs.get(base).enclosure(enctype, index) content_type = enclosure.get_content_type() if enclosure.exists() and not self.formatter_manager.known(content_type): mime_type, encoding = mimetypes.guess_type("dummy.%s" % content_type) if not mime_type: mime_type = "application/octet-stream" return NonWikiPage(key, enclosure, mime_type) page_part = EnclosurePagePart(key, self.resource_manager, request, main_resource, self.config, enclosure, self.formatter_manager, base) if main_resource: # if there's a parent resource, we're done return page_part if page_part.exists(): return HTMLPage(key, page_part, self.resource_manager, request, main_resource, self.config) else: return HTMLPage404(key, self.resource_manager, request, main_resource, self.config) # @@@ superclass should do this def post(self, resource_id, request, main_resource): return None class EnclosurePagePart(WikiPagePart): def __init__(self, resource_id, resource_manager, request, main_resource, config, file_object, formatter_manager, base_resource): WikiPagePart.__init__(self, resource_id, resource_manager, request, main_resource, config, file_object, formatter_manager) self.base_resource = base_resource def get_html(self): base_link = self.config.home_href + self.base_resource # @@@ templatize return """

    Return to parent.

    """ % base_link + WikiPagePart.get_html(self)leonardo-0.6.0/lib/providers/login_logout/0000755000076500007650000000000010247462064021735 5ustar jtauberjtauber00000000000000leonardo-0.6.0/lib/providers/login_logout/__init__.py0000644000076500007650000000145310247461761024054 0ustar jtauberjtauber00000000000000# # Copyright (C) 2003-2004 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # """ Login/logout plugin. """leonardo-0.6.0/lib/providers/login_logout/login_logout.config0000644000076500007650000000041110247461761025624 0ustar jtauberjtauber00000000000000# Configuration file for login/logout provider [login_logout] login_path : %(path_prefix)slogin logout_path : %(path_prefix)slogout login_href : %(cgi_root)s%(login_path)s logout_href : %(cgi_root)s%(logout_path)s log_return_field : return leonardo-0.6.0/lib/providers/login_logout/login_logout_provider.py0000755000076500007650000001413510247461761026734 0ustar jtauberjtauber00000000000000# # Copyright (C) 2003-2005 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # __provider__ = "LoginLogoutProvider" __contributions__ = {"menu": "menu_part"} import urllib from auth import OK from web_resource import PagePart from providers.page.page_provider import HTMLPage import templates import config def menu_part(request, resource, main_resource, config): if request.logged_in(): user_id = request.get_user() logout_href = config.get("login_logout", "logout_href") + "?" + config.get("login_logout", "log_return_field") + "=" + urllib.quote(request.relative_path) menu_part = templates.logged_in_menu % locals() else: login_href = config.get("login_logout", "login_href") + "?" + config.get("login_logout", "log_return_field") + "=" + urllib.quote(request.relative_path) menu_part = templates.logged_out_menu % locals() return menu_part class LoginLogoutProvider: def __init__(self, resource_manager, lfs, config): self.resource_manager = resource_manager self.lfs = lfs self.config = config self.login_path = config.get("login_logout", "login_path") self.logout_path = config.get("login_logout", "logout_path") def get(self, resource_id, request, main_resource): return self.handle(resource_id, request, main_resource) def post(self, resource_id, request, main_resource): return self.handle(resource_id, request, main_resource) def handle(self, resource_id, request, main_resource): """ handles both GET and POST. """ if resource_id == self.login_path: page_part = LoginPagePart(resource_id, request, self.config) elif resource_id == self.logout_path: page_part = LogoutPagePart(resource_id, request, self.config) else: return None html_page = HTMLPage(resource_id, page_part, self.resource_manager, request, main_resource, self.config) html_page.expiry = 0 # @@@ put on HTMLPage itself if hasattr(page_part, "cookie"): html_page.cookie = page_part.cookie return html_page class LoginPagePart(PagePart): def __init__(self, resource_id, request, config): PagePart.__init__(self, resource_id) # form fields email_name = "email" password_name = "passwd" return_name = config.get("login_logout", "log_return_field") session_status = request.check_session() action = config.get("login_logout", "login_href") return_path = request.fields.getvalue(return_name, "") if request.method == "GET": status_code = session_status[0] if session_status[0] == OK: user_id = session_status[1] content = templates.already_logged_in % locals() else: content = templates.login_form % locals() else: # POST # log out if someone else session_status = request.check_session() if session_status[0] == OK: request.delete_session(session_status[2]) email = request.fields.getvalue(email_name, "") passwd = request.fields.getvalue(password_name, "") return_path = request.fields.getvalue(return_name, "") return_href = config.get("DEFAULT", "cgi_root") + return_path status_code = session_status[0] if request.correct_password(email, passwd): # @@@ should consider putting cookie creation code on # response object import Cookie ip_address = request.remote_address self.cookie = Cookie.SimpleCookie() self.cookie["session_id"] = request.create_session(email, ip_address) self.cookie["session_id"]["expires"] = 86400 # @@@ parameterize out self.cookie["session_id"]["path"] = "/" # @@@ should be home_href # bit of a hack, inserting the cookie after the fact request.cookie = self.cookie content = templates.successful_login % locals() else: content = templates.incorrect_password % locals() self.title = templates.login_title self.html = content class LogoutPagePart(PagePart): def __init__(self, resource_id, request, config): PagePart.__init__(self, resource_id) return_name = config.get("login_logout", "log_return_field") action = config.get("login_logout", "logout_href") return_path = request.fields.getvalue(return_name, "") return_href = config.get("DEFAULT", "home_href") + return_path if request.method == "GET": content = templates.confirm_logout % locals() else: # POST session_status = request.check_session() if session_status[0] == OK: request.delete_session(session_status[2]) user_id = session_status[1] content = templates.successful_logout % locals() else: status_code = session_status[0] content = templates.not_logged_in % locals() self.title = templates.logout_title self.html = content leonardo-0.6.0/lib/providers/login_logout/templates.py0000644000076500007650000000450710247461761024316 0ustar jtauberjtauber00000000000000# # Copyright (C) 2003-2004 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # login_title = "Login" logout_title = "Logout" already_logged_in = """

    You are already logged in as %(user_id)s

    """ login_form = """
    Email Address
    Password
     

    %(status_code)s

    """ successful_login = """

    Successful login, %(email)s from %(ip_address)s

    Return to %(return_path)s.

    """ incorrect_password = """

    Incorrect Email/Password.

    """ + login_form confirm_logout = """

    To confirm logout, press the button below.

    """ successful_logout = """

    You are now logged out, %(user_id)s.

    Return to %(return_path)s.

    """ not_logged_in = """

    You are not currently logged in.

    %(status_code)s

    """ logged_in_menu = """

    Logged in as: %(user_id)s

    Logout

    """ logged_out_menu = """

    Login

    """ leonardo-0.6.0/lib/providers/manager.py0000755000076500007650000000705310247461761021233 0ustar jtauberjtauber00000000000000# # Copyright (C) 2003-2005 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # provider_list = [ "providers.enclosure", "providers.login_logout", "providers.category", "providers.trackback", "providers.comment", "providers.editform", "providers.put", "providers.delete", "providers.blog", "providers.atom", "providers.draft", "providers.blogcalendar", "providers.upload", "providers.menu", "providers.css", "providers.propertylist", "providers.page", ] import filesystem class ProviderManager: def __init__(self, config): # initialise config for package_name in provider_list: config.add(package_name) config.read_main() self.providers = [] self.contributors = {} lfs_root = config.get("DEFAULT", "lfs_root") lfs = filesystem.LeonardoFileSystem(lfs_root) # register resource providers for provider_package_name in provider_list: provider_module_name = provider_package_name + "." + provider_package_name.split('.')[-1] + "_provider" provider_module = get_module(provider_module_name) if provider_module.__provider__: self.providers.append(getattr(provider_module, provider_module.__provider__)(self, lfs, config)) for key, contribution_function in provider_module.__contributions__.items(): self.contributors.setdefault(key, []).append(getattr(provider_module, contribution_function)) def get_contributors(self, key): return self.contributors.get(key, []) def get(self, resource_id, request, main_resource): """ Attempts to retrieve the resource with the given resource_id. request is also passed in to provide authentication information and HTTP parameters. @@@ This could be improved. main_resource is None if the requested resource is what the client directly requested. Otherwise it is the actual resource object requested by the client (and the resource in resource_id is just a component being retrieved to contribute to the the main_resource). """ for provider in self.providers: resource = provider.get(resource_id, request, main_resource) if resource: return resource return None def post(self, resource_id, request, main_resource): for provider in self.providers: resource = provider.post(resource_id, request, main_resource) if resource: return resource return None def get_module(name): module = __import__(name) components = name.split('.') for comp in components[1:]: module = getattr(module, comp) return module leonardo-0.6.0/lib/providers/menu/0000755000076500007650000000000010247462064020200 5ustar jtauberjtauber00000000000000leonardo-0.6.0/lib/providers/menu/__init__.py0000644000076500007650000000145410247461761022320 0ustar jtauberjtauber00000000000000# # Copyright (C) 2003-2004 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # """ Menu provider plugin. """leonardo-0.6.0/lib/providers/menu/menu.config0000644000076500007650000000016110247461761022334 0ustar jtauberjtauber00000000000000# Configuration file for menu provider [menu] menu_key : __MENU__ main_menu_key : %(path_prefix)s/__menu__ leonardo-0.6.0/lib/providers/menu/menu_provider.py0000644000076500007650000000520710247461761023437 0ustar jtauberjtauber00000000000000# # Copyright (C) 2003-2004 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # __provider__ = "MenuProvider" __contributions__ = {} from web_resource import PagePart import providers.page.templates as templates # @@@ should be local class MenuProvider: def __init__(self, resource_manager, file_system, config): self.resource_manager = resource_manager self.file_system = file_system self.config = config self.menu_key = config.get("menu", "menu_key") def get(self, resource_id, request, main_resource): if resource_id == self.menu_key: return MenuPagePart(self.resource_manager, request, main_resource, self.config) else: return None def post(self, resource_id, request, main_resource): return None class MenuPagePart(PagePart): """ The page part representing the full menu, including the content provided by contributors to "menu". This resource is never requested directly, only as part of a page. The main (or inner) menu, which forms part of the content of this resource, is a resource in its own right with id config.main_menu_key. The main menu can be requested directly and edited like a normal page part resource. """ def __init__(self, resource_manager, request, main_resource, config): self.resource_manager = resource_manager self.request = request self.main_resource = main_resource self.config = config self.main_menu = resource_manager.get(config.get("menu", "main_menu_key"), request, self) def get_html(self): html = self.main_menu.get_html() html += templates.menu_separator % locals() for provider in self.resource_manager.get_contributors("menu"): html += provider(self.request, self.main_resource, None, self.config) return html leonardo-0.6.0/lib/providers/page/0000755000076500007650000000000010247462064020150 5ustar jtauberjtauber00000000000000leonardo-0.6.0/lib/providers/page/__init__.py0000644000076500007650000000144310247461761022266 0ustar jtauberjtauber00000000000000# # Copyright (C) 2003-2004 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # """ Page plugin. """leonardo-0.6.0/lib/providers/page/page.config0000644000076500007650000000025410247461761022257 0ustar jtauberjtauber00000000000000# Configuration file for page provider # Note that site_title, site_sub_title and copyright_holder always come from # main configuration file. [page] home_key : __home__ leonardo-0.6.0/lib/providers/page/page_provider.py0000755000076500007650000002357610247461761023373 0ustar jtauberjtauber00000000000000# # Copyright (C) 2003-2005 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # __provider__ = "PageProvider" __contributions__ = {} import re import mimetypes from formatters.manager import FormatterManager from web_resource import PagePart, TopLevelResource, FileObjectResource import templates class PageProvider: def __init__(self, resource_manager, lfs, config): self.resource_manager = resource_manager self.lfs = lfs self.config = config self.home_key = config.get("page", "home_key") self.formatter_manager = FormatterManager(config) def get(self, resource_id, request, main_resource): page_part = self.get_page(resource_id, request, main_resource) if main_resource: # if there's a parent resource, we're done return page_part if isinstance(page_part, NonWikiPage): # if it's a non wiki page, we're done return page_part key = page_part.get_id() if page_part.exists(): return HTMLPage(key, page_part, self.resource_manager, request, main_resource, self.config) else: # new page if request.logged_in(): return PageDoesNotExist(key, self.resource_manager, request, main_resource, self.config) else: return HTMLPage404(key, self.resource_manager, request, main_resource, self.config) def post(self, resource_id, request, main_resource): page_part = self.get_page(resource_id, request, main_resource) for provider in self.resource_manager.get_contributors("post_processing"): result = provider(request, page_part, None, self.config) if result: return result # @@@ what can we do about duplication here if isinstance(page_part, NonWikiPage): # if it's a non wiki page, we're done return page_part key = page_part.get_id() if page_part.exists(): return HTMLPage(key, page_part, self.resource_manager, request, main_resource, self.config) else: # new page if request.logged_in(): return PageDoesNotExist(key, self.resource_manager, request, main_resource, self.config) else: return HTMLPage404(key, self.resource_manager, request, main_resource, self.config) def get_page(self, resource_id, request, main_resource): if resource_id == "": key = self.home_key else: key = resource_id file_object = self.lfs.get(key) content_type = file_object.get_content_type() if file_object.exists() and not self.formatter_manager.known(content_type): mime_type, encoding = mimetypes.guess_type("dummy.%s" % content_type) if not mime_type: mime_type = "application/octet-stream" return NonWikiPage(key, file_object, mime_type) return WikiPagePart(key, self.resource_manager, request, main_resource, self.config, file_object, self.formatter_manager) class NonWikiPage(FileObjectResource, TopLevelResource): def __init__(self, resource_id, file_object, mime_type): TopLevelResource.__init__(self, resource_id, mime_type) FileObjectResource.__init__(self, file_object) def is_read_only(self): return False class HTMLPage(TopLevelResource): def __init__(self, resource_id, page_part, resource_manager, request, main_resource, config): TopLevelResource.__init__(self, resource_id, "text/html; charset=utf-8") self.resource_manager = resource_manager self.request = request self.main_resource = main_resource self.config = config self.site_title = config.get("page", "site_title") self.site_sub_title = config.get("page", "site_sub_title") self.home_href = config.get("DEFAULT", "home_href") self.copyright_holder = config.get("page", "copyright_holder") self.home_key = config.get("page", "home_key") self.menu_key = config.get("menu", "menu_key") self.make_html(page_part, request) def exists(self): return True def get_content(self): return self.html def is_read_only(self): return True def make_html(self, page_part, request): page_title = page_part.get_title() if page_title: title = "%s : %s" % (self.site_title, page_title) else: title = self.site_title content = page_part.get_html() lastmod = page_part.get_lastmod() menu = self.resource_manager.get(self.menu_key, request, page_part).get_html() self.html = self.page_template(title, page_title, menu, content, lastmod) def page_template(self, title, main_title, menu, content, lastmod): if lastmod: import time lastmod = time.strftime(templates.time_format, time.gmtime(lastmod)) lastmod_display = templates.lastmod_display % locals() else: lastmod_display = "" if self.site_sub_title: site_sub_title = self.site_sub_title sub_title = templates.sub_title % locals() else: sub_title = "" site_title = self.site_title home_page = self.home_href copyright_holder = self.copyright_holder head_links = "" for provider in self.resource_manager.get_contributors("head_links"): head_links += provider(self.request, self, self.main_resource, self.config) if main_title: title_html = templates.title_template % locals() else: title_html = "" return templates.page_template % locals() class ForbiddenPage(HTMLPage): def __init__(self, resource_id, resource_manager, request, main_resource, config): HTMLPage.__init__(self, resource_id, None, resource_manager, request, main_resource, config) self.status = "403 Forbidden" def make_html(self, page_part, request): site_title = self.site_title title = templates.operation_not_allowed_title % locals() content = templates.operation_not_allowed % locals() time = None menu = self.resource_manager.get(self.menu_key, request, self).get_html() self.html = self.page_template(title, title, menu, content, time) class PageDoesNotExist(HTMLPage): def __init__(self, resource_id, resource_manager, request, main_resource, config): HTMLPage.__init__(self, resource_id, None, resource_manager, request, main_resource, config) self.status = "404 Not Found" def make_html(self, page_part, request): site_title = self.site_title title = templates.page_does_not_exist_title % locals() content = templates.page_does_not_exist % locals() time = None menu = self.resource_manager.get(self.menu_key, request, self).get_html() self.html = self.page_template(title, title, menu, content, time) def is_read_only(self): return False class HTMLPage404(HTMLPage): def __init__(self, resource_id, resource_manager, request, main_resource, config): HTMLPage.__init__(self, resource_id, None, resource_manager, request, main_resource, config) self.status = "404 Not Found" def make_html(self, page_part, request): site_title = self.site_title title = templates.title_404 % locals() content = templates.content_404 % locals() time = None menu = self.resource_manager.get(self.menu_key, request, self).get_html() self.html = self.page_template(title, title, menu, content, time) def is_read_only(self): return True class WikiPagePart(FileObjectResource, PagePart): # @@@ perhaps things like resource_manager, request, config should be moved to superclass __init__ def __init__(self, resource_id, resource_manager, request, main_resource, config, file_object, formatter_manager): PagePart.__init__(self, resource_id) FileObjectResource.__init__(self, file_object) self.resource_manager = resource_manager self.request = request self.main_resource = main_resource self.config = config self.formatter_manager = formatter_manager self.title = None def get_html(self): content = self.get_content() content_type = self.get_content_type() html = self.formatter_manager.format(content, content_type, self.file_object, self.resource_getter_) for provider in self.resource_manager.get_contributors("page_end"): html += provider(self.request, self, self.main_resource, self.config) return html def resource_getter_(self, resource_id): return self.resource_manager.get(resource_id, self.request, self) def get_title(self): return self.get_property("page_title") def is_read_only(self): return False leonardo-0.6.0/lib/providers/page/templates.py0000644000076500007650000000370710247461761022532 0ustar jtauberjtauber00000000000000# # Copyright (C) 2003-2005 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # page_does_not_exist = """

    Page does not exist. Create it with Edit Page if you like.

    """ page_does_not_exist_title = "Page Does Not Exist" operation_not_allowed = """

    Operation not allowed.

    """ operation_not_allowed_title = "Operation Not Allowed" title_404 = "File Not Found" content_404 = """

    File not found.

    """ time_format = "%A %d %B, %Y" lastmod_display = """This page last modified %(lastmod)s""" sub_title = "

    %(site_sub_title)s

    " title_template = """

    %(main_title)s

    """ page_template = """ %(title)s %(head_links)s

    %(site_title)s

    %(sub_title)s
    %(title_html)s %(content)s
    %(lastmod_display)s Copyright 2003-2005 %(copyright_holder)s
    """ menu_separator = """

     

    """ leonardo-0.6.0/lib/providers/propertylist/0000755000076500007650000000000010247462063022013 5ustar jtauberjtauber00000000000000leonardo-0.6.0/lib/providers/propertylist/__init__.py0000644000076500007650000000146510247461761024136 0ustar jtauberjtauber00000000000000# # Copyright (C) 2003-2005 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # """ Property list provider plugin. """leonardo-0.6.0/lib/providers/propertylist/propertylist_provider.py0000755000076500007650000000446410247461761027076 0ustar jtauberjtauber00000000000000# # Copyright (C) 2003-2005 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # """ This just a little sample provider that lists all the properties across the site, their values and the resources that have them. """ __provider__ = "PropertyListProvider" __contributions__ = {} from web_resource import PagePart from providers.page.page_provider import HTMLPage, ForbiddenPage class PropertyListProvider: def __init__(self, resource_manager, lfs, config): self.resource_manager = resource_manager self.lfs = lfs self.config = config def get(self, resource_id, request, main_resource): if not resource_id.startswith("propertylist"): return None page_part = PropertyListPagePart(resource_id, self.lfs) return HTMLPage(resource_id, page_part, self.resource_manager, request, main_resource, self.config) def post(self, resource_id, request, main_resource): pass class PropertyListPagePart(PagePart): def __init__(self, resource_id, lfs): PagePart.__init__(self, resource_id) self.title = "Property List" self.html = "
      " for prop in lfs.list_properties(): self.html += "
    • %(prop)s
        " % locals() for value, resources in lfs.find_property(prop).items(): self.html += "
      • %(value)s
          " % locals() for resource in resources: self.html += "
        • %(resource)s
        • " % locals() self.html += "
      • " self.html += "
    • " self.html += "
    "leonardo-0.6.0/lib/providers/put/0000755000076500007650000000000010247462064020044 5ustar jtauberjtauber00000000000000leonardo-0.6.0/lib/providers/put/__init__.py0000644000076500007650000000145310247461761022163 0ustar jtauberjtauber00000000000000# # Copyright (C) 2003-2004 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # """ Put provider plugin. """leonardo-0.6.0/lib/providers/put/put.config0000644000076500007650000000037110247461761022047 0ustar jtauberjtauber00000000000000# Configuration file for put provider [put] put_path : %(path_prefix)sput put_href : %(cgi_root)s%(put_path)s put_resource_field : resource put_content_field : page_content put_content_type_field : content_type leonardo-0.6.0/lib/providers/put/put_provider.py0000755000076500007650000001025610247461761023152 0ustar jtauberjtauber00000000000000# # Copyright (C) 2003-2005 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # """ POSTing to the 'put' resource is intended as an alternative to PUTing a resource in cases like HTML forms where you can't directly PUT. """ __provider__ = "PutProvider" __contributions__ = {} import urllib from web_resource import PagePart from providers.page.page_provider import HTMLPage, ForbiddenPage import templates class PutProvider: def __init__(self, resource_manager, lfs, config): self.resource_manager = resource_manager self.lfs = lfs self.config = config self.put_path = config.get("put", "put_path") def get(self, resource_id, request, main_resource): if resource_id != self.put_path: return None return ForbiddenPage(resource_id, self.resource_manager, request, main_resource, self.config) def post(self, resource_id, request, main_resource): if resource_id != self.put_path: return None if not request.logged_in(): return ForbiddenPage(resource_id, self.resource_manager, request, main_resource, self.config) page_part = PutPagePart(resource_id, self.resource_manager, request, self.config) return HTMLPage(resource_id, page_part, self.resource_manager, request, main_resource, self.config) class PutPagePart(PagePart): def __init__(self, resource_id, resource_manager, request, config): PagePart.__init__(self, resource_id) resource_to_put = request.fields.getvalue(config.get("put", "put_resource_field")) if resource_to_put: page = resource_manager.get(resource_to_put, request, self) if page.is_read_only(): title = templates.put_read_only_title % locals() content = templates.put_read_only_content % locals() else: new_content = request.fields.getvalue(config.get("put", "put_content_field")) new_content_type = request.fields.getvalue(config.get("put", "put_content_type_field")) page_title = request.fields.getvalue(config.get("editform", "edit_title_field"), None) page.set_property("page_title", page_title) for provider in resource_manager.get_contributors("post_processing"): provider(request, page, None, config) if page.exists(): replace = True else: replace = False page.set_content(new_content, new_content_type) resource_link = config.get("DEFAULT", "cgi_root") + urllib.quote(resource_to_put) resource_label = resource_to_put resource_type = new_content_type if replace: title = templates.put_replace_title % locals() content = templates.put_replace_content % locals() else: title = templates.put_create_title % locals() content = templates.put_create_content % locals() else: # no resource_id provided title = templates.put_missing_id_title % locals() content = templates.put_missing_id_content % locals() self.title = title self.html = content leonardo-0.6.0/lib/providers/put/templates.py0000644000076500007650000000241510247461761022421 0ustar jtauberjtauber00000000000000# # Copyright (C) 2003-2004 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # put_replace_title = "Resource replaced" put_replace_content = 'Resource %(resource_label)s replaced as %(resource_type)s.' put_create_title = "Resource created" put_create_content = 'Resource %(resource_label)s created as %(resource_type)s.' put_missing_id_title = "Missing Resource ID" put_missing_id_content = "Missing Resource ID." put_read_only_title = "Can't PUT read-only resource" put_read_only_content = "Can't PUT read-only resource."leonardo-0.6.0/lib/providers/static/0000755000076500007650000000000010247462063020522 5ustar jtauberjtauber00000000000000leonardo-0.6.0/lib/providers/static/__init__.py0000644000076500007650000000147710247461761022650 0ustar jtauberjtauber00000000000000# # Copyright (C) 2003-2004 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # """ Package for Leonardo resource providers. """leonardo-0.6.0/lib/providers/static/provider.py0000755000076500007650000000560710247461761022745 0ustar jtauberjtauber00000000000000# # Copyright (C) 2003-2004 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # from web_resource import TopLevelResource # ************************************************************** # THIS MODULE IS NOW DEPRECATED # non-wiki files now live under lfs and get served up by page.py # ************************************************************** class StaticFileProvider: def __init__(self, config): self.static_dir = config.static_dir def get(self, resource_id, request, main_resource): if resource_id[:4] not in ["1996", "1997", "1998", "1999", "2000", "2001", "2002", "2003", "2004", "2005"]: return None path = resource_id if path[-1] == "/": path += "index.html" # @@@ should extend this to other filenames path = path.strip("/") ext = path[path.rfind("."):] if ext in [".htm", ".html"]: mime_type = "text/html" elif ext in [".jpg", ".jpeg"]: mime_type = "image/jpeg" elif ext in [".css"]: mime_type = "text/css" else: mime_type = "text/plain" try: f = file(self.static_dir + path, "rb") x = f.read() f.close() return StaticFile(path, x, mime_type) except: return StaticFile404(path) def post(self, resource_id, request, main_resource): return None class StaticFile(TopLevelResource): def __init__(self, resource_id, content, mime_type): TopLevelResource.__init__(self, resource_id, mime_type) self.content = content def exists(self): return True def get_content(self): return self.content def get_lastmod(self): # @@@ return 0 def is_read_only(self): return True # @@@ for now class StaticFile404(StaticFile): def __init__(self, resource_id): StaticFile.__init__(self, resource_id, "File Not Found.", "text/plain") self.status = "404 Not Found" def exists(self): return False leonardo-0.6.0/lib/providers/trackback/0000755000076500007650000000000010247462063021160 5ustar jtauberjtauber00000000000000leonardo-0.6.0/lib/providers/trackback/__init__.py0000644000076500007650000000146110247461761023277 0ustar jtauberjtauber00000000000000# # Copyright (C) 2003-2004 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # """ Trackback provider plugin. """leonardo-0.6.0/lib/providers/trackback/templates.py0000644000076500007650000000375110247461761023542 0ustar jtauberjtauber00000000000000# # Copyright (C) 2003-2005 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # toggle_trackbacks_confirm_title = "%(site_title)s : toggle trackbacks on %(resource_to_toggle)s?" toggle_trackbacks_confirm_form = """

    Toggle Trackbacks on %(resource_to_toggle)s?

    Cancel """ #toggle_trackbacks_menu = """ #

    toggle_trackbacks Page

    #""" toggle_trackbacks_missing_id_title = "Missing Resource ID" toggle_trackbacks_missing_id_content = "Missing Resource ID." toggle_trackbacks_page_not_exist_title = "%(site_title)s : %(resource_to_toggle)s does not exist" toggle_trackbacks_page_not_exist_content = "%(resource_to_toggle)s does not exist." toggle_trackbacks_read_only_title = "Can't toggle trackbacks on a read-only resource" toggle_trackbacks_read_only_content = "Can't toggle trackbacks on a read-only resource." toggle_trackbacks_done_title = "%(site_title)s: %(resource_to_toggle)s trackbacks toggled" toggle_trackbacks_done_content = """%(resource_to_toggle)s trackbacks toggled to %(new_value)s."""leonardo-0.6.0/lib/providers/trackback/trackback_provider.py0000644000076500007650000001444610247461761025406 0ustar jtauberjtauber00000000000000# # Copyright (C) 2003-2005 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # __provider__ = "TrackbackProvider" __contributions__ = {"edit_form": "trackbacks_allowed_edit_form", "draft_hidden": "trackbacks_allowed_draft_hidden", "page_end" : "trackback_page_end", "blog_entry_footer" : "trackback_blog_entry_footer", "post_processing": "trackbacks_post_processing"} import urllib from web_resource import TopLevelResource, PagePart from providers.page.page_provider import HTMLPage, ForbiddenPage import templates def trackbacks_allowed_edit_form(request, resource, main_resource, config): # @@@ templatize if resource: allow_trackbacks = resource.get_property("allow_trackbacks") else: allow_trackbacks = "" s = """ Allow Trackbacks?
    """ return s def trackbacks_allowed_draft_hidden(request, resource, main_resource, config): # @@@ templatize if resource: allow_trackbacks = resource.get_property("allow_trackbacks") else: allow_trackbacks = "" s = """ """ % locals() return s # @@@ templatize def trackback_blog_entry_footer(request, resource, main_resource, config): if resource.get_property("allow_trackbacks", "NO") != "NO": trackback_count = len(resource.enclosures("trackback")) if trackback_count == 1: s = " : 1 trackback" else: s = " : %s trackbacks" % trackback_count else: s = "" return s # @@@ templatize def trackback_page_end(request, resource, main_resource, config): if main_resource == None and resource.get_property("allow_trackbacks", "NO") != "NO": enclosures = resource.enclosures("trackback") html = """

    Trackbacks (%s)

    """ % len(enclosures) for trackback in enclosures: url = trackback.get_property("url") title = trackback.get_property("title") or url blog_name = trackback.get_property("blog_name") or "unknown" content = trackback.get_content() # @@@ escape characters from content lastmod = trackback.get_lastmod() if lastmod: import time lastmod_display = time.strftime("%A %d %B, %Y", time.gmtime(lastmod)) else: lastmod_display = "" citation = """%(title)s""" % locals() html += """

    %(citation)s from %(blog_name)s on %(lastmod_display)s:

    %(content)s
    """ % locals() else: html = "" return html def trackbacks_post_processing(request, resource, main_resource, config): allow_trackbacks = request.fields.getvalue("allow_trackbacks") if allow_trackbacks and request.logged_in(): resource.set_property("allow_trackbacks", allow_trackbacks) if resource.get_property("allow_trackback", "NO") != "YES": return None url = request.fields.getvalue("url", None) if url: return self.add_trackback(resource, request, main_resource) def add_trackback(self, resource, request, main_resource): title = request.fields.getvalue("title", None) excerpt = request.fields.getvalue("excerpt", None) url = request.fields.getvalue("url", None) blog_name = request.fields.getvalue("blog_name", None) inner_resource = resource # @@@ should this be wrapped by a trackback object existing_trackbacks = inner_resource.enclosures("trackback") next_index = 0 for trackback in existing_trackbacks: if int(trackback.index) > next_index: next_index = int(trackbaack.index) next_index += 1 new_trackback = inner_resource.enclosure("trackback", next_index) new_trackback.set_content(excerpt, "txt") if title: new_trackback.set_property("title", title) if url: new_trackback.set_property("url", url) if blog_name: new_trackback.set_property("blog_name", blog_name) return TrackbackResultResource(resource.get_id()) class TrackbackProvider: def __init__(self, resource_manager, lfs, config): self.resource_manager = resource_manager self.lfs = lfs self.config = config def get(self, resource_id, request, main_resource): return None def post(self, resource_id, request, main_resource): pass class TrackbackResultResource(TopLevelResource): def __init__(self, resource_id): TopLevelResource.__init__(self, resource_id, "text/xml") def get_content(self): return """ 0 """leonardo-0.6.0/lib/providers/upload/0000755000076500007650000000000010247462063020517 5ustar jtauberjtauber00000000000000leonardo-0.6.0/lib/providers/upload/__init__.py0000644000076500007650000000145610247461761022642 0ustar jtauberjtauber00000000000000# # Copyright (C) 2003-2004 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # """ Upload provider plugin. """leonardo-0.6.0/lib/providers/upload/templates.py0000644000076500007650000000264110247461761023076 0ustar jtauberjtauber00000000000000# # Copyright (C) 2003-2005 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # upload_title = "Upload File" upload_form = """
    Path
    File
    Content Type
     
    """ upload_menu = """

    Upload File

    """ leonardo-0.6.0/lib/providers/upload/upload.config0000644000076500007650000000020110247461761023167 0ustar jtauberjtauber00000000000000# Configuration file for upload provider [upload] upload_path : %(path_prefix)supload upload_href : %(cgi_root)s%(upload_path)s leonardo-0.6.0/lib/providers/upload/upload_provider.py0000755000076500007650000000536510247461761024307 0ustar jtauberjtauber00000000000000# # Copyright (C) 2003-2005 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # __provider__ = "UploadFormProvider" __contributions__ = {"menu": "upload_menu_part"} import urllib from web_resource import PagePart from providers.page.page_provider import HTMLPage, ForbiddenPage import templates def upload_menu_part(request, resource, main_resource, config): if request.logged_in(): upload_href = config.get("upload", "upload_href") menu_part = templates.upload_menu % locals() else: menu_part = "" return menu_part class UploadFormProvider: def __init__(self, resource_manager, lfs, config): self.resource_manager = resource_manager self.lfs = lfs self.config = config self.upload_path = config.get("upload", "upload_path") def get(self, resource_id, request, main_resource): if resource_id != self.upload_path: return None if not request.logged_in(): return ForbiddenPage(resource_id, self.resource_manager, request, self.config) page_part = UploadPagePart(resource_id, self.resource_manager, request, self.config) html_page = HTMLPage(resource_id, page_part, self.resource_manager, request, main_resource, self.config) return html_page def post(self, resource_id, request, main_resource): return None class UploadPagePart(PagePart): def __init__(self, resource_id, resource_manager, request, config): PagePart.__init__(self, resource_id) action = config.get("put", "put_href") file_content_name = config.get("put", "put_content_field") file_content_type_name = config.get("put", "put_content_type_field") path_name = config.get("put", "put_resource_field") site_title = config.get("page", "site_title") self.title = templates.upload_title % locals() content = templates.upload_form % locals() self.html = content leonardo-0.6.0/lib/request_response.py0000644000076500007650000001043010247461761021200 0ustar jtauberjtauber00000000000000# # Copyright (C) 2003-2005 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # """ This module defines request and response objects for handling communication from and to the client (e.g. web browser). """ import os import cgi import time import auth from auth import OK from web_resource import TopLevelResource class Request: def __init__(self, config): self.env = os.environ self.fields = cgi.FieldStorage() self.path_info = self.env.get("PATH_INFO", "/") self.relative_path = self.path_info.strip("/") self.method = self.env.get("REQUEST_METHOD", "") self.query = self.env.get("QUERY_STRING", "") self.remote_address = self.env.get("REMOTE_ADDR", "") self.cookie = self.env.get("HTTP_COOKIE", None) self.if_modified_since = self.env.get("HTTP_IF_MODIFIED_SINCE", None) self.if_none_match = self.env.get("HTTP_IF_NONE_MATCH", None) self.session_mgr = auth.SessionManager(self, config.get("DEFAULT", "data_dir")) self.user_mgr = auth.UserManager(self, config.get("DEFAULT", "data_dir")) def logged_in(self): """Is the user logged in?""" return (self.session_mgr.check_session()[0] == OK) def get_user(self): """Get the current user""" return self.session_mgr.check_session()[1] def correct_password(self, user_id, passwd): """Is the given user id, password combination correct?""" return self.user_mgr.correct_password(user_id, passwd) def check_session(self): return self.session_mgr.check_session() def create_session(self, uid, ip_address): return self.session_mgr.create_session(uid, ip_address) def delete_session(self, sid): return self.session_mgr.delete_session(sid) def not_modified(self, resource): if hasattr(resource, "lastmod"): if self.if_modified_since: lastmod = time.strptime(self.if_modified_since, "%a, %d %b %Y %H:%M:%S %Z") if time.mktime(resource.lastmod) <= time.mktime(lastmod): return True return False class Response: def __init__(self, resource=None, status=None): self.status = status self.cookie = None self.content = None self.content_type = None self.lastmod = None self.headers = {} if isinstance(resource, TopLevelResource): self.content_type = resource.get_mime_type() self.content = resource.get_content() if hasattr(resource, "status"): self.status = resource.status if hasattr(resource, "cookie"): self.cookie = resource.cookie if hasattr(resource, "expiry"): self.headers["Expires"] = 0 if hasattr(resource, "lastmod"): lastmod = time.strftime("%a, %d %b %Y %H:%M:%S GMT", resource.lastmod) self.headers["Last-Modified"] = lastmod else: self.status = "403 Forbidden" def send(self, out): if self.status: out.write("Status: %s\n" % self.status) for name, value in self.headers.items(): out.write("%s: %s\n" % (name, value)) if self.cookie: out.write("%s\n" % self.cookie) if self.content_type: out.write("Content-type: %s\n" % self.content_type) if self.content: out.write("\n") out.write(self.content) leonardo-0.6.0/lib/web_resource.py0000755000076500007650000000736710247461761020300 0ustar jtauberjtauber00000000000000# # Copyright (C) 2003-2005 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # class Resource: """ A resource is content object that can be returned to the client / browser in one or more forms either as the entire response or as a part of the response. Typically sublcassed, a resource object wraps a data source (such as a leonardo "file") and may provide format translation (such as from a wiki format to HTML). Examples of resources include wiki pages, blog entries, menus, etc. """ def __init__(self, resource_id): self.resource_id = resource_id def get_id(self): return self.resource_id def get_title(self): return self.resource_id class PagePart(Resource): """ A resource that is part of a page. The key method that PagePart adds is get_html(). If the page part is editable, then get_content() will return the underlying content that can be edited. """ def __init__(self, resource_id, title=None, html=None): Resource.__init__(self, resource_id) self.title = title self.html = html def get_title(self): return self.title def get_html(self): return self.html def get_lastmod(self): return 0 def exists(self): return True def is_read_only(self): return True # default class TopLevelResource(Resource): """ A resource that is returned directly to the client / browser rather than as part of an enclosing resource. """ def __init__(self, resource_id, mime_type): Resource.__init__(self, resource_id) self.mime_type = mime_type def get_mime_type(self): return self.mime_type class FileObjectResource: """ A mix-in for resources that wrap an LFS file object. """ def __init__(self, file_object): self.file_object = file_object def exists(self): return self.file_object.exists() def get_lastmod(self): return self.file_object.get_lastmod() def get_content(self): return self.file_object.get_content() def get_content_type(self): return self.file_object.get_content_type() def set_content(self, content, content_type): self.file_object.set_content(content, content_type) def delete(self): self.file_object.delete() def is_read_only(self): return True # default def get_creation_time(self): return self.file_object.get_creation_time() def get_property(self, name, default=None): return self.file_object.get_property(name, default) def set_property(self, name, value): return self.file_object.set_property(name, value) def enclosures(self, enctype): return self.file_object.enclosures(enctype) def enclosure(self, enctype, index): return self.file_object.enclosure(enctype, index) leonardo-0.6.0/README0000644000076500007650000000102710247461761015334 0ustar jtauberjtauber00000000000000Leonardo 0.6.0 http://jtauber.com/leonardo Leonardo is a personal wiki and blog server written in Python. QUICKSTART * Run python test_server.py * To create a user, cd into bin and run create_user.py (bin must be parallel to data otherwise edit USER_DB) * Further customize by editing cgi-bin/leonardo.config * If you install lib somewhere other than parallel to cgi-bin, you'll want to change leonardo_lib in cgi-bin/leonardo.py also see EXTRAS. Feel free to ask the Leonardo mailing list for any help.leonardo-0.6.0/test_server.py0000755000076500007650000000505310247461761017401 0ustar jtauberjtauber00000000000000#!/usr/bin/env python # # Copyright (C) 2003-2004 James Tauber # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # # Simulates Apache with the following directive: # # ScriptAlias / /cgi-bin/leonardo.py/ # # Useful for getting going before you deploy on an actual webserver import CGIHTTPServer from BaseHTTPServer import HTTPServer import sys sys.path.append("cgi-bin") def usage(): print """ -h, --help : this help message -n, --no-browser : don't start browser -p , --port= : port to run on if not 8000 """ import getopt try: opts, args = getopt.getopt(sys.argv[1:], "hnp:", ["help", "no-browser", "port="]) except getopt.GetoptError: usage() sys.exit(2) if args: usage() sys.exit(2) start_browser = True port = 8000 for o, a in opts: if o in ("-n", "--no-browser"): start_browser = False if o in ("-h", "--help"): usage() sys.exit() if o in ("-p", "--port"): port = int(a) import os class Handler(CGIHTTPServer.CGIHTTPRequestHandler): def do_POST(self): # for some reason the query string from the last request hangs # around without this. os.environ['QUERY_STRING'] = "" self.cgi_info = "/cgi-bin", "leonardo.py/" + self.path self.run_cgi() def do_GET(self): # for some reason the query string from the last request hangs # around without this. os.environ['QUERY_STRING'] = "" ims = self.headers.getheader('If-Modified-Since') if ims: os.environ['HTTP_IF_MODIFIED_SINCE'] = ims self.cgi_info = "/cgi-bin", "leonardo.py/" + self.path self.run_cgi() server_address = ("", port) httpd = HTTPServer(server_address, Handler) if start_browser: import webbrowser webbrowser.open("http://localhost:%s/" % port, 1) print "Serving HTTP on port", port, "..." httpd.serve_forever() leonardo-0.6.0/UPGRADE0000644000076500007650000000303210247461761015464 0ustar jtauberjtauber00000000000000Upgrading from 0.5.x to 0.6.x ----------------------------- 1. back up your entire existing Leonardo installation, *especially* your data. 2. update leonardo.py as per README QUICKSTART 3. update leonardo.config as per README QUICKSTART but with any additional configuration changes you have made. Because of the changes to the format, you will have to do this manually. 4. if you have made changes to the templates, you will need to upgrade those manually. 5. assuming no changes have been made to templates, you can just copy over new lib/ directory. 6. double check that you backed up your data directory! 7. if you previously used the static provider, you will need to run bin/ convert_static.py to convert the static files over to LFS. If you have a directory '/static/1996' that you'd like to convert to '/lfs/1996', run convert_static.py /static/1996 /lfs/1996 8. you really should have backed up your data directory by now. 9. convert your LFS to the new database-based properties using bin/convert_lfs.py 10. add something like the following to your css: div.comment, div.trackback { border-top: 1px solid #999; margin: 10px 5px 5px 5px; padding: 3px; } p.comment_citation, p.trackback_citation { font-size : 0.8em; font-style: italic; } .footnotes { font-size : smaller; border-top : 1px solid #DDD; padding-top : 10px; } 11. DONE!