./0000755000076600007660000000000010764306263011766 5ustar00tony127tony12700000000000000ABOUT0000644000076600007660000000011010750060206012403 0ustar00tony127tony12700000000000000This is an example of a simple blog implemented in the web2py framework.LICENSE0000644000076600007660000000235610737735331012646 0ustar00tony127tony12700000000000000Copyright (c) 2007, Massimo Di Pierro All rights reserved. Licensed under GPL v2.0 We also allow the redistribution of unmodified binary versions of web2py provided that they contain a link to the official web2py site. This means you can redistribute web2py in binary or other closed source form together with the applications you develop as long as you acknowledge the author. If you make any modifcation to web2py you must distribute it together with the modified source code according to GPLv2.0. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. __init__.py0000644000076600007660000000000010764306263013730 0ustar00tony127tony12700000000000000cache/0000755000076600007660000000000010764306473012677 5ustar00tony127tony12700000000000000controllers/0000755000076600007660000000000010764306263014177 5ustar00tony127tony12700000000000000controllers/appadmin.py0000644000076600007660000001257010764306263016347 0ustar00tony127tony12700000000000000########################################################### ### make sure administrator is on localhost ############################################################ import os from gluon.contenttype import contenttype from gluon.fileutils import check_credentials person = "Blog user" if request.env.remote_addr!=request.env.http_host.split(':')[0]: raise HTTP(400) if not check_credentials(request): redirect('/admin') response.view='appadmin.html' response.menu=[['design',False,'/admin/default/design/%s' % request.application], ['db',False,'/%s/%s/index' % (request.application, request.controller)], ['state',False,'/%s/%s/state' % (request.application, request.controller)]] ########################################################### ### list all tables in database ############################################################ def index(): import types as _types _dbs={} for _key,_value in globals().items(): if isinstance(_value,SQLDB): tables=_dbs[_key]=[] for _tablename in _value.tables: tables.append((_key,_tablename)) return dict(dbs=_dbs, person = person) ########################################################### ### insert a new record ############################################################ def insert(): try: dbname=request.args[0] db=eval(dbname) table=request.args[1] form=SQLFORM(db[table]) except: redirect(URL(r=request,f='index')) if form.accepts(request.vars,session): response.flash='new record inserted' return dict(form=form, person = person) ########################################################### ### list all records in table and insert new record ############################################################ def download(): filename=request.args[0] response.headers['Content-Type']=contenttype(filename) return open(os.path.join(request.folder,'uploads/','%s' % filename),'rb').read() def csv(): import gluon.contenttype, csv, cStringIO response.headers['Content-Type']=gluon.contenttype.contenttype('.csv') try: dbname=request.vars.dbname db=eval(dbname) records=db(request.vars.query).select() except: redirect(URL(r=request,f='index')) s=cStringIO.StringIO() writer = csv.writer(s) writer.writerow(records.colnames) c=range(len(records.colnames)) for i in range(len(records)): writer.writerow([records.response[i][j] for j in c]) ### FILL HERE return s.getvalue() def import_csv(table,file): import csv reader = csv.reader(file) colnames=None for line in reader: if not colnames: colnames=[x[x.find('.')+1:] for x in line] c=[i for i in range(len(line)) if colnames[i]!='id'] else: items=[(colnames[i],line[i]) for i in c] table.insert(**dict(items)) def select(): try: dbname=request.args[0] db=eval(dbname) if not request.vars.query: table=request.args[1] query='%s.id>0' % table else: query=request.vars.query except: redirect(URL(r=request,f='index')) if request.vars.csvfile!=None: try: import_csv(db[table],request.vars.csvfile.file) response.flash='data uploaded' except: reponse.flash='unable to parse csv file' if request.vars.delete_all and request.vars.delete_all_sure=='yes': try: db(query).delete() response.flash='records deleted' except: response.flash='invalid SQL FILTER' elif request.vars.update_string: try: env=dict(db=db,query=query) exec('db(query).update('+request.vars.update_string+')') in env response.flash='records updated' except: response.flash='invalid SQL FILTER or UPDATE STRING' if request.vars.start: start=int(request.vars.start) else: start=0 limitby=(start,start+100) try: records=db(query).select(limitby=limitby) except: response.flash='invalid SQL FILTER' return dict(records='no records',nrecords=0,query=query,start=0) linkto=URL(r=request,f='update/%s'% (dbname)) upload=URL(r=request,f='download') return dict(start=start,query=query,\ nrecords=len(records),\ records=SQLTABLE(records,linkto,upload,_class='sortable'), person = person) ########################################################### ### edit delete one record ############################################################ def update(): try: dbname=request.args[0] db=eval(dbname) table=request.args[1] except: redirect(URL(r=request,f='index')) try: id=int(request.args[2]) record=db(db[table].id==id).select()[0] except: redirect(URL(r=request,f='select/%s/%s'%(dbname,table))) form=SQLFORM(db[table],record,deletable=True, linkto=URL(r=request,f='select/'+dbname), upload=URL(r=request,f='download/')) if form.accepts(request.vars,session): response.flash='done!' redirect(URL(r=request,f='select/%s/%s'%(dbname,table))) return dict(form=form, person = person) ########################################################### ### get global variables ############################################################ def state(): return dict(state=request.env)controllers/default.py0000644000076600007660000000576210764306263016207 0ustar00tony127tony12700000000000000import os from gluon.contenttype import contenttype from gluon.fileutils import check_credentials record=db(db.pagename.id == 1).select()[0] person = record.title admin = True ########################################################### ### main index ############################################################ def index(): person = "Blog user" rows = db().select(db.image.ALL) try: if check_credentials(request): admin = True except: admin = False return dict(images = rows, admin = admin, person = person) ########################################################### ### show a record ############################################################ def show(): id = int(request.args[0]) row = db(db.image.id == id).select()[0] myform = SQLFORM(db.comment, fields = ['author', 'email', 'body']) myform.vars.image_id = id; if myform.accepts(request.vars,session): response.flash = "comment posted" try: if check_credentials(request): admin = True except: admin = False comments = db(db.comment.image_id == id).select() return dict(image = row, comments = comments, myform = myform, admin = admin, person = person) ########################################################### ### download file ############################################################ def download(): filename=request.args[0] response.headers['Content-Type']=contenttype(filename) return open(os.path.join(request.folder,'uploads/','%s' % filename),'rb').read() ########################################################### ### insert a new record ############################################################ def insert(): if not admin: redirect(URL(r=request,f='index')) form=SQLFORM(db.image) if form.accepts(request.vars,session): response.flash='new record inserted' return dict(form=form, person = person) ########################################################### ### edit delete one record ############################################################ def update(): if not admin: redirect(URL(r=request,f='index')) id=int(request.args[0]) record=db(db.image.id==id).select()[0] form=SQLFORM(db.image,record,deletable=True) #upload=URL(r=request,f='download/')) if form.accepts(request.vars,session): response.flash='done!' redirect(URL(r=request,f='index')) return dict(form=form, person = person) ########################################################## ### edit title ############################################################ def title(): if not admin: redirect(URL(r=request,f='index')) id=int(request.args[0]) record=db(db.pagename.id == 1).select()[0] form=SQLFORM(db.pagename, record, deletable=False) if form.accepts(request.vars,session): response.flash='done!' redirect(URL(r=request,f='index')) return dict(form = form, person = person)databases/0000755000076600007660000000000010764306263013560 5ustar00tony127tony12700000000000000databases/db.db0000644000076600007660000001400010764301615014443 0ustar00tony127tony12700000000000000SQLite format 3@  [9}[!tableuseruserCREATE TABLE user( id INTEGER PRIMARY KEY AUTOINCREMENT, email CHAR(32), password CHAR(32), verification CHAR(32) , usr_name CHAR(32))~[tableimageimageCREATE TABLE image( id INTEGER PRIMARY KEY AUTOINCREMENT, title CHAR(32), file CHAR(64) , body TEXT)9ItablecommentcommentCREATE TABLE comment( id INTEGER PRIMARY KEY AUTOINCREMENT, author CHAR(32), email CHAR(32), body TEXT, image_id REFERENCES image(id) ON DELETE CASCADE )P++Ytablesqlite_sequencesqlite_sequenceCREATE TABLE sqlite_sequence(name,seq)l+tablepagenamepagenameCREATE TABLE pagename( id INTEGER PRIMARY KEY AUTOINCREMENT, title CHAR(32) )  <<<<Cmgraph 2image.file.258814267401.JPGthis is the second pic that has some ghetto art.k)E)Tony Marg Titoimage.file.0557133922261.JPGThis is a t:.'C'This is a Carimage.file.406227780432.jpgThis is a car{-ICThis is the Golden Gate Bridgeimage.file.365119113168.jpgThis is the Golden Gate Bridge in San Francisco, California.t,GC{This is Half Dome at Yosemiteimage.file.499407055515.jpgThis is a picture of Half Dome at Yosemite, California.  pagenameuser comment( image. *TsN*iiiiiii'7Tonytony@tony.comThis was at the Monterey Aquarium. It is one of the largest Aquariums in California.(' MegatronFun Kayyy! '5Margmarg@marg.comYup. It's an otter.('3Tonytony@tony.comLooks like an otter('3Margmarg@marg.comYup. It's an otter.'%#!Internet Catcat@cat.comlooks lame&['!Tonytony@tony.comLooks cool&7';Tonytony@tony.comMargaret in Greece 2007%'YTonytony@tony.comAt Alex Smoke. The sh"('Mike make@mike.comWay cool.-#''#Tonytony@tony.comLooks nice..&#Joe saysjoe@joe.comCool-$%#!Joe saysjoe@joe.comLooks cool,?#'[Marymary@mary.comI'm going on vacation to San Francisco.-X"' Mikemike@mike.comIt costs five dollars to drive over this bridge from Sausalito.-D!#kJoejoe@joe.comThere is a walkway to walk across the bridge. -3 'AMike mike@mike.comI went there last Spring. ,/';Tonytony@tony.comThat looks really cool!, xxS#MMrad@rad.com6de99124428351# Mrad@rad.com57c0531e13f40b91b3b0f1a30b529a1dS'MMdude@dude.com6de9912442835da15fb7d32e35dcad07b543376b5721da011b230ba7ae9dd619 !Blog user3 Blog user Blog user Blog user 2databases/f6db3e6e66dc0b6aea6b47a87ef29c1f_comment.table0000644000076600007660000000023410764306467023271 0ustar00tony127tony12700000000000000(dp1 S'body' p2 S'TEXT' p3 sS'image_id' p4 g3 sS'id' p5 S'INTEGER PRIMARY KEY AUTOINCREMENT' p6 sS'email' p7 S'CHAR(32)' p8 sS'author' p9 S'CHAR(32)' p10 s.databases/f6db3e6e66dc0b6aea6b47a87ef29c1f_image.table0000644000076600007660000000020610747676467022723 0ustar00tony127tony12700000000000000(dp1 S'body' p2 S'TEXT' p3 sS'id' p4 S'INTEGER PRIMARY KEY AUTOINCREMENT' p5 sS'file' p6 S'CHAR(64)' p7 sS'title' p8 S'CHAR(32)' p9 s.databases/f6db3e6e66dc0b6aea6b47a87ef29c1f_pagename.table0000644000076600007660000000012410750650377023377 0ustar00tony127tony12700000000000000(dp1 S'id' p2 S'INTEGER PRIMARY KEY AUTOINCREMENT' p3 sS'title' p4 S'CHAR(32)' p5 s.databases/f6db3e6e66dc0b6aea6b47a87ef29c1f_user.table0000644000076600007660000000026710750664113022601 0ustar00tony127tony12700000000000000(dp1 S'email' p2 S'CHAR(32)' p3 sS'password' p4 S'CHAR(32)' p5 sS'usr_name' p6 S'CHAR(32)' p7 sS'verification' p8 S'CHAR(32)' p9 sS'id' p10 S'INTEGER PRIMARY KEY AUTOINCREMENT' p11 s.databases/sql.log0000644000076600007660000000147110750650377015070 0ustar00tony127tony12700000000000000timestamp: 2008-01-13T18:29:29.874492 CREATE TABLE image( id INTEGER PRIMARY KEY AUTOINCREMENT, title CHAR(32), file CHAR(64) ); success! timestamp: 2008-01-13T18:29:29.878242 CREATE TABLE comment( id INTEGER PRIMARY KEY AUTOINCREMENT, author CHAR(32), email CHAR(32), body TEXT, image_id REFERENCES image(id) ON DELETE CASCADE ); success! timestamp: 2008-01-29T13:23:35.052681 ALTER TABLE image ADD COLUMN body TEXT; success! timestamp: 2008-02-01T02:46:20.829338 CREATE TABLE user( id INTEGER PRIMARY KEY AUTOINCREMENT, email CHAR(32), password CHAR(32), verification CHAR(32) ); success! timestamp: 2008-02-01T02:49:47.148224 ALTER TABLE user ADD COLUMN usr_name CHAR(32); success! timestamp: 2008-02-01T09:03:59.788124 CREATE TABLE pagename( id INTEGER PRIMARY KEY AUTOINCREMENT, title CHAR(32) ); success! errors/0000755000076600007660000000000010764306263013145 5ustar00tony127tony12700000000000000languages/0000755000076600007660000000000010764306263013577 5ustar00tony127tony12700000000000000models/0000755000076600007660000000000010764306263013114 5ustar00tony127tony12700000000000000models/db.py0000644000076600007660000000057610764306263014063 0ustar00tony127tony12700000000000000# try something like db=SQLDB("sqlite://db.db") db.define_table('image', SQLField('title'), SQLField('file','upload'), SQLField('body','text')) db.define_table('comment', SQLField('author'), SQLField('email'), SQLField('body', 'text'), SQLField('image_id',db.image)) db.define_table('pagename', SQLField('title', default = "Blog user"))modules/0000755000076600007660000000000010764306263013301 5ustar00tony127tony12700000000000000modules/__init__.py0000644000076600007660000000000010764306263015400 0ustar00tony127tony12700000000000000private/0000755000076600007660000000000010764306263013303 5ustar00tony127tony12700000000000000sessions/0000755000076600007660000000000010764306473013502 5ustar00tony127tony12700000000000000static/0000755000076600007660000000000010764306263013120 5ustar00tony127tony12700000000000000static/sorttable.js0000644000076600007660000004102510737213573015460 0ustar00tony127tony12700000000000000/* SortTable version 2 7th April 2007 Stuart Langridge, http://www.kryogenix.org/code/browser/sorttable/ Instructions: Download this file Add to your HTML Add class="sortable" to any table you'd like to make sortable Click on the headers to sort Thanks to many, many people for contributions and suggestions. Licenced as X11: http://www.kryogenix.org/code/browser/licence.html This basically means: do what you want with it. */ var stIsIE = /*@cc_on!@*/false; sorttable = { init: function() { // quit if this function has already been called if (arguments.callee.done) return; // flag this function so we don't do the same thing twice arguments.callee.done = true; // kill the timer if (_timer) clearInterval(_timer); if (!document.createElement || !document.getElementsByTagName) return; sorttable.DATE_RE = /^(\d\d?)[\/\.-](\d\d?)[\/\.-]((\d\d)?\d\d)$/; forEach(document.getElementsByTagName('table'), function(table) { if (table.className.search(/\bsortable\b/) != -1) { sorttable.makeSortable(table); } }); }, makeSortable: function(table) { if (table.getElementsByTagName('thead').length == 0) { // table doesn't have a tHead. Since it should have, create one and // put the first table row in it. the = document.createElement('thead'); the.appendChild(table.rows[0]); table.insertBefore(the,table.firstChild); } // Safari doesn't support table.tHead, sigh if (table.tHead == null) table.tHead = table.getElementsByTagName('thead')[0]; if (table.tHead.rows.length != 1) return; // can't cope with two header rows // Sorttable v1 put rows with a class of "sortbottom" at the bottom (as // "total" rows, for example). This is B&R, since what you're supposed // to do is put them in a tfoot. So, if there are sortbottom rows, // for backwards compatibility, move them to tfoot (creating it if needed). sortbottomrows = []; for (var i=0; i5' : ' ▴'; this.appendChild(sortrevind); return; } if (this.className.search(/\bsorttable_sorted_reverse\b/) != -1) { // if we're already sorted by this column in reverse, just // re-reverse the table, which is quicker sorttable.reverse(this.sorttable_tbody); this.className = this.className.replace('sorttable_sorted_reverse', 'sorttable_sorted'); this.removeChild(document.getElementById('sorttable_sortrevind')); sortfwdind = document.createElement('span'); sortfwdind.id = "sorttable_sortfwdind"; sortfwdind.innerHTML = stIsIE ? ' 6' : ' ▾'; this.appendChild(sortfwdind); return; } // remove sorttable_sorted classes theadrow = this.parentNode; forEach(theadrow.childNodes, function(cell) { if (cell.nodeType == 1) { // an element cell.className = cell.className.replace('sorttable_sorted_reverse',''); cell.className = cell.className.replace('sorttable_sorted',''); } }); sortfwdind = document.getElementById('sorttable_sortfwdind'); if (sortfwdind) { sortfwdind.parentNode.removeChild(sortfwdind); } sortrevind = document.getElementById('sorttable_sortrevind'); if (sortrevind) { sortrevind.parentNode.removeChild(sortrevind); } this.className += ' sorttable_sorted'; sortfwdind = document.createElement('span'); sortfwdind.id = "sorttable_sortfwdind"; sortfwdind.innerHTML = stIsIE ? ' 6' : ' ▾'; this.appendChild(sortfwdind); // build an array to sort. This is a Schwartzian transform thing, // i.e., we "decorate" each row with the actual sort key, // sort based on the sort keys, and then put the rows back in order // which is a lot faster because you only do getInnerText once per row row_array = []; col = this.sorttable_columnindex; rows = this.sorttable_tbody.rows; for (var j=0; j 12) { // definitely dd/mm return sorttable.sort_ddmm; } else if (second > 12) { return sorttable.sort_mmdd; } else { // looks like a date, but we can't tell which, so assume // that it's dd/mm (English imperialism!) and keep looking sortfn = sorttable.sort_ddmm; } } } } return sortfn; }, getInnerText: function(node) { // gets the text we want to use for sorting for a cell. // strips leading and trailing whitespace. // this is *not* a generic getInnerText function; it's special to sorttable. // for example, you can override the cell text with a customkey attribute. // it also gets .value for fields. hasInputs = (typeof node.getElementsByTagName == 'function') && node.getElementsByTagName('input').length; if (node.getAttribute("sorttable_customkey") != null) { return node.getAttribute("sorttable_customkey"); } else if (typeof node.textContent != 'undefined' && !hasInputs) { return node.textContent.replace(/^\s+|\s+$/g, ''); } else if (typeof node.innerText != 'undefined' && !hasInputs) { return node.innerText.replace(/^\s+|\s+$/g, ''); } else if (typeof node.text != 'undefined' && !hasInputs) { return node.text.replace(/^\s+|\s+$/g, ''); } else { switch (node.nodeType) { case 3: if (node.nodeName.toLowerCase() == 'input') { return node.value.replace(/^\s+|\s+$/g, ''); } case 4: return node.nodeValue.replace(/^\s+|\s+$/g, ''); break; case 1: case 11: var innerText = ''; for (var i = 0; i < node.childNodes.length; i++) { innerText += sorttable.getInnerText(node.childNodes[i]); } return innerText.replace(/^\s+|\s+$/g, ''); break; default: return ''; } } }, reverse: function(tbody) { // reverse the rows in a tbody newrows = []; for (var i=0; i=0; i--) { tbody.appendChild(newrows[i]); } delete newrows; }, /* sort functions each sort function takes two parameters, a and b you are comparing a[0] and b[0] */ sort_numeric: function(a,b) { aa = parseFloat(a[0].replace(/[^0-9.-]/g,'')); if (isNaN(aa)) aa = 0; bb = parseFloat(b[0].replace(/[^0-9.-]/g,'')); if (isNaN(bb)) bb = 0; return aa-bb; }, sort_alpha: function(a,b) { if (a[0]==b[0]) return 0; if (a[0] 0 ) { var q = list[i]; list[i] = list[i+1]; list[i+1] = q; swap = true; } } // for t--; if (!swap) break; for(var i = t; i > b; --i) { if ( comp_func(list[i], list[i-1]) < 0 ) { var q = list[i]; list[i] = list[i-1]; list[i-1] = q; swap = true; } } // for b++; } // while(swap) } } /* ****************************************************************** Supporting functions: bundled here to avoid depending on a library ****************************************************************** */ // Dean Edwards/Matthias Miller/John Resig /* for Mozilla/Opera9 */ if (document.addEventListener) { document.addEventListener("DOMContentLoaded", sorttable.init, false); } /* for Internet Explorer */ /*@cc_on @*/ /*@if (@_win32) document.write("