parchemin 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +20 -0
- data/README.markdown +27 -0
- data/Rakefile +48 -0
- data/VERSION +1 -0
- data/app/public/images/feed-icon.gif +0 -0
- data/app/public/images/feed-icon.png +0 -0
- data/app/public/images/user.png +0 -0
- data/app/views/_base.sass +242 -0
- data/app/views/article_details.haml +7 -0
- data/app/views/index.haml +17 -0
- data/app/views/layout.haml +37 -0
- data/app/views/layout.sass +191 -0
- data/app/views/new_comment.haml +23 -0
- data/app/views/rss.builder +18 -0
- data/app/views/show.haml +24 -0
- data/app/views/static.haml +1 -0
- data/bin/parchemin +33 -0
- data/bin/templates/about.markdown +3 -0
- data/bin/templates/abstract.markdown +1 -0
- data/bin/templates/config.ru.haml +9 -0
- data/lib/parchemin/application.rb +73 -0
- data/lib/parchemin/config/compass.rb +15 -0
- data/lib/parchemin/config/config.rb +65 -0
- data/lib/parchemin/config/environment.rb +55 -0
- data/lib/parchemin/models/article.rb +95 -0
- data/lib/parchemin/models/comment.rb +18 -0
- data/lib/parchemin/models/static.rb +22 -0
- data/lib/parchemin.rb +16 -0
- data/spec/parchemin_spec.rb +139 -0
- data/spec/spec_helper.rb +22 -0
- metadata +225 -0
    
        data/bin/parchemin
    ADDED
    
    | @@ -0,0 +1,33 @@ | |
| 1 | 
            +
            #!/usr/bin/env ruby
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require 'haml'
         | 
| 4 | 
            +
            require 'fileutils'
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            #############################################
         | 
| 7 | 
            +
            # create the parchemin-based blog directory #
         | 
| 8 | 
            +
            #############################################
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            # The blog must be given a name
         | 
| 11 | 
            +
            unless ARGV.size == 2
         | 
| 12 | 
            +
              puts "Usage: parchemin BLOG_NAME AUTHOR_NAME"
         | 
| 13 | 
            +
              exit
         | 
| 14 | 
            +
            end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            blog_name = ARGV[0]
         | 
| 17 | 
            +
            author_name = ARGV[1]
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            # Create the directory structure
         | 
| 20 | 
            +
            Dir.mkdir(blog_name)
         | 
| 21 | 
            +
            Dir.mkdir("#{blog_name}/articles")
         | 
| 22 | 
            +
            Dir.mkdir("#{blog_name}/statics")
         | 
| 23 | 
            +
             | 
| 24 | 
            +
            # create the statics
         | 
| 25 | 
            +
            FileUtils.cp File.join(File.dirname(__FILE__), "templates/about.markdown"), "#{blog_name}/statics/about.markdown"
         | 
| 26 | 
            +
            FileUtils.cp File.join(File.dirname(__FILE__), "templates/abstract.markdown"), "#{blog_name}/statics/abstract.markdown"
         | 
| 27 | 
            +
             | 
| 28 | 
            +
            # Create the rack file
         | 
| 29 | 
            +
            template = File.read(File.join(File.dirname(__FILE__), "templates/config.ru.haml"))
         | 
| 30 | 
            +
            haml_engine = Haml::Engine.new(template)
         | 
| 31 | 
            +
            File.open("#{blog_name}/config.ru", 'w') do |f|
         | 
| 32 | 
            +
              f.write(haml_engine.render(Object.new, :blog_name => blog_name, :author_name => author_name, :dirname => `pwd`))
         | 
| 33 | 
            +
            end
         | 
| @@ -0,0 +1,3 @@ | |
| 1 | 
            +
            Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            Curae molestie ullamco felis proin tempor proident, nostra rutrum vitae varius in sapien. Facilisis nullam nam consectetuer netus blandit laboris nonummy nam dolor et, gravida ea ex volutpat non lectus imperdiet nascetur stevirota sociis. Fames velit nunc cupidatat viverra, imperdiet magnis nullam adipiscing imperdiet mi morbi. Vivamus nascetur litora dictumst ad proident facilisi, nullam eros ligula blandit elementum fugiat mollis leo semper. Incididunt etiam interdum eiusmod dolore non lobortis dictum magna odio est, suspendisse laoreet ex sint volutpat bibendum hac reprehenderit.
         | 
