make an engine of the cms

This commit is contained in:
dinedine 2010-06-03 17:32:40 +02:00
parent 188fae991f
commit 9e7d1d3a08
104 changed files with 329 additions and 906 deletions

5
.gitignore vendored
View File

@ -7,3 +7,8 @@ rerun.txt
uploads
spec/tmp
public/sites
public/uploads
pkg
*.gemspec
rails_3_gems
doc/performance.txt

16
Gemfile
View File

@ -8,14 +8,20 @@ gem "liquid"
gem "bson_ext", ">= 1.0.1"
gem "mongo_ext"
gem "mongoid", ">= 2.0.0.beta6"
gem "mongoid_acts_as_tree", :git => 'git://github.com/evansagge/mongoid_acts_as_tree.git'
gem "mongoid_acts_as_tree", ">= 0.1.2"
gem "warden"
gem "devise", ">= 1.1.rc0"
gem "haml", '>= 3.0.1' #, :git => 'git://github.com/nex3/haml.git'
gem "formtastic", :git => 'git://github.com/justinfrench/formtastic.git', :branch => 'rails3'
gem "mongoid_acts_as_tree", :git => 'git://github.com/evansagge/mongoid_acts_as_tree.git'
gem "carrierwave", :git => "http://github.com/jnicklas/carrierwave.git"
gem "haml", '>= 3.0.1'
gem "rmagick"
gem "jeweler"
gem "mimetype-fu", :require => "mimetype_fu"
gem "formtastic-rails3", :require => "formtastic"
gem "carrierwave-rails3", :require => "carrierwave"
# gem 'formtastic-rails3', :require => 'formtastic', :path => 'rails_3_gems/formtastic'
# gem "formtastic", :git => 'git://github.com/justinfrench/formtastic.git', :branch => 'rails3'
# gem "carrierwave", :git => "http://github.com/jnicklas/carrierwave.git"
# gem "carrierwave", :path => 'rails_3_gems/carrierwave'
# Development environment

View File

@ -8,3 +8,25 @@ require 'rake/testtask'
require 'rake/rdoctask'
Rails::Application.load_tasks
begin
require "jeweler"
Jeweler::Tasks.new do |gem|
gem.name = "locomotive_cms"
gem.summary = "Locomotive cms engine"
gem.files = Dir["Gemfile", "{lib}/**/*", "{app}/**/*", "{config}/**/*",
"{public}/stylesheets/**/*", "{public}/javascripts/**/*", "{public}/images/**/*",
"{vendor}/**/*"]
# other fields that would normally go in your gemspec
# like authors, email and has_rdoc can also be included here
bundle = Bundler::Definition.from_gemfile('Gemfile')
bundle.dependencies.each do |dep|
if dep.groups.include?(:default)
gem.add_dependency(dep.name, dep.requirement.to_s)
end
end
end
rescue
puts "Jeweler or one of its dependencies is not installed."
end

View File

@ -1 +1 @@
0.0.0
0.0.1

View File

@ -3,7 +3,7 @@ module Admin
include Locomotive::Routing::SiteDispatcher
layout 'admin'
layout 'admin/application'
before_filter :authenticate_account!

View File

@ -3,7 +3,7 @@ module Admin
include Locomotive::Routing::SiteDispatcher
layout 'login'
layout 'admin/login'
before_filter :require_site

View File

@ -0,0 +1,15 @@
module Admin
class RenderingController < ActionController::Base
include Locomotive::Routing::SiteDispatcher
include Locomotive::Render
before_filter :require_site
def show
render_locomotive_page
end
end
end

View File

@ -3,7 +3,7 @@ module Admin
include Locomotive::Routing::SiteDispatcher
layout 'login'
layout 'admin/login'
before_filter :require_site

View File

@ -1,11 +1,3 @@
class ApplicationController < ActionController::Base
protect_from_forgery
# before_filter :set_locale
#
# protected
#
# def set_locale
# I18n.locale = 'fr'
# end
end

View File

@ -1,13 +0,0 @@
class PagesController < ActionController::Base
include Locomotive::Routing::SiteDispatcher
include Locomotive::Render
before_filter :require_site
def show
render_locomotive_page
end
end

View File

@ -1,4 +1,13 @@
module Admin::BaseHelper
def title(title = nil)
if title.nil?
@content_for_title
else
@content_for_title = title
''
end
end
def admin_menu_item(name, url)
label = content_tag(:em) + escape_once('&nbsp;') + t("admin.shared.menu.#{name}")
@ -28,4 +37,18 @@ module Admin::BaseHelper
end
end
def growl_message
if not flash.empty?
%{
$(document).ready(function() {
$.growl("#{flash.keys.first}", "#{flash.values.first}");
});
}.to_s
end
end
def nocoffee_tag
link_to content_tag(:em, 'no') + 'Coffee', 'http://www.nocoffee.fr', :id => 'nocoffee'
end
end

View File

@ -0,0 +1,17 @@
module Admin::LoginHelper
def login_flash_message
if not flash.empty?
content_tag :div, flash.values.first,
:id => "flash-#{flash.keys.first}",
:class => 'application-message'
else
''
end
end
def login_button_tag(label)
content_tag(:button, content_tag(:span, label), :type => 'submit', :class => 'button')
end
end

View File

@ -1,40 +0,0 @@
module ApplicationHelper
def title(title = nil)
if title.nil?
@content_for_title
else
@content_for_title = title
''
end
end
def flash_message
if not flash.empty?
content_tag :div, flash.values.first,
:id => "flash-#{flash.keys.first}",
:class => 'application-message'
else
''
end
end
def growl_message
if not flash.empty?
%{
$(document).ready(function() {
$.growl("#{flash.keys.first}", "#{flash.values.first}");
});
}.to_s
end
end
def nocoffee_tag
link_to content_tag(:em, 'no') + 'Coffee', 'http://www.nocoffee.fr', :id => 'nocoffee'
end
def submit_button_tag(label)
content_tag(:button, content_tag(:span, label), :type => 'submit', :class => 'button')
end
end

