# -*- mode: ruby; -*- # Stream of Conciousness v.1.0beta1 # rsayers@robsayers.com class StreamOfConsciousness attr_accessor :settings, :sideitems def initialize require 'cgi' require 'ftools' if RUBY_VERSION.to_f < 1.9 require 'erb' settings={} @pageno=1 @entries=[] @categories=[] @sideitems=[] @plugins=[] @templates={} @cgi=CGI.new @cgi.header @mode='' @path_info=[] @path_info=@cgi.path_info.to_s.split('/') @path_info.shift @path_info << '/' if @path_info.last.nil? if @path_info.last.match(/\d+$/) @pageno=@path_info.pop.to_i end @path_info << '/' if @path_info.last.nil? eval(File.read('blog.conf.rb')) if File.exists?('blog.conf.rb') if (settings.nil?) then @settings = { :blog_title => "Blog Title", # What's this blog's description (for outgoing RSS feed)? :blog_description => "A Stream of Consciousness Blog", # What's this blog's primary language (for outgoing RSS feed)? :blog_language => "en", # Where are this blog's entries kept? :datadir => "/home/username/blogdata", #What directory will static pages be served from? :pagedir => "/home/username/pagedata", :pagevar => "pages", # What's my preferred base URL for this blog (leave blank for automatic)? :url => "http://www.mysite.com", # How many entries should I show on the home page? :num_entries => 10, # What file extension signifies a blosxom entry? :file_extension => "txt", # What is the default flavour? :default_flavour => "html", :plugindir => "/home/username/plugins", :themedir => "/home/username/theme" } else @settings=settings end @templates[:header]=%( <%=@settings[:blog_title]%> <%=do_hook('html_head') %>
) @templates[:footer]=%(
) @templates[:sidebar]=%( <%unless @sideitems.nil? %> <% @sideitems.each do |item| %>

<%=item['title']%>

<%=item['content'].call %> <% end %> <% end %>) @templates[:rss]=%( <%=@settings[:blog_title]%> <%=@settings[:url]%> <%=@settings[:blog_description]%> <%=@entries.first.date%> Stream of Consciousness <% @entries.each do |post| %> <%= post.title %> <%= @settings[:url] %><%= post.category %>/<%= post.filename %> ]]> <%=post.date%> <%=@settings[:url]%><%=post.category%>/<%=post.filename%> <% end %> ) @templates[:layout]=%( <%=template :header%>

<%=block.call if block_given? %>
<%=template :footer%> ) @templates[:navigation]=%() @templates[:page]=%(
<%=@entry.body%>
) @templates[:entry]=%(
<%=@entry.date.strftime('%B %d %Y')%>
<%=@entry.body%>
Posted in <%=@entry.category%>

) @templates[:css]=%( * { font-family: Helvetica; } a { text-decoration: none; border-bottom: 1px dashed #929292;color:#929292; } body { padding-left: 10px; } #header { margin-bottom: 10px; width: 800px; border-top:5px solid black; background-color: #eeeeee} #left { width: 600px; float:left;} #content { width: 800px;} #right {float:right;text-align:center } #right ul { list-style: none; } #right ul li { background-color: #eeeeee;width:170px;margin-left:-50px; border-bottom:1px solid black;text-align:left; border-left:2px solid black; padding-left: 10px } #right ul li a { color: black; text-decoration:none; border-bottom: 0} .postbody { text-align: justify;font-size:11pt; font-family: times; letter-spacing: 1px; margin-bottom:10px; } #footer { clear: both; } #blogtitle { font-size: 18pt; font-weight:bold; } #blogsubtitle { clear:both; display:block; font-family:Times; font-style: italic} .title { font-weight: bold; float:left;} .date {float: right; color: #929292} .postbody{border-top: 2px solid #929292; clear:both;} .postfooter { text-align: center; margin-bottom:20px;font-weight:bold } #footer { text-align: center; width:800px; background-color:#eeeeee;border-bottom:5px solid black} #nav { text-align: center; margin-bottom:10px; } pre,code {width:500px;overflow:auto; font-family:courier; font-size:11pt;letter-spacing:0px; background-color:#eeeeee} hr { display:none}) load_plugins load_templates get_categories get_pages @numpages=1 # Default Side items, page and category lists if (File.exist?(@settings[:pagedir])) then @sideitems << {'title'=>'Pages','content'=>lambda{ r='' return r }} end @sideitems << {'title'=>'Categories','content'=>lambda{ r='' return r }} do_hook('sideitems') end def dispatch output='' if @path_info.last.match('.*\.xml$') then @mode='xml' @cgi.header('Content-type: text/xml') @path_info.pop get_entries @path_info.join('/') puts template :rss elsif @path_info[0]=='pages' @mode='page' get_page puts template(:layout) { @entry=@entries.first template(:page) } elsif @path_info.last.match('.*\.html$') then @mode='view' filename=@path_info.join('/') filename.gsub!('.html','.txt') if File.exist?(@settings[:datadir]+'/'+filename) then get_entry(filename) output='' @entry=@entries.first puts template(:layout) { output << do_hook("before_single_entry") output << template(:entry) output << do_hook("after_single_entry") output } else error "Error: the requested entry was not found" end else @mode='list' if File.exist?( @settings[:datadir]+'/'+@path_info.join('/') ) then get_entries @path_info.join('/') do_hook('before_list_entry') puts template(:layout) { @entries.each do |e| @entry=e output << template(:entry) end output << template(:navigation) output } else error "Error: the specified path was not found" end end end def load_plugins plugin_hook='' code=lambda{} return if !File.exist?(@settings[:plugindir]) Dir.chdir(@settings[:plugindir]) list=Dir.glob(File.join("**","*.rb")) list.each do |f| eval(File.read(@settings[:plugindir]+'/'+f)) @plugins << { :hook => plugin_hook, :code => code } end end def load_templates return if !File.exist?(@settings[:themedir]) Dir.chdir(@settings[:themedir]) list=Dir.glob(File.join("**","*.rhtml")) list.each do |f| name=f.gsub('.rhtml','').to_sym @templates[name]=File.read(@settings[:themedir]+'/'+f) end end def template(name,&block) tpl=ERB.new(@templates[name]) tpl.result(binding) end def do_hook(hook) @plugins.each do |p| if p[:hook]==hook then return p[:code].call end end "" end def get_entry(filename) @entries << load_entry(@settings[:datadir]+'/'+filename) end def get_page filename=@settings[:pagedir]+ '/' + @path_info.last filename.gsub!('.html','.txt') @entries << load_entry(filename) end def get_categories @categories=[] @categories << '/' Dir.chdir(@settings[:datadir]) list=Dir.glob(File.join("**","*")) list.each do |e| @categories << '/'+e if FileTest.directory?(@settings[:datadir] + '/' + e) end @categories.sort! end def get_pages @pages=[] if (File.exist?(@settings[:pagedir])) then Dir.chdir(@settings[:pagedir]) list=Dir.glob(File.join("**","*.txt")) list.each do |e| @pages << {'filename'=>e.gsub('.txt','.html'),'title'=>File.open(e).readline} end end end def error(msg) puts template(:layout) { msg } end def load_entry(filename) File.open(filename,"r:iso-8859-1:utf-8") do |f| title=f.readline body=f.read.gsub("\r","").gsub("\n","
") date=f.mtime category="page" category=get_cat_from_file(filename) if @mode != "page" tmp,filename=File.split(filename) Entry.new(title,body,date,category,filename) end end def get_cat_from_file(filename) fullpath=File.expand_path(filename) tmp,category=fullpath.split(@settings[:datadir]) category,file=File.split(category) category end def get_entries(category='/') begin Dir.chdir(@settings[:datadir] + '/' + category ) rescue end list=Dir.glob(File.join("**","*.#{@settings[:file_extension]}")) list.each do |post| @entries << load_entry(post) end @entries.sort! { |x,y| y.date <=> x.date } start = (@pageno.to_i * @settings[:num_entries].to_i) - @settings[:num_entries].to_i start = 0 if @pageno == 1 @numpages=(@entries.length.to_f / @settings[:num_entries].to_f).ceil @entries=@entries[start,@settings[:num_entries].to_i] do_hook('load_entries'); end end class Entry attr_accessor :title, :body, :date, :category, :filename def initialize(title,body,date,category,filename) @title=title @body=body @date=date @category=category @filename=filename.gsub('.txt','.html') end end settings={} blog=StreamOfConsciousness.new blog.dispatch