Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Add scripts to administer the blog as an alternative to using /admin/

  • Loading branch information...
commit 51999e8ec3117f8ba00a3dbf7525b434da8660a7 1 parent 13645c4
@aht aht authored committed
View
49 script/draft
@@ -0,0 +1,49 @@
+#!/usr/bin/env python
+
+"""
+Post a single unindexed page at /draft/title, where the title and body of the
+page is extracted from the HTML markup of the given file.
+
+Usage: draft [-l] filepath
+
+By default, requests are made to {APPID}.appspot.com.
+The script will print out the URL of the draft page if success.
+
+Options:
+ -l make requests to to localhost:8080
+"""
+import BeautifulSoup
+import datetime
+import getopt
+import sys
+import os
+
+if sys.argv[1] == '-l':
+ host = 'localhost:8080'
+ filename = sys.argv[2]
+else:
+ host = None
+ filename = sys.argv[1]
+
+import remote
+remote.attach(host)
+
+import config
+import models
+import static
+import utils
+
+
+soup = BeautifulSoup.BeautifulSoup(open(filename).read())
+title = unicode(soup.title.string)
+post = models.BlogPost(
+ title=title,
+ body=u''.join(unicode(s) for s in soup.body.contents if s),
+ published=datetime.datetime.now()
+ )
+path = '/draft/' + utils.slugify(title)
+rendered = utils.render_template("draft.html", {'post': post})
+
+static.set(path, rendered, config.html_mime_type, indexed=False)
+
+print 'http://' + (host or (remote.APPID + '.appspot.com')) + path
View
34 script/post_deploy
@@ -0,0 +1,34 @@
+#!/usr/bin/env python2.5
+
+"""
+Run a post_deploy task using deferred.
+
+Usage: post_deploy [-l | -v version]
+
+By default, requests are made to {APPID}.appspot.com.
+
+Options:
+ -l make requests to localhost:8080
+ -v make requests to $version.latest.{APPID}.appspot.com
+"""
+
+import sys
+import subprocess
+
+import remote
+
+if len(sys.argv) == 2 and sys.argv[1] == '-l':
+ host = 'localhost:8080'
+elif len(sys.argv) == 3 and sys.argv[1] == '-v':
+ host = sys.argv[2] + '.latest.' + remote.APPID + '.appspot.com'
+else:
+ host = None
+
+remote.attach(host)
+
+from google.appengine.ext import deferred
+
+import post_deploy
+
+
+deferred.defer(post_deploy.run_deploy_task)
View
78 script/publish
@@ -0,0 +1,78 @@
+#!/usr/bin/env python
+
+"""
+Publish and tag a given file, with title and body extracted from the HTML
+markup of the file. The corresponding draft page, if any, will be deleted if
+the publish request succeed.
+
+Usage: publish [-l] [-t tagstring] [-f] filepath
+
+By default, requests are made to {APPID}.appspot.com. The script will fail if
+content already exists on the given path.
+
+Options:
+ -l make requests to localhost:8080
+ -t use the supplied tags, which should be given as a comma-separated string
+ -f force update
+"""
+
+import BeautifulSoup
+import datetime
+import getopt
+import os
+import sys
+
+host = None
+forced = False
+tags = []
+
+opts, args = getopt.getopt(sys.argv[1:], 'flt:')
+for o, v in opts:
+ if o == '-l':
+ host = 'localhost:8080'
+ elif o == '-t':
+ tags = set(map(unicode, v.split(',')))
+ elif o == '-f':
+ forced = True
+filename = args[0]
+
+import remote
+remote.attach(host)
+
+from google.appengine.api import memcache
+
+import config
+import models
+import static
+import utils
+
+
+soup = BeautifulSoup.BeautifulSoup(open(filename).read())
+title = unicode(soup.title.string)
+body = u''.join(unicode(s) for s in soup.body.contents if s)
+post = models.BlogPost(
+ title=title,
+ body=body,
+ tags=tags,
+ published=datetime.datetime.now()
+ )
+path = utils.format_post_path(post, 0)
+
+if not static.add(path, '', config.html_mime_type):
+ if forced:
+ post = models.BlogPost.gql('WHERE path = :1', path).get()
+ post.title = title
+ post.body = body
+ post.tags = tags
+ else:
+ sys.exit("error: content exists on path %s, use -f to force update" % path)
+
+static.get(path).delete()
+post.put()
+post.publish()
+
+draftpath = '/draft/'+ utils.slugify(title)
+draft = static.get(draftpath)
+if draft:
+ draft.delete()
+ memcache.delete(draftpath)
View
34 script/regen
@@ -0,0 +1,34 @@
+#!/usr/bin/env python
+
+"""
+Regenerate all pages using deferred.
+
+Usage: regen [-l | -v version]
+
+By default, requests are made to {APPID}.appspot.com.
+
+Options:
+ -l make requests to localhost:8080
+ -v make requests to $version.latest.{APPID}.appspot.com
+"""
+import sys
+
+import remote
+
+if len(sys.argv) == 2 and sys.argv[1] == '-l':
+ host = 'localhost:8080'
+elif len(sys.argv) == 3 and sys.argv[1] == '-v':
+ host = sys.argv[2] + '.latest.' + remote.APPID + '.appspot.com'
+else:
+ host = None
+
+remote.attach(host)
+
+from google.appengine.ext import deferred
+
+import static
+import post_deploy
+
+
+deferred.defer(post_deploy.PostRegenerator().regenerate)
+deferred.defer(post_deploy.post_deploy, post_deploy.BLOGGART_VERSION)
View
72 script/remote.py
@@ -0,0 +1,72 @@
+#!/usr/bin/env python
+
+import getpass
+import os
+import sys
+
+## Application specific
+SDK_DIR = '/usr/local/google_appengine'
+APP_DIR = '/home/aht/src/bloggart'
+APPID = 'bloggart-demo'
+EMAIL = 'my.email@host.dom'
+
+REMOTE_API_PATH = '/remote_api'
+
+## Extra paths to be inserted into sys.path,
+## including the SDK, it's libraries, your APPDIR, and APPDIR/lib
+EXTRA_PATHS = [
+ SDK_DIR,
+ os.path.join(SDK_DIR, 'lib', 'antlr3'),
+ os.path.join(SDK_DIR, 'lib', 'django'),
+ os.path.join(SDK_DIR, 'lib', 'webob'),
+ os.path.join(SDK_DIR, 'lib', 'yaml', 'lib'),
+ APP_DIR,
+ os.path.join(APP_DIR, 'lib'),
+]
+sys.path = EXTRA_PATHS + sys.path
+
+from google.appengine.ext.remote_api import remote_api_stub
+
+def attach(host=None):
+ def auth_func():
+ if host and host.startswith('localhost'):
+ return ('foo', 'bar')
+ else:
+ return (EMAIL, getpass.getpass())
+ remote_api_stub.ConfigureRemoteApi(APPID, REMOTE_API_PATH, auth_func, host)
+ remote_api_stub.MaybeInvokeAuthentication()
+ os.environ['SERVER_SOFTWARE'] = 'Development (remote_api)/1.0'
+
+
+if __name__ == '__main__':
+ if len(sys.argv) == 2 and sys.argv[1] == '-l':
+ host = 'localhost:8080'
+ else:
+ host = None
+
+ attach(host)
+
+ from google.appengine.ext import db
+ from google.appengine.api import memcache
+
+ BANNER = "App Engine remote_api shell\n" + \
+ "Python %s\n" % sys.version + \
+ "The db, and memcache modules are imported."
+
+ ## Use readline for completion/history if available
+ try:
+ import readline
+ except ImportError:
+ pass
+ else:
+ HISTORY_PATH = os.path.expanduser('~/.remote_api_shell_history')
+ readline.parse_and_bind('tab: complete')
+ if os.path.exists(HISTORY_PATH):
+ readline.read_history_file(HISTORY_PATH)
+ import atexit
+ atexit.register(lambda: readline.write_history_file(HISTORY_PATH))
+
+ sys.ps1 = '%s <-- ' % (host or APPID)
+
+ import code
+ code.interact(banner=BANNER, local=globals())
Please sign in to comment.
Something went wrong with that request. Please try again.