Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

git-svn-id: http://micolog.googlecode.com/svn/trunk@2 fd139d67-4554-0…

…410-8437-97b8145f5b4d
  • Loading branch information...
commit 9879ac3f5fb9374e8f90f97c01c4d45127ef2c20 1 parent 1845b07
coolchyni authored
View
21 LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2008 Aaron Raddon
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
View
20 app.yaml
@@ -0,0 +1,20 @@
+application: mlog
+version: 1
+runtime: python
+api_version: 1
+
+handlers:
+- url: /rpc
+ script: metaweblog.py
+
+- url: /rpc/.*
+ script: metaweblog.py
+
+- url: /themes/[\w\-]+/templates/.*
+ script: blog.py
+
+- url: /themes
+ static_dir: themes
+
+- url: /.*
+ script: blog.py
View
0  app/__init__.py
No changes.
View
117 app/webapp/__init__.py
@@ -0,0 +1,117 @@
+#!/usr/bin/env python
+#
+# Copyright 2007 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+import cgi,os
+import StringIO
+import logging
+import re
+import sys
+import traceback
+import urlparse
+import webob
+import wsgiref.headers
+import wsgiref.util
+from google.appengine.ext.webapp import *
+
+class RequestHandler(RequestHandler):
+ def __init__(self):
+ self.template_vals = {}
+
+ def __before__(self,*args):
+ """
+ Allows common code to be used for all get/post/delete methods
+ """
+ pass
+
+ def __after__(self,*args):
+ """
+ This runs AFTER response is returned to browser.
+ If you have follow up work that you don't want to do while
+ browser is waiting put it here such as sending emails etc
+ """
+ pass
+
+
+
+
+
+class WSGIApplication2(WSGIApplication):
+ """
+ Modifyed to add new methods __before__ and __after__
+ before the get/post/delete/etc methods and then
+ AFTER RESPONSE. This is important because it means you
+ can do work after the response has been returned to the browser
+ """
+ def __init__(self, url_mapping, debug=False):
+ """Initializes this application with the given URL mapping.
+
+ Args:
+ url_mapping: list of (URI, RequestHandler) pairs (e.g., [('/', ReqHan)])
+ debug: if true, we send Python stack traces to the browser on errors
+ """
+ self._init_url_mappings(url_mapping)
+ self.__debug = debug
+ WSGIApplication.active_instance = self
+ self.current_request_args = ()
+
+ def __call__(self, environ, start_response):
+ """Called by WSGI when a request comes in."""
+ request = Request(environ)
+ response = Response()
+
+ WSGIApplication.active_instance = self
+
+ handler = None
+ groups = ()
+ for regexp, handler_class in self._url_mapping:
+ match = regexp.match(request.path)
+ if match:
+ handler = handler_class()
+ handler.initialize(request, response)
+ groups = match.groups()
+ break
+
+ self.current_request_args = groups
+
+ if handler:
+ try:
+ handler.__before__(*groups)
+ method = environ['REQUEST_METHOD']
+ if method == 'GET':
+ handler.get(*groups)
+ elif method == 'POST':
+ handler.post(*groups)
+ elif method == 'HEAD':
+ handler.head(*groups)
+ elif method == 'OPTIONS':
+ handler.options(*groups)
+ elif method == 'PUT':
+ handler.put(*groups)
+ elif method == 'DELETE':
+ handler.delete(*groups)
+ elif method == 'TRACE':
+ handler.trace(*groups)
+ else:
+ handler.error(501)
+ response.wsgi_write(start_response)
+ handler.__after__(*groups)
+ except Exception, e:
+ handler.handle_exception(e, self.__debug)
+ else:
+ response.set_status(404)
+ response.wsgi_write(start_response)
+ return ['']
View
189 base.py
@@ -0,0 +1,189 @@
+import os,logging
+import re
+from functools import wraps
+from google.appengine.api import users
+from google.appengine.ext import webapp
+from google.appengine.ext import db
+from google.appengine.ext.webapp import template
+from google.appengine.api import memcache
+import app.webapp as webapp2
+from model import *
+import wsgiref.handlers
+from mimetypes import types_map
+from datetime import datetime, timedelta
+
+logging.info('module base reloaded')
+
+def requires_admin(method):
+ @wraps(method)
+ def wrapper(self, *args, **kwargs):
+ if not self.is_login:
+ self.redirect(users.create_login_url(self.request.uri))
+ return
+ elif not self.is_admin:
+ return self.error(403)
+ else:
+ return method(self, *args, **kwargs)
+ return wrapper
+
+def printinfo(method):
+ @wraps(method)
+ def wrapper(self, *args, **kwargs):
+ print self #.__name__
+ print dir(self)
+ for x in self.__dict__:
+ print x
+ return method(self, *args, **kwargs)
+ return wrapper
+
+
+class Pager(object):
+
+ def __init__(self, model=None,query=None, items_per_page=10):
+ if model:
+ self.query = model.all()
+ elif query:
+ self.query=query
+
+ self.items_per_page = items_per_page
+
+ def fetch(self, p):
+ max_offset = self.query.count()
+ n = max_offset / self.items_per_page
+ if max_offset % self.items_per_page != 0:
+ n += 1
+
+ if p < 0 or p > n:
+ p = 1
+ offset = (p - 1) * self.items_per_page
+ results = self.query.fetch(self.items_per_page, offset)
+
+ links = {'prev': p - 1, 'next': p + 1, 'last': n}
+ if links['next'] > n:
+ links['next'] = 0
+
+ return (results, links)
+
+
+class BaseRequestHandler(webapp2.RequestHandler):
+ def __init__(self):
+ pass
+
+ def initialize(self, request, response):
+ webapp2.RequestHandler.initialize(self, request, response)
+ self.blog = g_blog
+ self.login_user = users.get_current_user()
+ self.is_login = (self.login_user != None)
+ if self.is_login:
+ self.loginurl=users.create_logout_url(self.request.uri)
+ #self.user = User.all().filter('user = ', self.login_user).get() or User(user = self.login_user)
+ else:
+ self.loginurl=users.create_login_url(self.request.uri)
+ #self.user = None
+
+ self.is_admin = users.is_current_user_admin()
+ if self.is_admin:
+ self.auth = 'admin'
+ elif self.is_login:
+ self.auth = 'login'
+ else:
+ self.auth = 'guest'
+
+ try:
+ self.referer = self.request.headers['referer']
+ except:
+ self.referer = None
+
+
+
+ self.template_vals = {'self':self,'blog':self.blog}
+
+ def __before__(self,*args):
+ pass
+
+ def __after__(self,*args):
+ pass
+
+ def error(self,errorcode,message='an error occured'):
+ if errorcode == 404:
+ message = 'Sorry, we were not able to find the requested page. We have logged this error and will look into it.'
+ elif errorcode == 403:
+ message = 'Sorry, that page is reserved for administrators. '
+ elif errorcode == 500:
+ message = "Sorry, the server encountered an error. We have logged this error and will look into it."
+
+ self.template_vals.update( {'errorcode':errorcode,'message':message})
+ if errorcode>0:
+ self.response.set_status(errorcode)
+
+
+ errorfile=getattr(self.blog.theme,'error'+str(errorcode))
+ if not errorfile:
+ errorfile=self.blog.theme.error
+ self.response.out.write( template.render(errorfile, self.template_vals))
+
+
+ def render(self,template_file,values):
+ """
+ Helper method to render the appropriate template
+ """
+
+
+ html = memcache.get('%s:page:%s' % (self.login_user, self.request.path_qs))
+
+
+ if html == None:
+ #try:
+ sfile=getattr(self.blog.theme, template_file)
+ self.template_vals.update(values)
+ html = template.render(sfile, self.template_vals)
+ #except Exception, e: # if theme files are not found, fall back to default theme
+ #return self.response.out.write('template file "%s" dose not exist.'%(template_file))
+ #return self.error(-1,'template file "%s" dose not exist.'%(sfile))
+
+# memcache.set('%s:page:%s' % (self.login_user, self.request.path_qs), html)
+
+ self.response.out.write(html)
+
+
+ def render2(self,template_file,template_vals={}):
+ """
+ Helper method to render the appropriate template
+ """
+
+ self.template_vals.update(template_vals)
+ path = os.path.join(self.blog.rootdir, template_file)
+ self.response.out.write(template.render(path, self.template_vals))
+
+
+ def param(self, name, **kw):
+ return self.request.get(name, **kw)
+
+ def write(self, s):
+ self.response.out.write(s)
+
+
+
+ def chk_login(self, redirect_url='/'):
+ if self.is_login:
+ return True
+ else:
+ self.redirect(redirect_url)
+ return False
+
+ def chk_admin(self, redirect_url='/'):
+ if self.is_admin:
+ return True
+ else:
+ self.redirect(redirect_url)
+ return False
+
+class BasePublicPage(BaseRequestHandler):
+ def initialize(self, request, response):
+ BaseRequestHandler.initialize(self,request, response)
+ m_pages=Entry.all().filter('entrytype =','page').filter('published =',True).filter('entry_parent =',0)
+ self.template_vals.update({
+ 'menu_pages':m_pages,
+ 'categories':Category.all(),
+ 'recent_comments':Comment.all().order('-date').fetch(5)
+ })
View
291 blog.py
@@ -0,0 +1,291 @@
+import cgi, os
+import wsgiref.handlers
+from google.appengine.ext.webapp import template, \
+ WSGIApplication
+from google.appengine.api import users
+import app.webapp as webapp2
+from google.appengine.ext import db
+from base import *
+from datetime import datetime ,timedelta
+import base64
+
+
+def doRequestHandle(old_handler,new_handler,**args):
+ new_handler.initialize(old_handler.request,old_handler.response)
+ return new_handler.get(**args)
+
+class MainPage(BasePublicPage):
+ def get(self,page=0):
+
+ postid=self.param('p')
+ if postid:
+ try:
+ postid=int(postid)
+ return doRequestHandle(self,SinglePost(),postid=postid) #singlepost.get(postid=postid)
+ except:
+ return self.error(404)
+
+
+ page=int(page)
+ max_page = (self.blog.entrycount - 1) / self.blog.posts_per_page
+
+
+ if page < 0 or page > max_page:
+ return self.error(404)
+
+ entries = Entry.all().filter('entrytype =','post').\
+ filter("published =", True).order('-date')
+
+
+ show_prev =entries and (not (page == 0))
+ show_next =entries and ( not (page == max_page))
+
+
+ self.render('index',{'entries':entries,
+ 'show_prev' : show_prev,
+ 'show_next' : show_next,
+ 'pageindex':page
+ })
+
+
+class EntrysByCategory(BasePublicPage):
+ def get(self,slug=None):
+ if not slug:
+ self.error(404)
+ return
+ try:
+ page_index=int (self.param('page'))
+ except:
+ page_index=1
+ cats=Category.all().filter('slug =',slug)
+ if cats:
+ entrys=Entry.all().filter('categorie_keys =',cats[0].key())
+ entrys,links=Pager(query=entrys).fetch(page_index)
+ self.render('category',{'entrys':entrys,'category':cats[0],'pager':links})
+
+class EntrysByTag(BasePublicPage):
+ def get(self,slug=None):
+ if not slug:
+ self.error(404)
+ return
+ try:
+ page_index=int (self.param('page'))
+ except:
+ page_index=1
+ import urllib
+ slug=urllib.unquote(urllib.unquote(slug))
+ entrys=Entry.all().filter('tags =',slug)
+ entrys,links=Pager(query=entrys).fetch(page_index)
+ self.render('tag',{'entrys':entrys,'tag':slug,'pager':links})
+
+
+
+class SinglePost(BasePublicPage):
+ #@printinfo
+ def get(self,slug=None,postid=None):
+ if postid:
+ entries = Entry.all().filter("published =", True).filter('post_id =', postid).fetch(1)
+ else:
+ entries = Entry.all().filter("published =", True).filter('link =', slug).fetch(1)
+ if not entries or len(entries) == 0:
+ return self.error(404)
+
+ entry=entries[0]
+ comments=Comment.all().filter("entry =",entry)
+
+ commentuser=self.request.cookies.get('commentuser', '')
+ commentuser=base64.b64decode(commentuser).split('#@#')
+ if entry.entrytype=='post':
+ self.render('single',
+ {'entry':entry,
+ 'comments':comments,
+ 'user_name':commentuser[0],
+ 'user_email':commentuser[1],
+ 'user_url':commentuser[2],
+
+ })
+ else:
+ self.render('page',
+ {'entry':entry,
+ 'comments':comments,
+ 'user_name':commentuser[0],
+ 'user_email':commentuser[1],
+ 'user_url':commentuser[2],
+
+
+ })
+
+
+class FeedHandler(BaseRequestHandler):
+ def get(self,tags=None):
+ entries = Entry.all().filter('entrytype =','post').order('-date').fetch(10)
+ if entries and entries[0]:
+ last_updated = entries[0].date
+ last_updated = last_updated.strftime("%Y-%m-%dT%H:%M:%SZ")
+ for e in entries:
+ e.formatted_date = e.date.strftime("%Y-%m-%dT%H:%M:%SZ")
+ self.response.headers['Content-Type'] = 'application/atom+xml'
+ self.render2('views/atom.xml',{'entries':entries,'last_updated':last_updated})
+
+class Error404(BaseRequestHandler):
+ #@printinfo
+ def get(self,slug=None):
+ self.error(404)
+
+class Post_comment(BaseRequestHandler):
+ #@printinfo
+ def post(self,slug=None):
+ if self.is_admin:
+ name=self.blog.author
+ email=self.login_user.email()
+ url=self.blog.baseurl
+ else:
+ name=self.param('author')
+ email=self.param('email')
+ url=self.param('url')
+ key=self.param('key')
+ content=self.param('comment')
+ if not (name and email and content):
+ self.error(-101,'Please input name, email and comment .')
+ else:
+ comment=Comment(author=name,
+ content=content,
+ email=email,
+ entry=Entry.get(key),
+ weburl=url)
+
+ info_str=base64.b64encode('#@#'.join([name.encode('utf8'),email.encode('utf8'),url.encode('utf8')]))
+
+ self.response.headers.add_header( 'Set-Cookie',
+ 'commentuser=%s;expires=%s;domain=%s;path=/'
+ %( info_str,
+ (datetime.now()+timedelta(days=100)).strftime("%a, %d-%b-%Y %H:%M:%S GMT"),
+ ''
+ )
+ )
+
+ comment.put()
+ self.redirect(self.referer)
+
+class ChangeTheme(BaseRequestHandler):
+ @requires_admin
+ def get(self,slug=None):
+ theme=self.param('t')
+ g_blog.theme_name=theme
+ g_blog.get_theme()
+ self.redirect('/')
+
+class admin_import(BaseRequestHandler):
+ @requires_admin
+ def get(self,slug=None):
+ self.render2('views/admin/import.html')
+ @requires_admin
+ def post(self):
+ import xml.etree.ElementTree as et
+ wpfile=self.param('wpfile')
+ doc=et.fromstring(wpfile)
+ #use namespace
+ wpns='{http://wordpress.org/export/1.0/}'
+
+ contentns="{http://purl.org/rss/1.0/modules/content/}"
+ et._namespace_map[wpns]='wp'
+ et._namespace_map[contentns]='content'
+
+ channel=doc.find('channel')
+ self.write('Blog:'+channel.findtext('title')+'<br>')
+ categories=channel.findall(wpns+'category')
+ for cate in categories:
+ self.write('cate:'+cate.findtext(wpns+'cat_name')+'<br>')
+
+ nicename=cate.findtext(wpns+'category_nicename')
+ cat=Category.get_by_key_name('cat_'+nicename)
+ if not cat:
+ cat=Category(key_name='cat_'+nicename)
+ cat.name=cate.findtext(wpns+'cat_name')
+ cat.slug=nicename
+ cat.put()
+
+## tags=channel.findall(wpns+'tag')
+## for tag in tags:
+## self.write('tag:'+tag.findtext(wpns+'tag_name')+'<br>')
+## ntag=Tag()
+## ntag.tag=tag.findtext(wpns+'tag_name')
+## ntag.put()
+ items=channel.findall('item')
+ for item in items:
+ self.write(item.findtext('title'))
+ entry=Entry()
+ entry.title=item.findtext('title')
+ logging.info(entry.title)
+ entry.author=self.login_user
+ entry.is_wp=True
+ entry.date=datetime.strptime( item.findtext('pubDate'),"%a, %d %b %Y %H:%M:%S +0000")
+ entry.entrytype=item.findtext(wpns+'post_type')
+ entry.content=item.findtext(contentns+'encoded')
+ entry.post_id=int(item.findtext(wpns+'post_id'))
+ entry.slug=item.findtext(wpns+'post_name')
+ entry.entry_parent=int(item.findtext(wpns+'post_parent'))
+ entry.menu_order=int(item.findtext(wpns+'menu_order'))
+
+
+ cats=item.findall('category')
+
+ for cat in cats:
+ if cat.attrib.has_key('nicename'):
+ cat_type=cat.attrib['domain']
+ nicename=cat.attrib['nicename']
+ if cat_type=='tag':
+ entry.tags.append(cat.text)
+ else:
+ c=Category.get_by_key_name('cat_'+nicename)
+ if c:
+ entry.categorie_keys.append(c.key())
+
+ pub_status=item.findtext(wpns+'status')
+ if pub_status=='publish':
+ key=entry.publish(True)
+ else:
+ key=entry.save()
+
+ comments=item.findall(wpns+'comment')
+
+ for com in comments:
+ comment_approved=int(com.findtext(wpns+'comment_approved'))
+ if comment_approved:
+
+ comment=Comment(author=com.findtext(wpns+'comment_author'),
+ content=com.findtext(wpns+'comment_content'),
+ entry=entry,
+ )
+ try:
+ comment.email=com.findtext(wpns+'comment_author_email')
+ comment.weburl=com.findtext(wpns+'comment_author_url')
+ except:
+ pass
+ comment.put()
+
+
+
+
+def main():
+ application = webapp2.WSGIApplication2(
+ [('/skin',ChangeTheme),
+ ('/themes/[\\w\\-]+/templates/.*',Error404),
+ ('/feed', FeedHandler),
+ ('/post_comment',Post_comment),
+ ('/page/(?P<page>\d+)', MainPage),
+ ('/admin/import',admin_import),
+ ('/category/(.*)',EntrysByCategory),
+ ('/tag/(.*)',EntrysByTag),
+
+ ('/', MainPage),
+ ('/([\\w\\-\\./]+)', SinglePost),
+
+
+ ('.*',Error404),
+
+ ],debug=True)
+ wsgiref.handlers.CGIHandler().run(application)
+
+if __name__ == "__main__":
+ main()
View
51 index.yaml
@@ -0,0 +1,51 @@
+indexes:
+
+# AUTOGENERATED
+
+# This index.yaml is automatically updated whenever the dev_appserver
+# detects that a new type of query is run. If you want to manage the
+# index.yaml file manually, remove the above marker line (the line
+# saying "# AUTOGENERATED"). If you want to manage some indexes
+# manually, move them above the marker line. The index.yaml file is
+# automatically uploaded to the admin console when you next deploy
+# your application using appcfg.py.
+
+# Unused in query history -- copied from input.
+- kind: Archive
+ properties:
+ - name: date
+ direction: desc
+
+# Used 253 times in query history.
+- kind: Comment
+ properties:
+ - name: date
+ direction: desc
+
+# Used 58 times in query history.
+- kind: Entry
+ properties:
+ - name: entrytype
+ - name: date
+ direction: desc
+
+# Used 291 times in query history.
+- kind: Entry
+ properties:
+ - name: entrytype
+ - name: published
+ - name: date
+ direction: desc
+
+# Used 5 times in query history.
+- kind: Entry
+ properties:
+ - name: entrytype=
+ - name: date
+ direction: desc
+
+# Used 35 times in query history.
+- kind: Logger
+ properties:
+ - name: date
+ direction: desc
View
203 metaweblog.py
@@ -0,0 +1,203 @@
+import wsgiref.handlers
+import xmlrpclib
+import sys
+import cgi
+from datetime import datetime
+from SimpleXMLRPCServer import SimpleXMLRPCDispatcher
+from functools import wraps
+
+sys.path.append('modules')
+from app.base import *
+from app.model import *
+
+def checkauth(pos=1):
+ def _decorate(method):
+ def _wrapper(*args, **kwargs):
+ username = args[pos+0]
+ password = args[pos+1]
+ args = args[0:pos]+args[pos+2:]
+ if not (g_blog.rpcuser==username) and (g_blog.rpcpassword==password):
+ raise ValueError("Authentication Failure")
+ return method(*args, **kwargs)
+
+ return _wrapper
+ return _decorate
+
+def format_date(d):
+ if not d: return None
+ return xmlrpclib.DateTime(d.isoformat())
+
+def entry_struct(entry):
+ categories=[]
+ if entry.categorie_keys:
+ categories =[cate.name for cate in entry.categories]
+ struct = {
+ 'postid': entry.key().id(),
+ 'title': entry.title,
+ 'link': entry.fullurl(),
+ 'permaLink': entry.fullurl(),
+ 'description': unicode(entry.content),
+ 'categories': categories,
+ 'userid': 1,
+ # 'mt_excerpt': '',
+ # 'mt_text_more': '',
+ # 'mt_allow_comments': 1,
+ # 'mt_allow_pings': 1}
+ }
+ if entry.date:
+ struct['dateCreated'] = format_date(entry.date)
+ return struct
+
+class Logger(db.Model):
+ request = db.TextProperty()
+ response = db.TextProperty()
+ date = db.DateTimeProperty(auto_now_add=True)
+
+@checkauth()
+def blogger_getUsersBlogs(discard):
+ return [{'url' : g_blog.baseurl, 'blogid' : '001', 'blogName' : g_blog.title}]
+
+@checkauth()
+def metaWeblog_newPost(blogid, struct, publish):
+ if publish:
+ if struct.has_key('categories'):
+ cates = struct['categories']
+ else:
+ cates = []
+
+ newcates=[]
+ for cate in cates:
+ c=Category.all().filter('name =',cate)
+ if c:
+ newcates.append(c[0].key())
+ entry=Entry(title = struct['title'],
+ content = struct['description'],
+ categorie_keys=newcates
+ )
+ entry.publish(True)
+ postid =entry.key().id()
+ return str(postid)
+ else:
+ return 'notpublished'
+
+@checkauth()
+def metaWeblog_editPost(postid, struct, publish):
+ if publish:
+
+ if struct.has_key('categories'):
+ cates = struct['categories']
+ else:
+ cates = []
+ newcates=[]
+ for cate in cates:
+ c=Category.all().filter('name =',cate)
+ if c:
+ newcates.append(c[0].key())
+ entry=Entry.get_by_id(int(postid))
+
+ entry.title = struct['title']
+ entry.content = struct['description']
+ entry.categorie_keys=newcates
+ entry.publish(True)
+
+ return True
+ else:
+ return True
+@checkauth()
+def metaWeblog_getCategories(blogid):
+ categories =Category.all()
+ cates=[]
+ for cate in categories:
+ cates.append({ 'categoryId' : cate.key().id(),
+ 'parentId':0,
+ 'description':cate.name,
+ 'categoryName':cate.name,
+ 'htmlUrl':'',
+ 'rssUrl':''
+ })
+ return cates
+
+@checkauth()
+def metaWeblog_getPost(postid):
+ entry = Entry.get_by_id(int(postid))
+ return entry_struct(entry)
+
+@checkauth()
+def metaWeblog_getRecentPosts(blogid, num):
+ entrys = Entry.all().filter('entrytype =','post').order('-date').fetch(min(num, 20))
+ return [entry_struct(entry) for entry in entrys]
+
+@checkauth(pos=2)
+def blogger_deletePost(appkey, postid, publish):
+ post=Entry.get_by_id(postid)
+ post.delete()
+ return True
+
+class PlogXMLRPCDispatcher(SimpleXMLRPCDispatcher):
+ def __init__(self, funcs):
+ SimpleXMLRPCDispatcher.__init__(self, True, 'utf-8')
+ self.funcs = funcs
+
+dispatcher = PlogXMLRPCDispatcher({
+ 'blogger.getUsersBlogs' : blogger_getUsersBlogs,
+ #'blogger.deletePost' : blogger_deletePost,
+ 'metaWeblog.newPost' : metaWeblog_newPost,
+ 'metaWeblog.editPost' : metaWeblog_editPost,
+ 'metaWeblog.getCategories' : metaWeblog_getCategories,
+ 'metaWeblog.getPost' : metaWeblog_getPost,
+ 'metaWeblog.getRecentPosts' : metaWeblog_getRecentPosts,
+ })
+
+
+# {{{ Handlers
+class CallApi(BaseRequestHandler):
+ def get(self):
+ Logger(request = self.request.uri, response = '----------------------------------').put()
+ self.write('<h1>please use POST</h1>')
+
+ def post(self):
+ #self.response.headers['Content-Type'] = 'application/xml; charset=utf-8'
+ request = self.request.body
+ response = dispatcher._marshaled_dispatch(request)
+ Logger(request = unicode(request, 'utf-8'), response = unicode(response, 'utf-8')).put()
+ self.write(response)
+
+class View(BaseRequestHandler):
+ @requires_admin
+ def get(self):
+ self.write('<html><body><h1>Logger</h1>')
+ for log in Logger.all().order('-date'):
+ self.write("<p>date: %s</p>" % log.date)
+ self.write("<h1>Request</h1>")
+ self.write('<pre>%s</pre>' % cgi.escape(log.request))
+ self.write("<h1>Reponse</h1>")
+ self.write('<pre>%s</pre>' % cgi.escape(log.response))
+ self.write("<hr />")
+ self.write('</body></html>')
+
+class DeleteLog(BaseRequestHandler):
+ def get(self):
+ if self.chk_admin():
+ for log in Logger.all():
+ log.delete()
+
+
+ self.redirect('/')
+#}}}
+
+
+def main():
+ #webapp.template.register_template_library("filter")
+ application = webapp.WSGIApplication(
+ [
+ ('/rpc', CallApi),
+ ('/rpc/view', View),
+ ('/rpc/dellog', DeleteLog),
+
+ ],
+ debug=True)
+ wsgiref.handlers.CGIHandler().run(application)
+
+if __name__ == '__main__':
+ main()
+
View
292 model.py
@@ -0,0 +1,292 @@
+import os,logging
+from google.appengine.api import users
+from google.appengine.ext import db
+from google.appengine.ext.db import Model as DBModel
+from datetime import datetime
+
+
+
+class Theme:
+ def __init__(self, name='default'):
+ self.name = name
+ self.mapping_cache = {}
+ self.dir = '/themes/%s' % name
+ self.viewdir=os.path.join(os.getcwd(), 'view')
+ self.server_dir = os.path.join(os.getcwd(), 'themes', self.name)
+
+ def __getattr__(self, name):
+ if self.mapping_cache.has_key(name):
+ return self.mapping_cache[name]
+ else:
+ path = os.path.join(self.server_dir, 'templates', name + '.html')
+ if not os.path.exists(path):
+ path = os.path.join(os.getcwd(), 'themes', 'default', 'templates', name + '.html')
+ if os.path.exists(path):
+ self.mapping_cache[name] = path
+ return path
+ else:
+ self.mapping_cache[name] = path
+ return path
+ return None
+
+
+class ThemeIterator:
+ def __init__(self, theme_path='themes'):
+ self.iterating = False
+ self.theme_path = theme_path
+ self.list = []
+
+ def __iter__(self):
+ return self
+
+ def next(self):
+ if not self.iterating:
+ self.iterating = True
+ self.list = os.listdir(self.theme_path)
+ self.cursor = 0
+
+ if self.cursor >= len(self.list):
+ self.iterating = False
+ raise StopIteration
+ else:
+ value = self.list[self.cursor]
+ self.cursor += 1
+ return (str(value), unicode(value))
+
+
+class BaseModel(db.Model):
+ def __init__(self, parent=None, key_name=None, _app=None, **kwds):
+ self.__isdirty = False
+ DBModel.__init__(self, parent=None, key_name=None, _app=None, **kwds)
+
+ def __setattr__(self,attrname,value):
+ """
+ DataStore api stores all prop values say "email" is stored in "_email" so
+ we intercept the set attribute, see if it has changed, then check for an
+ onchanged method for that property to call
+ """
+ if (attrname.find('_') != 0):
+ if hasattr(self,'_' + attrname):
+ curval = getattr(self,'_' + attrname)
+ if curval != value:
+ self.__isdirty = True
+ if hasattr(self,attrname + '_onchange'):
+ getattr(self,attrname + '_onchange')(curval,value)
+
+ DBModel.__setattr__(self,attrname,value)
+
+class Cache(db.Model):
+ cachekey = db.StringProperty(multiline=False)
+ content = db.TextProperty()
+
+class Blog(db.Model):
+ owner = db.UserProperty()
+ author=db.StringProperty(default='admin')
+ rpcuser=db.StringProperty(default='admin')
+ rpcpassowrd=db.StringProperty(default='mlog')
+ description = db.TextProperty()
+ baseurl = db.StringProperty(multiline=False,default='http://yourapp.appspot.com')
+ urlpath = db.StringProperty(multiline=False)
+ title = db.StringProperty(multiline=False,default='Mlog')
+ subtitle = db.StringProperty(multiline=False,default='Your Blog Subtitle')
+ entrycount = db.IntegerProperty(default=0)
+ posts_per_page= db.IntegerProperty(default=10)
+ feedurl = db.StringProperty(multiline=False,default='http://feeds.feedburner.com/yoursitesname')
+ blogversion = db.StringProperty(multiline=False,default='1.00')
+ theme_name = db.StringProperty(multiline=False,default='default')
+ enable_memcache = db.BooleanProperty(default = False)
+ link_format=db.StringProperty(multiline=False,default='')
+ theme=None
+
+ def save(self):
+ self.put()
+
+ def initialsetup(self):
+ self.title = 'Your Blog Title'
+ self.subtitle = 'Your Blog Subtitle'
+
+ def get_theme(self):
+ self.theme= Theme(self.theme_name);
+ return self.theme
+
+
+class Category(db.Model):
+ name=db.StringProperty(multiline=False)
+ slug=db.StringProperty(multiline=False)
+ @property
+ def posts(self):
+ return Entry.all().filter('entrytype =','post').filter('categorie_keys =',self)
+
+ @property
+ def count(self):
+ return self.posts.count()
+
+
+class Archive(db.Model):
+ monthyear = db.StringProperty(multiline=False)
+ """March-08"""
+ entrycount = db.IntegerProperty(default=0)
+ date = db.DateTimeProperty(auto_now_add=True)
+
+class Tag(db.Model):
+ tag = db.StringProperty(multiline=False)
+ tagcount = db.IntegerProperty(default=0)
+ @property
+ def posts(self):
+ return Entry.all('entrytype =','post').filter('tags =',self)
+
+class Link(db.Model):
+ href = db.StringProperty(multiline=False,default='')
+ linktype = db.StringProperty(multiline=False,default='blogroll')
+ linktext = db.StringProperty(multiline=False,default='')
+
+class Entry(BaseModel):
+ author = db.UserProperty()
+ published = db.BooleanProperty(default=False)
+ content = db.TextProperty(default='')
+ title = db.StringProperty(multiline=False,default='')
+ date = db.DateTimeProperty(auto_now_add=True)
+ tags = db.StringListProperty()
+ categorie_keys=db.ListProperty(db.Key)
+ slug = db.StringProperty(multiline=False,default='')
+ link= db.StringProperty(multiline=False,default='')
+ monthyear = db.StringProperty(multiline=False)
+ entrytype = db.StringProperty(multiline=False,default='post',choices=[
+ 'post','page'])
+ entry_parent=db.IntegerProperty(default=0)#When level=0 show on main menu.
+ menu_order=db.IntegerProperty()
+ commentcount = db.IntegerProperty(default=0)
+
+ #compatible with wordpress
+ is_wp=db.BooleanProperty(default=False)
+ post_id= db.IntegerProperty()
+
+
+
+
+
+ def fullurl(self):
+ return g_blog.baseurl+'/'+self.link;
+
+ @property
+ def categories(self):
+ try:
+ return db.get(self.categorie_keys)
+ except:
+ return []
+
+## def get_categories(self):
+## return ','.join([cate for cate in self.categories])
+##
+## def set_categories(self, cates):
+## if cates:
+## catestemp = [db.Category(cate.strip()) for cate in cates.split(',')]
+## self.catesnew = [cate for cate in catestemp if not cate in self.categories]
+## self.categorie = tagstemp
+## scates = property(get_categories,set_categories)
+
+
+ def comments(self):
+ return Comment.all().filter('entry =',self)
+
+ def update_archive(self):
+ """Checks to see if there is a month-year entry for the
+ month of current blog, if not creates it and increments count"""
+ my = self.date.strftime('%b-%Y') # May-2008
+ archive = Archive.all().filter('monthyear',my).fetch(10)
+ if self.entrytype == 'post':
+ if archive == []:
+ archive = Archive(monthyear=my)
+ self.monthyear = my
+ archive.put()
+ else:
+ # ratchet up the count
+ archive[0].entrycount += 1
+ archive[0].put()
+
+
+ def save(self):
+ """
+ Use this instead of self.put(), as we do some other work here
+ """
+
+
+ my = self.date.strftime('%b-%Y') # May-2008
+ self.monthyear = my
+
+
+
+ return self.put()
+
+ def publish(self,newval=True):
+ if newval:
+
+ if not self.is_saved():
+ self.save()
+ if not self.is_wp:
+ self.post_id=self.key().id()
+
+ vals={'year':self.date.year,'month':self.date.month,'day':self.date.day,
+ 'postname':self.slug,'post_id':self.post_id}
+
+ if not self.link:
+ if g_blog.link_format and self.slug:
+ self.link=g_blog.link_format.strip()%vals
+ else:
+ self.link='?p=%(post_id)s'%vals
+
+ if not self.published:
+ g_blog.entrycount+=1
+ self.published=True
+
+ g_blog.save()
+ self.save()
+ else:
+ self.published=false
+ if self.published:
+ g_blog.entrycount-=1
+ g_blog.save()
+ self.save()
+
+class User(db.Model):
+ user = db.UserProperty(required = True)
+ dispname = db.StringProperty()
+ website = db.LinkProperty()
+ isadmin=db.BooleanProperty(default=False)
+
+ def __unicode__(self):
+ if self.dispname:
+ return self.dispname
+ else:
+ return self.user.nickname()
+
+ def __str__(self):
+ return self.__unicode__().encode('utf-8')
+
+class Comment(db.Model):
+ entry = db.ReferenceProperty(Entry)
+ date = db.DateTimeProperty(auto_now_add=True)
+ content = db.TextProperty(required=True)
+ author=db.StringProperty()
+ email=db.EmailProperty()
+ weburl=db.URLProperty()
+ status=db.IntegerProperty(default=0)
+ @property
+ def shortcontent(self,len=20):
+ return self.content[:len]
+
+
+#setting
+logging.info('module setting reloaded')
+g_blog = Blog.get_by_key_name('default')
+if not g_blog:
+ g_blog = Blog(key_name = 'default')
+
+g_blog.put()
+
+g_blog.get_theme()
+
+g_blog.rootdir=os.path.dirname(__file__)
+
+
+
View
1  run.bat
@@ -0,0 +1 @@
+dev_appserver.py ..\mlog
View
1  themes/a.js
@@ -0,0 +1 @@
+sdfsdfxss
View
0  themes/blue/2.html
No changes.
View
1  themes/blue/templates/test.html
@@ -0,0 +1 @@
+test2222222222222222222
View
319 themes/default/freshpress.css
@@ -0,0 +1,319 @@
+/*
+Theme Name: FreshPress 1.2
+Theme URI: http://www.freshpressthemes.com
+Author: Weborithm
+Author URI: http://www.weborithm.com/
+Description: Inspired by WordPress 2.5 release "Brecker". View more <a href="http://www.freshpressthemes.com">Fresh Themes</a>. If you need help with this theme please <a href="../wp-content/themes/FreshPress/readme.htm" target="_blank" >click here</a>.
+
+This theme was designed and built by Hyder Jaffari of Weborithm Design Studio.
+
+*/
+/* Layout.css */
+/*two equal 174px right columns
+#leftsidebar {width: 174px;}
+#rightsidebar {width: 174px;}
+#content {width: 576px;margin: 0px 15px 0px 0px;}
+ */
+/*one right column right columns */
+#leftsidebar {width: 0px;}
+#rightsidebar {width: 274px;}
+#content {width: 665px;margin: 0px 0px 0px 0px;}
+
+body {margin: 0px;padding: 0px;font: 0.9em Tahoma, Verdana, sans-serif;}
+.clear {padding: 0px;margin: 0px;clear: both;}
+
+/* Link Elements Starts */
+#dashboard .dash a {padding: 0px;text-decoration: none;color: #dadada;margin: 0px;}
+#nav ul li a {color: #2583ad;text-decoration: none;}
+#content a, #featured p a, #rightsidebar ul li a, #leftsidebar ul li a, #fmore ul li a {color: #2583ad;text-decoration: underline;}
+#featured h2 a, #content h2 a, #header h1 a {color: #fff;text-decoration: none;}
+#content h2 a {color: #333;}
+#header h1 a {color: #555;}
+.fcomments a {color: #264761 !important;text-decoration: none;}
+/* Link Elements Ends */
+
+/* Link Hover Elements Starts */
+#nav ul li a:hover, #header h1 a:hover, #dashboard a:hover, #content a:hover, #rightsidebar ul li a:hover, #leftsidebar ul li a:hover, #featured p a:hover, #fmore ul li a:hover, .footerc ul li a:hover, .footerc p a:hover {
+ color: #d54e21;text-decoration: none;}
+.fcomments a:hover {color: #d54e21 !important;}
+#featured h2 a:hover {color: #333;}
+#credits a:hover {color: #a3c800;text-decoration: none;}
+/* Link Hover Elements Ends */
+
+#hiddenmessage {text-align:center;margin: 0px 40px 0px 0px;display:none;color: #B6411A;font-size: 1.4em;}
+
+/* Other Theme Properties Starts */
+
+img.alignright {float: right;margin: 0px 0px 10px 10px;padding: 0px;border: 1px solid #ccc;}
+img.alignleft {float: left;margin: 0px 10px 10px 0px;padding: 0px;border: 1px solid #ccc;}
+.alignright {float: right;padding: 0px;}
+.alignleft {float: left;padding: 0px;}
+.navigation {display: block;text-align: center;padding: 10px;font-size: 1em;}
+.video {text-align:center;margin: 0px;padding: 0px 0px 20px;}
+#dashboard, #nav ul li a, .fcomments a, #content .post h2 {letter-spacing: 1px;}
+#content h3, #comments h3 {margin: 10px;padding: 0px;border-bottom: 1px solid #e5e5e5;font: normal 1.4em Georgia, "Times New Roman", Times, serif;color: #333;}
+#comments h3 {margin: 0px 0px 2px;padding:5px;background: #ccc;border-bottom: none;}
+/* Other Theme Properties Ends */
+
+/* Dashboard Area Starts */
+#dashboard {padding: 10px 0px;background: #464646;color: #cccccc;}
+#dashboard .dash {width: 972px;margin: auto;text-align: right;}
+/* Dashboard Area Ends */
+
+/* Search Elements Starts */
+#searchtop {float: left;border:1px solid #333;}
+#searchtop #s {font-size: 1em;padding: 2px 5px;color: #333;border: none;}
+#searchform {margin: auto;text-align:center;padding: 0px 0px 10px;}
+#searchform #s {border:1px solid #333;width: 166px;padding: 2px;margin: 0px 0px 5px;}
+/* Search Elements Ends */
+
+/* Header Elements Starts */
+#header {background: #e4f2fd;padding: 20px 0px;border-bottom: 1px solid #c6d9e9;}
+.headings {width: 972px;margin: auto;}
+#header h1 {font: normal 2em Georgia, "Times New Roman", Times, serif;color: #555555;margin: 0px;padding: 0px;float: left;}
+#header h2 {float: right;padding: 9px 0px 0px;margin: 0px;color: #d54e21;font: normal 1.4em Georgia, "Times New Roman", Times, serif;}
+/* Header Elements Ends */
+
+/* Navigation Starts */
+#nav {padding: 0px;margin: 0px 0px 15px;border-bottom: 1px solid #dadada;}
+#nav ul {list-style: none;margin: 10px auto;padding: 0px;width: 972px;}
+#nav ul li {float: left;display: block;font-size: 1em;font-weight: bold;color: #2583ad;padding: 0px 20px 0px 0px;margin: 0px;}
+/* Navigation Ends */
+
+/* Main Container Starts */
+#container {padding: 0px 0px 20px;margin: 0px auto 0px;width: 972px;}
+/* Main Container Ends */
+
+/* Featured Area Starts */
+#featured {line-height: normal;width: 966px;border: 1px solid #2583ad;margin: 0px 0px 15px;padding: 2px;}
+#featured h2 {background: #d54e21;padding: 10px;margin: 0px;text-align: left;font: bold 1.4em Georgia, "Times New Roman", Times, serif;}
+#featured h2 span {padding: 0px;width: 800px;float: left;}
+.fcomments {margin: 0px;padding: 4px 7px;float: right;display: block;background: #ebebeb;text-decoration: none;color: #264761;font: bold 0.6565em Tahoma, Verdana, sans-serif;}
+#featured p {padding: 10px 10px 0px;color: #333;font-size: 0.9786em;line-height: 20px;margin: 0px;}
+#featured blockquote {border-bottom: 2px solid #E5E5E5;border-right: 1px solid #E5E5E5;margin: 10px 20px 0px;padding: 0px 5px;background: #f2f2f2 url(images/quote.gif) no-repeat left top;}
+#featured blockquote p {margin: 0px;padding: 5px;font-size: 1.1em;line-height: 24px;}
+#featured ul, #featured ol {margin: 10px 10px 0px 30px;padding: 0px;list-style:square;}
+#featured ul li, #featured ol li {margin: 0px;padding: 3px 0px 6px;font-size: 0.9em;}
+#fpost {padding: 0px;width: 576px;float: left;margin: 10px 0px;border-right: 1px solid #ccc;}
+#fpost .date {padding: 0px 10px;font-size: 0.7em;font-weight: bold;}
+#fmore {float: right;width: 365px;margin: 0px 10px 0px 0px;}
+#fmore h2 {color: #333;background: none;font-size: 1.2em;border-bottom: 2px solid #E4F2FD;border-top: 1px solid #E4F2FD;padding: 5px 0px;margin: 10px 0px 5px;}
+#fmore ul {margin: 5px 5px 5px 15px;padding: 0px;list-style: square;}
+#fmore ul li {padding: 6px 0px;margin: 0px;font-size: 0.8em;color: #333;}
+#fmore a.fmorec {background: #fff;font-size: 0.9em;text-decoration: none;}
+/* Featured Area Ends */
+
+/* Content Starts */
+#content {float: left;padding: 2px;border: 1px solid #ccc;}
+#content h2 {color: #333;font: bold 1.4em Georgia, "Times New Roman", Times, serif;border-bottom: 2px solid #E4F2FD;border-top: 1px solid #E4F2FD;margin: 0px 5px;padding: 5px 0px;}
+#content .date {padding: 10px;font-size: 0.7em;font-weight: bold;}
+#content .meta {padding: 10px 10px 20px;font-size: 0.8em;font-weight: normal;}
+#content .meta ul {list-style: none;margin: 0px;padding: 5px 0px;}
+#content .meta ul li {float: left;padding: 0px 5px 0px 0px;display: block;}
+#content .post {margin: 10px 10px 0px;padding: 0px;font-size: 1.0em;color: #333;}
+#content .post h2 {margin: 0px 0px 20px;padding: 0px;background: none;border-bottom: 2px solid #E4F2FD;border-top: none;font: normal 1.5em Georgia, "Times New Roman", Times, serif;color: #2583ad;}
+#content .post h3 {margin: 0px 0px 20px;padding: 0px;border-bottom: 1px solid #e5e5e5;font: normal 1.4em Georgia, "Times New Roman", Times, serif;color: #333;}
+#content .post p {padding: 0px 0px 20px;line-height: 20px;margin: 0px;}
+#content .post ul, #content .post ol {margin: 0px 35px 20px 35px;padding: 0px;}
+#content .post ul li, #content .post ol li {margin: 0px;padding: 3px 0px 6px;}
+#content .post blockquote {border-bottom: 2px solid #E5E5E5;border-right: 1px solid #E5E5E5;margin: 0px 20px 20px;padding: 5px 10px 0px;background: #f2f2f2 url(images/quote.gif) no-repeat left top;text-indent: 30px;}
+#content .post blockquote p {margin: 0px;padding: 5px 5px 10px;font-size: 1.1em;line-height: 24px;}
+#content .quoteleft {width: 200px;float: left;padding: 5px 10px;background: #f2f2f2 url(images/quote.gif) no-repeat left top;text-indent: 30px;color: #000;margin: 10px 10px 0px 0px;}
+#content .quoteright {width: 200px;float: right;padding: 5px 10px;background: #f2f2f2 url(images/quote.gif) no-repeat left top;text-indent: 30px;color: #000;margin: 10px 0px 0px 10px;}
+#content .commentmeta {font-size: 0.8em;font-weight: bold;text-align:right;border-bottom: 1px solid #ccc;margin: 0px 0px 25px;}
+#content .commentmeta a {background: #fff;padding: 5px;top: 7px;position: relative;text-decoration: none;border: 1px solid #ccc;}
+/* Content Ends */
+
+/* Left Sidebar Starts */
+#rightsidebar h3, #leftsidebar h3, #rightsidebar h2, #leftsidebar h2 {font: normal 1.1em Georgia, "Times New Roman", Times, serif;background: #E4F2FD;padding: 5px;margin: 0px 0px 10px;color: #333;}
+#rightsidebar li, #leftsidebar li {list-style: none;}
+#rightsidebar ul, #leftsidebar ul {margin: 10px 5px 10px 20px;padding: 0px;}
+#rightsidebar ul li, #leftsidebar ul li {padding: 3px 0px 6px;margin: 0px;font-size: 0.8em;color: #333;list-style: square;}
+#leftsidebar {float: left;padding: 2px;border: 1px solid #ccc;}
+/* Left Sidebar Ends */
+
+/* Right Sidebar Starts */
+#rightsidebar {padding: 2px;border: 1px solid #ccc;float: right;margin: 0px 0px 0px 15px;}
+/* Right Sidebar Ends */
+
+/* Sidebar Calendar Starts */
+#calendar_wrap {margin: 0px;padding: 0px 0px 10px;}
+#wp-calendar {width: 174px;}
+#today {text-align: center;background: #C4E2FB!important;}
+table#wp-calendar td {text-align: center;background: #e4f2fd;}
+#today a, #wp-calendar a {color: #2583ad;}
+#today a:hover, #wp-calendar a:hover {color: #d54e21;text-decoration: none;}
+#prev {text-align: left !important;padding: 0px 2px;}
+#next {text-align: right !important;padding: 0px 2px;}
+/* Sidebar Calendar Ends */
+
+/* Sidebar Tags Starts */
+#tag_cloud {padding: 0px 0px 10px !important;}
+#tag_cloud a {color: #2583ad;font-size: 100% !important;line-height: 22px;padding: 0px 2px;}
+#tag_cloud a:hover {color: #d54e21;text-decoration: none;}
+.textwidget, .adrotatorwidget {margin: 0px;padding: 0px 0px 10px;}
+/* Sidebar Tags Ends */
+
+
+/* Box Links, and action bar border: red 1px solid; */
+.boxlinks {font-size: 85%;}
+.inlineboxlinks {padding: 1em;margin: 1em 0;clear: left;}
+.actionbar {margin: 0px;clear: right; padding: 0px;font-size: 115%;display: block; width:100%;height:33px; }
+.actionbar a {font-size: 123%;background:#fafafa;height:22px;}
+.right {float: right;}
+.boxlinks2 {font-size: 85%;margin-top:-24px; margin-right:-11px;background-color:#ffffff;}
+.boxlinks2 a {border: 1px solid #235C9D;text-decoration: none;padding: 3px 5px;}
+.boxlinks a, .boxlinks span {margin-top:2px; display: block;vertical-align: bottom; float: left;padding: 0.2em 0.5em;margin-right: 0.15em;}
+.boxlinks span.current {border: 1px solid #235C9D;font-weight: bold;background: #235C9D;color: #fff;}
+.boxlinks a {border: 1px solid #235C9D;text-decoration: none;}
+.boxlinks a:hover {background:#E1ECF9;}
+.boxlinks a.nextprev {font-weight: bold;}
+.boxlinks span.nextprev {color: #666;}
+.boxlinks span.nextprev {border: 1px solid #ddd;color: #999;}
+ul.boxlink {list-style-type:none;}
+div.boxlinks a.current {border-bottom: 1px solid #E1ECF9;;background:#E1ECF9; }
+.tab-spacer{background:#E1ECF9;border:0px solid #8db2e3;border-top:0 none;height:2px;font-size:1px;line-height:1px;}
+div.formbox {border:1px solid #8db2e3;margin-top:20px;}
+
+/* code formatting for posts */
+.code {color: #63FF00;background: #000;overflow: auto;font: normal 12px "bitstream vera sans mono", monaco "lucida console", "courier new", courier, serif;margin: 0.9em 0; padding: 8px;}
+
+/* Footer Starts */
+
+#footer {background: #464646;padding: 0px;margin: 0px 0px 0px 0px;padding: 0px 0px 45px 0px;}
+.footerinner {width: 972px;margin:auto;padding: 15px 0px 15px 0px;}
+.footerc {float: left;border: 1px solid #333;margin: 0px 22px 15px 0px;padding: 2px;width: 303px;color: #dadada;}
+.footercalt {float: left;border: 1px solid #333;margin: 0px 0px 15px 0px;padding: 2px;width: 303px;color: #dadada;}
+.footerc h3, .footercalt h3 {font: normal 1.1em Georgia, "Times New Roman", Times, serif;color: #ccc;margin: 0px;padding:5px;background: #333;letter-spacing: 1px;}
+.footerc ul, .footercalt ul {margin: 5px 0px 5px 20px;padding: 0px;list-style: square;}
+.footerc ul li, .footercalt ul li {padding: 3px 0px 6px;margin: 0px;font-size: 0.9em;}
+.footerc p, .footercalt p {padding: 5px;margin: 0px;line-height: 22px;font-size: 0.9em;}
+.footerc ul li a, .footerc p a, .footercalt ul li a, .footercalt p a, #credits a {color: #dadada;}
+#credits {float: left;width: 962px;padding: 5px;font-size: 0.8em;color: #ccc;height: 29px;}
+#credits img { float: left;}
+#credits span {float:right;line-height: 26px;}
+
+/* Footer Ends */
+/* ADMIN area */
+.secondary {color:#999999;font-size: 80%;}
+#editable-post-name {background-color:#FFFBCC;}
+/* Comments Starts */
+#comments {margin: 0px;padding: 2px 0px;border-top: 1px solid #ccc;}
+#respond {margin: 2px 0px;border-bottom: 1px solid #ccc;border-top: 1px solid #ccc;background: #fff;}
+#respond h4 {margin: 2px 0px;font: normal 1.4em Georgia, "Times New Roman", Times, serif;color: #333;padding:5px;background: #ccc;}
+/* Main Comment Elements */
+
+ol#commentlist {margin: 0px;padding: 10px 10px 10px 30px;border-top: 1px solid #ccc;}
+ol#commentlist li { /* This is for the normal entry headings */
+ font-size: 0.8em;color: #515151;margin: 0px;padding: 10px;border: 1px solid #F0F0F0;border-bottom: none;}
+ol#commentlist .entry { /* This is for the normal entry comments */
+ background: #fff;border: 1px solid #F0F0F0;margin: 0px 0px 20px;padding: 10px;}
+ol#commentlist li.alternate { /* This is for the alternate entry headings */
+ margin: 0px;padding: 10px;border: 1px solid #CCC;border-bottom: none;background: #f9f9f9;}
+ol#commentlist .alternate { /* This is for the alternate entry comments */
+ border: 1px solid #ccc;margin: 0px 0px 20px;padding: 10px;background: #f9f9f9;}
+ol#commentlist li.author { /* This is for the author entry headings */
+ margin: 0px;padding: 10px;border: 1px solid #CCC;border-bottom: none;}
+ol#commentlist .author { /* This is for the author entry comments */
+ border: 1px solid #ccc;margin: 0px 0px 20px;padding: 10px;background: #e4f2fd;}
+ol#commentlist .entry p, ol#commentlist .author p, ol#commentlist .alternate p {
+ font-size: 0.9em;color: #333;padding: 0px;margin: 0px;line-height: 20px;}
+ol#commentlist .entry blockquote, ol#commentlist .author blockquote, ol#commentlist .alternate blockquote {
+ padding: 5px 5px 0px;margin: 0px 20px 10px;font-size: 0.9em;}
+ol#commentlist .entry blockquote p, ol#commentlist .author blockquote p, ol#commentlist .alternate blockquote p {
+ line-height: 20px;padding: 0px 0px 5px;}
+ol#commentlist #comment span {float: right;}
+ol#commentlist li .avatar { border: 1px solid #ccc;padding: 2px;background: #fff;}
+#comment_form {padding: 0px 10px;}
+#comment_form input {width: 240px;padding: 5px;margin: 0px 10px 0px 0px;border: 1px solid #ccc;background: #F8F8F8;}
+#comment_form textarea {width: 542px;padding: 5px;border: 1px solid #ccc;background: #F8F8F8;}
+#comment_form #submit {width: 240px;padding: 5px;border: 1px solid #ccc;background: #e4f2fd;font: 120% Georgia, "Times New Roman", Times, serif;color: #333;}
+#comment_form #submit:hover {border: 1px solid #333;background: #d54e21;color: #fff;}
+#comment_form input[type="text"]:focus { background: #ffffff;border: 1px solid #d54e21;}
+#comment_form textarea:focus {background: #fff;border: 1px solid #d54e21;}
+/* Comments Ends */
+
+/* Form elements */
+
+/* Colors & Style */
+form {background-color:#FAFAFA; }
+form fieldset {background-color:#FAFAFA; border-color: #000000; border-width: 0px; border-style: solid;}
+form fieldset legend {font-size: 1.3em; font-weight: normal; color: #235C9D;}
+input, select, textarea {font-family: Tahoma, Arial, sans-serif; font-size: 1.1em; color: #000000;}
+form div fieldset {border-color: #666666;}
+form .instructions {background-color:#FFFFCC;text-align: left;}
+form div input.inputSubmit, form div input.inputButton, input.inputSubmit, input.inputButton {background-color: #cccccc; color: #000000; width: auto; padding: 0 6px; margin: 0;}
+form input, form select, form textarea { background-color: #ffffff;}
+
+/*form div {width: 354px;} */
+form div fieldset { margin: 0 0 0 144px; width: 197px;}
+form div label { width: 130px;}
+form div fieldset div { width: 480px;}
+form div label.labelCheckbox, form div label.labelRadio { width: 430px; margin: 0 0 5px 142px;}
+form div fieldset label.labelCheckbox, form div fieldset label.labelRadio { width: 380px;}
+form div select, form div textarea { width: 430px;}
+form fieldset div input { width: 430px;}
+form div input.inputFile { width: 400px;}
+form div select.selectOne, form div select.selectMultiple { width: 430px; }
+form div input.inputCheckbox, form div input.inputRadio, input.inputCheckbox, input.inputRadio { margin: 0 0 0 140px;}
+form div.submit {width: 214px;padding: 0 0 0 146px;}
+form div small { margin: 0 0 5px 142px;}
+
+
+/*Dialog form*/
+form.small fieldset div { width: 100%;}
+form.small div.instructions {background-color:#FFFFCC;text-align: left;}
+form.small fieldset {background-color:#ffffff;border: red 0px solid; padding: 0px;margin: 6px;}
+form.small div label { width: 130px;}
+form.small label.labelCheckbox, form.small div label.labelRadio { width: 200px; margin: 0 0 5px 142px;}
+form.small fieldset label.labelCheckbox, form.small div fieldset label.labelRadio { width: 150px;}
+form.small select, form.small div textarea { width: 200px;}
+form.small fieldset div input { width: 150px;}
+form.small input.inputCheckbox, form.small div input.inputRadio, input.inputCheckbox, input.inputRadio {width: 14px; margin: 0 0 0 0px;}
+
+
+
+/* Buttons --*/
+
+form .actions {padding: 10px;padding: 10px;background-color: #F5F5F5;border-top: 2px solid #235C9D;text-align: right;}
+form div.actions input {background-color: #EBE9ED;}
+form .primaryAction {}
+form .secondaryAction {color: grey;}
+form .secondaryAction:hover {color: black;}
+
+/* general style */
+form .instructions { margin: 1.5em 0;padding: 3px; background-color:#FFFFCC;margin: 0px 0 0 0;}
+form {margin: 0; padding: 0;}
+form fieldset { clear: both; padding: 10px; margin: 0 0 10px 0;}/**/
+/* */
+form fieldset legend {margin: 0 0 0 0;padding: 0 5px;}
+label {font-size: 1.0em;}
+label u {font-style: normal; text-decoration: underline;}
+textarea { overflow: auto;}
+form div { clear: left; display: block; height: expression('1%');margin: 5px 0 0 0;padding: 1px 3px;}
+form div fieldset {clear: none;border-width: 1px;border-style: solid; padding: 0 5px 5px 5px;}
+form div fieldset legend {font-size: 1.0em; padding: 0 3px 0 9px;}
+form div.required fieldset legend {font-weight: bold;}
+form div label {display: block;float: left;padding: 3px 5px; margin: 0 0 5px 0; text-align: right;}
+form div.optional label, label.optional {font-weight: normal;}
+form div.required label, label.required {font-weight: bold;}
+form div label.labelCheckbox, form div label.labelRadio {float: none; display: block; height: expression('1%'); padding: 0;text-align: left;}
+form div fieldset label.labelCheckbox, form div fieldset label.labelRadio { margin: 0 0 5px 0;}
+form div img { border: 1px solid #000000;}
+form div input, form div select, form div textarea {margin: 0 0 0 0;}
+form div select.selectOne, form div select.selectMultiple { padding: 1px 3px;}
+form div input.inputCheckbox, form div input.inputRadio, input.inputCheckbox, input.inputRadio {display: inline; height: 14px; width: 14px; background-color: transparent; border-width: 0; padding: 0;}
+form div.submit div { display: inline; float: left; text-align: left; width: auto; padding: 0; margin: 0;}
+form div input.inputSubmit, form div input.inputButton, input.inputSubmit, input.inputButton { width: auto; padding: 0 6px; margin: 0;}
+form div.submit div input.inputSubmit, form div.submit div input.inputButton { float: right; margin: 0 0 0 5px;}
+form div small {display: block; padding: 1px 3px; font-size: 88%; height: expression('1%');}
+form fieldset legend { line-height: 150%;}
+form textarea.expanding { overflow: auto; overflow-x: auto; overflow-y: visible;}
+div.optional label:before {content: '';}
+div.required label:before {content: '';}
+form textarea.wide { margin: 30px 0px 0 -144px; width:100%; overflow: auto; overflow-x: auto; overflow-y: visible;}
+form div label.labelCheckbox, form div label.labelRadio, label.labelCheckbox, label.labelRadio {display: block; height: expression('1%'); padding: 4px 0px 0px 18px; text-indent: -18px; line-height: 120%;}
+form div label.labelCheckbox input.inputCheckbox, form div label.labelRadio input.inputRadio, label.labelCheckbox input.inputCheckbox, label.labelRadio input.inputRadio {margin: 0px 0px 0px 0px;}
+form div label.compact { display: inline; width: auto; padding: 4px 10px 0px 0px; text-indent: 0px; margin: 0px 0px 0px 0px;}
+form div.notes p, form div small { line-height: 125%;}
+form div.wide small { margin: 0px 0px 5px 0px;}
Please sign in to comment.
Something went wrong with that request. Please try again.