tagging. princely

rails2
Espen Antonsen 2009-05-22 22:38:52 +02:00
parent b7eb8027dc
commit c6882bae3c
17 changed files with 321 additions and 2 deletions

View File

@ -1,6 +1,15 @@
class Album < ActiveRecord::Base
has_many :photos
has_many :photos, :dependent => :destroy
validates_uniqueness_of :path, :message => "Album already exsists on disc"
before_destroy :destroy_directory
private
def destroy_directory
#puts "DELETE DIRECTORY " + APP_CONFIG[:photos_path] + self.path
#Dir.delete( APP_CONFIG[:photos_path] + self.path + "/" ) if File.exists?( APP_CONFIG[:photos_path] + self.path )
#Dir.delete( APP_CONFIG[:thumbs_path] + self.path ) if File.exists?( APP_CONFIG[:thumbs_path] + self.path )
end
end

View File

@ -1,5 +1,18 @@
class Photo < ActiveRecord::Base
belongs_to :album
has_many :photo_tags, :dependent => :destroy
has_many :tags, :through => :photo_tags
validates_uniqueness_of :path, :message => "Photo already exsists on disc"
before_destroy :destroy_file
private
def destroy_file
puts "DELETE FILE " + APP_CONFIG[:photos_path] + self.path
File.delete( APP_CONFIG[:photos_path] + self.path ) if File.exists?( APP_CONFIG[:photos_path] + self.path )
File.delete( APP_CONFIG[:thumbs_path] + self.album.path + "/" + self.id.to_s + "_small" + File.extname( APP_CONFIG[:photos_path] + self.path ) ) if File.exists?( APP_CONFIG[:thumbs_path] + self.album.path + "/" + self.id.to_s + "_small" + File.extname( APP_CONFIG[:photos_path] + self.path ) )
File.delete( APP_CONFIG[:thumbs_path] + self.album.path + "/" + self.id.to_s + "_large" + File.extname( APP_CONFIG[:photos_path] + self.path ) ) if File.exists?( APP_CONFIG[:thumbs_path] + self.album.path + "/" + self.id.to_s + "_large" + File.extname( APP_CONFIG[:photos_path] + self.path ) )
end
end

4
app/models/photo_tag.rb Normal file
View File

@ -0,0 +1,4 @@
class PhotoTag < ActiveRecord::Base
belongs_to :tag
belongs_to :photo
end

4
app/models/tag.rb Normal file
View File

@ -0,0 +1,4 @@
class Tag < ActiveRecord::Base
has_many :photo_tags
has_many :photos, :through => :photo_tags
end

View File

@ -0,0 +1,12 @@
class CreateTags < ActiveRecord::Migration
def self.up
create_table :tags do |t|
t.string :title, :length => 150, :null => false
t.timestamps
end
end
def self.down
drop_table :tags
end
end

View File

@ -0,0 +1,13 @@
class CreatePhotoTags < ActiveRecord::Migration
def self.up
create_table :photo_tags do |t|
t.references :tag
t.references :photo
t.timestamps
end
end
def self.down
drop_table :photo_tags
end
end

View File

@ -9,7 +9,7 @@
#
# It's strongly recommended to check this file into your version control system.
ActiveRecord::Schema.define(:version => 20090522131931) do
ActiveRecord::Schema.define(:version => 20090522190622) do
create_table "albums", :force => true do |t|
t.string "title", :null => false
@ -19,6 +19,13 @@ ActiveRecord::Schema.define(:version => 20090522131931) do
t.text "path"
end
create_table "photo_tags", :force => true do |t|
t.integer "tag_id"
t.integer "photo_id"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "photos", :force => true do |t|
t.string "title", :null => false
t.text "description"
@ -28,6 +35,12 @@ ActiveRecord::Schema.define(:version => 20090522131931) do
t.text "path"
end
create_table "tags", :force => true do |t|
t.string "title", :null => false
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "users", :force => true do |t|
t.string "email", :null => false
t.string "crypted_password", :null => false

7
test/fixtures/photo_tags.yml vendored Normal file
View File

@ -0,0 +1,7 @@
# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
# one:
# column: value
#
# two:
# column: value

7
test/fixtures/tags.yml vendored Normal file
View File

@ -0,0 +1,7 @@
# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
# one:
# column: value
#
# two:
# column: value

View File

@ -0,0 +1,8 @@
require 'test_helper'
class PhotoTagTest < ActiveSupport::TestCase
# Replace this with your real tests.
test "the truth" do
assert true
end
end

8
test/unit/tag_test.rb Normal file
View File

@ -0,0 +1,8 @@
require 'test_helper'
class TagTest < ActiveSupport::TestCase
# Replace this with your real tests.
test "the truth" do
assert true
end
end

20
vendor/plugins/princely/MIT-LICENSE vendored Normal file
View File

@ -0,0 +1,20 @@
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.

50
vendor/plugins/princely/README vendored Normal file
View File