View File

@ -1,9 +1,6 @@
module Models
module Extensions
module Asset
module Models
module Extensions
module Asset
module Vignette
def vignette_url
@ -37,10 +34,7 @@ module Models
File.join("admin", "icons", "filetype", size.to_s, filename + ".png")
end
end
end
end
end
end
end
end

View File

@ -1,9 +1,6 @@
module Models
module Extensions
module Page
module Models
module Extensions
module Page
module Parts
extend ActiveSupport::Concern
@ -50,12 +47,8 @@ module Models
self.save
end
end
end
end
end
end
end
end
end
end

View File

@ -1,9 +1,6 @@
module Models
module Extensions
module Page
module Models
module Extensions
module Page
module Render
def render(context)
@ -16,10 +13,7 @@ module Models
end
end
end
end
end
end
end
end
end

View File

@ -1,9 +1,6 @@
module Models
module Extensions
module Page
module Models
module Extensions
module Page
module Tree
extend ActiveSupport::Concern
@ -93,12 +90,8 @@ module Models
end
end
end
end
end
end
end
end
end
end
end

View File

@ -61,7 +61,7 @@ class AssetUploader < CarrierWave::Uploader::Base
:audio => [/^audio/, 'application/ogg', 'application/x-mp3'],
:pdf => ['application/pdf', 'application/x-pdf'],
:stylesheet => ['text/css'],
:javascript => ['text/javascript', 'text/js', 'application/x-javascript']
:javascript => ['text/javascript', 'text/js', 'application/x-javascript', 'application/javascript']
}
end

View File

@ -6,6 +6,21 @@ class ThemeAssetUploader < AssetUploader
process :set_size
process :set_width_and_height
version :thumb do
process :resize_to_fill => [50, 50]
process :convert => 'png'
end
version :medium do
process :resize_to_fill => [80, 80]
process :convert => 'png'
end
version :preview do
process :resize_to_fit => [880, 1100]
process :convert => 'png'
end
def store_dir
"sites/#{model.site_id}/themes/#{model.id}"
end

View File

@ -1,18 +1,18 @@
- title t('.title')
= semantic_form_for(resource, :as => resource_name, :url => password_path(resource_name), :html => { :method => :put }) do |f|
= semantic_form_for(resource, :as => resource_name, :url => password_path, :html => { :method => :put }) do |f|
= f.hidden_field :reset_password_token
.inner
= flash_message
= login_flash_message
= f.inputs do
= f.input :password, :label => t('.password'), :required => false
= f.input :password_confirmation, :label => t('.password_confirmation'), :required => false
%p.link
= link_to t('.link'), new_account_session_path(resource_name)
= link_to t('.link'), new_account_session_path
.footer
= submit_button_tag t('admin.buttons.change_password')
= login_button_tag t('admin.buttons.change_password')

View File

@ -1,17 +1,17 @@
- title t('.title')
= semantic_form_for(resource, :as => resource_name, :url => password_path(resource_name)) do |f|
= semantic_form_for(resource, :as => resource_name, :url => password_path) do |f|
= f.hidden_field :reset_password_token
.inner
= flash_message
= login_flash_message
= f.inputs do
= f.input :email, :label => t('.email'), :required => false
%p.link
= link_to t('.link'), new_account_session_path(resource_name)
= link_to t('.link'), new_account_session_path
.footer
= submit_button_tag t('admin.buttons.send_password')
= login_button_tag t('admin.buttons.send_password')

View File

@ -2,14 +2,14 @@
= semantic_form_for(resource, :as => resource_name, :url => session_path(resource_name)) do |f|
.inner
= flash_message
= login_flash_message
= f.inputs do
= f.input :email, :label => t('.email'), :required => false
= f.input :password, :label => t('.password'), :required => false
%p.link
= link_to t('.link'), new_password_path(resource_name)
= link_to t('.link'), new_password_path
.footer
= submit_button_tag t('admin.buttons.login')
= login_button_tag t('admin.buttons.login')

View File

@ -4,13 +4,13 @@
%meta{ :name => 'locale', :content => I18n.locale }
= stylesheet_link_tag 'blueprint/screen', :media => 'screen'
= stylesheet_link_tag 'admin/blueprint/screen', :media => 'screen'
/ [if IE]
= stylesheet_link_tag 'blueprint/ie', :media => 'screen'
= stylesheet_link_tag 'admin/blueprint/ie', :media => 'screen'
= stylesheet_link_tag 'admin/layout', 'admin/plugins/toggle', 'admin/menu', 'admin/buttons', 'admin/formtastic', 'admin/formtastic_changes', 'admin/application', :media => 'screen', :cache => Rails.env.production?
= javascript_include_tag 'jquery', 'jquery.ui', 'rails', 'admin/plugins/toggle', 'admin/plugins/growl', 'admin/plugins/cookie', 'admin/application', :cache => Rails.env.production?
= javascript_include_tag 'admin/jquery', 'admin/jquery.ui', 'admin/rails', 'admin/plugins/toggle', 'admin/plugins/growl', 'admin/plugins/cookie', 'admin/application', :cache => Rails.env.production?
%script{ :type => 'text/javascript' }
= find_and_preserve(growl_message)

View File

