jakewendt-simply_documents 1.3.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. data/README.rdoc +70 -0
  2. data/app/controllers/documents_controller.rb +99 -0
  3. data/app/models/document.rb +28 -0
  4. data/app/views/documents/_document.html.erb +15 -0
  5. data/app/views/documents/_form.html.erb +13 -0
  6. data/app/views/documents/edit.html.erb +14 -0
  7. data/app/views/documents/index.html.erb +15 -0
  8. data/app/views/documents/new.html.erb +11 -0
  9. data/app/views/documents/preview.html.erb +17 -0
  10. data/config/document.yml +54 -0
  11. data/config/routes.rb +5 -0
  12. data/generators/simply_documents/USAGE +0 -0
  13. data/generators/simply_documents/simply_documents_generator.rb +87 -0
  14. data/generators/simply_documents/templates/autotest_simply_documents.rb +2 -0
  15. data/generators/simply_documents/templates/functional/documents_controller_test.rb +220 -0
  16. data/generators/simply_documents/templates/javascripts/documents.js +0 -0
  17. data/generators/simply_documents/templates/migrations/add_attachments_document_to_document.rb +19 -0
  18. data/generators/simply_documents/templates/migrations/create_documents.rb +19 -0
  19. data/generators/simply_documents/templates/migrations/polymorphicize_document_owner.rb +13 -0
  20. data/generators/simply_documents/templates/simply_documents.rake +6 -0
  21. data/generators/simply_documents/templates/stylesheets/documents.css +4 -0
  22. data/generators/simply_documents/templates/unit/document_test.rb +18 -0
  23. data/lib/jakewendt-simply_documents.rb +1 -0
  24. data/lib/simply_documents.rb +54 -0
  25. data/lib/simply_documents/autotest.rb +26 -0
  26. data/lib/simply_documents/factories.rb +4 -0
  27. data/lib/simply_documents/file_utils_extension.rb +18 -0
  28. data/lib/simply_documents/owner.rb +12 -0
  29. data/lib/simply_documents/tasks.rb +1 -0
  30. data/lib/simply_documents/test_tasks.rb +56 -0
  31. data/lib/tasks/application.rake +40 -0
  32. data/lib/tasks/database.rake +52 -0
  33. data/lib/tasks/documentation.rake +68 -0
  34. data/lib/tasks/rcov.rake +44 -0
  35. data/lib/tasks/simply_authorized.rake +2 -0
  36. data/lib/tasks/simply_helpful.rake +2 -0
  37. data/lib/tasks/simply_sessions.rake +5 -0
  38. data/lib/tasks/ucb_ccls_engine_tasks.rake +50 -0
  39. data/rails/init.rb +1 -0
  40. data/test/app/controllers/application_controller.rb +41 -0
  41. data/test/app/controllers/home_controller.rb +10 -0
  42. data/test/app/models/user.rb +3 -0
  43. data/test/assets/edit_save_wireframe.pdf +0 -0
  44. data/test/config/routes.rb +9 -0
  45. data/test/functional/documents/documents_controller_test.rb +222 -0
  46. data/test/unit/documents/document_test.rb +18 -0
  47. metadata +271 -0