| @@ -0,0 +1 @@ | |
| 1 | 
            +
            Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
         | 
| @@ -0,0 +1,9 @@ | |
| 1 | 
            +
            require 'parchemin'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            Parchemin::Config.blog_name = "#{blog_name}"
         | 
| 4 | 
            +
            Parchemin::Config.author_name = "#{author_name}"
         | 
| 5 | 
            +
            Parchemin::Config.host = "www.#{blog_name}.com"
         | 
| 6 | 
            +
            Parchemin::Config.project_path = "#{dirname.strip}/#{blog_name}"
         | 
| 7 | 
            +
            Parchemin::Config.db_name = "#{blog_name}"
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            run Parchemin::Application
         | 
| @@ -0,0 +1,73 @@ | |
| 1 | 
            +
            # coding: utf-8
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require File.join(File.dirname(__FILE__), "config/config")
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            module Parchemin
         | 
| 6 | 
            +
              class Application < Sinatra::Base
         | 
| 7 | 
            +
                
         | 
| 8 | 
            +
                set :public, File.expand_path(File.join(File.dirname(__FILE__), "../../app/public"))
         | 
| 9 | 
            +
                set :views, File.expand_path(File.join(File.dirname(__FILE__), "../../app/views"))
         | 
| 10 | 
            +
                
         | 
| 11 | 
            +
                require File.join(File.dirname(__FILE__), "config/environment")
         | 
| 12 | 
            +
                
         | 
| 13 | 
            +
                before do
         | 
| 14 | 
            +
                  @blog_name = Parchemin::Config.blog_name
         | 
| 15 | 
            +
                  @author_name = Parchemin::Config.author_name
         | 
| 16 | 
            +
                  @abstract = Parchemin::Static.new('abstract')
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
                
         | 
| 19 | 
            +
                get '/:name.css' do
         | 
| 20 | 
            +
                  content_type 'text/css', :charset => 'utf-8'
         | 
| 21 | 
            +
                  sass(:"#{params[:name]}", Compass.sass_engine_options )
         | 
| 22 | 
            +
                end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                get '/' do
         | 
| 25 | 
            +
                  @articles = Parchemin::Article.all
         | 
| 26 | 
            +
                  haml :index
         | 
| 27 | 
            +
                end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                get '/articles/:article' do |filename|
         | 
| 30 | 
            +
                  @article = Parchemin::Article.new("#{Parchemin::Config.articles_path}/#{filename}.markdown")
         | 
| 31 | 
            +
                  @comments = @article.comments
         | 
| 32 | 
            +
                  @comment = Parchemin::Comment.new
         | 
| 33 | 
            +
                  haml :show
         | 
| 34 | 
            +
                end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                get '/tags/:tag' do |tag|
         | 
| 37 | 
            +
                  @tag = tag
         | 
| 38 | 
            +
                  @articles = Parchemin::Article.all(:tag => tag)
         | 
| 39 | 
            +
                  haml :index
         | 
| 40 | 
            +
                end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                get '/search' do
         | 
| 43 | 
            +
                  @search = params[:search]
         | 
| 44 | 
            +
                  @articles = Parchemin::Article.search(params[:search])
         | 
| 45 | 
            +
                  haml :index
         | 
| 46 | 
            +
                end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                get '/statics/:static' do |static|
         | 
| 49 | 
            +
                  @static = Parchemin::Static.new(params[:static])
         | 
| 50 | 
            +
                  haml :static
         | 
| 51 | 
            +
                end
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                post '/comment' do
         | 
| 54 | 
            +
                  @article = Parchemin::Article.new("#{params[:comment][:article]}.markdown")
         | 
| 55 | 
            +
                  @comments = @article.comments
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                  @comment = Parchemin::Comment.new(params[:comment])
         | 
| 58 | 
            +
                  if @comment.save
         | 
| 59 | 
            +
                    flash[:notice] = "Commentaire ajouté avec succès. Merci."
         | 
| 60 | 
            +
                    redirect "/articles/#{@article.id}"
         | 
| 61 | 
            +
                  else
         | 
| 62 | 
            +
                    flash[:error] = "Données non valides. Verifiez le formulaire svp."
         | 
| 63 | 
            +
                    haml :show
         | 
| 64 | 
            +
                  end
         | 
| 65 | 
            +
                end
         | 
| 66 | 
            +
             | 
| 67 | 
            +
                get '/rss' do
         | 