@ -4,9 +4,9 @@
%head
%title= escape_once("#{Locomotive.config.name} &mdash; #{current_site.name}")
= stylesheet_link_tag 'blueprint/screen', 'admin/login', :media => 'screen'
= stylesheet_link_tag 'admin/blueprint/screen', 'admin/login', :media => 'screen'
/ [if IE]
= stylesheet_link_tag('blueprint/ie', :media => 'screen')
= stylesheet_link_tag('admin/blueprint/ie', :media => 'screen')
%body
#wrapper

View File

@ -1,8 +0,0 @@
<html>
<head>
<title><%= current_site.name %></title>
</head>
<body>
<h1>...rendering liquid templates soon</h1>
</body>
</html>

View File

@ -1,16 +1,7 @@
require 'lib/locomotive.rb'
require 'lib/core_ext.rb'
require File.dirname(__FILE__) + '/../../lib/locomotive.rb'
require File.dirname(__FILE__) + '/../../lib/core_ext.rb'
Locomotive.configure do |config|
config.default_domain = 'example.com'
config.lastest_items_nb = 5
end
# TODO: embed them in Locomotive right after configure
ActionMailer::Base.default_url_options[:host] = Locomotive.config.default_domain + (Rails.env.development? ? ':3000' : '')
Rails.application.config.session_store :cookie_store, {
:key => '_locomotive_session',
:domain => ".#{Locomotive.config.default_domain}"
}
end

View File

@ -1,6 +1,6 @@
Locomotive::Application.configure do
config.generators do |g|
g.integration_tool :rspec
g.test_framework :rspec
end
end
# Locomotive::Application.configure do
# config.generators do |g|
# g.integration_tool :rspec
# g.test_framework :rspec
# end
# end

View File

@ -1,4 +1,5 @@
Locomotive::Application.routes.draw do |map|
# Locomotive::Application.routes.draw do |map|
Rails.application.routes.draw do |map|
constraints(Locomotive::Routing::DefaultConstraint) do
root :to => 'home#show'
@ -51,6 +52,6 @@ Locomotive::Application.routes.draw do |map|
end
# magic urls
match '/' => 'pages#show'
match '*path' => 'pages#show'
match '/' => 'admin/rendering#show'
match '*path' => 'admin/rendering#show'
end

View File

@ -1,23 +0,0 @@
# class DeviseCreateAccounts < ActiveRecord::Migration
# def self.up
# create_table(:accounts) do |t|
# t.authenticatable :encryptor => :sha1, :null => false
# t.confirmable
# t.recoverable
# t.rememberable
# t.trackable
# # t.lockable
#
# t.timestamps
# end
#
# add_index :accounts, :email, :unique => true
# add_index :accounts, :confirmation_token, :unique => true
# add_index :accounts, :reset_password_token, :unique => true
# # add_index :accounts, :unlock_token, :unique => true
# end
#
# def self.down
# drop_table :accounts
# end
# end

View File

@ -1,4 +1,8 @@
BOARD:
- make an engine:
- move initializers to lib/...
- write doc about setting up the parent app
x helpers do not work
- theme assets: disable version if not image
- refactoring: CustomFields::CustomField => CustomFields::Field
- new types for custom field
@ -20,6 +24,7 @@ BACKLOG:
BUGS:
- when assigning new layout, disabled parts show up :-( (js problem)
- password resets
NICE TO HAVE:
- asset collections: custom resizing if image

View File

@ -1,7 +1,6 @@
Before('@site_up') do
create_site_and_admin_account
create_layout_samples
create_index_page
end
Before('@authenticated') do
@ -44,6 +43,8 @@ end
def create_site_and_admin_account
@site = Factory(:site, :name => 'Locomotive test website', :subdomain => 'test')
@admin = Factory(:account, { :name => 'Admin', :email => 'admin@locomotiveapp.org' })
@site.memberships.build :account => @admin, :admin => true
@site.save
end
def create_layout_samples
@ -55,9 +56,5 @@ def create_layout_samples
<div id="main">\{\{ content_for_layout \}\}</div>
</body>
</html>})
Factory(:layout, :site => @site)
end
def create_index_page
Factory(:page, :site => @site, :layout => @site.layouts.last, :parts => [PagePart.new(:slug => 'layout', :name => 'Body', :value => 'Hello world')])
Factory(:layout, :site => @site)
end

View File

@ -0,0 +1,35 @@
class LocomotiveGenerator < Rails::Generators::NamedBase
class_option :update, :type => :boolean, :default => false,
:desc => "Just update public files, do not create seed"
def self.source_root
@_locomotive_source_root ||= File.dirname(__FILE__)
end
def copy_public_files
directory "../../public", "public", :recursive => true
exit(0) if options.update?
end
# def invoke_model
# invoke "model", [name].concat(migration_columns),
# :timestamps => false, :test_framework => false, :migration => options.migration?
# end
#
# def add_model_config
# inject_into_class "app/models/#{file_name}.rb", class_name, <<-CONTENT
# include RailsMetrics::ORM::#{Rails::Generators.options[:rails][:orm].to_s.camelize}
# CONTENT
# end
#
# def add_application_config
# inject_into_class "config/application.rb", "Application", <<-CONTENT
# # Set rails metrics store
# config.rails_metrics.set_store = lambda { ::#{class_name} }
#
# CONTENT
# end
end

View File

@ -3,9 +3,8 @@ require 'locomotive/configuration'
require 'locomotive/liquid'
require 'locomotive/mongoid'
module Locomotive
class << self
attr_accessor :config
@ -18,6 +17,19 @@ module Locomotive
def self.configure
self.config ||= Configuration.new
yield(self.config)
after_configure
end
def self.after_configure
raise '[Error] Locomotive needs a default domain name' if Locomotive.config.default_domain.blank?
ActionMailer::Base.default_url_options[:host] = Locomotive.config.default_domain + (Rails.env.development? ? ':3000' : '')
Rails.application.config.session_store :cookie_store, {
:key => Locomotive.config.cookie_key,
:domain => ".#{Locomotive.config.default_domain}"
}
end
end