@@ -0,0 +1,70 @@
1
+ = SimplyDocuments
2
+
3
+ == ToDo
4
+
5
+
6
+
7
+ == Required Gem Sources
8
+
9
+ gem sources -a http://rubygems.org
10
+ gem sources -a http://gems.github.com
11
+
12
+
13
+ == Required Gems
14
+
15
+ * {jakewendt-assert_this_and_that}[http://github.com/jakewendt/assert_this_and_that]
16
+ * {jakewendt-ruby_extension}[http://github.com/jakewendt/ruby_extension] - modifications, updates and patches for ruby.
17
+ * rails ~> 2
18
+ * chronic
19
+ * ruby-hmac
20
+ * aws-s3
21
+ * ssl_requirement
22
+ * ryanb-acts-as-list
23
+ * RedCloth
24
+ * paperclip
25
+ * thoughtbot-factory_girl
26
+ * {jakewendt-simply_helpful}[http://github.com/jakewendt/simply_helpful]
27
+ * {jakewendt-simply_authorized}[http://github.com/jakewendt/simply_authorized]
28
+ * {jakewendt-calnet_authenticated}[http://github.com/jakewendt/calnet_authenticated]
29
+
30
+
31
+ == Installation and Usage
32
+
33
+ cp config/s3.yml.example config/s3.yml
34
+ # Add your own s3 access keys. Leave 'test' as it is.
35
+
36
+ config.gem 'jakewendt-simply_documents',
37
+ :source => 'http://rubygems.org'
38
+
39
+ class User (or whatever)
40
+ document_owner
41
+ end
42
+
43
+ script/generate simply_documents
44
+
45
+ User.find_create_and_update_by_uid('859908').deputize
46
+
47
+ == Testing (as an app)
48
+
49
+ rake db:migrate
50
+ rake db:fixtures:load
51
+ rake test
52
+ script/server
53
+
54
+
55
+ == Gemified with Jeweler
56
+
57
+ vi Rakefile
58
+ rake version:write
59
+
60
+ rake version:bump:patch
61
+ rake version:bump:minor
62
+ rake version:bump:major
63
+
64
+ rake gemspec
65
+
66
+ rake install
67
+ rake release
68
+
69
+
70
+ Copyright (c) 2010 [Jake Wendt], released under the MIT license
@@ -0,0 +1,99 @@
1
+ class DocumentsController < ApplicationController
2
+
3
+ before_filter :login_required
4
+
5
+ before_filter :may_maintain_pages_required
6
+ before_filter :document_required, :only => :show
7
+ before_filter :id_required,
8
+ :only => [ :edit, :update, :destroy, :preview ]
9
+
10
+ def show
11
+ if @document.document.path.blank?
12
+ flash[:error] = "Does not contain a document"
13
+ redirect_to preview_document_path(@document)
14
+ elsif @document.document.exists?
15
+ #puts "Document exists!"
16
+ if @document.document.options[:storage] == :filesystem # &&
17
+ # File.exists?(@document.document.path)
18
+ # basically development or non-s3 setup
19
+ send_file @document.document.path
20
+ else
21
+ #puts "Storage is S3?"
22
+
23
+ # Privacy filters are still not active
24
+ # basically a private s3 file
25
+ # redirect_to @document.s3_url
26
+ redirect_to @document.document.expiring_url
27
+
28
+ end
29
+ else
30
+ flash[:error] = "Document does not exist at the expected location."
31
+ redirect_to preview_document_path(@document)
32
+ end
33
+ end
34
+
35
+ def preview
36
+ # # otherwise looks for template for pdf, jpg or whatever
37
+ # params[:format] = 'html'
38
+ end
39
+
40
+ def index
41
+ @documents = Document.all
42
+ end
43
+
44
+ def new
45
+ @document = Document.new
46
+ end
47
+
48
+ def create
49
+ @document = Document.new(params[:document])
50
+ @document.save!
51
+ redirect_to preview_document_path(@document)
52
+ rescue ActiveRecord::RecordInvalid
53
+ flash.now[:error] = "Error"
54
+ render :action => 'new'
55
+ end
56
+
57
+ def update
58
+ @document.update_attributes!(params[:document])
59
+ redirect_to preview_document_path(@document)
60
+ rescue ActiveRecord::RecordInvalid
61
+ flash.now[:error] = "Error"
62
+ render :action => 'edit'
63
+ end
64
+
65
+ def destroy
66
+ @document.destroy
67
+ redirect_to documents_path
68
+ end
69
+
70
+ protected
71
+
72
+ def id_required
73
+ if !params[:id].blank? and Document.exists?(params[:id])
74
+ @document = Document.find(params[:id])
75
+ else
76
+ access_denied("Valid document id required!", documents_path)
77
+ end
78
+ end
79
+
80
+ def document_required
81
+ if !params[:id].blank? and Document.exists?(params[:id])
82
+ @document = Document.find(params[:id])
83
+ elsif !params[:id].blank? and Document.exists?(
84
+ :document_file_name => "#{params[:id]}.#{params[:format]}")
85
+ documents = Document.find(:all, :conditions => {
86
+ :document_file_name => "#{params[:id]}.#{params[:format]}"})
87
+ # Due to the unique index, there can be only one!
88
+ # if documents.length > 1
89
+ # access_denied("More than one document matches #{params[:id]}!",
90
+ # documents_path)
91
+ # else
92
+ @document=documents[0]
93
+ # end
94
+ else
95
+ access_denied("Valid document id required!", documents_path)
96
+ end
97
+ end
98
+
99
+ end
@@ -0,0 +1,28 @@
1
+ require 'hmac-sha1'
2
+ #
3
+ # http://amazon.rubyforge.org/
4
+ #
5
+ class Document < ActiveRecord::Base
6
+ belongs_to :owner, :polymorphic => true
7
+
8
+ validates_presence_of :title
9
+ validates_length_of :title, :minimum => 4
10
+
11
+ validates_uniqueness_of :document_file_name, :allow_nil => true
12
+
13
+ before_validation :nullify_blank_document_file_name
14
+
15
+ has_attached_file :document,
16
+ YAML::load(ERB.new(IO.read(File.expand_path(
17
+ File.join(File.dirname(__FILE__),'../..','config/document.yml')
18
+ ))).result)[Rails.env]
19
+
20
+ def nullify_blank_document_file_name
21
+ self.document_file_name = nil if document_file_name.blank?
22
+ end
23
+
24
+ def to_s
25
+ title
26
+ end
27
+
28
+ end
@@ -0,0 +1,15 @@
1
+ <% content_tag_for( :tr, document, :class => 'row' ) do %>
2
+ <td class='title'>
3
+ <%= link_to document.title, preview_document_path(document) %>
4
+ </td>
5
+ <td class='path'>
6
+ <%= document.document_file_name %>
7
+ </td>
8
+ <td class='manage'>
9
+ <%= button_link_to 'Edit', edit_document_path(document) %>&nbsp;
10
+ <% destroy_link_to 'Destroy', document_path(document) do %>
11
+ <%= hidden_field_tag 'confirm', "Destroy document '#{document}'?",
12
+ :id => nil %>
13
+ <% end %>
14
+ </td>
15
+ <% end %><!-- class='document row' -->
@@ -0,0 +1,13 @@
1
+ <% stylesheets('documents') %>
2
+
3
+ <%= f.wrapped_text_field :title %>
4
+
5
+ <div>
6
+ <div class='document'>
7
+ <%= f.wrapped_file_field :document %>
8
+ <% unless @document.new_record? -%>
9
+ (<%= @document.document.url -%>)
10
+ <% end -%><br />
11
+ </div>
12
+ </div>
13
+ <%= f.wrapped_text_area :abstract %>
@@ -0,0 +1,14 @@
1
+ <h2>Editing Document</h2>
2
+
3
+ <% form_for(@document,
4
+ :html => { :multipart => true }) do |f| %>
5
+ <%= f.error_messages %>
6
+ <%= render 'form',:f => f %>
7
+ <p>
8
+ <%= f.submit( "Update this Document" )%>&nbsp;
9
+ <%= button_link_to 'Preview this Document',
10
+ preview_document_path(@document) %>&nbsp;
11
+ <%= button_link_to 'Download this Document', @document %>&nbsp;
12
+ <%= button_link_to 'Back to Documents', documents_path %>
13
+ </p>
14
+ <% end %>
@@ -0,0 +1,15 @@
1
+ <% javascripts('simply_helpful') %>
2
+ <% stylesheets('documents') %>
3
+
4
+ <h2>Documents</h2>
5
+ <% if @documents.length > 0 %>
6
+ <table id='documents'><tbody>
7
+ <%= render :partial => 'document', :collection => @documents %>
8
+ </tbody></table><!-- id='documents' -->
9
+ <% else %>
10
+ Sorry, but no documents yet.
11
+ <% end %>
12
+
13
+ <p>
14
+ <%= button_link_to 'Create New Document', new_document_path %>
15
+ </p>
@@ -0,0 +1,11 @@
1
+ <h2>New Document</h2>
2
+
3
+ <% form_for(@document,
4
+ :html => { :multipart => true }) do |f| %>
5
+ <%= f.error_messages %>
6
+ <%= render 'form',:f => f %>
7
+ <p>
8
+ <%= f.submit( "Create new Document" )%>
9
+ <%= button_link_to 'Back to Documents', documents_path %>
10
+ </p>
11
+ <% end %>
@@ -0,0 +1,17 @@
1
+ <%# stylesheets('document') %>
2
+
3
+ <p>
4
+ <b>Title:</b>
5
+ <%=h @document.title %>
6
+ </p>
7
+
8
+ <p>
9
+ <b>Abstract:</b>
10
+ <%=h @document.abstract %>
11
+ </p>
12
+
13
+ <%= button_link_to 'Download this Document',
14
+ document_path(@document) %>&nbsp;
15
+ <%= button_link_to 'Edit this Document',
16
+ edit_document_path(@document) %>&nbsp;
17
+ <%= button_link_to 'Back to Documents', documents_path %>
@@ -0,0 +1,54 @@
1
+ #DEFAULTS: &DEFAULTS
2
+ # :styles:
3
+ # :full: '900'
4
+ # :large: '800'
5
+ # :medium: '600'
6
+ # :small: '150x50'
7
+
8
+ # :attachment is the attachment name NOT the model name
9
+ # for document they are the same
10
+
11
+ <% common = "documents/:id/:filename" %>
12
+
13
+ #>> Rails.root.to_s.split('/')
14
+ #=> ["", "var", "lib", "tomcat5", "webapps", "clic", "WEB-INF"]
15
+
16
+ #>> Rails.root.to_s.split('/')
17
+ #=> ["", "Users", "jakewendt", "github_repo", "jakewendt", "ucb_ccls_clic"]
18
+
19
+ <%
20
+ app_name = ( defined?(RAILS_APP_NAME) ) ?
21
+ RAILS_APP_NAME :
22
+ Rails.root.to_s.split('/').reject{|x|x == "WEB-INF"}.last
23
+ %>
24
+
25
+ development:
26
+ :path: <%= "#{Rails.root}/development/#{common}" %>
27
+ # <<: *DEFAULTS
28
+
29
+ test:
30
+ :path: <%= "#{Rails.root}/test/#{common}" %>
31
+ # <<: *DEFAULTS
32
+
33
+ #production:
34
+ # :path: <%= "/home/tomcat/#{app_name}/:attachment/:id/:filename" %>
35
+ ## # <<: *DEFAULTS
36
+
37
+ production:
38
+ # Set the storage class to RRS which is cheaper than
39
+ # the default of STANDARD
40
+ :s3_headers:
41
+ x-amz-storage-class: REDUCED_REDUNDANCY
42
+ # public_read or private
43
+ :s3_permissions: :private
44
+ :storage: :s3
45
+ :s3_protocol: https
46
+ :s3_credentials: <%="#{Rails.root}/config/s3.yml" %>
47
+ :bucket: <%= app_name %>
48
+ # common has a : as the first char so it needs special care
49
+ # or the string will magically be turned into a symbol
50
+ # which isn't what we want
51
+ # Not anymore.
52
+ :path: <%= common %>
53
+ # S3 must have a defined path or will generate
54
+ # "Stack level too deep" errors
@@ -0,0 +1,5 @@
1
+ ActionController::Routing::Routes.draw do |map|
2
+
3
+ map.resources :documents, :member => { :preview => :get }
4
+
5
+ end
File without changes
@@ -0,0 +1,87 @@
1
+ class SimplyDocumentsGenerator < Rails::Generator::Base
2
+
3
+ def manifest
4
+ # See Rails::Generator::Commands::Create
5
+ # rails-2.3.10/lib/rails_generator/commands.rb
6
+ # for code methods for record (Manifest)
7
+ record do |m|
8
+ m.directory('config/autotest')
9
+ m.file('autotest_simply_documents.rb', 'config/autotest/simply_documents.rb')
10
+ m.directory('lib/tasks')
11
+ m.file('simply_documents.rake', 'lib/tasks/simply_documents.rake')
12
+
13
+ # File.open('Rakefile','a'){|f|
14
+ # f.puts <<-EOF
15
+ ## From `script/generate simply_documents` ...
16
+ #require 'simply_documents/test_tasks'
17
+ # EOF
18
+ # }
19
+ #
20
+ # File.open('.autotest','a'){|f|
21
+ # f.puts <<-EOF
22
+ ## From `script/generate simply_documents` ...
23
+ #require 'simply_documents/autotest'
24
+ # EOF
25
+ # }
26
+
27
+ %w( create_documents
28
+ add_attachments_document_to_document
29
+ polymorphicize_document_owner
30
+ ).each do |migration|
31
+ m.migration_template "migrations/#{migration}.rb",
32
+ 'db/migrate', :migration_file_name => migration
33
+ end
34
+
35
+ m.directory('public/javascripts')
36
+ Dir["#{File.dirname(__FILE__)}/templates/javascripts/*js"].each{|file|
37
+ f = file.split('/').slice(-2,2).join('/')
38
+ m.file(f, "public/javascripts/#{File.basename(file)}")
39
+ }
40
+ m.directory('public/stylesheets')
41
+ Dir["#{File.dirname(__FILE__)}/templates/stylesheets/*css"].each{|file|
42
+ f = file.split('/').slice(-2,2).join('/')
43
+ m.file(f, "public/stylesheets/#{File.basename(file)}")
44
+ }
45
+ # m.directory('test/functional/documents')
46
+ # Dir["#{File.dirname(__FILE__)}/templates/functional/*rb"].each{|file|
47
+ # f = file.split('/').slice(-2,2).join('/')
48
+ # m.file(f, "test/functional/documents/#{File.basename(file)}")
49
+ # }
50
+ # m.directory('test/unit/documents')
51
+ # Dir["#{File.dirname(__FILE__)}/templates/unit/*rb"].each{|file|
52
+ # f = file.split('/').slice(-2,2).join('/')
53
+ # m.file(f, "test/unit/documents/#{File.basename(file)}")
54
+ # }
55
+ end
56
+ end
57
+
58
+ end
59
+ module Rails::Generator::Commands
60
+ class Create
61
+ def migration_template(relative_source,
62
+ relative_destination, template_options = {})
63
+ migration_directory relative_destination
64
+ migration_file_name = template_options[
65
+ :migration_file_name] || file_name
66
+ if migration_exists?(migration_file_name)
67
+ puts "Another migration is already named #{migration_file_name}: #{existing_migrations(migration_file_name).first}: Skipping"
68
+ else
69
+ template(relative_source, "#{relative_destination}/#{next_migration_string}_#{migration_file_name}.rb", template_options)
70
+ end
71
+ end
72
+ end # Create
73
+ class Base
74
+ protected
75
+ # the loop through migrations happens so fast
76
+ # that they all have the same timestamp which
77
+ # won't work when you actually try to migrate.
78
+ # All the timestamps MUST be unique.
79
+ def next_migration_string(padding = 3)
80
+ @s = (!@s.nil?)? @s.to_i + 1 : if ActiveRecord::Base.timestamped_migrations
81
+ Time.now.utc.strftime("%Y%m%d%H%M%S")
82
+ else
83
+ "%.#{padding}d" % next_migration_number
84
+ end
85
+ end
86
+ end # Base
87
+ end