require 'set' IGNORED_PAGES = Set['sitemap.xml'] LANGS = Set['en', 'pt', 'fr', 'eo'] # jp zh es de TRACKERS = '-a udp://tracker.coppersurfer.tk:6969/announce -a udp://tracker.ccc.de:80/announce -a udp://tracker.publicbt.com:80 -a udp://tracker.istole.it:80 -a http://tracker.openbittorrent.com:80/announce -a http://tracker.ipv6tracker.org:80/announce' module Jekyll class Linter < Generator safe true @@known_ids = Set[] def insert_id(name, document) lang = document.data['lang'] ref = document.data['ref'] id = "#{name}:#{lang}:#{ref}" if @@known_ids.include? id then raise "Duplicate ID found: '#{id}'" else @@known_ids.add id end end def assert_unique_ids(site) site.collections.each do |name, collection| collection.docs.each do |document| insert_id name, document end end site.pages.each do |page| unless IGNORED_PAGES.include? page.path insert_id 'page', page end end end def slugify(s) s.ljust(100) .gsub(/[\W]+/, ' ') .strip .gsub(/\s\s+/, '-') .downcase .gsub(' ', '-') .gsub('_', '-') end def assert(value, message) unless value raise message end value end def assert_field(document, field) f = document.data[field] raise "Undefined '#{field}' for #{document.path}" unless f f end COLLECTION_LAYOUTS = { 'page' => 'page', 'articles' => 'post', 'pastebins' => 'post', 'tils' => 'post', 'slides' => 'slides', 'podcasts' => 'cast', 'screencasts' => 'cast' } def assert_frontmatter_fields(site, name, document) title = assert_field document, 'title' lang = assert_field document, 'lang' ref = assert_field document, 'ref' layout = assert_field document, 'layout' date = document.date.strftime('%Y-%m-%d') unless layout == 'page' slug = layout == 'page' ? ref : assert_field(document, 'slug') extension = name == 'slides' ? 'slides' : 'md' unless LANGS.member? lang raise "Invalid lang '#{lang}' in #{document.path}" end if COLLECTION_LAYOUTS[name] != layout raise "Layout mismatch: expected '#{COLLECTION_LAYOUTS[name]}', got '#{layout}' for #{document.path}" end if lang == 'en' unless ['index', 'root', 'tils'].include? ref if slugify(title) != ref then raise "#{ref} isn't a slug of the title.\nref: '#{ref}'\ntitle slug: '#{slugify(title)}'" p slugify(title) end end end unless layout == 'page' then path = "_#{name}/#{date}-#{slug}.#{extension}" unless path == document.relative_path then raise "date/filename mismatch:\ndate+slug: #{path}\nfilename: #{document.relative_path}" end if lang == 'en' then unless ref == slug then raise "ref/slug mismatch:\nref: #{ref}\nslug: #{slug}" end end end if name == 'podcasts' then flac = "resources/podcasts/#{date}-#{slug}.flac" unless File.exist? flac then raise "Missing FLAC file '#{flac}'" end file = "#{date}-#{slug}.ogg" ogg = "resources/podcasts/#{date}-#{slug}.ogg" unless File.exist? ogg then puts "Missing '#{ogg}' file, generating..." puts `ffmpeg -i #{flac} -ar 48000 -vn -c:a libvorbis -b:a 320k #{ogg}` site.static_files << Jekyll::StaticFile.new(site, site.source, '', ogg) end torrent = "#{ogg}.torrent" unless File.exist? torrent then webseed = "#{site.config['url']}/#{ogg}" puts "Missing '#{torrent}' file, generating..." puts `mktorrent #{TRACKERS} -f -v -d -c '#{document.content}' -n #{file} -w #{webseed} -o #{torrent} #{ogg}` end end if name == 'screencasts' then mkv = "resources/screencasts/#{date}-#{slug}.mkv" unless File.exist? mkv then raise "Missing MKV file '#{mkv}'" end torrent = "#{mkv}.torrent" unless File.exist? torrent then webseed = "#{site.config['url']}/#{mkv}" file = "#{date}-#{slug}.mkv" puts "Missing '#{torrent}' file, generating..." puts `mktorrent #{TRACKERS} -f -v -d -c '#{document.content}' -n #{file} -w #{webseed} -o #{torrent} #{mkv}` end end end def assert_frontmatter(site) site.collections.each do |name, collection| collection.docs.each do |document| assert_frontmatter_fields site, name, document end end site.pages.each do |page| unless IGNORED_PAGES.include? page.path assert_frontmatter_fields site, 'page', page end end end def generate(site) assert_unique_ids(site) assert_frontmatter(site) end end end