View File

@ -1,5 +1,4 @@
module Locomotive
module Locomotive
class Configuration
@@defaults = {
@ -8,7 +7,8 @@ module Locomotive
:reserved_subdomains => %w{www admin email blog webmail mail support help site sites},
# :forbidden_paths => %w{layouts snippets stylesheets javascripts assets admin system api},
:reserved_slugs => %w{stylesheets javascripts assets admin images api pages},
:locales => %w{en fr}
:locales => %w{en fr},
:cookie_key => '_locomotive_session'
}
cattr_accessor :settings
@ -62,8 +62,6 @@ module Locomotive
else
send(:[], name.to_sym, &block)
end
end
end
end
end

View File

@ -1,5 +1,2 @@
Devise::SessionsController.class_eval do
end

32
lib/locomotive/engine.rb Normal file
View File

@ -0,0 +1,32 @@
puts "...Locomotive engine loaded"
# require 'liquid'
# require 'devise'
# require 'carrierwave'
# require 'formtastic'
# require 'mongoid'
# require 'mongoid_acts_as_tree'
require File.dirname(__FILE__) + '/../../vendor/plugins/custom_fields/init.rb'
module Locomotive
class Engine < Rails::Engine
initializer "locomotive.add_helpers" do |app|
path = [*ActionController::Base.helpers_path] << File.dirname(__FILE__) + "/../../app/helpers"
ActionController::Base.helpers_path = path
end
initializer "locomotive.require_dependencies" do
require 'bundler'
gemfile = Bundler::Definition.from_gemfile(root.join('Gemfile'))
specs = gemfile.dependencies.select do |d|
d.name != 'jeweler' and (d.groups & [:default, :production]).any?
end
specs.collect { |s| s.autorequire || [s.name] }.flatten.each do |r|
require r
end
end
end
end

View File

@ -1,9 +1,7 @@
module Locomotive
module Liquid
class DbFileSystem
module Locomotive
module Liquid
class DbFileSystem
# Works only with snippets
def read_template_file(site, template_path)
raise FileSystemError, "Illegal snippet name '#{template_path}'" unless template_path =~ /^[^.\/][a-zA-Z0-9_\/]+$/
@ -13,10 +11,8 @@ module Locomotive
raise FileSystemError, "No such snippet '#{template_path}'" if snippet.nil?
snippet.template
end
end
end
end
end
end
end

View File

@ -1,7 +1,5 @@
module Locomotive
module Liquid
module Locomotive
module Liquid
module Drops
class AssetCollections < ::Liquid::Drop
@ -17,7 +15,5 @@ module Locomotive
end
end
end
end

View File

@ -1,12 +1,9 @@
# Code taken from Mephisto sources (http://mephistoblog.com/)
module Locomotive
module Liquid
module Drops
module Liquid
module Drops
class Base < ::Liquid::Drop
class_inheritable_reader :liquid_attributes
write_inheritable_attribute :liquid_attributes, []
attr_reader :source
@ -43,13 +40,11 @@ module Locomotive
protected
def liquify(*records, &block)
self.class.liquify(*records, &block)
end
end
def liquify(*records, &block)
self.class.liquify(*records, &block)
end
end
end
end
end

View File

@ -1,9 +1,6 @@
module Locomotive
module Liquid
module Drops
module Locomotive
module Liquid
module Drops
class Content < Base
@@forbidden_attributes = %w{_id _version _index}
@ -16,10 +13,7 @@ module Locomotive
end
end
end
end
end
end
end
end

View File

@ -1,9 +1,6 @@
module Locomotive
module Liquid
module Drops
class Contents < ::Liquid::Drop
def initialize(site)
@ -59,12 +56,8 @@ module Locomotive
:total_pages => @collection.total_pages,
:per_page => @collection.per_page
}
end
end
end
end
end
end
end

View File

@ -1,9 +1,6 @@
module Locomotive
module Liquid
module Drops
module Locomotive
module Liquid
module Drops
class Javascripts < ::Liquid::Drop
def initialize(site)
@ -16,9 +13,6 @@ module Locomotive
end
end
end
end
end

View File

@ -1,9 +1,6 @@
module Locomotive
module Liquid
module Drops
module Locomotive
module Liquid
module Drops
class Stylesheets < ::Liquid::Drop
def initialize(site)
@ -17,8 +14,6 @@ module Locomotive
end
end
end
end
end

View File

@ -1,9 +1,6 @@
module Locomotive
module Liquid
module Filters
module Locomotive
module Liquid
module Filters
module Date
def localized_date(input, *args)
@ -27,10 +24,7 @@ module Locomotive
end
::Liquid::Template.register_filter(Date)
end
end
::Liquid::Template.register_filter(Date)
end
end
end

View File

@ -1,9 +1,6 @@
module Locomotive
module Liquid
module Filters
module Liquid
module Filters
module Html
# Write the link to a stylesheet resource
@ -112,7 +109,6 @@ module Locomotive
::Liquid::Template.register_filter(Html)
end
end
end
end

View File

@ -1,9 +1,6 @@
module Locomotive
module Liquid
module Filters
module Filters
module Misc
def underscore(input)
@ -28,8 +25,6 @@ module Locomotive
::Liquid::Template.register_filter(Misc)
end
end
end
end

View File

@ -1,7 +1,5 @@
module Locomotive
module Liquid
module Locomotive
module Liquid
module LiquifyTemplate
def self.included(base)
@ -53,10 +51,7 @@ module Locomotive
end
end
end
end
end
end
end
end
end

View File

