mirror of
https://github.com/samsonjs/samhuri.net.git
synced 2026-04-27 14:57:40 +00:00
update build & publish scripts
This commit is contained in:
parent
47cdd8509a
commit
b73a290903
5 changed files with 205 additions and 211 deletions
24
Makefile
24
Makefile
|
|
@ -1,21 +1,27 @@
|
||||||
JSON=harp.json $(shell echo public/*.json) $(shell echo public/*/*.json)
|
|
||||||
EJS=$(shell echo public/*.ejs) $(shell echo public/*/*.ejs)
|
|
||||||
JAVASCRIPTS=$(shell echo public/js/*.js)
|
|
||||||
STYLESHEETS=$(shell echo public/css/*.css)
|
|
||||||
POSTS=$(shell echo public/posts/*.html) $(shell echo public/posts/*.md)
|
|
||||||
|
|
||||||
all: compile
|
all: compile
|
||||||
|
|
||||||
compile: posts
|
compile: posts
|
||||||
@echo
|
@echo
|
||||||
./bin/compile.sh
|
./bin/compile.sh
|
||||||
|
|
||||||
posts: $(POSTS)
|
posts:
|
||||||
@echo
|
@echo
|
||||||
./bin/posts.rb public public
|
./bin/posts.rb public public
|
||||||
|
|
||||||
publish: compile
|
publish: compile
|
||||||
@echo
|
@echo
|
||||||
./bin/publish.sh --delete public/
|
./bin/publish.sh www/.htaccess
|
||||||
|
./bin/publish.sh www/favicon.ico
|
||||||
|
./bin/publish.sh www/feed.xml
|
||||||
|
./bin/publish.sh www/*.html
|
||||||
|
./bin/publish.sh www/*.png
|
||||||
|
./bin/publish.sh www/f/
|
||||||
|
./bin/publish.sh --delete www/Chalk
|
||||||
|
./bin/publish.sh --delete www/css
|
||||||
|
./bin/publish.sh --delete www/images
|
||||||
|
./bin/publish.sh --delete www/js
|
||||||
|
./bin/publish.sh --delete www/posts
|
||||||
|
./bin/publish.sh --delete www/projects
|
||||||
|
./bin/publish.sh --delete www/tweets
|
||||||
|
|
||||||
.PHONY: publish
|
.PHONY: compile publish
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,11 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
harp compile public public
|
bin/rss.rb public
|
||||||
|
|
||||||
for FILENAME in public/posts/*.html public/projects/*.html; do
|
mkdir -p www
|
||||||
|
harp compile public www
|
||||||
|
|
||||||
|
for FILENAME in www/*.html www/posts/*.html www/projects/*.html; do
|
||||||
[[ "$FILENAME" = "index.html" ]] && continue
|
[[ "$FILENAME" = "index.html" ]] && continue
|
||||||
|
|
||||||
DIRNAME="${FILENAME%.html}"
|
DIRNAME="${FILENAME%.html}"
|
||||||
|
|
|
||||||
188
bin/posts.rb
188
bin/posts.rb
|
|
@ -1,188 +0,0 @@
|
||||||
#!/usr/bin/env ruby
|
|
||||||
# encoding: utf-8
|
|
||||||
|
|
||||||
require 'time'
|
|
||||||
require 'rubygems'
|
|
||||||
require 'bundler/setup'
|
|
||||||
require 'builder'
|
|
||||||
require 'json'
|
|
||||||
require 'rdiscount'
|
|
||||||
require 'mustache'
|
|
||||||
|
|
||||||
DEFAULT_KEYWORDS = %w[samsonjs sjs sami samhuri sami samhuri samhuri.net]
|
|
||||||
|
|
||||||
def main
|
|
||||||
srcdir = ARGV.shift.to_s
|
|
||||||
destdir = ARGV.shift.to_s
|
|
||||||
Dir.mkdir(destdir) unless File.exists?(destdir)
|
|
||||||
unless File.directory? srcdir
|
|
||||||
puts 'usage: blog.rb <source dir> <dest dir>'
|
|
||||||
exit 1
|
|
||||||
end
|
|
||||||
b = Blag.new srcdir, destdir
|
|
||||||
puts 'title: ' + b.title
|
|
||||||
puts 'subtitle: ' + b.subtitle
|
|
||||||
puts 'url: ' + b.url
|
|
||||||
puts "#{b.posts.size} posts"
|
|
||||||
b.generate!
|
|
||||||
puts 'done blog'
|
|
||||||
end
|
|
||||||
|
|
||||||
class Blag
|
|
||||||
attr_accessor :title, :subtitle, :url
|
|
||||||
|
|
||||||
def self.go! src, dest
|
|
||||||
self.new(src, dest).generate!
|
|
||||||
end
|
|
||||||
|
|
||||||
def initialize src, dest
|
|
||||||
@src = src
|
|
||||||
@dest = dest
|
|
||||||
read_blog
|
|
||||||
end
|
|
||||||
|
|
||||||
def generate!
|
|
||||||
generate_posts_json
|
|
||||||
generate_rss
|
|
||||||
end
|
|
||||||
|
|
||||||
def generate_posts_json
|
|
||||||
posts_data = posts.reverse.inject({}) do |all, p|
|
|
||||||
all[p[:slug]] = {
|
|
||||||
title: p[:title],
|
|
||||||
date: p[:date],
|
|
||||||
timestamp: p[:timestamp],
|
|
||||||
tags: p[:tags],
|
|
||||||
author: p[:author],
|
|
||||||
url: p[:relative_url],
|
|
||||||
link: p[:link],
|
|
||||||
styles: p[:styles]
|
|
||||||
}.delete_if { |k, v| v.nil? }
|
|
||||||
|
|
||||||
all
|
|
||||||
end
|
|
||||||
json = JSON.pretty_generate posts_data
|
|
||||||
filename = File.join @dest, 'posts', '_data.json'
|
|
||||||
File.open(filename, 'w') { |f| f.puts json }
|
|
||||||
|
|
||||||
filename = File.join @dest, '_data.json'
|
|
||||||
data = JSON.parse File.read(filename)
|
|
||||||
post = latest_post
|
|
||||||
data['latest'] = posts_data[post[:slug]].merge('body' => post[:body])
|
|
||||||
json = JSON.pretty_generate data
|
|
||||||
File.open(filename, 'w') { |f| f.puts json }
|
|
||||||
end
|
|
||||||
|
|
||||||
def generate_rss
|
|
||||||
# posts rss
|
|
||||||
File.open(rss_file, 'w') { |f| f.puts rss_for_posts.target! }
|
|
||||||
end
|
|
||||||
|
|
||||||
def latest_post
|
|
||||||
posts.first
|
|
||||||
end
|
|
||||||
|
|
||||||
def posts
|
|
||||||
prefix = @src + '/posts/'
|
|
||||||
@posts ||= Dir[File.join(prefix, '*')].sort.reverse.map do |filename|
|
|
||||||
next if File.directory?(filename) || filename =~ /_data\.json/
|
|
||||||
|
|
||||||
lines = File.readlines filename
|
|
||||||
post = {
|
|
||||||
slug: filename.sub(prefix, '').sub(/\.(html|md)$/i, '')
|
|
||||||
}
|
|
||||||
loop do
|
|
||||||
line = lines.shift.strip
|
|
||||||
m = line.match /^(\w+):/
|
|
||||||
if m && param = m[1].downcase
|
|
||||||
post[param.to_sym] = line.sub(Regexp.new('^' + param + ':\s*', 'i'), '').strip
|
|
||||||
elsif line.match /^----\s*$/
|
|
||||||
lines.shift while lines.first.strip.empty?
|
|
||||||
break
|
|
||||||
else
|
|
||||||
puts "ignoring unknown header: #{line}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if post[:styles]
|
|
||||||
post[:styles] = post[:styles].split(/\s*,\s*/)
|
|
||||||
end
|
|
||||||
post[:type] = post[:link] ? :link : :post
|
|
||||||
post[:title] += " →" if post[:type] == :link
|
|
||||||
post[:tags] = (post[:tags] || '').split(/\s*,\s*/)
|
|
||||||
post[:relative_url] = '/posts/' + post[:slug]
|
|
||||||
post[:url] = @url + post[:relative_url]
|
|
||||||
post[:timestamp] = post[:timestamp].to_i
|
|
||||||
post[:content] = lines.join
|
|
||||||
post[:body] = RDiscount.new(post[:content], :smart).to_html
|
|
||||||
post[:rfc822] = Time.at(post[:timestamp]).rfc822
|
|
||||||
post
|
|
||||||
end.compact.sort { |a, b| b[:timestamp] <=> a[:timestamp] }
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def blog_file
|
|
||||||
File.join(@src, '_data.json')
|
|
||||||
end
|
|
||||||
|
|
||||||
def read_blog
|
|
||||||
blog = JSON.parse(File.read(blog_file))
|
|
||||||
@title = blog['title']
|
|
||||||
@subtitle = blog['subtitle']
|
|
||||||
@url = blog['url']
|
|
||||||
end
|
|
||||||
|
|
||||||
def rss_template(type)
|
|
||||||
if type == :post
|
|
||||||
@post_rss_template ||= File.read(File.join('templates', 'post.rss.html'))
|
|
||||||
elsif type == :link
|
|
||||||
@link_rss_template ||= File.read(File.join('templates', 'link.rss.html'))
|
|
||||||
else
|
|
||||||
raise 'unknown post type: ' + type
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def rss_file
|
|
||||||
File.join @dest, 'sjs.rss'
|
|
||||||
end
|
|
||||||
|
|
||||||
def rss_html post
|
|
||||||
Mustache.render rss_template(post[:type]), post: post
|
|
||||||
end
|
|
||||||
|
|
||||||
def rss_for_posts options = {}
|
|
||||||
title = options[:title] || @title
|
|
||||||
subtitle = options[:subtitle] || @subtitle
|
|
||||||
url = options[:url] || @url
|
|
||||||
rss_posts ||= options[:posts] || posts[0, 10]
|
|
||||||
|
|
||||||
xml = Builder::XmlMarkup.new
|
|
||||||
xml.instruct! :xml, :version => '1.0'
|
|
||||||
xml.instruct! 'xml-stylesheet', :href => 'http://samhuri.net/css/style.css', :type => 'text/css'
|
|
||||||
|
|
||||||
xml.rss :version => '2.0' do
|
|
||||||
xml.channel do
|
|
||||||
xml.title title
|
|
||||||
xml.description subtitle
|
|
||||||
xml.link url
|
|
||||||
xml.pubDate posts.first[:rfc822]
|
|
||||||
|
|
||||||
rss_posts.each do |post|
|
|
||||||
xml.item do
|
|
||||||
xml.title post[:title]
|
|
||||||
xml.description rss_html(post)
|
|
||||||
xml.pubDate post[:rfc822]
|
|
||||||
xml.author post[:author]
|
|
||||||
xml.link post[:link] || post[:url]
|
|
||||||
xml.guid post[:url]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
xml
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
main if $0 == __FILE__
|
|
||||||
|
|
@ -8,20 +8,40 @@ bail() {
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
publish_host=samhuri.net
|
publish_host="samhuri.net"
|
||||||
publish_dir=samhuri.net/public/
|
publish_dir="samhuri.net/public/"
|
||||||
|
prefix=""
|
||||||
|
delete=""
|
||||||
|
|
||||||
# test
|
break_while=0
|
||||||
if [[ "$1" = "-t" ]]; then
|
while [[ $# > 1 ]]; do
|
||||||
prefix=echo
|
|
||||||
shift
|
|
||||||
fi
|
|
||||||
|
|
||||||
# --delete, passed to rsync
|
arg="$1"
|
||||||
if [[ "$1" = "--delete" ]]; then
|
|
||||||
delete="--delete"
|
case "$arg" in
|
||||||
shift
|
|
||||||
fi
|
-t|--test)
|
||||||
|
prefix=echo
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
|
||||||
|
-d|--delete)
|
||||||
|
# passed to rsync
|
||||||
|
delete="--delete"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
|
||||||
|
# we're at the paths, no more options
|
||||||
|
*)
|
||||||
|
break_while=1
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
|
||||||
|
esac
|
||||||
|
|
||||||
|
[[ $break_while -eq 1 ]] && break
|
||||||
|
|
||||||
|
done
|
||||||
|
|
||||||
if [[ $# -eq 0 ]]; then
|
if [[ $# -eq 0 ]]; then
|
||||||
if [[ "$delete" != "" ]]; then
|
if [[ "$delete" != "" ]]; then
|
||||||
|
|
|
||||||
153
bin/rss.rb
Executable file
153
bin/rss.rb
Executable file
|
|
@ -0,0 +1,153 @@
|
||||||
|
#!/usr/bin/env ruby
|
||||||
|
# encoding: utf-8
|
||||||
|
|
||||||
|
require 'time'
|
||||||
|
require 'rubygems'
|
||||||
|
require 'bundler/setup'
|
||||||
|
require 'builder'
|
||||||
|
require 'json'
|
||||||
|
require 'rdiscount'
|
||||||
|
require 'mustache'
|
||||||
|
|
||||||
|
def main
|
||||||
|
dir = ARGV.shift.to_s
|
||||||
|
unless File.directory? dir
|
||||||
|
puts 'usage: rss.rb <dir>'
|
||||||
|
exit 1
|
||||||
|
end
|
||||||
|
b = Blag.new dir
|
||||||
|
b.generate!
|
||||||
|
end
|
||||||
|
|
||||||
|
class Blag
|
||||||
|
|
||||||
|
def self.go! dir
|
||||||
|
self.new(dir).generate!
|
||||||
|
end
|
||||||
|
|
||||||
|
def initialize dir
|
||||||
|
@dir = dir
|
||||||
|
end
|
||||||
|
|
||||||
|
def generate!
|
||||||
|
generate_latest_post_json
|
||||||
|
generate_rss
|
||||||
|
end
|
||||||
|
|
||||||
|
def generate_latest_post_json
|
||||||
|
post = latest_post
|
||||||
|
data['latest'] = {
|
||||||
|
title: post['title'],
|
||||||
|
date: post['date'],
|
||||||
|
timestamp: post['timestamp'],
|
||||||
|
tags: post['tags'],
|
||||||
|
author: post['author'],
|
||||||
|
url: post['relative_url'],
|
||||||
|
link: post['link'],
|
||||||
|
styles: post['styles'],
|
||||||
|
body: post['body']
|
||||||
|
}.delete_if { |k, v| v.nil? }
|
||||||
|
json = JSON.pretty_generate data
|
||||||
|
File.open(data_file, 'w') { |f| f.puts json }
|
||||||
|
end
|
||||||
|
|
||||||
|
def generate_rss
|
||||||
|
File.open(rss_file, 'w') { |f| f.puts feed_xml.target! }
|
||||||
|
end
|
||||||
|
|
||||||
|
def latest_post
|
||||||
|
posts.first
|
||||||
|
end
|
||||||
|
|
||||||
|
def posts
|
||||||
|
@posts ||= begin
|
||||||
|
prefix = @dir + '/posts/'
|
||||||
|
json = File.read File.join(prefix, '_data.json')
|
||||||
|
data = JSON.parse json
|
||||||
|
data.map do |slug, post|
|
||||||
|
filename = File.join prefix, slug + '.md'
|
||||||
|
content = File.read filename
|
||||||
|
post['slug'] = slug
|
||||||
|
post['type'] = post['link'] ? :link : :post
|
||||||
|
post['title'] += " →" if post['type'] == :link
|
||||||
|
post['relative_url'] = '/posts/' + slug
|
||||||
|
post['url'] = root_url + post['relative_url']
|
||||||
|
post['content'] = content
|
||||||
|
post['body'] = RDiscount.new(post['content'], :smart).to_html
|
||||||
|
post['rfc822'] = Time.at(post['timestamp']).rfc822
|
||||||
|
post
|
||||||
|
end.sort_by { |p| -p['timestamp'] }.first(10)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def title
|
||||||
|
data['title']
|
||||||
|
end
|
||||||
|
|
||||||
|
def subtitle
|
||||||
|
data['subtitle']
|
||||||
|
end
|
||||||
|
|
||||||
|
def root_url
|
||||||
|
data['url']
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def data_file
|
||||||
|
File.join @dir, '_data.json'
|
||||||
|
end
|
||||||
|
|
||||||
|
def data
|
||||||
|
@data ||= JSON.parse File.read(data_file)
|
||||||
|
end
|
||||||
|
|
||||||
|
def rss_template(type)
|
||||||
|
if type == :post
|
||||||
|
@post_rss_template ||= File.read(File.join('templates', 'post.rss.html'))
|
||||||
|
elsif type == :link
|
||||||
|
@link_rss_template ||= File.read(File.join('templates', 'link.rss.html'))
|
||||||
|
else
|
||||||
|
raise 'unknown post type: ' + type
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def rss_file
|
||||||
|
File.join @dir, 'feed.xml'
|
||||||
|
end
|
||||||
|
|
||||||
|
def rss_html post
|
||||||
|
Mustache.render rss_template(post['type']), post: post
|
||||||
|
end
|
||||||
|
|
||||||
|
def feed_xml
|
||||||
|
xml = Builder::XmlMarkup.new
|
||||||
|
xml.instruct! :xml, version: '1.0'
|
||||||
|
xml.instruct! 'xml-stylesheet', href: 'http://samhuri.net/css/style.css', type: 'text/css'
|
||||||
|
|
||||||
|
xml.rss version: '2.0' do
|
||||||
|
xml.channel do
|
||||||
|
xml.title title
|
||||||
|
xml.description subtitle
|
||||||
|
xml.link root_url
|
||||||
|
xml.pubDate posts.first['rfc822']
|
||||||
|
|
||||||
|
posts.each do |post|
|
||||||
|
xml.item do
|
||||||
|
xml.title post['title']
|
||||||
|
xml.description rss_html(post)
|
||||||
|
xml.pubDate post['rfc822']
|
||||||
|
xml.author post['author']
|
||||||
|
xml.link post['link'] || post['url']
|
||||||
|
xml.guid post['url']
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
xml
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
main if $0 == __FILE__
|
||||||
Loading…
Reference in a new issue