cortex-reaver 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +25 -0
- data/README +48 -0
- data/bin/console +11 -0
- data/bin/cortex_reaver +110 -0
- data/bin/import.rb +78 -0
- data/lib/cortex_reaver.rb +114 -0
- data/lib/cortex_reaver/config.rb +21 -0
- data/lib/cortex_reaver/controller/comment.rb +113 -0
- data/lib/cortex_reaver/controller/config.rb +14 -0
- data/lib/cortex_reaver/controller/journal.rb +40 -0
- data/lib/cortex_reaver/controller/main.rb +56 -0
- data/lib/cortex_reaver/controller/page.rb +34 -0
- data/lib/cortex_reaver/controller/photograph.rb +45 -0
- data/lib/cortex_reaver/controller/project.rb +40 -0
- data/lib/cortex_reaver/controller/tag.rb +67 -0
- data/lib/cortex_reaver/controller/user.rb +71 -0
- data/lib/cortex_reaver/helper/activity.rb +9 -0
- data/lib/cortex_reaver/helper/attachments.rb +139 -0
- data/lib/cortex_reaver/helper/auth.rb +45 -0
- data/lib/cortex_reaver/helper/canonical.rb +55 -0
- data/lib/cortex_reaver/helper/crud.rb +317 -0
- data/lib/cortex_reaver/helper/date.rb +29 -0
- data/lib/cortex_reaver/helper/error.rb +14 -0
- data/lib/cortex_reaver/helper/feeds.rb +88 -0
- data/lib/cortex_reaver/helper/form.rb +114 -0
- data/lib/cortex_reaver/helper/navigation.rb +142 -0
- data/lib/cortex_reaver/helper/photographs.rb +25 -0
- data/lib/cortex_reaver/helper/tags.rb +47 -0
- data/lib/cortex_reaver/helper/workflow.rb +27 -0
- data/lib/cortex_reaver/migrations/001_users.rb +24 -0
- data/lib/cortex_reaver/migrations/002_pages.rb +29 -0
- data/lib/cortex_reaver/migrations/003_journals.rb +26 -0
- data/lib/cortex_reaver/migrations/004_photographs.rb +24 -0
- data/lib/cortex_reaver/migrations/005_projects.rb +27 -0
- data/lib/cortex_reaver/migrations/006_tags.rb +64 -0
- data/lib/cortex_reaver/migrations/007_comments.rb +40 -0
- data/lib/cortex_reaver/migrations/008_config.rb +23 -0
- data/lib/cortex_reaver/model/comment.rb +109 -0
- data/lib/cortex_reaver/model/journal.rb +53 -0
- data/lib/cortex_reaver/model/page.rb +87 -0
- data/lib/cortex_reaver/model/photograph.rb +133 -0
- data/lib/cortex_reaver/model/project.rb +49 -0
- data/lib/cortex_reaver/model/tag.rb +72 -0
- data/lib/cortex_reaver/model/user.rb +147 -0
- data/lib/cortex_reaver/public/css/admin.css +45 -0
- data/lib/cortex_reaver/public/css/custom.css +0 -0
- data/lib/cortex_reaver/public/css/form.css +51 -0
- data/lib/cortex_reaver/public/css/main.css +325 -0
- data/lib/cortex_reaver/public/css/photo.css +113 -0
- data/lib/cortex_reaver/public/css/ramaze_error.css +90 -0
- data/lib/cortex_reaver/public/css/text.css +25 -0
- data/lib/cortex_reaver/public/dispatch.fcgi +11 -0
- data/lib/cortex_reaver/public/images/CortexReaver.gif +0 -0
- data/lib/cortex_reaver/public/images/atom-xml-icon.png +0 -0
- data/lib/cortex_reaver/public/images/body.png +0 -0
- data/lib/cortex_reaver/public/images/border_bottom.png +0 -0
- data/lib/cortex_reaver/public/images/border_bottom_left.png +0 -0
- data/lib/cortex_reaver/public/images/border_bottom_right.png +0 -0
- data/lib/cortex_reaver/public/images/border_left.png +0 -0
- data/lib/cortex_reaver/public/images/border_right.png +0 -0
- data/lib/cortex_reaver/public/images/border_top.png +0 -0
- data/lib/cortex_reaver/public/images/border_top_left.png +0 -0
- data/lib/cortex_reaver/public/images/border_top_right.png +0 -0
- data/lib/cortex_reaver/public/images/comment.gif +0 -0
- data/lib/cortex_reaver/public/images/dark_trans.png +0 -0
- data/lib/cortex_reaver/public/images/delete.gif +0 -0
- data/lib/cortex_reaver/public/images/edit.gif +0 -0
- data/lib/cortex_reaver/public/images/header.png +0 -0
- data/lib/cortex_reaver/public/images/header.xcf +0 -0
- data/lib/cortex_reaver/public/images/header_background.png +0 -0
- data/lib/cortex_reaver/public/images/parent.gif +0 -0
- data/lib/cortex_reaver/public/images/rss-xml-icon.png +0 -0
- data/lib/cortex_reaver/public/images/sections.png +0 -0
- data/lib/cortex_reaver/public/images/sections_highlight.png +0 -0
- data/lib/cortex_reaver/public/js/admin.js +36 -0
- data/lib/cortex_reaver/public/js/cookie.js +27 -0
- data/lib/cortex_reaver/public/js/jquery.js +32 -0
- data/lib/cortex_reaver/public/js/photo.js +33 -0
- data/lib/cortex_reaver/snippets/array.rb +7 -0
- data/lib/cortex_reaver/snippets/ramaze/dispatcher/file.rb +37 -0
- data/lib/cortex_reaver/support/attachments.rb +235 -0
- data/lib/cortex_reaver/support/cached_rendering.rb +79 -0
- data/lib/cortex_reaver/support/canonical.rb +107 -0
- data/lib/cortex_reaver/support/comments.rb +69 -0
- data/lib/cortex_reaver/support/pagination.rb +38 -0
- data/lib/cortex_reaver/support/renderer.rb +196 -0
- data/lib/cortex_reaver/support/sequenceable.rb +248 -0
- data/lib/cortex_reaver/support/tags.rb +108 -0
- data/lib/cortex_reaver/support/timestamps.rb +33 -0
- data/lib/cortex_reaver/version.rb +8 -0
- data/lib/cortex_reaver/view/adminbox.rhtml +56 -0
- data/lib/cortex_reaver/view/blank_layout.rhtml +46 -0
- data/lib/cortex_reaver/view/comments/comment.rhtml +34 -0
- data/lib/cortex_reaver/view/comments/form.rhtml +25 -0
- data/lib/cortex_reaver/view/comments/list.rhtml +5 -0
- data/lib/cortex_reaver/view/comments/post_form.rhtml +36 -0
- data/lib/cortex_reaver/view/config/form.rhtml +10 -0
- data/lib/cortex_reaver/view/error.rhtml +72 -0
- data/lib/cortex_reaver/view/journals/form.rhtml +12 -0
- data/lib/cortex_reaver/view/journals/journal.rhtml +39 -0
- data/lib/cortex_reaver/view/journals/list.rhtml +33 -0
- data/lib/cortex_reaver/view/journals/short.rhtml +3 -0
- data/lib/cortex_reaver/view/journals/show.rhtml +5 -0
- data/lib/cortex_reaver/view/pages/form.rhtml +12 -0
- data/lib/cortex_reaver/view/pages/list.rhtml +26 -0
- data/lib/cortex_reaver/view/pages/show.rhtml +12 -0
- data/lib/cortex_reaver/view/photographs/atom_fragment.rhtml +82 -0
- data/lib/cortex_reaver/view/photographs/form.rhtml +19 -0
- data/lib/cortex_reaver/view/photographs/grid.rhtml +36 -0
- data/lib/cortex_reaver/view/photographs/list.rhtml +9 -0
- data/lib/cortex_reaver/view/photographs/short.rhtml +3 -0
- data/lib/cortex_reaver/view/photographs/show.rhtml +114 -0
- data/lib/cortex_reaver/view/photographs/sidebar.rhtml +7 -0
- data/lib/cortex_reaver/view/projects/form.rhtml +13 -0
- data/lib/cortex_reaver/view/projects/list.rhtml +27 -0
- data/lib/cortex_reaver/view/projects/show.rhtml +38 -0
- data/lib/cortex_reaver/view/tags/form.rhtml +9 -0
- data/lib/cortex_reaver/view/tags/list.rhtml +28 -0
- data/lib/cortex_reaver/view/tags/show.rhtml +51 -0
- data/lib/cortex_reaver/view/text_layout.rhtml +78 -0
- data/lib/cortex_reaver/view/users/form.rhtml +16 -0
- data/lib/cortex_reaver/view/users/list.rhtml +38 -0
- data/lib/cortex_reaver/view/users/login.rhtml +13 -0
- data/lib/cortex_reaver/view/users/register.rhtml +13 -0
- data/lib/cortex_reaver/view/users/show.rhtml +37 -0
- data/lib/cortex_reaver/view/users/user.rhtml +35 -0
- data/lib/proto/cortex_reaver.yaml +28 -0
- metadata +285 -0
@@ -0,0 +1,40 @@
|
|
1
|
+
module CortexReaver
|
2
|
+
class JournalController < Ramaze::Controller
|
3
|
+
MODEL = Journal
|
4
|
+
|
5
|
+
map '/journals'
|
6
|
+
layout '/text_layout'
|
7
|
+
deny_layout :atom
|
8
|
+
template :edit, :form
|
9
|
+
template :new, :form
|
10
|
+
engine :Erubis
|
11
|
+
|
12
|
+
helper :error,
|
13
|
+
:auth,
|
14
|
+
:form,
|
15
|
+
:workflow,
|
16
|
+
:navigation,
|
17
|
+
:date,
|
18
|
+
:tags,
|
19
|
+
:canonical,
|
20
|
+
:crud,
|
21
|
+
:attachments,
|
22
|
+
:feeds
|
23
|
+
|
24
|
+
on_second_save do |journal, request|
|
25
|
+
journal.tags = request[:tags]
|
26
|
+
add_attachments(journal, request[:attachments])
|
27
|
+
journal.body = request[:body]
|
28
|
+
end
|
29
|
+
|
30
|
+
on_save do |journal, request|
|
31
|
+
journal.title = request[:title]
|
32
|
+
journal.name = Journal.canonicalize request[:name], journal.id
|
33
|
+
journal.user = session[:user]
|
34
|
+
end
|
35
|
+
|
36
|
+
for_feed do |journal, x|
|
37
|
+
x.content journal.body_cache, :type => 'html'
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'builder'
|
2
|
+
|
3
|
+
module CortexReaver
|
4
|
+
class MainController < Ramaze::Controller
|
5
|
+
map '/'
|
6
|
+
layout '/text_layout'
|
7
|
+
helper :workflow, :auth, :error, :navigation, :date, :tags, :form, :feeds
|
8
|
+
engine :Erubis
|
9
|
+
|
10
|
+
# the index action is called automatically when no other action is specified
|
11
|
+
def index(id = nil)
|
12
|
+
if id and @page = Page.get(id)
|
13
|
+
# Render that page.
|
14
|
+
@title = @page.title
|
15
|
+
|
16
|
+
workflow "Edit this page", R(PageController, :edit, @page.name)
|
17
|
+
workflow "Delete this page", R(PageController, :delete, @page.name)
|
18
|
+
|
19
|
+
render_template 'pages/show'
|
20
|
+
elsif id
|
21
|
+
# Didn't have that page
|
22
|
+
error_404
|
23
|
+
else
|
24
|
+
# Default welcome page
|
25
|
+
@photographs = Photograph.recent
|
26
|
+
@journals = Journal.recent
|
27
|
+
|
28
|
+
if @photographs.size > 0
|
29
|
+
@sidebar ||= []
|
30
|
+
@sidebar.unshift render_template('photographs/sidebar.rhtml')
|
31
|
+
end
|
32
|
+
|
33
|
+
workflow "New Page", R(JournalController, :new)
|
34
|
+
workflow "New Project", R(JournalController, :new)
|
35
|
+
workflow "New Journal", R(JournalController, :new)
|
36
|
+
workflow "New Photograph", R(JournalController, :new)
|
37
|
+
|
38
|
+
feed 'Photographs', Rs(PhotographController, :atom)
|
39
|
+
feed 'Journals', Rs(JournalController, :atom)
|
40
|
+
feed 'Projects', Rs(ProjectController, :atom)
|
41
|
+
feed 'Comments', Rs(CommentController, :atom)
|
42
|
+
|
43
|
+
render_template 'journals/list.rhtml'
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
# the string returned at the end of the function is used as the html body
|
50
|
+
# if there is no template for the action. if there is a template, the string
|
51
|
+
# is silently ignored
|
52
|
+
def notemplate
|
53
|
+
"there is no 'notemplate.xhtml' associated with this action"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module CortexReaver
|
2
|
+
class PageController < Ramaze::Controller
|
3
|
+
MODEL = Page
|
4
|
+
|
5
|
+
map '/pages'
|
6
|
+
layout '/text_layout'
|
7
|
+
template :edit, :form
|
8
|
+
template :new, :form
|
9
|
+
engine :Erubis
|
10
|
+
|
11
|
+
helper :error,
|
12
|
+
:auth,
|
13
|
+
:form,
|
14
|
+
:workflow,
|
15
|
+
:navigation,
|
16
|
+
:date,
|
17
|
+
:tags,
|
18
|
+
:canonical,
|
19
|
+
:crud,
|
20
|
+
:attachments
|
21
|
+
|
22
|
+
on_second_save do |page, request|
|
23
|
+
page.tags = request[:tags]
|
24
|
+
add_attachments(page, request[:attachments])
|
25
|
+
end
|
26
|
+
|
27
|
+
on_save do |page, request|
|
28
|
+
page.title = request[:title]
|
29
|
+
page.name = Page.canonicalize request[:name], page.id
|
30
|
+
page.body = request[:body]
|
31
|
+
page.user = session[:user]
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'exifr'
|
2
|
+
require 'RMagick'
|
3
|
+
module CortexReaver
|
4
|
+
class PhotographController < Ramaze::Controller
|
5
|
+
MODEL = Photograph
|
6
|
+
|
7
|
+
map '/photographs'
|
8
|
+
layout '/blank_layout'
|
9
|
+
layout '/text_layout' => [:index, :edit, :new, :page]
|
10
|
+
template_paths << 'view'
|
11
|
+
template :edit, :form
|
12
|
+
template :new, :form
|
13
|
+
engine :Erubis
|
14
|
+
|
15
|
+
helper :error,
|
16
|
+
:auth,
|
17
|
+
:form,
|
18
|
+
:workflow,
|
19
|
+
:navigation,
|
20
|
+
:date,
|
21
|
+
:tags,
|
22
|
+
:canonical,
|
23
|
+
:crud,
|
24
|
+
:attachments,
|
25
|
+
:photographs,
|
26
|
+
:feeds
|
27
|
+
|
28
|
+
|
29
|
+
on_save do |photograph, request|
|
30
|
+
photograph.title = request[:title]
|
31
|
+
photograph.name = Photograph.canonicalize request[:name], photograph.id
|
32
|
+
photograph.user = session[:user]
|
33
|
+
end
|
34
|
+
|
35
|
+
on_second_save do |photograph, request|
|
36
|
+
photograph.tags = request[:tags]
|
37
|
+
photograph.image = request[:image][:tempfile] if request[:image]
|
38
|
+
photograph.infer_date_from_exif! if request[:infer_date]
|
39
|
+
end
|
40
|
+
|
41
|
+
for_feed do |photograph, x|
|
42
|
+
x.content render_template('atom_fragment.rhtml', :photograph => photograph)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module CortexReaver
|
2
|
+
class ProjectController < Ramaze::Controller
|
3
|
+
MODEL = Project
|
4
|
+
|
5
|
+
map '/projects'
|
6
|
+
layout '/text_layout'
|
7
|
+
template :edit, :form
|
8
|
+
template :new, :form
|
9
|
+
engine :Erubis
|
10
|
+
|
11
|
+
helper :error,
|
12
|
+
:auth,
|
13
|
+
:form,
|
14
|
+
:workflow,
|
15
|
+
:navigation,
|
16
|
+
:date,
|
17
|
+
:tags,
|
18
|
+
:canonical,
|
19
|
+
:crud,
|
20
|
+
:attachments,
|
21
|
+
:feeds
|
22
|
+
|
23
|
+
on_second_save do |project, request|
|
24
|
+
project.tags = request[:tags]
|
25
|
+
add_attachments(project, request[:attachments])
|
26
|
+
end
|
27
|
+
|
28
|
+
on_save do |project, request|
|
29
|
+
project.title = request[:title]
|
30
|
+
project.description = request[:description]
|
31
|
+
project.name = Journal.canonicalize request[:name], project.id
|
32
|
+
project.body = request[:body]
|
33
|
+
project.user = session[:user]
|
34
|
+
end
|
35
|
+
|
36
|
+
for_feed do |project, x|
|
37
|
+
x.content project.body_cache, :type => 'html'
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module CortexReaver
|
2
|
+
class TagController < Ramaze::Controller
|
3
|
+
MODEL = Tag
|
4
|
+
|
5
|
+
map '/tags'
|
6
|
+
layout '/text_layout'
|
7
|
+
template :edit, :form
|
8
|
+
template :new, :form
|
9
|
+
engine :Erubis
|
10
|
+
|
11
|
+
helper :error,
|
12
|
+
:auth,
|
13
|
+
:form,
|
14
|
+
:workflow,
|
15
|
+
:navigation,
|
16
|
+
:canonical,
|
17
|
+
:crud
|
18
|
+
|
19
|
+
on_save do |tag, request|
|
20
|
+
tag.title = request[:title]
|
21
|
+
tag.name = Tag.canonicalize request[:name], tag.id
|
22
|
+
end
|
23
|
+
|
24
|
+
def index(*ids)
|
25
|
+
if ids.size > 0
|
26
|
+
raw_redirect Rs([:show] + ids), :status => 301
|
27
|
+
else
|
28
|
+
# Index
|
29
|
+
@title = "All Tags"
|
30
|
+
@tags = Tag.order(:count).reverse
|
31
|
+
render_template :list
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def show(*ids)
|
36
|
+
# Find tags
|
37
|
+
tags = []
|
38
|
+
bad_ids = []
|
39
|
+
ids.each do |id|
|
40
|
+
if tag = Tag.get(id)
|
41
|
+
tags << tag
|
42
|
+
else
|
43
|
+
bad_ids << id
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# Error message
|
48
|
+
unless bad_ids.empty?
|
49
|
+
flash[:error] = "No tags called #{h bad_ids.join(', ')}."
|
50
|
+
end
|
51
|
+
|
52
|
+
if tags.empty?
|
53
|
+
# Index
|
54
|
+
redirect :index
|
55
|
+
else
|
56
|
+
# Specific tags
|
57
|
+
@tags = tags
|
58
|
+
@title = "Tags: #{h tags.join(', ')}"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# Tags are only created through tagging.
|
63
|
+
def new
|
64
|
+
error_404
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module CortexReaver
|
2
|
+
class UserController < Ramaze::Controller
|
3
|
+
MODEL = User
|
4
|
+
|
5
|
+
map '/users'
|
6
|
+
layout '/text_layout'
|
7
|
+
template :edit, :form
|
8
|
+
template :new, :form
|
9
|
+
engine :Erubis
|
10
|
+
|
11
|
+
helper :error,
|
12
|
+
:auth,
|
13
|
+
:form,
|
14
|
+
:workflow,
|
15
|
+
:navigation,
|
16
|
+
:date,
|
17
|
+
:tags,
|
18
|
+
:canonical,
|
19
|
+
:crud,
|
20
|
+
:aspect
|
21
|
+
|
22
|
+
on_save do |user, request|
|
23
|
+
user.login = request[:login]
|
24
|
+
user.name = request[:name]
|
25
|
+
user.http = request[:http]
|
26
|
+
user.email = request[:email]
|
27
|
+
user.admin = request[:admin] || false
|
28
|
+
|
29
|
+
unless request[:password].blank? and request[:password_confirmation].blank?
|
30
|
+
# Set password
|
31
|
+
user.password = request[:password]
|
32
|
+
user.password_confirmation = request[:password_confirmation]
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# Listing users outright is a little dodgy.
|
37
|
+
before :index do
|
38
|
+
require_admin
|
39
|
+
end
|
40
|
+
|
41
|
+
def login
|
42
|
+
@title = "Login"
|
43
|
+
|
44
|
+
if request.post?
|
45
|
+
if user = do_login(request[:login], request[:password])
|
46
|
+
# Successful login
|
47
|
+
flash[:notice] = "Welcome, #{user.name}."
|
48
|
+
|
49
|
+
if uri = session.delete(:target_uri) || request[:target_uri]
|
50
|
+
# Send the user to their original destination.
|
51
|
+
redirect uri
|
52
|
+
else
|
53
|
+
# Try the main page.
|
54
|
+
redirect R(:/)
|
55
|
+
end
|
56
|
+
else
|
57
|
+
# Nope, no login.
|
58
|
+
flash[:error] = "Wrong username or password."
|
59
|
+
redirect Rs(:login)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def logout
|
65
|
+
if user = do_logout
|
66
|
+
flash[:notice] = "Goodbye, #{user.name}"
|
67
|
+
end
|
68
|
+
redirect '/'
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,139 @@
|
|
1
|
+
module Ramaze
|
2
|
+
module Helper
|
3
|
+
# Helps with attachments. Requires CRUD.
|
4
|
+
module Attachments
|
5
|
+
Helper::LOOKUP << self
|
6
|
+
|
7
|
+
# Deletes an attachment on a model identified by id.
|
8
|
+
def delete_attachment(id, name)
|
9
|
+
require_admin
|
10
|
+
|
11
|
+
unless @model = model_class.get(id)
|
12
|
+
flash[:error] = "No such #{model_class.to_s.downcase} (#{h id}) exists."
|
13
|
+
redirect Rs()
|
14
|
+
end
|
15
|
+
|
16
|
+
unless attachment = @model.attachment(name)
|
17
|
+
flash[:error] = "No such attachment (#{h name}) exists."
|
18
|
+
redirect @model.url
|
19
|
+
end
|
20
|
+
|
21
|
+
begin
|
22
|
+
attachment.delete
|
23
|
+
flash[:notice] = "Deleted attachment #{h name}."
|
24
|
+
rescue => e
|
25
|
+
flash[:error] = "Couldn't delete attachment #{h name}: #{h e.message}."
|
26
|
+
end
|
27
|
+
|
28
|
+
redirect @model.url
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
# Saves all attachments from a request which match form to model. Returns true if
|
34
|
+
# all were successful. Returns an array of attachments which were added.
|
35
|
+
def add_attachments(model, attachments)
|
36
|
+
attachments.each do |key, file|
|
37
|
+
puts "adding #{key}: #{file.inspect}"
|
38
|
+
if tempfile = file[:tempfile] and filename = file[:filename] and not filename.blank?
|
39
|
+
model.attachment(filename).file = tempfile
|
40
|
+
end
|
41
|
+
end
|
42
|
+
attachments
|
43
|
+
end
|
44
|
+
|
45
|
+
# Renders an attachments form for a model. Shows current attachments,
|
46
|
+
# provides links to edit/delete, and a multiple-upload box. Doesn't
|
47
|
+
# include form tags.
|
48
|
+
def attachment_form(model)
|
49
|
+
s = "<div id=\"files\" class=\"files\">\n <ul>\n "
|
50
|
+
model.attachments.each do |attachment|
|
51
|
+
s << "<li><a href=\"#{attachment.public_path}\">#{attachment.name}</a> (#{A('delete', :href => Rs(:delete_attachment, model.name, attachment.name))})</li>\n"
|
52
|
+
end
|
53
|
+
s << "</ul>\n</div>\n\n"
|
54
|
+
|
55
|
+
s << <<EOF
|
56
|
+
<script type="text/javascript">
|
57
|
+
// The number of created attachments.
|
58
|
+
var created_attachments = 0;
|
59
|
+
// The number of existing attachments.
|
60
|
+
var existing_attachments = 0;
|
61
|
+
|
62
|
+
function add_attachment_field_to(element) {
|
63
|
+
// The attachment id we'll be creating;
|
64
|
+
var id = created_attachments++;
|
65
|
+
existing_attachments++;
|
66
|
+
|
67
|
+
// The paragraph which contains our file entry line.
|
68
|
+
var p = document.createElement('p');
|
69
|
+
|
70
|
+
// Label.
|
71
|
+
var label = document.createElement('label');
|
72
|
+
label.setAttribute('for', 'attachments_' + id);
|
73
|
+
label.appendChild(document.createTextNode('Attach:'));
|
74
|
+
p.appendChild(label);
|
75
|
+
|
76
|
+
// File field.
|
77
|
+
field = document.createElement('input');
|
78
|
+
field.setAttribute('id', 'attachments_' + id);
|
79
|
+
field.setAttribute('name', 'attachments[' + id + ']');
|
80
|
+
field.setAttribute('size', '30');
|
81
|
+
field.setAttribute('type', 'file');
|
82
|
+
field.setAttribute('onchange', 'attachment_field_changed(this);');
|
83
|
+
p.appendChild(field);
|
84
|
+
|
85
|
+
// Remove button
|
86
|
+
remove = document.createElement('input');
|
87
|
+
remove.setAttribute('type', 'button');
|
88
|
+
remove.setAttribute('value', 'Clear');
|
89
|
+
remove.setAttribute('onclick', 'clear_attachment_field(this.previousSibling);');
|
90
|
+
p.appendChild(remove);
|
91
|
+
|
92
|
+
// Add paragraph to element.
|
93
|
+
element.appendChild(p);
|
94
|
+
}
|
95
|
+
|
96
|
+
function attachment_field_changed(field) {
|
97
|
+
if (field.value.length == 0) {
|
98
|
+
remove_attachment_field(field);
|
99
|
+
}
|
100
|
+
if (field.value.length > 0) {
|
101
|
+
add_attachment_field_to(field.parentNode.parentNode);
|
102
|
+
}
|
103
|
+
}
|
104
|
+
|
105
|
+
function clear_attachment_field(field) {
|
106
|
+
field.value = '';
|
107
|
+
attachment_field_changed(field);
|
108
|
+
}
|
109
|
+
|
110
|
+
function remove_attachment_field(field) {
|
111
|
+
if (existing_attachments > 1) {
|
112
|
+
field.parentNode.parentNode.removeChild(field.parentNode);
|
113
|
+
existing_attachments--;
|
114
|
+
}
|
115
|
+
}
|
116
|
+
|
117
|
+
// Add the first attachment field.
|
118
|
+
add_attachment_field_to(document.getElementById('files'));
|
119
|
+
</script>
|
120
|
+
EOF
|
121
|
+
end
|
122
|
+
|
123
|
+
# An HTML table of all attachments on a model
|
124
|
+
def attachment_list(model)
|
125
|
+
s = '<div class="attachments">'
|
126
|
+
s << '<h2>Files</h2>'
|
127
|
+
s << '<table>'
|
128
|
+
model.attachments.each do |attachment|
|
129
|
+
s << "
|
130
|
+
<tr>
|
131
|
+
<td><a href=\"#{attr_h attachment.public_path}\">#{h attachment.name}</a></td>
|
132
|
+
<td class=\"date\">#{File.mtime(attachment.local_path).strftime('%A, %d %B %Y, %H:%M')}</td>
|
133
|
+
</tr>"
|
134
|
+
end
|
135
|
+
s << "</table>\n</div>"
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|