@ -1,27 +1,21 @@
module Locomotive
module Liquid
module Tags
module Liquid
module Tags
class Blueprint < ::Liquid::Tag
def render(context)
%{
<link href="/stylesheets/blueprint/screen.css" media="screen, projection" rel="stylesheet" type="text/css" />
<link href="/stylesheets/blueprint/print.css" media="print" rel="stylesheet" type="text/css" />
<link href="/stylesheets/admin/blueprint/screen.css" media="screen, projection" rel="stylesheet" type="text/css" />
<link href="/stylesheets/admin/blueprint/print.css" media="print" rel="stylesheet" type="text/css" />
<!--[if IE]>
<link href="/stylesheets/blueprint/ie.css" media="screen, projection" rel="stylesheet" type="text/css" />
<link href="/stylesheets/admin/blueprint/ie.css" media="screen, projection" rel="stylesheet" type="text/css" />
<![endif]-->
}
end
end
::Liquid::Template.register_tag('blueprint_stylesheets', Blueprint)
end
end
::Liquid::Template.register_tag('blueprint_stylesheets', Blueprint)
end
end
end

View File

@ -1,9 +1,6 @@
module Liquid
module Locomotive
module Tags
module Liquid
module Locomotive
module Tags
class Jquery < ::Liquid::Tag
def render(context)
@ -14,10 +11,7 @@ module Liquid
end
end
::Liquid::Template.register_tag('jQuery', Jquery)
end
end
::Liquid::Template.register_tag('jQuery', Jquery)
end
end
end

View File

@ -1,9 +1,6 @@
module Locomotive
module Liquid
module Tags
class WithScope < ::Liquid::Block
def initialize(tag_name, markup, tokens)
@ -36,10 +33,7 @@ module Locomotive
end
end
::Liquid::Template.register_tag('with_scope', WithScope)
end
end
::Liquid::Template.register_tag('with_scope', WithScope)
end
end
end

View File

@ -1 +1 @@
Dir[File.join(Rails.root, 'app', 'models', 'extensions', '**', '*.rb')].each { |lib| require lib }
Dir[File.join(File.dirname(__FILE__), '..', '..', '..', 'app', 'models', 'extensions', '**', '*.rb')].each { |lib| require lib }

View File

Before

Width:  |  Height:  |  Size: 321 B

After

Width:  |  Height:  |  Size: 321 B

View File

Before

Width:  |  Height:  |  Size: 6.5 KiB

After

Width:  |  Height:  |  Size: 6.5 KiB

View File

