Compare commits
10 commits
d671fbbd72
...
b35e3a1d2d
Author | SHA1 | Date | |
---|---|---|---|
b35e3a1d2d | |||
67cdbeb36c | |||
c22e7b2291 | |||
ff8adf9bb7 | |||
cf5dc5eb41 | |||
e84d3d754c | |||
4c37591b26 | |||
e2f7982038 | |||
138acfdd40 | |||
2ab0aac8a5 |
2 changed files with 228 additions and 83 deletions
40
README.md
40
README.md
|
@ -4,6 +4,44 @@ Crunch is a python based command line utility that allows for manual rebuilding
|
||||||
index pages, error pages and the home page. It also supports parsing email to create new
|
index pages, error pages and the home page. It also supports parsing email to create new
|
||||||
posts. It was created to run amdavidson.com.
|
posts. It was created to run amdavidson.com.
|
||||||
|
|
||||||
|
Usage (from `crunch.py --help`):
|
||||||
|
|
||||||
|
usage: crunch.py [-h] [--all] [--clean] [--dependencies] [--email] [--error]
|
||||||
|
[--extras] [--feed] [--galleries] [--home] [--indexes]
|
||||||
|
[--new] [--no-http] [--pages] [--posts] [--serve] [--setup]
|
||||||
|
[--single SINGLE] [--verbose]
|
||||||
|
|
||||||
|
optional arguments:
|
||||||
|
-h, --help show this help message and exit
|
||||||
|
--all Builds the entire site.
|
||||||
|
--clean Empties the build folder.
|
||||||
|
--dependencies Builds all the dependencies, ignored unless used with
|
||||||
|
--single, --new, or --email.
|
||||||
|
--email Reads an email message from STDIN and parses to create a
|
||||||
|
new post. Overrides --all, --posts, --indexes, --home, and
|
||||||
|
--single
|
||||||
|
--error Generates static error pages.
|
||||||
|
--extras Generates minified css and js files.
|
||||||
|
--feed Generates RSS feed.
|
||||||
|
--galleries Generates galleries.
|
||||||
|
--home Builds the home page.
|
||||||
|
--indexes Builds the index pages.
|
||||||
|
--new Starts an interactive sesson to create a new post. *Not yet
|
||||||
|
implemented*
|
||||||
|
--no-http Prevents crunch from contacting external sources during the
|
||||||
|
build.
|
||||||
|
--pages Builds all static pages.
|
||||||
|
--posts Builds all posts.
|
||||||
|
--serve Starts a lightweight HTTP server to serve build folder to
|
||||||
|
localhost. Not intended for production use.
|
||||||
|
--setup Creates a basic blog framework to start with. *Not yet
|
||||||
|
implemented.*
|
||||||
|
--single SINGLE Builds a single post. Takes a filename as an argument or
|
||||||
|
use - to read from STDIN. Overrides all other build instructions.
|
||||||
|
*Not yet implemented.*
|
||||||
|
--verbose Enables information display other than errors.
|
||||||
|
|
||||||
|
|
||||||
The configuration is stored in a file called conf.yaml in the same directory as crunch.
|
The configuration is stored in a file called conf.yaml in the same directory as crunch.
|
||||||
|
|
||||||
An example configuration follows:
|
An example configuration follows:
|
||||||
|
@ -30,6 +68,8 @@ An example configuration follows:
|
||||||
public_folder: public
|
public_folder: public
|
||||||
images_folder: images
|
images_folder: images
|
||||||
galleries_folder: galleries
|
galleries_folder: galleries
|
||||||
|
css_folder: css
|
||||||
|
scripts_folder: scripts
|
||||||
home_count: 5
|
home_count: 5
|
||||||
image_width: 640
|
image_width: 640
|
||||||
image_height: 640
|
image_height: 640
|
||||||
|
|
|
@ -29,7 +29,7 @@ except:
|
||||||
yaml_available = False
|
yaml_available = False
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import markdown
|
import markdown2
|
||||||
markdown_available = True
|
markdown_available = True
|
||||||
except:
|
except:
|
||||||
markdown_available = False
|
markdown_available = False
|
||||||
|
@ -58,6 +58,8 @@ if argparse_available:
|
||||||
post. Overrides --all, --posts, --indexes, --home, and --single')
|
post. Overrides --all, --posts, --indexes, --home, and --single')
|
||||||
parser.add_argument('--error', dest='error', action='store_true',
|
parser.add_argument('--error', dest='error', action='store_true',
|
||||||
help='Generates static error pages.')
|
help='Generates static error pages.')
|
||||||
|
parser.add_argument('--extras', dest='extras', action='store_true',
|
||||||
|
help='Generates minified css and js files.')
|
||||||
parser.add_argument('--feed', dest='feed', action='store_true',
|
parser.add_argument('--feed', dest='feed', action='store_true',
|
||||||
help='Generates RSS feed.')
|
help='Generates RSS feed.')
|
||||||
parser.add_argument('--galleries', dest='galleries', action='store_true',
|
parser.add_argument('--galleries', dest='galleries', action='store_true',
|
||||||
|
@ -120,8 +122,8 @@ posts_folder = base_folder + '/' + conf['posts_folder']
|
||||||
public_folder = base_folder + '/' + conf['public_folder']
|
public_folder = base_folder + '/' + conf['public_folder']
|
||||||
images_folder = base_folder + '/' + conf['images_folder']
|
images_folder = base_folder + '/' + conf['images_folder']
|
||||||
galleries_folder = base_folder + '/' + conf['galleries_folder']
|
galleries_folder = base_folder + '/' + conf['galleries_folder']
|
||||||
|
css_folder = base_folder + '/' + conf['css_folder']
|
||||||
|
scripts_folder = base_folder + '/' + conf['scripts_folder']
|
||||||
|
|
||||||
|
|
||||||
### Classes
|
### Classes
|
||||||
|
@ -215,7 +217,7 @@ class Post:
|
||||||
# if markdown is available, use that to process the post body.
|
# if markdown is available, use that to process the post body.
|
||||||
self.markdown = body
|
self.markdown = body
|
||||||
if markdown_available:
|
if markdown_available:
|
||||||
self.content = markdown.markdown(str(body))
|
self.content = markdown2.markdown(str(body), extras=["code-color", "code-friendly"])
|
||||||
else:
|
else:
|
||||||
if args.verbose: print 'WARN: markdown unavailable, using raw post data.'
|
if args.verbose: print 'WARN: markdown unavailable, using raw post data.'
|
||||||
self.content = self.markdown
|
self.content = self.markdown
|
||||||
|
@ -286,10 +288,7 @@ def format_layout(page):
|
||||||
|
|
||||||
<link rel="icon" type="image/png" href="/images/favicon.png" />
|
<link rel="icon" type="image/png" href="/images/favicon.png" />
|
||||||
|
|
||||||
<link rel="stylesheet" type="text/css" href="/css/base.css" />
|
<link rel="stylesheet" type="text/css" href="/css/app.css" />
|
||||||
<link rel="stylesheet" type="text/css" href="/css/skeleton.css" />
|
|
||||||
<link rel="stylesheet" type="text/css" href="/css/layout.css" />
|
|
||||||
<link rel="stylesheet" type="text/css" href="http://fonts.googleapis.com/css?family=Muli:300,300italic|PT+Sans+Narrow:700|Anonymous+Pro" />
|
|
||||||
|
|
||||||
<link rel="alternate" type="application/atom+xml" title="amdavidson.com feed"
|
<link rel="alternate" type="application/atom+xml" title="amdavidson.com feed"
|
||||||
href="/index.xml" />
|
href="/index.xml" />
|
||||||
|
@ -307,23 +306,25 @@ def format_layout(page):
|
||||||
%(body)s
|
%(body)s
|
||||||
</div>
|
</div>
|
||||||
<div class="four columns">
|
<div class="four columns">
|
||||||
<h6>About</h6>
|
<h6><a href="/about.htm">about</a></h6>
|
||||||
<p class="small">amdavidson.com is a simple blog run by Andrew Davidson, a
|
<p class="small">amdavidson.com is a simple blog run by Andrew Davidson, a
|
||||||
manufacturing engineer with a blogging habit. He sometimes posts 140 character
|
manufacturing engineer with a blogging habit. He sometimes posts 140 character
|
||||||
<a href="http://twitter.com/amdavidson">tidbits</a>, shares
|
<a href="http://twitter.com/amdavidson">tidbits</a>, shares
|
||||||
<a href="/">photos</a>, and saves
|
<a href="/">photos</a>, and saves
|
||||||
<a href="http://pinboard.in/u:amdavidson/">links</a>. You can also see posts
|
<a href="http://pinboard.in/u:amdavidson/">links</a>. You can also see posts
|
||||||
dating <a href="/archives">back to 2005</a>.</p>
|
dating <a href="/archives.htm">back to 2005</a>.</p>
|
||||||
|
|
||||||
<div id="twitter" style="display:none;">
|
<div id="twitter" style="display:none;">
|
||||||
<h6><a href="http://twitter.com/amdavidson">Twitter</a></h6>
|
<h6><a href="http://twitter.com/amdavidson">tweeted</a></h6>
|
||||||
<p class="small"><span id="tweet"></span></p>
|
<p class="small"><span id="tweet"></span><br/>
|
||||||
|
<span id="tweet-date"></span></p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="pinboard" style="display:none;">
|
<div id="pinboard" style="display:none;">
|
||||||
<h6><a href="http://pinboard.in/u:amdavidson">Pinboard</a></h6>
|
<h6><a href="http://pinboard.in/u:amdavidson">bookmarked</a></h6>
|
||||||
<p class="small"><a id="pin-link" href="/"><span id="pin-title"></span></a><br/>
|
<p class="small"><a id="pin-link" href="/"><span id="pin-title"></span></a><br/>
|
||||||
<span id="pin-description"></span></p>
|
<span id="pin-description"></span><br/>
|
||||||
|
<span id="pin-date"></span></p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h6>Search</h6>
|
<h6>Search</h6>
|
||||||
|
@ -339,19 +340,10 @@ def format_layout(page):
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js">
|
|
||||||
</script>
|
|
||||||
<script src="/scripts/jquery.timeago.js"></script>
|
|
||||||
<script src="/scripts/twitter.js"></script>
|
|
||||||
<script src="/scripts/pinboard.js"></script>
|
|
||||||
|
|
||||||
<script type="text/javascript">
|
|
||||||
jQuery(document).ready(function() {
|
|
||||||
jQuery("span.timeago").timeago();
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
|
<script src="/scripts/zepto.min.js"></script>
|
||||||
|
<script src="/scripts/app.js"></script>
|
||||||
<script src="http://mint.amdavidson.com/?js" type="text/javascript"></script>
|
<script src="http://mint.amdavidson.com/?js" type="text/javascript"></script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
@ -434,20 +426,26 @@ def format_gallery_single(image):
|
||||||
<div class="eleven columns">
|
<div class="eleven columns">
|
||||||
<h3>%(name)s</h3>
|
<h3>%(name)s</h3>
|
||||||
<p style="text-align:center;"><a href="%(full_url)s">
|
<p style="text-align:center;"><a href="%(full_url)s">
|
||||||
<img src="%(mid_url)s" />
|
<img class="scale-with-grid" src="%(mid_url)s" />
|
||||||
</a></p>
|
</a></p>
|
||||||
</div>
|
</div>
|
||||||
""" % { 'name': image.name(), 'full_url': image.full_url(), 'mid_url': image.mid_url() }
|
""" % { 'name': image.name(), 'full_url': image.full_url(), 'mid_url': image.mid_url() }
|
||||||
|
|
||||||
def format_gallery_thumb(image):
|
def format_gallery_thumb(image):
|
||||||
return """
|
return """
|
||||||
<a href="%(mid_page)s"><img src="%(thm_path)s" /></a>
|
<div class="thumbnail">
|
||||||
|
<a href="%(mid_page)s"><img src="%(thm_path)s" /></a>
|
||||||
|
</div>
|
||||||
""" % { 'mid_page': image.mid_page(), 'thm_path': image.thumbnail_url() }
|
""" % { 'mid_page': image.mid_page(), 'thm_path': image.thumbnail_url() }
|
||||||
|
|
||||||
##########################################################################################
|
##########################################################################################
|
||||||
### Helper Functions
|
### Helper Functions
|
||||||
##########################################################################################
|
##########################################################################################
|
||||||
|
|
||||||
|
|
||||||
|
# get_recent() takes in an integer that sets the number of recent posts to get, it
|
||||||
|
# returns a list of post objects in reverse chronological order. This function is used
|
||||||
|
# in crunch_feed() and crunch_home().
|
||||||
def get_recent(count):
|
def get_recent(count):
|
||||||
# Create an empty variable to store posts in.
|
# Create an empty variable to store posts in.
|
||||||
post_list = []
|
post_list = []
|
||||||
|
@ -516,6 +514,8 @@ def ensure_build_folder():
|
||||||
shutil.copytree(public_folder, build_folder)
|
shutil.copytree(public_folder, build_folder)
|
||||||
shutil.copytree(images_folder, build_folder + '/' + conf['images_folder'])
|
shutil.copytree(images_folder, build_folder + '/' + conf['images_folder'])
|
||||||
os.mkdir(build_folder + '/' + conf['galleries_folder'])
|
os.mkdir(build_folder + '/' + conf['galleries_folder'])
|
||||||
|
os.mkdir(build_folder + '/' + conf['css_folder'])
|
||||||
|
os.mkdir(build_folder + '/' + conf['scripts_folder'])
|
||||||
return 2
|
return 2
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
@ -545,14 +545,17 @@ def crunch_pages():
|
||||||
if filename.endswith(conf['extension']):
|
if filename.endswith(conf['extension']):
|
||||||
if args.verbose: print 'Building ' + filename
|
if args.verbose: print 'Building ' + filename
|
||||||
|
|
||||||
# Fire up a markdown object.
|
# Split the page header from the body.
|
||||||
md = markdown.Markdown(extensions = ['meta'])
|
header, body = open(pages_folder + '/' + filename).read().split('\n\n', 1)
|
||||||
|
|
||||||
|
# Pull a dict from the yaml in the header.
|
||||||
|
y = yaml.load(header)
|
||||||
|
|
||||||
# Parse the post and grab the content.
|
# Parse the post and grab the content.
|
||||||
content = md.convert(open(pages_folder + '/' + filename).read())
|
content = markdown2.markdown(body, extras=["code-color", "code-friendly"])
|
||||||
|
|
||||||
# Pull the title out of the metadata.
|
# Pull the title out of the metadata.
|
||||||
title = md.Meta['title'][0]
|
title = y['title']
|
||||||
|
|
||||||
# Generate the url
|
# Generate the url
|
||||||
url = '/' + filename.rstrip(conf['extension']) + '.htm'
|
url = '/' + filename.rstrip(conf['extension']) + '.htm'
|
||||||
|
@ -602,28 +605,10 @@ def crunch_posts():
|
||||||
# Only process files with the correct extension per `conf.yaml`.
|
# Only process files with the correct extension per `conf.yaml`.
|
||||||
if i.endswith(conf['extension']):
|
if i.endswith(conf['extension']):
|
||||||
if args.verbose: print '\t\t' + i
|
if args.verbose: print '\t\t' + i
|
||||||
|
|
||||||
# Create a new post object and parse the post file.
|
|
||||||
post = Post()
|
|
||||||
f = open(posts_folder + '/' + year + '/' + month + '/' + i)
|
|
||||||
post.filename = i
|
|
||||||
post.parse(f.read())
|
|
||||||
f.close()
|
|
||||||
|
|
||||||
# Create a new page for this post.
|
# Process the post
|
||||||
page = Page()
|
crunch_single(open(posts_folder + '/' + year + '/' + month \
|
||||||
page.title = str(post.title) + ' | ' + page.title
|
+ '/' + i).read())
|
||||||
page.body = post.formatted()
|
|
||||||
|
|
||||||
# Save the page to the $build/$year/$month folder.
|
|
||||||
n = open(build_folder + '/' + year + '/' + month + '/' + post.slug + \
|
|
||||||
'.htm', "w")
|
|
||||||
n.writelines(page.formatted())
|
|
||||||
n.close
|
|
||||||
|
|
||||||
os.chmod(build_folder + '/' + year + '/' + month + '/' + post.slug + \
|
|
||||||
'.htm', 0644)
|
|
||||||
|
|
||||||
|
|
||||||
# Function to process the home file.
|
# Function to process the home file.
|
||||||
def crunch_home():
|
def crunch_home():
|
||||||
|
@ -660,8 +645,8 @@ def crunch_indexes():
|
||||||
if args.verbose: print 'Building the indexes.'
|
if args.verbose: print 'Building the indexes.'
|
||||||
|
|
||||||
# Start the body for the archives.htm page.
|
# Start the body for the archives.htm page.
|
||||||
archives_body = '<div class="eleven-columns"><h3>Post Archives</h3>\n' + \
|
archives_body = '\t<div class="eleven-columns">\n\t\t<h3>Post Archives</h3>\n\t</div>\n' + \
|
||||||
'<ul id="acc" class="square">\n'
|
'\t<div class="eleven-columns">\n\t\t<ul class="square">\n'
|
||||||
|
|
||||||
# Grab all the years in the posts folder.
|
# Grab all the years in the posts folder.
|
||||||
for year in sorted(os.listdir(posts_folder), reverse=True):
|
for year in sorted(os.listdir(posts_folder), reverse=True):
|
||||||
|
@ -671,8 +656,8 @@ def crunch_indexes():
|
||||||
if args.verbose: print 'Building indexes for ' + year + ':'
|
if args.verbose: print 'Building indexes for ' + year + ':'
|
||||||
|
|
||||||
# Add an entry to archives.htm
|
# Add an entry to archives.htm
|
||||||
archives_body += '<li><a href="/' + year + '">' + year + '</a>\n\t\
|
archives_body += '\t\t\t<li><a href="/' + year + '">' + year + '</a>\n\t\
|
||||||
<ul class="circle">\n'
|
\t\t<ul class="circle">\n'
|
||||||
|
|
||||||
# Make a corresponding year folder in the build folder if it doesn't exist.
|
# Make a corresponding year folder in the build folder if it doesn't exist.
|
||||||
year_path = build_folder + '/' + year
|
year_path = build_folder + '/' + year
|
||||||
|
@ -689,7 +674,7 @@ def crunch_indexes():
|
||||||
if args.verbose: print "\t" + month
|
if args.verbose: print "\t" + month
|
||||||
|
|
||||||
# Add an entry to archives.htm.
|
# Add an entry to archives.htm.
|
||||||
archives_body += '\t\t<li><a href="/' + year + '/' + month + '">' + month \
|
archives_body += '\t\t\t\t\t<li><a href="/' + year + '/' + month + '">' + month \
|
||||||
+ '</a>\n'
|
+ '</a>\n'
|
||||||
|
|
||||||
# Make a corresponding month folder in the build folder if it doesn't exist.
|
# Make a corresponding month folder in the build folder if it doesn't exist.
|
||||||
|
@ -730,11 +715,11 @@ def crunch_indexes():
|
||||||
month_page.body = month_body
|
month_page.body = month_body
|
||||||
|
|
||||||
# Write out the titles to the posts to archives.htm in ascending order.
|
# Write out the titles to the posts to archives.htm in ascending order.
|
||||||
archives_body += '\t\t\t<ul>\n'
|
archives_body += '\t\t\t\t\t\t<ul>\n'
|
||||||
for post in sorted(month_catch, key=lambda post: post.time, reverse=True):
|
for post in sorted(month_catch, key=lambda post: post.time, reverse=True):
|
||||||
archives_body += '\t\t\t\t<li><a href="' + post.url() + '">' + \
|
archives_body += '\t\t\t\t\t\t\t<li><a href="' + post.url() + '">' + \
|
||||||
str(post.title) + '</a></li>\n'
|
str(post.title) + '</a></li>\n'
|
||||||
archives_body += '\t\t\t</ul></li>\n'
|
archives_body += '\t\t\t\t\t\t</ul>\n\t\t\t\t\t</li>\n'
|
||||||
|
|
||||||
# Write out the month page into the build folder.
|
# Write out the month page into the build folder.
|
||||||
m = open(build_folder + '/' + year + '/' + month + '/index.htm', "w")
|
m = open(build_folder + '/' + year + '/' + month + '/index.htm', "w")
|
||||||
|
@ -743,7 +728,7 @@ def crunch_indexes():
|
||||||
os.chmod(build_folder + '/' + year + '/' + month + '/index.htm', 0644)
|
os.chmod(build_folder + '/' + year + '/' + month + '/index.htm', 0644)
|
||||||
|
|
||||||
# Close out the list of months in archive.htm
|
# Close out the list of months in archive.htm
|
||||||
archives_body += '\t</ul></li>\n'
|
archives_body += '\t\t\t\t</ul>\n\t\t\t</li>\n'
|
||||||
|
|
||||||
# Once all the posts for the current year have been processed, make a new
|
# Once all the posts for the current year have been processed, make a new
|
||||||
# Page object for the year.
|
# Page object for the year.
|
||||||
|
@ -764,7 +749,7 @@ def crunch_indexes():
|
||||||
os.chmod(build_folder + '/' + year + '/index.htm', 0644)
|
os.chmod(build_folder + '/' + year + '/index.htm', 0644)
|
||||||
|
|
||||||
# Close out the list of years in archive.htm
|
# Close out the list of years in archive.htm
|
||||||
archives_body += '</ul>\n</div>'
|
archives_body += '\t\t</ul>\n\t</div>'
|
||||||
|
|
||||||
archives_page = Page()
|
archives_page = Page()
|
||||||
archives_page.title = 'Archives | ' + archives_page.title
|
archives_page.title = 'Archives | ' + archives_page.title
|
||||||
|
@ -857,15 +842,21 @@ def crunch_email(message):
|
||||||
exif = dict(original._getexif().items())
|
exif = dict(original._getexif().items())
|
||||||
else:
|
else:
|
||||||
exif = False
|
exif = False
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if not exif == False:
|
if not exif == False:
|
||||||
if args.verbose: print 'Image is rotated, correcting.'
|
try:
|
||||||
if exif[orientation] == 3:
|
if args.verbose: print 'Image is rotated, correcting.'
|
||||||
original = original.rotate(180, expand=True)
|
if exif[orientation] == 3:
|
||||||
elif exif[orientation] == 6:
|
original = original.rotate(180, expand=True)
|
||||||
original = original.rotate(270, expand=True)
|
elif exif[orientation] == 6:
|
||||||
elif exif[orientation] == 8:
|
original = original.rotate(270, expand=True)
|
||||||
original = original.rotate(90, expand=True)
|
elif exif[orientation] == 8:
|
||||||
|
original = original.rotate(90, expand=True)
|
||||||
|
except:
|
||||||
|
if args.verbose: print 'Cannot detect rotation from EXIF.'
|
||||||
|
|
||||||
|
|
||||||
# Create empty resized var.
|
# Create empty resized var.
|
||||||
resized = False
|
resized = False
|
||||||
|
@ -973,6 +964,7 @@ def crunch_email(message):
|
||||||
f.write('title: ' + title + '\n')
|
f.write('title: ' + title + '\n')
|
||||||
f.write('date: ' + str(epoch_time) + '\n')
|
f.write('date: ' + str(epoch_time) + '\n')
|
||||||
f.write('author: ' + conf['author'] + '\n')
|
f.write('author: ' + conf['author'] + '\n')
|
||||||
|
f.write('slug: ' + slug + '\n')
|
||||||
if not short == None:
|
if not short == None:
|
||||||
f.write('short: ' + short + '\n')
|
f.write('short: ' + short + '\n')
|
||||||
f.write('\n')
|
f.write('\n')
|
||||||
|
@ -1194,6 +1186,7 @@ def crunch_gallery(name):
|
||||||
# Make a destination gallery.
|
# Make a destination gallery.
|
||||||
if not os.path.exists(build_folder + '/' + conf['galleries_folder'] + '/' + name):
|
if not os.path.exists(build_folder + '/' + conf['galleries_folder'] + '/' + name):
|
||||||
os.mkdir(build_folder + '/' + conf['galleries_folder'] + '/' + name)
|
os.mkdir(build_folder + '/' + conf['galleries_folder'] + '/' + name)
|
||||||
|
os.chmod(build_folder + '/' + conf['galleries_folder'] + '/' + name, 0755)
|
||||||
|
|
||||||
images = ''
|
images = ''
|
||||||
|
|
||||||
|
@ -1201,12 +1194,19 @@ def crunch_gallery(name):
|
||||||
for file in os.listdir(galleries_folder + '/' + name):
|
for file in os.listdir(galleries_folder + '/' + name):
|
||||||
|
|
||||||
# Process the meta data file.
|
# Process the meta data file.
|
||||||
if file == 'meta.md':
|
if file == 'meta.yaml':
|
||||||
if args.verbose: print '\tProcessing metadata.'
|
if args.verbose: print '\tProcessing metadata.'
|
||||||
md = markdown.Markdown(extensions = ['meta'])
|
|
||||||
description = md.convert(open(galleries_folder + '/' + name + '/' + file, \
|
a = open(galleries_folder + '/' + name + '/' + file, \
|
||||||
'r').read())
|
'r').read().split('\n\n', 1)
|
||||||
|
|
||||||
|
y = yaml.load(a[0])
|
||||||
|
|
||||||
|
try:
|
||||||
|
description = '<div class="eleven columns">' + \
|
||||||
|
markdown2.markdown(str(a[1]), extras=["code-color", "code-friendly"])
|
||||||
|
except:
|
||||||
|
description = '<div class="eleven columns">'
|
||||||
|
|
||||||
# Copy all the images.
|
# Copy all the images.
|
||||||
if filter(file.endswith, image_extensions):
|
if filter(file.endswith, image_extensions):
|
||||||
|
@ -1231,15 +1231,19 @@ def crunch_gallery(name):
|
||||||
os.chmod(build_folder + '/' + conf['galleries_folder'] + '/' + name + '/' + \
|
os.chmod(build_folder + '/' + conf['galleries_folder'] + '/' + name + '/' + \
|
||||||
i.name() + '.htm', 0644)
|
i.name() + '.htm', 0644)
|
||||||
|
|
||||||
|
|
||||||
|
images += "</div>"
|
||||||
|
|
||||||
gal_page = Page()
|
gal_page = Page()
|
||||||
|
|
||||||
leader = '<h3>' + str(md.Meta['title'][0]) + '</h3>\n<p class="small">' + \
|
leader = '<div class="eleven columns">\n<h3>' + str(y['title']) + \
|
||||||
time.strftime("posted on %Y-%m-%d at %I:%M %p",
|
'</h3>\n<p class="small">' + \
|
||||||
time.localtime(float(md.Meta['date'][0]))) + '</p>'
|
time.strftime("posted on %Y-%m-%d at %I:%M %p", \
|
||||||
|
time.localtime(float(y['date']))) + '</p></div>'
|
||||||
|
|
||||||
gal_page.body = leader + description + images
|
gal_page.body = leader + description + images
|
||||||
|
|
||||||
gal_page.title = str(md.Meta['title'][0]) + ' | ' + gal_page.title
|
gal_page.title = str(y['title']) + ' | ' + gal_page.title
|
||||||
|
|
||||||
f = open(build_folder + '/' + conf['galleries_folder'] + '/' + name + '/index.htm', 'w')
|
f = open(build_folder + '/' + conf['galleries_folder'] + '/' + name + '/index.htm', 'w')
|
||||||
f.writelines(gal_page.formatted())
|
f.writelines(gal_page.formatted())
|
||||||
|
@ -1256,7 +1260,101 @@ def crunch_gallery_all():
|
||||||
for dir in [x[0] for x in os.walk(galleries_folder)]:
|
for dir in [x[0] for x in os.walk(galleries_folder)]:
|
||||||
if not re.search(conf['galleries_folder'] + '$', dir):
|
if not re.search(conf['galleries_folder'] + '$', dir):
|
||||||
crunch_gallery(os.path.basename(dir))
|
crunch_gallery(os.path.basename(dir))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Combine and minify CSS and JS.
|
||||||
|
def crunch_extras():
|
||||||
|
if args.verbose: print 'Combining and minifying stylesheets and scripts.'
|
||||||
|
|
||||||
|
# Make some empty variables to put the minified content in.
|
||||||
|
css_min = []
|
||||||
|
js_min = []
|
||||||
|
|
||||||
|
# Iterate through the css files.
|
||||||
|
for file in sorted(os.listdir(css_folder)):
|
||||||
|
|
||||||
|
# Ignore excluded files.
|
||||||
|
if not file.startswith('_'):
|
||||||
|
|
||||||
|
# Only Process all the non-minified CSS files.
|
||||||
|
if file.endswith('.css') and not file.endswith('.min.css'):
|
||||||
|
|
||||||
|
# Read the file into a tmp var.
|
||||||
|
tmp = open(css_folder + '/' + file).read()
|
||||||
|
|
||||||
|
# Kill all the comments.
|
||||||
|
tmp = re.sub( r'/\*[\s\S]*?\*/', '', tmp)
|
||||||
|
|
||||||
|
# Minimize the whitespace.
|
||||||
|
tmp = ' '.join(tmp.split())
|
||||||
|
|
||||||
|
# Add it to the new file.
|
||||||
|
css_min.append(tmp)
|
||||||
|
|
||||||
|
# If the file is minified, we still want it but don't want to waste time.
|
||||||
|
if file.endswith('.min.css'):
|
||||||
|
css_min.append(open(css_folder + '/' + file).read())
|
||||||
|
|
||||||
|
# If the file is excluded just copy it over.
|
||||||
|
if file.startswith('_'):
|
||||||
|
shutil.copy2(css_folder + '/' + file, build_folder + '/' + \
|
||||||
|
conf['css_folder'] + '/' + file.lstrip('_'))
|
||||||
|
|
||||||
|
# Write out our new minified CSS file.
|
||||||
|
f = open(build_folder + '/' + conf['css_folder'] + '/app.css', 'w')
|
||||||
|
f.writelines(''.join(css_min))
|
||||||
|
f.close
|
||||||
|
os.chmod(build_folder + '/' + conf['css_folder'] + '/app.css', 0644)
|
||||||
|
|
||||||
|
# Iterate through JS files.
|
||||||
|
for file in sorted(os.listdir(scripts_folder)):
|
||||||
|
|
||||||
|
# Ignore excluded files.
|
||||||
|
if not file.startswith('_'):
|
||||||
|
|
||||||
|
# Only bother with JS files and ignore pre-minified ones.
|
||||||
|
if file.endswith('.js') and not file.endswith('.min.js'):
|
||||||
|
# Read the file into a tmp var.
|
||||||
|
for line in open(scripts_folder + '/' + file).readlines():
|
||||||
|
|
||||||
|
# Ignore comments lines.
|
||||||
|
if not re.match('//', line) and not re.match('\s+//', line):
|
||||||
|
|
||||||
|
# minimize whitespace
|
||||||
|
line = ' '.join(line.split())
|
||||||
|
|
||||||
|
# add the minimized js to the new file
|
||||||
|
js_min.append(line)
|
||||||
|
|
||||||
|
# Kill all the comments.
|
||||||
|
#tmp = re.sub( r'\/\*.+?\*\/|\/\/.*(?=[\n\r])', "", tmp)
|
||||||
|
|
||||||
|
# Minimize the whitespace. Can't eliminate as some is critical.
|
||||||
|
# Cannot be used unless comments are removed.
|
||||||
|
#tmp = re.sub(r'\s+', ' ', tmp)
|
||||||
|
|
||||||
|
#js_min.append(tmp)
|
||||||
|
|
||||||
|
# Included the minified js file, but don't process it.
|
||||||
|
if file.endswith('.min.js'):
|
||||||
|
js_min.append(open(scripts_folder + '/' + file).read())
|
||||||
|
|
||||||
|
# Copy excluded files straight over with no changes.
|
||||||
|
if file.startswith('_'):
|
||||||
|
shutil.copy2(scripts_folder + '/' + file, build_folder + '/' + \
|
||||||
|
conf['scripts_folder'] + '/' + file.lstrip('_'))
|
||||||
|
|
||||||
|
# Write out our new minified JS file.
|
||||||
|
f = open(build_folder + '/' + conf['scripts_folder'] + '/app.js', 'w')
|
||||||
|
f.writelines(''.join(js_min))
|
||||||
|
f.close
|
||||||
|
os.chmod(build_folder + '/' + conf['scripts_folder'] + '/app.js', 0644)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
##########################################################################################
|
##########################################################################################
|
||||||
### Party Time.
|
### Party Time.
|
||||||
|
@ -1296,7 +1394,7 @@ def main():
|
||||||
|
|
||||||
# Re-process everything.
|
# Re-process everything.
|
||||||
if args.all:
|
if args.all:
|
||||||
if args.verbose: print 'Building it all.'
|
if args.verbose: print 'Building all the things.'
|
||||||
# Make sure we have a build folder to use.
|
# Make sure we have a build folder to use.
|
||||||
ensure_build_folder()
|
ensure_build_folder()
|
||||||
|
|
||||||
|
@ -1318,12 +1416,15 @@ def main():
|
||||||
# Rebuild the feed.
|
# Rebuild the feed.
|
||||||
crunch_feed()
|
crunch_feed()
|
||||||
|
|
||||||
|
# Rebuild the extras.
|
||||||
|
crunch_extras()
|
||||||
|
|
||||||
# Build the galleries.
|
# Build the galleries.
|
||||||
crunch_gallery_all()
|
crunch_gallery_all()
|
||||||
|
|
||||||
# We're going to do a partial rebuild.
|
# We're going to do a partial rebuild.
|
||||||
elif args.posts or args.home or args.indexes or args.feed or args.galleries or \
|
elif args.posts or args.home or args.indexes or args.feed or args.galleries or \
|
||||||
args.pages:
|
args.pages or args.extras:
|
||||||
|
|
||||||
ensure_build_folder()
|
ensure_build_folder()
|
||||||
|
|
||||||
|
@ -1353,6 +1454,10 @@ def main():
|
||||||
if args.feed:
|
if args.feed:
|
||||||
crunch_feed()
|
crunch_feed()
|
||||||
|
|
||||||
|
# Build the extras if the --extras flag is set.
|
||||||
|
if args.extras:
|
||||||
|
crunch_extras()
|
||||||
|
|
||||||
# Build the galleries if the --galleries flag is set.
|
# Build the galleries if the --galleries flag is set.
|
||||||
if args.galleries:
|
if args.galleries:
|
||||||
crunch_gallery_all()
|
crunch_gallery_all()
|
||||||
|
@ -1398,7 +1503,7 @@ def main():
|
||||||
server = SocketServer.TCPServer(("", conf['server_port']), handler)
|
server = SocketServer.TCPServer(("", conf['server_port']), handler)
|
||||||
except:
|
except:
|
||||||
print "Port occupied... Retrying."
|
print "Port occupied... Retrying."
|
||||||
time.sleep(10)
|
time.sleep(5)
|
||||||
|
|
||||||
# Change to the build folder.
|
# Change to the build folder.
|
||||||
os.chdir(build_folder)
|
os.chdir(build_folder)
|
Loading…
Reference in a new issue