Skip to content

Commit

Permalink
First version
Browse files Browse the repository at this point in the history
  • Loading branch information
judofyr committed Oct 3, 2010
0 parents commit ec1fcc9
Show file tree
Hide file tree
Showing 12 changed files with 367 additions and 0 deletions.
13 changes: 13 additions & 0 deletions Gemfile
@@ -0,0 +1,13 @@
source "http://rubygems.org/"

# Framework
gem "camping"

# Template engine
gem "tilt"
gem "haml"

# Maruku for content
gem "maruku"
gem "ultraviolet"

2 changes: 2 additions & 0 deletions config.ru
@@ -0,0 +1,2 @@
require 'timeless'
run Timeless
45 changes: 45 additions & 0 deletions maruku-uv.rb
@@ -0,0 +1,45 @@
require 'uv'
require 'maruku'

module MaRuKu::Out::HTML
def to_html_code;
source = self.raw_code
lang = self.attributes[:lang] || @doc.attributes[:code_lang]
lang = 'xml' if lang=='html'

use_syntax = get_setting :html_use_syntax

element =
if lang
begin
# eliminate trailing newlines otherwise Syntax crashes
source = source.gsub(/\n*\Z/,'')

html = Uv.parse(source, "xhtml", lang, false, "idle")
html = html.gsub(/\'/,''') # IE bug
html = html.gsub(/'/,''') # IE bug

code = Document.new(html, {:respect_whitespace =>:all}).root
code.name = 'code'
code.attributes['class'] = lang
code.attributes['lang'] = lang

pre = Element.new 'pre'
pre << code
pre
rescue Object => e
maruku_error"Error while using the syntax library for code:\n#{source.inspect}"+
"Lang is #{lang} object is: \n"+
self.inspect +
"\nException: #{e.class}: #{e.message}\n\t#{e.backtrace.join("\n\t")}"

tell_user("Using normal PRE because the syntax library did not work.")
to_html_code_using_pre(source)
end
else
to_html_code_using_pre(source)
end

add_ws element
end
end
108 changes: 108 additions & 0 deletions timeless.rb
@@ -0,0 +1,108 @@
require 'bundler'
Bundler.setup

require 'yaml'
require 'time'

require 'camping'
require 'tilt'
require 'haml'
require 'maruku'
require './maruku-uv'

Camping.goes :Timeless

require './timeless/models/entry'
require './timeless/models/change'

class NotFound < StandardError; end

module Timeless
set :views, File.dirname(__FILE__) + '/timeless/views'
set :dynamic_templates, true

set :haml, {
:format => :html5,
:escape_html => true,
:ugly => true
}

def service(*a)
super
rescue NotFound
@status = 404
@method = :r404
super(@env["PATH_INFO"])
end
end

module Timeless::Controllers
class Index
def get
@change = Change.last
render :index
end

def main_class; "frontpage" end
end

class Stylesheet < R '/style\.css'
def get
@headers['Content-Type'] = "text/css"
File.read("public/style.css")
end
end

class Changelog < R '/changelog'
def get
@changes = Change.all
render :changes
end
end

class ChangelogN
def get(id)
@change = Change.new(id)
case @change.type
when :entry
redirect(Entry, @change.entry)
when :text
render :layout, :layout => false do
render :_change, :locals => { :change => @change }
end
end
end
end

class Feed < R '/changelog\.xml'
def get
@headers['Content-Type'] = 'text/xml'
@changes = Change.all.reject { |c| c["feed"] == false }
render :feed, :layout => false
end
end

class Entry < R '/(.+?)'
def get(name)
@entry = Models::Entry.new(name)

if @entry.file?
@headers['Content-Type'] = Rack::Mime.mime_type(File.extname(@entry.name))
@entry.to_html
else
render :entry
end
end
end
end

module Timeless::Helpers
def main_class; false end

def entry_index
entries = Timeless::Models::Entry.all.reject { |e| e.file? }
half = entries.size / 2
[entries[0...half], entries[half..-1]]
end
end

50 changes: 50 additions & 0 deletions timeless/models/change.rb
@@ -0,0 +1,50 @@
module Timeless::Models
class Change
attr_reader :id

def self.last
new(Dir["changes/*.yaml"].sort.last[/\d+/])
end

def self.all(options = {})
limit = (options[:limit] || 0) - 1
Dir["changes/*.yaml"].sort.reverse[0..limit].map { |c| new(c[/\d+/]) }
end

def initialize(id)
@id = id.to_i
raise NotFound unless exists?
end

def filename; "changes/#{@id}.yaml"; end
def exists?; File.exists?(filename) end

def content
@content ||= YAML.load_file(filename)
end

def [](key); content[key.to_s]; end
def created_at; Time.parse(self["created_at"]) end