| 68 | 
            +
                  @host = Parchemin::Config.host
         | 
| 69 | 
            +
                  @articles = Parchemin::Article.all
         | 
| 70 | 
            +
                  builder :rss
         | 
| 71 | 
            +
                end
         | 
| 72 | 
            +
              end
         | 
| 73 | 
            +
            end
         | 
| @@ -0,0 +1,15 @@ | |
| 1 | 
            +
            # coding: utf-8
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Parchemin
         | 
| 4 | 
            +
              class Application
         | 
| 5 | 
            +
                configure do
         | 
| 6 | 
            +
                  Compass.configuration do |config|
         | 
| 7 | 
            +
                    config.project_path = File.dirname(__FILE__)
         | 
| 8 | 
            +
                    config.sass_dir = 'views'
         | 
| 9 | 
            +
                  end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                  set :haml, { :format => :html5 }
         | 
| 12 | 
            +
                  set :sass, Compass.sass_engine_options
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
              end
         | 
| 15 | 
            +
            end
         | 
| @@ -0,0 +1,65 @@ | |
| 1 | 
            +
            # coding: utf-8
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Parchemin
         | 
| 4 | 
            +
              module Config
         | 
| 5 | 
            +
                
         | 
| 6 | 
            +
                def self.author_name=(name)
         | 
| 7 | 
            +
                  @author_name = name
         | 
| 8 | 
            +
                end
         | 
| 9 | 
            +
                
         | 
| 10 | 
            +
                def self.author_name
         | 
| 11 | 
            +
                  raise "The author_name configuration variable has not been set" if @author_name.nil?
         | 
| 12 | 
            +
                  @author_name
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
                
         | 
| 15 | 
            +
                def self.blog_name=(name)
         | 
| 16 | 
            +
                  @blog_name = name
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
                
         | 
| 19 | 
            +
                def self.blog_name
         | 
| 20 | 
            +
                  raise "The blog_name configuration variable has not been set" if @blog_name.nil?
         | 
| 21 | 
            +
                  @blog_name
         | 
| 22 | 
            +
                end
         | 
| 23 | 
            +
                
         | 
| 24 | 
            +
                def self.host=(host)
         | 
| 25 | 
            +
                  @host = host
         | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
                
         | 
| 28 | 
            +
                def self.host
         | 
| 29 | 
            +
                  raise "The host configuration variable has not been set" if @host.nil?
         | 
| 30 | 
            +
                  @host
         | 
| 31 | 
            +
                end
         | 
| 32 | 
            +
                
         | 
| 33 | 
            +
                def self.project_path=(path)
         | 
| 34 | 
            +
                  @project_path = path
         | 
| 35 | 
            +
                end
         | 
| 36 | 
            +
                
         | 
| 37 | 
            +
                def self.project_path
         | 
| 38 | 
            +
                  raise "The project_path configuration variable has not been set" if @project_path.nil?
         | 
| 39 | 
            +
                  @project_path
         | 
| 40 | 
            +
                end
         | 
| 41 | 
            +
                
         | 
| 42 | 
            +
                def self.articles_path=(path)
         | 
| 43 | 
            +
                  @articles_path = path
         | 
| 44 | 
            +
                end
         | 
| 45 | 
            +
                
         | 
| 46 | 
            +
                def self.articles_path
         | 
| 47 | 
            +
                  @articles_path ||= "#{project_path}/articles"
         | 
| 48 | 
            +
                end
         | 
| 49 | 
            +
                
         | 
| 50 | 
            +
                def self.statics_path=(path)
         | 
| 51 | 
            +
                  @statics_path = path
         | 
| 52 | 
            +
                end
         | 
| 53 | 
            +
                
         | 
| 54 | 
            +
                def self.statics_path
         | 
| 55 | 
            +
                  @statics_path ||= "#{project_path}/statics"
         | 
| 56 | 
            +
                end
         | 
| 57 | 
            +
                   
         | 
| 58 | 
            +
                def self.db_name=(name)
         | 
| 59 | 
            +
                  Mongoid.configure do |config|
         | 
| 60 | 
            +
                    config.allow_dynamic_fields = false
         | 
| 61 | 
            +
                    config.master = Mongo::Connection.new.db(name)
         | 
| 62 | 
            +
                  end
         | 
| 63 | 
            +
                end
         | 
| 64 | 
            +
              end
         | 