@ -0,0 +1,50 @@
Princely
========
Princely is a simple wrapper for the Prince XML PDF generation library
(http://www.princexml.com). It is almost entirely based on the SubImage
Prince library found on this blog post:
http://sublog.subimage.com/articles/2007/05/29/html-css-to-pdf-using-ruby-on-rails
I have taken the helpers and made them a little bit more generalized and
reusable, and created a render option set for pdf generation. The plugin
will also automatically register the PDF MimeType so that you can use
pdf in controller respond_to blocks.
Example
=======
class Provider::EstimatesController < Provider::BaseController
def show
respond_to do |format|
format.html
format.pdf do
render :pdf => "file_name",
:template => "controller/action.pdf.erb",
:stylesheets => ["application","prince"]
:layout => "pdf"
end
end
end
def pdf
make_and_send_pdf("file_name")
end
end
Render Defaults
===============
The defaults for the render options are as follows:
layout: false
template: the template for the current controller/action
stylesheets: none
Resources
=========
Trac: http://trac.intridea.com/trac/public/
Copyright (c) 2007 Michael Bleigh and Intridea, Inc., released under the MIT license

15
vendor/plugins/princely/Rakefile vendored Normal file
View File

@ -0,0 +1,15 @@
require 'rake'
require 'rake/testtask'
require 'rake/rdoctask'
desc 'Default: run unit tests.'
task :default => :test
desc 'Generate documentation for the princely plugin.'
Rake::RDocTask.new(:rdoc) do |rdoc|
rdoc.rdoc_dir = 'rdoc'
rdoc.title = 'Princely'
rdoc.options << '--line-numbers' << '--inline-source'
rdoc.rdoc_files.include('README')
rdoc.rdoc_files.include('lib/**/*.rb')
end

6
vendor/plugins/princely/init.rb vendored Normal file
View File

@ -0,0 +1,6 @@
require 'prince'
require 'pdf_helper'
Mime::Type.register 'application/pdf', :pdf
ActionController::Base.send(:include, PdfHelper)

View File

@ -0,0 +1,55 @@
module PdfHelper
require 'prince'
def self.included(base)
base.class_eval do
alias_method_chain :render, :princely
end
end
def render_with_princely(options = nil, *args, &block)
if options.is_a?(Hash) && options.has_key?(:pdf)
options[:name] ||= options.delete(:pdf)
make_and_send_pdf(options.delete(:name), options)
else
render_without_princely(options, *args, &block)
end
end
private
def make_pdf(options = {})
options[:stylesheets] ||= []
options[:layout] ||= false
options[:template] ||= File.join(controller_path,action_name)
prince = Prince.new()
# Sets style sheets on PDF renderer
prince.add_style_sheets(*options[:stylesheets].collect{|style| stylesheet_file_path(style)})
html_string = render_to_string(:template => options[:template], :layout => options[:layout])
# Make all paths relative, on disk paths...
html_string.gsub!(".com:/",".com/") # strip out bad attachment_fu URLs
html_string.gsub!( /src=["']+([^:]+?)["']/i ) { |m| "src=\"#{RAILS_ROOT}/public/" + $1 + '"' } # re-route absolute paths
# Remove asset ids on images with a regex
html_string.gsub!( /src=["'](\S+\?\d*)["']/i ) { |m| 'src="' + $1.split('?').first + '"' }
# Send the generated PDF file from our html string.
return prince.pdf_from_string(html_string)
end
def make_and_send_pdf(pdf_name, options = {})
send_data(
make_pdf(options),
:filename => pdf_name + ".pdf",
:type => 'application/pdf'
)
end
def stylesheet_file_path(stylesheet)
stylesheet = stylesheet.to_s.gsub(".css","")
File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR,"#{stylesheet}.css")
end
end

75
vendor/plugins/princely/lib/prince.rb vendored Normal file
View File

@ -0,0 +1,75 @@
# Prince XML Ruby interface.
# http://www.princexml.com
#
# Library by Subimage Interactive - http://www.subimage.com
#
#
# USAGE
# -----------------------------------------------------------------------------
# prince = Prince.new()
# html_string = render_to_string(:template => 'some_document')
# send_data(
# prince.pdf_from_string(html_string),
# :filename => 'some_document.pdf'
# :type => 'application/pdf'
# )
#
require 'logger'
class Prince
attr_accessor :exe_path, :style_sheets, :log_file, :logger
# Initialize method
#
def initialize()
# Finds where the application lives, so we can call it.
@exe_path = `which prince`.chomp
@style_sheets = ''
@log_file = "#{RAILS_ROOT}/log/prince.log"
@logger = RAILS_DEFAULT_LOGGER
end
# Sets stylesheets...
# Can pass in multiple paths for css files.
#
def add_style_sheets(*sheets)
for sheet in sheets do
@style_sheets << " -s #{sheet} "
end
end
# Returns fully formed executable path with any command line switches
# we've set based on our variables.
#
def exe_path
# Add any standard cmd line arguments we need to pass
@exe_path << " --input=html --server --log=#{@log_file} "
@exe_path << @style_sheets
return @exe_path
end
# Makes a pdf from a passed in string.
#
# Returns PDF as a stream, so we can use send_data to shoot
# it down the pipe using Rails.
#
def pdf_from_string(string)
path = self.exe_path()
# Don't spew errors to the standard out...and set up to take IO
# as input and output
path << ' --silent - -o -'
# Show the command used...
logger.info "\n\nPRINCE XML PDF COMMAND"
logger.info path
logger.info ''
# Actually call the prince command, and pass the entire data stream back.
pdf = IO.popen(path, "w+")
pdf.puts(string)
pdf.close_write
result = pdf.gets(nil)
pdf.close_read
return result
end
end