123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245 |
- #!/usr/bin/env python
- import os
- import glob
- import subprocess
- try:
- from xmlrpc.client import ServerProxy
- except ImportError:
- from xmlrpclib import ServerProxy
- from pprint import pprint
- import boto
- import boto.s3.bucket
- import boto.s3.key
- from fabric.api import task, local
- ##################################################
- SHORT_PROJECT_NAME = 'python'
- FULL_PROJECT_NAME = 'byte_of_{}'.format(SHORT_PROJECT_NAME)
- MARKDOWN_FILES = [
- {
- 'file' : '01-frontpage.md',
- 'slug' : "Python",
- 'title' : "Python",
- },
- {
- 'file' : '02-table-of-contents.md',
- 'slug' : "Python_en-Table_of_Contents",
- 'title' : "Table of Contents of A Byte of Python",
- },
- ]
- ## NOTES
- ## 1. This assumes that you have already created the S3 bucket whose name is stored in
- ## AWS_S3_BUCKET_NAME environment variable.
- ## 2. Under that S3 bucket, you have created a folder whose name is stored above as
- ## SHORT_PROJECT_NAME.
- ## 3. Under that S3 bucket, you have created a folder whose name is stored as
- ## SHORT_PROJECT_NAME/assets.
- ##################################################
- if os.environ.get('AWS_ACCESS_KEY_ID') is not None \
- and len(os.environ['AWS_ACCESS_KEY_ID']) > 0 \
- and os.environ.get('AWS_SECRET_ACCESS_KEY') is not None \
- and len(os.environ['AWS_SECRET_ACCESS_KEY']) > 0 \
- and os.environ.get('AWS_S3_BUCKET_NAME') is not None \
- and len(os.environ['AWS_S3_BUCKET_NAME']) > 0:
- AWS_ENABLED = True
- else:
- AWS_ENABLED = False
- print("NOTE: S3 uploading is disabled because of missing AWS key environment variables.")
- # In my case, they are the same - 'files.swaroopch.com'
- # http://docs.amazonwebservices.com/AmazonS3/latest/dev/VirtualHosting.html#VirtualHostingCustomURLs
- S3_PUBLIC_URL = os.environ['AWS_S3_BUCKET_NAME']
- # else
- #S3_PUBLIC_URL = 's3.amazonaws.com/{}'.format(os.environ['AWS_S3_BUCKET_NAME'])
- if os.environ.get('WORDPRESS_RPC_URL') is not None \
- and len(os.environ['WORDPRESS_RPC_URL']) > 0 \
- and os.environ.get('WORDPRESS_BASE_URL') is not None \
- and len(os.environ['WORDPRESS_BASE_URL']) > 0 \
- and os.environ.get('WORDPRESS_BLOG_ID') is not None \
- and len(os.environ['WORDPRESS_BLOG_ID']) > 0 \
- and os.environ.get('WORDPRESS_USERNAME') is not None \
- and len(os.environ['WORDPRESS_USERNAME']) > 0 \
- and os.environ.get('WORDPRESS_PASSWORD') is not None \
- and len(os.environ['WORDPRESS_PASSWORD']) > 0 \
- and os.environ.get('WORDPRESS_PARENT_PAGE_ID') is not None \
- and len(os.environ['WORDPRESS_PARENT_PAGE_ID']) > 0 \
- and os.environ.get('WORDPRESS_PARENT_PAGE_SLUG') is not None \
- and len(os.environ['WORDPRESS_PARENT_PAGE_SLUG']) > 0:
- WORDPRESS_ENABLED = True
- else:
- WORDPRESS_ENABLED = False
- print("NOTE: Wordpress uploading is disabled because of missing environment variables.")
- ##################################################
- def markdown_to_html(source_text):
- args = ['pandoc',
- '-f', 'markdown',
- '-t', 'html',
- '-S']
- p = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
- output = p.communicate(source_text)[0]
- # TODO Replace image URLs with uploaded AWS S3 assets public URLs
- return output
- def _upload_to_s3(filename, key):
- conn = boto.connect_s3()
- b = boto.s3.bucket.Bucket(conn, os.environ['AWS_S3_BUCKET_NAME'])
- k = boto.s3.key.Key(b)
- k.key = key
- k.set_contents_from_filename(filename)
- k.set_acl('public-read')
- print("Uploaded to S3 : http://{}/{}".format(S3_PUBLIC_URL, key))
- def upload_output_to_s3(filename):
- key = "{}/{}".format(SHORT_PROJECT_NAME, filename)
- _upload_to_s3(filename, key)
- def upload_asset_to_s3(filename):
- key = "{}/assets/{}".format(SHORT_PROJECT_NAME, filename)
- _upload_to_s3(filename, key)
- def _wordpress_get_pages():
- server = ServerProxy(os.environ['WORDPRESS_RPC_URL'])
- print("(Fetching list of pages from WP)")
- return server.wp.getPosts(os.environ['WORDPRESS_BLOG_ID'],
- os.environ['WORDPRESS_USERNAME'],
- os.environ['WORDPRESS_PASSWORD'],
- {'post_type' : 'page', 'number' : pow(10, 5)})
- def wordpress_new_page(slug, title, content):
- """Create a new Wordpress page.
- https://codex.wordpress.org/XML-RPC_WordPress_API/Posts#wp.newPost
- https://codex.wordpress.org/Function_Reference/wp_insert_post
- http://docs.python.org/library/xmlrpclib.html
- """
- server = ServerProxy(os.environ['WORDPRESS_RPC_URL'])
- return server.wp.newPost(os.environ['WORDPRESS_BLOG_ID'],
- os.environ['WORDPRESS_USERNAME'],
- os.environ['WORDPRESS_PASSWORD'],
- {
- 'post_name' : slug,
- 'post_content' : content,
- 'post_title' : title,
- 'post_parent' : os.environ['WORDPRESS_PARENT_PAGE_ID'],
- #'post_category' : os.environ['WORDPRESS_CATEGORY'], # TODO Take env var for category
- 'post_type' : 'page',
- 'post_status' : 'publish',
- 'comment_status' : 'closed',
- 'ping_status' : 'closed',
- })
- def wordpress_edit_page(post_id, content):
- """Edit a Wordpress page.
- https://codex.wordpress.org/XML-RPC_WordPress_API/Posts#wp.editPost
- https://codex.wordpress.org/Function_Reference/wp_insert_post
- http://docs.python.org/library/xmlrpclib.html
- """
- server = ServerProxy(os.environ['WORDPRESS_RPC_URL'])
- return server.wp.editPost(os.environ['WORDPRESS_BLOG_ID'],
- os.environ['WORDPRESS_USERNAME'],
- os.environ['WORDPRESS_PASSWORD'],
- post_id,
- {
- 'post_content' : content,
- })
- @task
- def wp():
- """https://codex.wordpress.org/XML-RPC_WordPress_API/Posts"""
- if WORDPRESS_ENABLED:
- existing_pages = _wordpress_get_pages()
- existing_page_slugs = [i.get('post_name') for i in existing_pages]
- for chapter in MARKDOWN_FILES:
- html = markdown_to_html(open(chapter['file']).read())
- if chapter['slug'].lower() in existing_page_slugs:
- page_id = [i for i in existing_pages \
- if i.get('post_name') == chapter['slug'].lower()] \
- [0] \
- ['post_id']
- print("Existing page to be updated: {} : {}".format(chapter['slug'], page_id))
- result = wordpress_edit_page(page_id, html)
- print("Result: {}".format(result))
- else:
- print("New page to be created: {}".format(chapter['slug']))
- result = wordpress_new_page(chapter['slug'], chapter['title'], html)
- print("Result: {}".format(result))
- page_url = "{}/{}/{}".format(os.environ['WORDPRESS_BASE_URL'],
- os.environ['WORDPRESS_PARENT_PAGE_SLUG'],
- chapter['slug'])
- print(page_url)
- print
- @task
- def epub():
- """http://johnmacfarlane.net/pandoc/epub.html"""
- args = ['pandoc',
- '-f', 'markdown',
- '-t', 'epub',
- '-o', '{}.epub'.format(FULL_PROJECT_NAME),
- '-S'] + [i['file'] for i in MARKDOWN_FILES]
- local(' '.join(args))
- if AWS_ENABLED:
- upload_output_to_s3('{}.epub'.format(FULL_PROJECT_NAME))
- @task
- def pdf():
- """http://johnmacfarlane.net/pandoc/README.html#creating-a-pdf"""
- args = ['pandoc',
- '-f', 'markdown',
- ##'-t', 'pdf', # Intentionally commented out due to https://github.com/jgm/pandoc/issues/571
- '-o', '{}.pdf'.format(FULL_PROJECT_NAME),
- '-S'] + [i['file'] for i in MARKDOWN_FILES]
- local(' '.join(args))
- if AWS_ENABLED:
- upload_output_to_s3('{}.pdf'.format(FULL_PROJECT_NAME))
- POSSIBLE_OUTPUTS = (
- '{}.epub'.format(FULL_PROJECT_NAME),
- '{}.pdf'.format(FULL_PROJECT_NAME),
- )
- @task
- def clean():
- """Remove generated output files"""
- for filename in POSSIBLE_OUTPUTS:
- if os.path.exists(filename):
- os.remove(filename)
- print("Removed {}".format(filename))
|