| 65 | 
            +
            end
         | 
| @@ -0,0 +1,55 @@ | |
| 1 | 
            +
            # coding: utf-8
         | 
| 2 | 
            +
            module Parchemin
         | 
| 3 | 
            +
              class Application
         | 
| 4 | 
            +
                # Rails-style request params hash
         | 
| 5 | 
            +
                before do
         | 
| 6 | 
            +
                  new_params = {}
         | 
| 7 | 
            +
                  params.each_pair do |full_key, value|
         | 
| 8 | 
            +
                    this_param = new_params
         | 
| 9 | 
            +
                    split_keys = full_key.split(/\]\[|\]|\[/)
         | 
| 10 | 
            +
                    split_keys.each_index do |index|
         | 
| 11 | 
            +
                      break if split_keys.length == index + 1
         | 
| 12 | 
            +
                      this_param[split_keys[index]] ||= {}
         | 
| 13 | 
            +
                      this_param = this_param[split_keys[index]]
         | 
| 14 | 
            +
                   end
         | 
| 15 | 
            +
                   this_param[split_keys.last] = value
         | 
| 16 | 
            +
                  end
         | 
| 17 | 
            +
                  request.params.replace new_params
         | 
| 18 | 
            +
                end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                # Partial implementation
         | 
| 21 | 
            +
                helpers do
         | 
| 22 | 
            +
                  def partial(template, *args)
         | 
| 23 | 
            +
                    options = args.last.is_a?(::Hash) ? args.pop : {}
         | 
| 24 | 
            +
                    options.merge!(:layout => false)
         | 
| 25 | 
            +
                    if collection = options.delete(:collection) then
         | 
| 26 | 
            +
                      collection.inject([]) do |buffer, member|
         | 
| 27 | 
            +
                        buffer << haml(template, options.merge(:layout => false, :locals => {template.to_sym => member}))
         | 
| 28 | 
            +
                      end.join("\n")
         | 
| 29 | 
            +
                    else
         | 
| 30 | 
            +
                      haml(template, options)
         | 
| 31 | 
            +
                    end
         | 
| 32 | 
            +
                  end
         | 
| 33 | 
            +
                end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                # Flash implementation
         | 
| 36 | 
            +
                use Rack::Session::Cookie
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                helpers do
         | 
| 39 | 
            +
                  def flash
         | 
| 40 | 
            +
                    @_flash ||= {}
         | 
| 41 | 
            +
                  end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                  def redirect(uri, *args)
         | 
| 44 | 
            +
                    session[:_flash] = flash unless flash.empty?
         | 
| 45 | 
            +
                    status 302
         | 
| 46 | 
            +
                    response['Location'] = uri
         | 
| 47 | 
            +
                    halt(*args)
         | 
| 48 | 
            +
                  end
         | 
| 49 | 
            +
                end
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                before do
         | 
| 52 | 
            +
                  @_flash, session[:_flash] = session[:_flash], nil if session[:_flash]
         | 
| 53 | 
            +
                end
         | 
| 54 | 
            +
              end
         | 
| 55 | 
            +
            end
         | 
| @@ -0,0 +1,95 @@ | |
| 1 | 
            +
            # coding: utf-8
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require 'date'
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            module Parchemin
         | 
| 6 | 
            +
              class Article
         | 
| 7 | 
            +
                attr_reader :title, :created_at, :abstract, :body, :filename, :tags
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                MONTHS = %w(janv fevr mars avr mai juin juill aout sept oct nov dec)
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                def initialize(filename)
         | 
| 12 | 
            +
                  @filename = filename.split('.').first
         | 
| 13 | 
            +
                  parse_attributes(filename)
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                def parse_attributes(filename)
         | 
| 17 | 
            +
                  body = ""
         | 
| 18 | 
            +
                  File.open(filename) do |f|
         | 
| 19 | 
            +
                    f.lines.each do |line|
         | 
| 20 | 
            +
                      if line.match /<!--\s(.*)\s-->/
         | 
| 21 | 
            +
                        $1.match /(.*)\s:\s(.*)/
         | 
| 22 | 
            +
                        eval "@#{$1} = #{$2}"
         | 
| 23 | 
            +
                      else
         | 
| 24 | 
            +
                        body += line
         | 
| 25 | 
            +
                      end
         | 
| 26 | 
            +
                    end
         | 
| 27 | 
            +
                  end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                  @body = RDiscount.new(body).to_html
         | 