def type
content.has_key?("entry") ? :entry : :text
end

def title
type == :entry ? entry.title : content["title"]
end

def to_html
type == :entry ? entry.to_snip : Maruku.new(content["text"]).to_html
end

def url
type == :entry ? "/#{entry.name}" : "/changelog/#{@id}"
end

def entry
@entry ||= Entry.new(content["entry"])
end
end
end

54 changes: 54 additions & 0 deletions timeless/models/entry.rb
@@ -0,0 +1,54 @@
module Timeless::Models
class Entry
attr_reader :name

def self.all
entries.map { |name| new(name) }
end

def self.entries
Dir["content/*"].reject { |f| f =~ /~/ }.map { |f| File.basename(f) }
end

def initialize(name)
@name = name
raise NotFound unless exists?
end

def to_param; @name end
def <=>(o); title <=> o.title end
def filename; "content/#{@name}" end
def file?; @name.include?(".") end
def exists?; File.exists?(filename) end

def to_html
file? ? content : maruku.to_html
end

def title
file? ? @name : maruku.get_setting(:title) || @name
end

def subtitle
file? ? "" : maruku.get_setting(:subtitle) || ""
end

def to_snip
Maruku.new(content(true)).to_html
end

def content(snip = false)
content = File.read(filename)
if snip
content =~ /\(snip\)/
$` || content
else
content.gsub('(snip)', '')
end
end

def maruku
@maruku ||= Maruku.new(content)
end
end
end
9 changes: 9 additions & 0 deletions timeless/views/_change.haml
@@ -0,0 +1,9 @@
%article
%header
%h1
%a{:href => change.url}= change.title

!= change.to_html
- if change.type == :entry
%p
%a{:href => change.url} Continue to full post.
7 changes: 7 additions & 0 deletions timeless/views/changes.haml
@@ -0,0 +1,7 @@
%header
%h1 Recent Changes

%div(class="changelog")
- @changes.each do |change|
!= render :_change, :locals => { :change => change }

4 changes: 4 additions & 0 deletions timeless/views/entry.haml
@@ -0,0 +1,4 @@
%header
%h1= @entry.title

%p!= @entry.to_html
25 changes: 25 additions & 0 deletions timeless/views/feed.erb
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>Magnus Holm's timeless repository</title>
<subtitle>Thoughts on life, internet and programming</subtitle>
<id>tag:judofyr.net,1992-10-15:/</id>
<link rel="self" type="application/atom+xml" href="http://timeless.judofyr.net/changelog.xml"/>
<link rel="alternate" type="text/html" href="http://timeless.judofyr.net/"/>
<updated><%= Time.now.xmlschema %></updated>
<author>
<name>Magnus Holm</name>
<email>judofyr@gmail.com</email>
<uri>http://judofyr.net</uri>
</author>
<% @changes.each do |change|;c=change.created_at.utc %>
<entry>
<title><%= change.title %></title>
<id>tag:timeless.judofyr.net,<%=c.xmlschema[0..9]%>:<%=c.to_i%></id>
<link href="http://timeless.judofyr.net<%= change.url %>"/>
<updated><%= c.xmlschema %></updated>
<published><%= c.xmlschema %></published>
<content type="html"><![CDATA[<%= change.to_html %>]]></content>
</entry>
<% end %>
</feed>

28 changes: 28 additions & 0 deletions timeless/views/index.haml
@@ -0,0 +1,28 @@
%div(class="changelog")
!= render :_change, :locals => { :change => @change }

%hr

%p(class="front-buttons")
%a(href="http://feeds.feedburner.com/MagnusHolm" class="d") Subscribe to the feed
%a(href="/timeless" class="a") What kind of blog is this really?
%a(href="#index" class="b") Check out all the articles below &darr;
%a(href="/changelog" class="c") Have a look at the recent changes
%div(style="clear:both")
%p(style="clear:both")

%hr

%h2 All articles

%nav(class="index" id="index")
- entry_index.each do |entries|
%div(class="column")
%ul
- entries.each do |entry|
%li
%a{:href => R(Entry, entry)}
= entry.title
%p= entry.subtitle
%div(style="clear:both")

22 changes: 22 additions & 0 deletions timeless/views/layout.haml
@@ -0,0 +1,22 @@
!!!
%head
%meta(charset="utf-8")
%title Timeless from Magnus Holm
%link{:rel => "stylesheet", :href => R(Stylesheet)}

%body(class=main_class)
%header(class="main")
%h1
%a{:href => R(Index)}
Magnus Holm's <strong>timeless</strong> repository

%article
!= yield

%footer
%p
2010 ©
%a(href="mailto:judofyr@gmail.com") Magnus Holm
%a{:href => R(Entry, 'comments')} Leave a comment

0 comments on commit ec1fcc9

Please sign in to comment.