@ -121,7 +121,7 @@ ul.assets li.asset h4 { margin: 0px; height: 30px; }
ul.assets li.asset h4 a {
position: relative;
top: 7px;
top: 0px;
left: 12px;
font-weight: bold;
font-size: 0.6em;

View File

Before

Width:  |  Height:  |  Size: 655 B

After

Width:  |  Height:  |  Size: 655 B

View File

Before

Width:  |  Height:  |  Size: 455 B

After

Width:  |  Height:  |  Size: 455 B

View File

Before

Width:  |  Height:  |  Size: 537 B

After

Width:  |  Height:  |  Size: 537 B

View File

Before

Width:  |  Height:  |  Size: 777 B

After

Width:  |  Height:  |  Size: 777 B

View File

Before

Width:  |  Height:  |  Size: 641 B

After

Width:  |  Height:  |  Size: 641 B

View File

Before

Width:  |  Height:  |  Size: 691 B

After

Width:  |  Height:  |  Size: 691 B

View File

Before

Width:  |  Height:  |  Size: 741 B

After

Width:  |  Height:  |  Size: 741 B

View File

Before

Width:  |  Height:  |  Size: 591 B

After

Width:  |  Height:  |  Size: 591 B

View File

Before

Width:  |  Height:  |  Size: 46 KiB

After

Width:  |  Height:  |  Size: 46 KiB

View File

Before

Width:  |  Height:  |  Size: 663 B

After

Width:  |  Height:  |  Size: 663 B

View File

Before

Width:  |  Height:  |  Size: 161 B

After

Width:  |  Height:  |  Size: 161 B

View File

@ -166,7 +166,7 @@ body {
/* ___ NoCoffee / Rails Tags ___ */
a#nocoffee { text-decoration: none; font-size: 1.1em; line-height: 20px; color: #505b64; padding-right: 20px; margin: 0 4px; background: transparent url(../../images/nocoffee.gif) no-repeat right 0px; }
a#nocoffee { text-decoration: none; font-size: 1.1em; line-height: 20px; color: #505b64; padding-right: 20px; margin: 0 4px; background: transparent url(../../images/admin/nocoffee.gif) no-repeat right 0px; }
a#nocoffee em { color: #ef3f44; font-weight: normal; font-style: normal; }
a#powered-by { text-decoration: none; font-size: 1.1em; color: #666; }

View File

@ -1,20 +0,0 @@
Copyright (c) 2007 [name of plugin creator]
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -1,16 +0,0 @@
MimetypeFu
==========
Some great Rails plugins like attachment_fu use the content type/mime type of a file to validate the instance of an object.
The plugin usually gets the mime type using the CGI request, however, if the file is already in the system, this approach won't work.
Adobe Flash is also known not to send the proper mime type.
As an alternative, I wrote mimetype_fu, a simple plugin which will try to guess the mimetype of a file based on its extension.
Note that mimetype_fu only looks at the extension to define its mime type if you are using Windows!
http://code.google.com/p/mimetype-fu/
Thanks to forestcarlisle for his big report and patch.
Copyright (c) 2008 Matt Aimonetti, released under the MIT license

View File

@ -1,22 +0,0 @@
require 'rake'
require 'rake/testtask'
require 'rake/rdoctask'
desc 'Default: run unit tests.'
task :default => :test
desc 'Test the mimetype_fu plugin.'
Rake::TestTask.new(:test) do |t|
t.libs << 'lib'
t.pattern = 'test/**/*_test.rb'
t.verbose = true
end
desc 'Generate documentation for the mimetype_fu plugin.'
Rake::RDocTask.new(:rdoc) do |rdoc|
rdoc.rdoc_dir = 'rdoc'
rdoc.title = 'MimetypeFu'
rdoc.options << '--line-numbers' << '--inline-source'
rdoc.rdoc_files.include('README')
rdoc.rdoc_files.include('lib/**/*.rb')
end

View File

@ -1,2 +0,0 @@
require File.dirname(__FILE__) + '/lib/extensions_const'
require File.dirname(__FILE__) + '/lib/mimetype_fu'

View File

@ -1 +0,0 @@
# Install hook code here

View File

@ -1 +0,0 @@
EXTENSIONS = YAML.load_file(File.dirname(__FILE__) + '/mime_types.yml').symbolize_keys

View File

@ -1,384 +0,0 @@
# EXTENSIONS => CONTENT TYPE
csh: application/x-csh
x_t: model/vnd.parasolid.transmit.text
kpt: application/vnd.kde.kpresenter
vst: application/vnd.visio
ksp: application/vnd.kde.kspread
fsc: application/vnd.fsc.weblaunch
vcs: text/x-vcalendar
hvs: application/vnd.yamaha.hv-script
seml: application/vnd.sealed.eml
lzh: application/octet-stream
movie: video/x-sgi-movie
wav: audio/x-wav
tbz2: application/x-gtar
plt: application/vnd.hp-HPGL
3gpp: video/3gpp
eol: audio/vnd.digital-winds
vsw: application/vnd.visio
rtf: text/rtf
rgb: image/x-rgb
midi: audio/x-midi
sit: application/x-stuffit
mov: video/quicktime
kfo: application/vnd.kde.kformula
rdf: application/rdf+xml
wpd: application/vnd.wordperfect
hbc: application/vnd.hbci
ogg: application/ogg
dwf: x-drawing/dwf
pbm: image/x-portable-bitmap
cpp: text/plain
smp3: audio/vnd.sealedmedia.softseal.mpeg
html: text/html
igs: model/iges
dwg: image/vnd.dwg
see: application/vnd.seemail
ram: audio/x-pn-realaudio
jad: text/vnd.sun.j2me.app-descriptor
iges: model/iges
pot: application/powerpoint
exe: application/octet-stream
siv: application/sieve
wml: text/vnd.wap.wml
hlp: text/plain
pkd: application/vnd.hbci
ice: x-conference/x-cooltalk
ustar: application/x-ustar
vis: application/vnd.visionary
pkipath: application/pkix-pkipath
ecelp4800: audio/vnd.nuera.ecelp4800
tgz: application/x-gtar
roff: text/troff
ltx: application/x-latex
nim: video/vnd.nokia.interleaved-multimedia
qcp: audio/QCELP
ai: application/postscript
sppt: application/vnd.sealed.ppt
igx: application/vnd.micrografx.igx
tcl: application/x-tcl
viv: video/vnd.vivo
css: text/css
js: text/javascript
wpl: application/vnd.ms-wpl
ami: application/vnd.amiga.ami
l16: audio/L16
vivo: video/vnd.vivo
dat: text/plain
vrml: x-world/x-vrml
pqa: application/vnd.palm
request: application/vnd.nervana
oprc: application/vnd.palm
vbk: audio/vnd.nortel.vbk
pki: application/pkixcmp
ras: image/x-cmu-raster
asc: text/plain
kom: application/vnd.hbci
jpeg: image/jpeg
sem: application/vnd.sealed.eml
chrt: application/vnd.kde.kchart
tif: image/tiff
cil: application/vnd.ms-artgalry
xwd: image/x-xwindowdump
dgn: image/x-vnd.dgn
mxu: video/vnd.mpegurl
csv: text/comma-separated-values
kon: application/vnd.kde.kontour
png: image/png
bkm: application/vnd.nervana
sxl: application/vnd.sealed.xls
xfdf: application/vnd.adobe.xfdf
snd: audio/basic
dl: video/dl
sxls: application/vnd.sealed.xls
karbon: application/vnd.kde.karbon
ico: image/vnd.microsoft.icon
sus: application/vnd.sus-calendar
pdb: x-chemical/x-pdb
wif: application/watcherinfo+xml
ser: application/x-java-serialized-object
xmt_txt: model/vnd.parasolid.transmit.text
upa: application/vnd.hbci
pnm: image/x-portable-anymap
jar: application/x-java-archive
qt: video/quicktime
tsv: text/tab-separated-values
rtx: text/richtext
mdi: image/vnd.ms-modi
rcprofile: application/vnd.ipunplugged.rcprofile
gl: video/gl
me: application/x-troff-me
man: application/x-troff-man
tr: text/troff
amr: audio/AMR
wp5: application/wordperfect5.1
pdf: application/pdf
pgb: image/vnd.globalgraphics.pgb
au: audio/basic
avi: video/x-msvideo
qxb: application/vnd.Quark.QuarkXPress
wp: application/wordperfect5.1
wmlsc: application/vnd.wap.wmlscriptc
wbxml: application/vnd.wap.wbxml
s1a: application/vnd.sealedmedia.softseal.pdf
saf: application/vnd.yamaha.smaf-audio
gtar: application/x-gtar
Z: application/x-compressed
crl: application/pkix-crl
pti: application/vnd.pvi.ptid1
rdz: application/vnd.data-vision.rdz
aif: audio/x-aiff
flo: application/vnd.micrografx.flo
qxd: application/vnd.Quark.QuarkXPress
rpm: audio/x-pn-realaudio-plugin
djv: image/vnd.djvu
jpe: image/jpeg
kne: application/vnd.Kinar
lvp: audio/vnd.lucent.voice
stml: application/vnd.sealedmedia.softseal.html
p7c: application/pkcs7-mime
dms: application/octet-stream
s1e: application/vnd.sealed.xls
sdf: application/vnd.Kinar
sc: application/vnd.ibm.secure-container
jnlp: application/x-java-jnlp-file
dvi: application/x-dvi
smov: video/vnd.sealedmedia.softseal.mov
jisp: application/vnd.jisp
aifc: audio/x-aiff
latex: application/x-latex
cc: text/plain
s1g: image/vnd.sealedmedia.softseal.gif
wv: application/vnd.wv.csp+wbxml
mseq: application/vnd.mseq
jpg: image/jpeg
mmf: application/vnd.smaf
xmt_bin: model/vnd.parasolid.transmit.binary
s1h: application/vnd.sealedmedia.softseal.html
mpc: application/vnd.mophun.certificate
hdf: application/x-hdf
stk: application/hyperstudio
txd: application/vnd.genomatix.tuxedo
ent: application/vnd.nervana
xml: text/xml
aiff: audio/x-aiff
sh: application/x-sh
mpe: video/mpeg
s1j: image/vnd.sealedmedia.softseal.jpg
psid: audio/prs.sid
mpga: audio/mpeg
pgm: image/x-portable-graymap
si: text/vnd.wap.si
stm: application/vnd.sealedmedia.softseal.html
lbd: application/vnd.llamagraphics.life-balance.desktop
flw: application/vnd.kde.kivio
mpg: video/mpeg
c: text/plain
sgi: image/vnd.sealedmedia.softseal.gif
zip: application/zip
ecelp7470: audio/vnd.nuera.ecelp7470
lbe: application/vnd.llamagraphics.life-balance.exchange+xml
qxl: application/vnd.Quark.QuarkXPress
p10: application/pkcs10
bpd: application/vnd.hbci
ief: image/ief
gz: application/x-gzip
doc: application/word
efif: application/vnd.picsel
jpm: image/jpm
hpgl: application/vnd.hp-HPGL
s1m: audio/vnd.sealedmedia.softseal.mpeg
xhtml: application/xhtml+xml
xpm: image/x-xpixmap
ms: application/x-troff-ms
bcpio: application/x-bcpio
sl: text/vnd.wap.sl
wrl: x-world/x-vrml
s1n: image/vnd.sealed.png
irm: application/vnd.ibm.rights-management
pgp: application/octet-stream
entity: application/vnd.nervana
mcd: application/vnd.mcd
ecelp9600: audio/vnd.nuera.ecelp9600
kwd: application/vnd.kde.kword
gif: image/gif
sdo: application/vnd.sealed.doc
cer: application/pkix-cert
m4u: video/vnd.mpegurl
rst: text/prs.fallenstein.rst
htm: text/html
mxmf: audio/vnd.nokia.mobile-xmf
psb: application/vnd.3gpp.pic-bw-small
knp: application/vnd.Kinar
cab: application/vnd.ms-cab-compressed
mj2: video/MJ2
sgm: text/sgml
wbmp: image/vnd.wap.wbmp
p7m: application/pkcs7-mime
spng: image/vnd.sealed.png
lha: application/octet-stream
s1p: application/vnd.sealed.ppt
texi: application/x-texinfo
s1q: video/vnd.sealedmedia.softseal.mov
troff: text/troff
h: text/plain
shtml: text/html
msh: model/mesh
irp: application/vnd.irepository.package+xml
rct: application/prs.nprend
smht: application/vnd.sealed.mht
s11: video/vnd.sealed.mpeg1
htke: application/vnd.kenameaapp
ps: application/postscript
mpm: application/vnd.blueice.multipass
dfac: application/vnd.dreamfactory
pvb: application/vnd.3gpp.pic-bw-var
lrm: application/vnd.ms-lrm
smh: application/vnd.sealed.mht
mpn: application/vnd.mophun.application
spd: application/vnd.sealedmedia.softseal.pdf
tiff: image/tiff
jp2: image/jp2
rpss: application/vnd.nokia.radio-presets
qxt: application/vnd.Quark.QuarkXPress
wmlc: application/vnd.wap.wmlc
rpst: application/vnd.nokia.radio-preset
etx: text/x-setext
bmp: image/bmp
s14: video/vnd.sealed.mpeg4
\"123\": application/vnd.lotus-1-2-3
mpp: application/vnd.ms-project
spf: application/vnd.yamaha.smaf-phrase
kar: audio/x-midi
mid: audio/x-midi
3gp: video/3gpp
3g2: video/3gpp2
hqx: application/mac-binhex40
p7s: application/pkcs7-signature
ppm: image/x-portable-pixmap
pspimage: image/x-paintshoppro
cdf: application/netcdf
texinfo: application/x-texinfo
sjp: image/vnd.sealedmedia.softseal.jpg
wbs: application/vnd.criticaltools.wbs+xml
emm: application/vnd.ibm.electronic-media
s1w: application/vnd.sealed.doc
ra: audio/x-realaudio
jpx: image/jpx
evc: audio/EVRC
mif: application/x-mif
qwd: application/vnd.Quark.QuarkXPress
mp2: video/mpeg
spdf: application/vnd.sealedmedia.softseal.pdf
tbz: application/x-gtar
txt: text/plain
x_b: model/vnd.parasolid.transmit.binary
mp3: audio/mpeg
class: application/x-java-vm
smo: video/vnd.sealedmedia.softseal.mov
mp4: video/vnd.objectvideo
m4v: video/x-m4v
htx: text/html
hbci: application/vnd.hbci
tex: application/x-tex
vsc: application/vnd.vidsoft.vidconference
wqd: application/vnd.wqd
mfm: application/vnd.mfmp
sgml: text/sgml
smp: audio/vnd.sealedmedia.softseal.mpeg
curl: application/vnd.curl
cw: application/prs.cww
djvu: image/vnd.djvu
tga: image/targa
vsd: application/vnd.visio
t: text/troff
wtb: application/vnd.webturbo
spn: image/vnd.sealed.png
plb: application/vnd.3gpp.pic-bw-large
pps: application/powerpoint
yaml: text/x-yaml
psp: image/x-paintshoppro
mjp2: video/MJ2
sms: application/vnd.3gpp.sms
hvd: application/vnd.yamaha.hv-dic
acutc: application/vnd.acucorp
ppt: application/powerpoint
les: application/vnd.hhe.lesson-player
vcf: text/x-vcard
sjpg: image/vnd.sealedmedia.softseal.jpg
kwt: application/vnd.kde.kword
sic: application/vnd.wap.sic
spp: application/vnd.sealed.ppt
cmc: application/vnd.cosmocaller
dot: application/word
sv4cpio: application/x-sv4cpio
cpio: application/x-cpio
sswf: video/vnd.sealed.swf
silo: model/mesh
sid: audio/prs.sid
yml: text/x-yaml
smv: audio/SMV
eps: application/postscript
ptid: application/vnd.pvi.ptid1
wks: application/vnd.lotus-1-2-3
z: application/x-compressed
hpp: text/plain
htmlx: text/html
ani: application/octet-stream
sig: application/pgp-signature
slc: application/vnd.wap.slc
rm: audio/x-pn-realaudio
smpg: video/vnd.sealed.mpeg4
wmls: text/vnd.wap.wmlscript
bin: application/x-mac
mesh: model/mesh
atc: application/vnd.acucorp
pfr: application/font-tdpfr
plj: audio/vnd.everad.plj
rnd: application/prs.nprend
xls: application/excel
tar: application/x-tar
mp3g: video/mpeg
sgif: image/vnd.sealedmedia.softseal.gif
oda: application/oda
sdoc: application/vnd.sealed.doc
kia: application/vnd.kidspiration
prc: application/vnd.palm
req: application/vnd.nervana
xyz: x-chemical/x-xyz
soc: application/sgml-open-catalog
xlt: application/excel
awb: audio/AMR-WB
susp: application/vnd.sus-calendar
xbm: image/x-xbm
ccc: text/vnd.net2phone.commcenter.command
hh: text/plain
qwt: application/vnd.Quark.QuarkXPress
shar: application/x-shar
ssw: video/vnd.sealed.swf
xul: application/vnd.mozilla.xul+xml
kcm: application/vnd.nervana
kpr: application/vnd.kde.kpresenter
cdy: application/vnd.cinderella
nc: application/netcdf
src: application/x-wais-source
sv4crc: application/x-sv4crc
dtd: text/xml
hvp: application/vnd.yamaha.hv-voice
cww: application/prs.cww
vss: application/vnd.visio
rb: application/x-ruby
log: text/plain
swf: application/x-shockwave-flash
flv: video/x-flv
asf: video/x-ms-asf
asx: video/x-ms-asf
wma: audio/x-ms-wma
wax: audio/x-ms-wax
wmv: audio/x-ms-wmv
wvx: video/x-ms-wvx
wm: video/x-ms-wm
wmx: video/x-ms-wmx
wmz: application/x-ms-wmz
wmd: application/x-ms-wmd

View File

@ -1,35 +0,0 @@
class File
def self.mime_type?(file)
if file.class == File
unless RUBY_PLATFORM.include? 'mswin32'
mime = `file -bir #{file.path}`.strip
else
mime = EXTENSIONS[File.extname(file.path).gsub('.','').downcase.to_sym]
end
elsif file.class == String
mime = EXTENSIONS[(file[file.rindex('.')+1, file.size]).downcase.to_sym]
elsif file.class == StringIO
temp = File.open(Dir.tmpdir + '/upload_file.' + Process.pid.to_s, "wb")
temp << file.string
temp.close
mime = `file -bir #{temp.path}`
mime = mime.gsub(/^.*: */,"")
mime = mime.gsub(/;.*$/,"")
mime = mime.gsub(/,.*$/,"")
File.delete(temp.path)
end
if mime
return mime
else
'unknown/unknown'
end
end
def self.extensions
EXTENSIONS
end
end

View File

@ -1,57 +0,0 @@
require File.dirname(__FILE__) + '/spec_helper'
require File.dirname(__FILE__) + '/../lib/mimetype_fu'
describe 'A file with a know extension' do
before(:each) do
@file = File.open(File.dirname(__FILE__) + '/fixtures/file.jpg')
end
it 'should have an extension' do
File.extname(@file.path).should == '.jpg'
end
it 'should have a mime type' do
File.mime_type?(@file).should == "image/jpeg"
end
end
describe 'A file with anunknow extension' do
before(:each) do
@file = File.open(File.dirname(__FILE__) + '/fixtures/file.unknown')
end
it 'should have an extension' do
File.extname(@file.path).should == '.unknown'
end
it 'should have an unkwown mime type' do
File.mime_type?(@file).should == "unknown/unknown"
end
end
describe 'A valid file path' do
before(:each) do
@file_path = "#{Dir.pwd} + /picture.png"
end
it 'should have a mime type' do
File.mime_type?(@file_path).should == "image/png"
end
end
describe "An unknown extension" do
before(:each) do
@file_path = 'file.unknown'
end
it 'should have an unknown mime type' do
File.mime_type?(@file_path).should == "unknown/unknown"
end
end

Some files were not shown because too many files have changed in this diff Show More