| 30 | 
            +
                end
         | 
| 31 | 
            +
                
         | 
| 32 | 
            +
                def id
         | 
| 33 | 
            +
                  File.basename(filename)
         | 
| 34 | 
            +
                end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                def month
         | 
| 37 | 
            +
                  MONTHS[@created_at.month-1]
         | 
| 38 | 
            +
                end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                def day
         | 
| 41 | 
            +
                  @created_at.day
         | 
| 42 | 
            +
                end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                def year
         | 
| 45 | 
            +
                  @created_at.year
         | 
| 46 | 
            +
                end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                def date
         | 
| 49 | 
            +
                  "#{day} #{month.capitalize} #{year}"
         | 
| 50 | 
            +
                end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                def <=>(article)
         | 
| 53 | 
            +
                  created_at <=> article.created_at
         | 
| 54 | 
            +
                end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                def self.all(conditions={})
         | 
| 57 | 
            +
                  articles = []
         | 
| 58 | 
            +
                  Dir.foreach(Parchemin::Config.articles_path) do |entry|
         | 
| 59 | 
            +
                    next if entry.match /^\./
         | 
| 60 | 
            +
                    article = Article.new("#{Parchemin::Config.articles_path}/#{entry}")
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                    if conditions.count == 0
         | 
| 63 | 
            +
                      articles << article
         | 
| 64 | 
            +
                    else
         | 
| 65 | 
            +
                      articles << article if not filtered?(article, conditions)
         | 
| 66 | 
            +
                    end
         | 
| 67 | 
            +
                  end
         | 
| 68 | 
            +
                  articles.sort.reverse
         | 
| 69 | 
            +
                end
         | 
| 70 | 
            +
             | 
| 71 | 
            +
                def self.search(search)
         | 
| 72 | 
            +
                  output = `grep -Hi '#{search}' #{Parchemin::Config.articles_path}/* | cut -d: -f1`
         | 
| 73 | 
            +
                  articles = output.split("\n").uniq.map { |filename| Article.new(filename) }
         | 
| 74 | 
            +
                  articles.sort.reverse
         | 
| 75 | 
            +
                end
         | 
| 76 | 
            +
                
         | 
| 77 | 
            +
                def comments
         | 
| 78 | 
            +
                  Comment.where(:article => @filename)
         | 
| 79 | 
            +
                end
         | 
| 80 | 
            +
             | 
| 81 | 
            +
                protected
         | 
| 82 | 
            +
             | 
| 83 | 
            +
                def self.filtered?(article, conditions)
         | 
| 84 | 
            +
                  filtered = true
         | 
| 85 | 
            +
                  conditions.each do |attribute, value|
         | 
| 86 | 
            +
                    if attribute.to_s == 'tag'
         | 
| 87 | 
            +
                      filtered &&= !(article.tags.include?(value))
         | 
| 88 | 
            +
                    else
         | 
| 89 | 
            +
                      filtered &&= !(article.send(attribute) == value)
         | 
| 90 | 
            +
                    end
         | 
| 91 | 
            +
                  end
         | 
| 92 | 
            +
                  filtered
         | 
| 93 | 
            +
                end
         | 
| 94 | 
            +
              end
         | 
| 95 | 
            +
            end
         | 
| @@ -0,0 +1,18 @@ | |
| 1 | 
            +
            # coding: utf-8
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Parchemin
         | 
| 4 | 
            +
              class Comment
         | 
| 5 | 
            +
                include Mongoid::Document
         | 
| 6 | 
            +
                include Mongoid::Timestamps
         | 
| 7 | 
            +
                
         | 
| 8 | 
            +
                field :author
         | 
| 9 | 
            +
                field :email
         | 
| 10 | 
            +
                field :website
         | 
| 11 | 
            +
                field :body
         | 
| 12 | 
            +
                field :article
         | 
| 13 | 
            +
                # field :created_at, :type => DateTime
         | 
| 14 | 
            +
                # field :updated_at, :type => DateTime
         | 
| 15 | 
            +
                
         | 
| 16 | 
            +
                validates_presence_of :author, :body, :article
         | 
| 17 | 
            +
              end
         | 
| 18 | 
            +
            end
         | 
| @@ -0,0 +1,22 @@ | |
| 1 | 
            +
            # coding: utf-8
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Parchemin
         | 
| 4 | 
            +
              class Static
         | 
