cortex-reaver 0.0.1
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 +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
|