| 5 | 
            +
                attr_reader :filename, :id
         | 
| 6 | 
            +
                
         | 
| 7 | 
            +
                def initialize(id)
         | 
| 8 | 
            +
                  @id = id
         | 
| 9 | 
            +
                  @filename = "#{Parchemin::Config.statics_path}/#{@id}.markdown"
         | 
| 10 | 
            +
                end
         | 
| 11 | 
            +
                
         | 
| 12 | 
            +
                def body(interpret_markdown=true)
         | 
| 13 | 
            +
                  raise "#{@filename} doesn't exist." if not File.exist?(@filename)
         | 
| 14 | 
            +
                  if interpret_markdown
         | 
| 15 | 
            +
                    @body ||= RDiscount.new(File.read(@filename)).to_html
         | 
| 16 | 
            +
                  else
         | 
| 17 | 
            +
                    @body ||= File.read(@filename)
         | 
| 18 | 
            +
                  end
         | 
| 19 | 
            +
                  @body
         | 
| 20 | 
            +
                end
         | 
| 21 | 
            +
              end
         | 
| 22 | 
            +
            end
         | 
    
        data/lib/parchemin.rb
    ADDED
    
    | @@ -0,0 +1,16 @@ | |
| 1 | 
            +
            require 'sinatra/base'
         | 
| 2 | 
            +
            require 'yaml'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            require 'mongoid'
         | 
| 5 | 
            +
            require 'rdiscount'
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            require 'haml'
         | 
| 8 | 
            +
            require 'sass'
         | 
| 9 | 
            +
            require 'compass'
         | 
| 10 | 
            +
            require 'susy'
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            require File.join(File.dirname(__FILE__), "parchemin/models/article")
         | 
| 13 | 
            +
            require File.join(File.dirname(__FILE__), "parchemin/models/static")
         | 
| 14 | 
            +
            require File.join(File.dirname(__FILE__), "parchemin/models/comment")
         | 
| 15 | 
            +
            require File.join(File.dirname(__FILE__), "parchemin/application")
         | 
| 16 | 
            +
             | 
| @@ -0,0 +1,139 @@ | |
| 1 | 
            +
            require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe "Parchemin" do
         | 
| 4 | 
            +
              include Rack::Test::Methods
         | 
| 5 | 
            +
              
         | 
| 6 | 
            +
              def app
         | 
| 7 | 
            +
                @app ||= Parchemin::Application
         | 
| 8 | 
            +
              end
         | 
| 9 | 
            +
              
         | 
| 10 | 
            +
              before :all do
         | 
| 11 | 
            +
                Parchemin::Comment.delete_all
         | 
| 12 | 
            +
              end
         | 
| 13 | 
            +
              
         | 
| 14 | 
            +
              it "renders the stylesheet" do
         | 
| 15 | 
            +
                get '/layout.css'
         | 
| 16 | 
            +
                last_response.should be_ok
         | 
| 17 | 
            +
              end
         | 
| 18 | 
            +
              
         | 
| 19 | 
            +
              it "renders the home page" do
         | 
| 20 | 
            +
                get '/'
         | 
| 21 | 
            +
                
         | 
| 22 | 
            +
                doc = Nokogiri::HTML(last_response.body)
         | 
| 23 | 
            +
                doc.css('.abstract').count.should == 4
         | 
| 24 | 
            +
                doc.css('.details').count.should == 4
         | 
| 25 | 
            +
                
         | 
| 26 | 
            +
                last_response.should be_ok
         | 
| 27 | 
            +
              end
         | 
| 28 | 
            +
              
         | 
| 29 | 
            +
              it "renders an article" do
         | 
| 30 | 
            +
                article = Parchemin::Article.new(File.expand_path(File.dirname(__FILE__) + '/bin/articles/lorem.markdown'))
         | 
| 31 | 
            +
                Parchemin::Comment.create(:article => article.filename, :author => 'Rawane', :body => 'test')
         | 
| 32 | 
            +
                Parchemin::Comment.create(:article => article.filename, :author => 'Rawane', :body => 'test')
         | 
| 33 | 
            +
                Parchemin::Comment.create(:article => article.filename, :author => 'Rawane', :body => 'test')
         | 
| 34 | 
            +
                
         | 
| 35 | 
            +
                get 'articles/lorem'
         | 
| 36 | 
            +
                
         | 
| 37 | 
            +
                doc = Nokogiri::HTML(last_response.body)
         | 
| 38 | 
            +
                doc.css('.comment').count.should == 3
         | 
| 39 | 
            +
                doc.css('.add').count.should == 1
         | 
| 40 | 
            +
                
         | 
| 41 | 
            +
                last_response.should be_ok
         | 
| 42 | 
            +
              end
         | 
| 43 | 
            +
              
         | 
| 44 | 
            +
              it "filters articles by tag" do
         | 
| 45 | 
            +
                get '/tags/tutorial'
         | 
| 46 | 
            +
                
         | 
| 47 | 
            +
                doc = Nokogiri::HTML(last_response.body)
         | 
| 48 | 
            +
                doc.css('.abstract').count.should == 2
         | 
| 49 | 
            +
                
         | 
| 50 | 
            +
                last_response.should be_ok
         | 
| 51 | 
            +
              end
         | 
| 52 | 
            +
              
         | 
| 53 | 
            +
              it "performs accurate searches" do
         | 
| 54 | 
            +
                get '/search', {:search => 'lorem ipsum'}
         | 
| 55 | 
            +
                
         | 
| 56 | 
            +
                doc = Nokogiri::HTML(last_response.body)
         | 
| 57 | 
            +
                doc.css('.abstract').count.should == 2
         | 
| 58 | 
            +
                
         | 
| 59 | 
            +
                last_response.should be_ok
         | 
| 60 | 
            +
              end
         | 
| 61 | 
            +
              
         | 
| 62 | 
            +
              it "creates articles comments with valid attributes" do
         | 
| 63 | 
            +
                article = Parchemin::Article.new(File.expand_path(File.dirname(__FILE__) + '/bin/articles/azerty.markdown'))
         | 
| 64 | 
            +
                
         | 
| 65 | 
            +
                post '/comment', {:comment => {:article => article.filename, :author => 'Rawane', :body => 'test'}}
         | 
| 66 | 
            +
                follow_redirect!
         | 
| 67 | 
            +
             | 
| 68 | 
            +
                last_request.url.should == "http://example.org/articles/#{article.id}"
         | 
| 69 | 
            +
                doc = Nokogiri::HTML(last_response.body)
         | 
| 70 | 
            +
                doc.css('.comment').count.should == 1
         | 
| 71 | 
            +
                
         | 
| 72 | 
            +
                article.comments.count.should == 1
         | 
| 73 | 
            +
                article.comments.first.author.should == 'Rawane'
         | 
| 74 | 
            +
                article.comments.first.body.should == 'test'
         | 
| 75 | 
            +
                
         | 
| 76 | 
            +
                last_response.should be_ok
         | 
| 77 | 
            +
              end
         | 
| 78 | 
            +
              
         | 
| 79 | 
            +
              it "does not create an article'comment with invalid attributes" do
         | 
| 80 | 
            +
                article = Parchemin::Article.new(File.expand_path(File.dirname(__FILE__) + '/bin/articles/tellus.markdown'))
         | 
| 81 | 
            +
                
         | 
| 82 | 
            +
                post '/comment', {:comment => {:article => article.filename, :author => 'Rawane'}}
         | 
| 83 | 
            +
                
         | 
| 84 | 
            +
                article.comments.count.should == 0
         | 
| 85 | 
            +
                
         | 
| 86 | 
            +
                last_response.should be_ok
         | 
| 87 | 
            +
              end
         | 
| 88 | 
            +
              
         | 
| 89 | 
            +
              it "renders the feeds" do
         | 
| 90 | 
            +
                get '/rss'
         | 
| 91 | 
            +
             | 
| 92 | 
            +
                doc = Nokogiri::XML(last_response.body)
         | 
| 93 | 
            +
                doc.css('item').count.should == 4
         | 
| 94 | 
            +
                
         | 
| 95 | 
            +
                last_response.should be_ok
         | 
| 96 | 
            +
              end
         | 
| 97 | 
            +
              
         | 
| 98 | 
            +
              it "display the application and author's names" do
         | 
| 99 | 
            +
                get '/'
         | 
| 100 | 
            +
                last_response.should be_ok
         | 
| 101 | 
            +
                doc = Nokogiri::HTML(last_response.body)
         | 
| 102 | 
            +
                doc.css('title').first.content.strip.should == 'Parchemin Test'
         | 
| 103 | 
            +
                doc.css('.brand').first.content.strip.should == 'Parchemin Test'
         | 
| 104 | 
            +
                doc.css('.tagline').first.content.strip.should == 'par Rawane ZOSSOU'
         | 
| 105 | 
            +
                
         | 
| 106 | 
            +
                get 'articles/lorem'
         | 
| 107 | 
            +
                last_response.should be_ok
         | 
| 108 | 
            +
                doc = Nokogiri::HTML(last_response.body)
         | 
| 109 | 
            +
                doc.css('title').first.content.strip.should == 'Parchemin Test'
         | 
| 110 | 
            +
                doc.css('.brand').first.content.strip.should == 'Parchemin Test'
         | 
| 111 | 
            +
                doc.css('.tagline').first.content.strip.should == 'par Rawane ZOSSOU'
         | 
| 112 | 
            +
                
         | 
| 113 | 
            +
                get '/tags/tutorial'
         | 
| 114 | 
            +
                last_response.should be_ok
         | 
| 115 | 
            +
                doc = Nokogiri::HTML(last_response.body)
         | 
| 116 | 
            +
                doc.css('title').first.content.strip.should == 'Parchemin Test'
         | 
| 117 | 
            +
                doc.css('.brand').first.content.strip.should == 'Parchemin Test'
         | 
| 118 | 
            +
                doc.css('.tagline').first.content.strip.should == 'par Rawane ZOSSOU'
         | 
| 119 | 
            +
                
         | 
| 120 | 
            +
                get '/search', {:search => 'lorem ipsum'}
         | 
| 121 | 
            +
                last_response.should be_ok
         | 
| 122 | 
            +
                doc = Nokogiri::HTML(last_response.body)
         | 
| 123 | 
            +
                doc.css('title').first.content.strip.should == 'Parchemin Test'
         | 
| 124 | 
            +
                doc.css('.brand').first.content.strip.should == 'Parchemin Test'
         | 
| 125 | 
            +
                doc.css('.tagline').first.content.strip.should == 'par Rawane ZOSSOU'
         | 
| 126 | 
            +
              end
         | 
| 127 | 
            +
              
         | 
| 128 | 
            +
              it "renders statics" do
         | 
| 129 | 
            +
                get '/statics/about'
         | 
| 130 | 
            +
                
         | 
| 131 | 
            +
                doc = Nokogiri::HTML(last_response.body)
         | 
| 132 | 
            +
                doc.css('title').first.content.strip.should == 'Parchemin Test'
         | 
| 133 | 
            +
                doc.css('.brand').first.content.strip.should == 'Parchemin Test'
         | 
| 134 | 
            +
                doc.css('.tagline').first.content.strip.should == 'par Rawane ZOSSOU'
         | 
| 135 | 
            +
                doc.css('p').count.should == 2
         | 
| 136 | 
            +
                
         | 
| 137 | 
            +
                last_response.should be_ok
         | 
| 138 | 
            +
              end
         | 
| 139 | 
            +
            end
         | 
    
        data/spec/spec_helper.rb
    ADDED
    
    | @@ -0,0 +1,22 @@ | |
| 1 | 
            +
            $LOAD_PATH.unshift(File.dirname(__FILE__))
         | 
| 2 | 
            +
            $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
         | 
| 3 | 
            +
            require 'parchemin'
         | 
| 4 | 
            +
            require 'rspec/core'
         | 
| 5 | 
            +
            require 'rspec/autorun'
         | 
| 6 | 
            +
            require 'rack/test'
         | 
| 7 | 
            +
            require 'nokogiri'
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            module Parchemin
         | 
| 10 | 
            +
              class Application
         | 
| 11 | 
            +
                set :environment, :test
         | 
| 12 | 
            +
                set :run, false
         | 
| 13 | 
            +
                set :raise_errors, true
         | 
| 14 | 
            +
                set :logging, false
         | 
| 15 | 
            +
              end
         | 
| 16 | 
            +
            end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
            Parchemin::Config.blog_name = "Parchemin Test"
         | 
| 19 | 
            +
            Parchemin::Config.author_name = "Rawane ZOSSOU"
         | 
| 20 | 
            +
            Parchemin::Config.host = "http://example.com"
         | 
| 21 | 
            +
            Parchemin::Config.project_path = File.join(File.dirname(__FILE__), 'bin')
         | 
| 22 | 
            +
            Parchemin::Config.db_name = 'parchemin_test'
         |