radiant-downloads-extension 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ module DownloadGroup
2
+ def self.included(base)
3
+ base.class_eval {
4
+ has_and_belongs_to_many :downloads
5
+ }
6
+ end
7
+ end
@@ -0,0 +1,165 @@
1
+ module DownloadTags
2
+ include Radiant::Taggable
3
+
4
+ class TagError < StandardError; end
5
+
6
+ # the root group tag is defined in reader_group and should only expand if there is a page group or message group
7
+
8
+ desc %{
9
+ Expands if this group has any downloads.
10
+
11
+ <pre><code><r:group:if_downloads>...</r:group:if_downloads /></code></pre>
12
+ }
13
+ tag "group:if_downloads" do |tag|
14
+ tag.expand if tag.locals.group.downloads.any?
15
+ end
16
+
17
+ desc %{
18
+ Expands if this group does not have any downloads.
19
+
20
+ <pre><code><r:group:unless_downloads>...</r:group:unless_downloads /></code></pre>
21
+ }
22
+ tag "group:unless_downloads" do |tag|
23
+ tag.expand unless tag.locals.group.downloads.any?
24
+ end
25
+
26
+ desc %{
27
+ Cycles through all downloads for the current group.
28
+ (which will only be defined if this is the home page for a group)
29
+
30
+ *Usage:*
31
+ <pre><code><r:group:downloads:each>...</r:group:downloads:each></code></pre>
32
+ }
33
+ tag 'group:downloads' do |tag|
34
+ tag.expand if tag.locals.group
35
+ end
36
+ tag 'group:downloads:each' do |tag|
37
+ result = []
38
+ tag.locals.group.downloads.each do |download|
39
+ tag.locals.download = download
40
+ result << tag.expand
41
+ end
42
+ result
43
+ end
44
+
45
+ desc %{
46
+ Expands if the current reader has any downloads.
47
+
48
+ <pre><code><r:reader:if_downloads>...</r:reader:if_downloads /></code></pre>
49
+ }
50
+ tag "reader:if_downloads" do |tag|
51
+ tag.expand if tag.locals.reader.downloads.any?
52
+ end
53
+
54
+ desc %{
55
+ Expands if the current reader does not have any downloads.
56
+
57
+ <pre><code><r:reader:unless_downloads>...</r:reader:unless_downloads /></code></pre>
58
+ }
59
+ tag "reader:unless_downloads" do |tag|
60
+ tag.expand unless tag.locals.reader.downloads.any?
61
+ end
62
+
63
+ desc %{
64
+ Cycles through all downloads for the current reader.
65
+
66
+ *Usage:*
67
+ <pre><code><r:reader:downloads:each>...</r:reader:downloads:each></code></pre>
68
+ }
69
+ tag 'reader:downloads' do |tag|
70
+ tag.locals.reader ||= current_reader
71
+ tag.expand if tag.locals.reader
72
+ end
73
+ tag 'reader:downloads:each' do |tag|
74
+ result = []
75
+ tag.locals.reader.downloads.each do |download|
76
+ tag.locals.download = download
77
+ result << tag.expand
78
+ end
79
+ result
80
+ end
81
+
82
+ desc %{
83
+ The root 'download' tag is not meant to be called directly.
84
+ All it does is summon a download object so that its fields can be displayed with eg.
85
+ <pre><code><r:download:url /></code></pre>
86
+ }
87
+
88
+ tag 'download' do |tag|
89
+ tag.expand
90
+ # tag.locals.download ||= _get_download(tag)
91
+ # if tag.locals.download
92
+ # tag.expand
93
+ # else
94
+ # %{No download found with id '#{tag.attr['id']}' or title '#{tag.attr['title']}'}
95
+ # end
96
+ end
97
+
98
+ desc %{
99
+ Returns title of current download.
100
+
101
+ *Usage:*
102
+ <pre><code><r:download:title /></code></pre>
103
+ }
104
+ tag 'download:title' do |tag|
105
+ if download = _get_download(tag)
106
+ download.name
107
+ end
108
+ end
109
+ tag 'download:name' do |tag|
110
+ if download = _get_download(tag)
111
+ download.name
112
+ end
113
+ end
114
+
115
+ desc %{
116
+ Returns description of current download.
117
+
118
+ *Usage:*
119
+ <pre><code><r:download:description /></code></pre>
120
+ }
121
+ tag 'download:description' do |tag|
122
+ if download = _get_download(tag)
123
+ download.description
124
+ end
125
+ end
126
+
127
+ desc %{
128
+ Returns the secure url of the current download.
129
+
130
+ *Usage:*
131
+ <pre><code><a href="<r:download:url id="4" />">...</a></code></pre>
132
+ }
133
+ tag 'download:url' do |tag|
134
+ if download = _get_download(tag)
135
+ download_path(download)
136
+ end
137
+ end
138
+
139
+ desc %{
140
+ Returns a link to the current download.
141
+ Attributes and enclosed link text are passed through in the usual way.
142
+
143
+ *Usage:*
144
+ <pre><code><r:download:link /></code></pre>
145
+ }
146
+ tag 'download:link' do |tag|
147
+ tag.locals.download = _get_download(tag)
148
+ options = tag.attr.dup
149
+ attributes = options.inject('') { |s, (k, v)| s << %{#{k.downcase}="#{v}" } }.strip
150
+ attributes = " #{attributes}" unless attributes.empty?
151
+ text = tag.double? ? tag.expand : tag.render('download:title')
152
+ %{<a href="#{tag.render('download:url')}"#{attributes}>#{text}</a>}
153
+ end
154
+
155
+
156
+ private
157
+
158
+ def _get_download(tag)
159
+ download = tag.locals.download
160
+ download ||= Download.find_by_id(tag.attr.delete('id')) if tag.attr['id']
161
+ download ||= Download.find_by_title(tag.attr.delete('title')) if tag.attr['title']
162
+ download
163
+ end
164
+
165
+ end
@@ -0,0 +1,38 @@
1
+ module DownloadUI
2
+
3
+ def self.included(base)
4
+ base.class_eval do
5
+
6
+ attr_accessor :download
7
+ alias_method :downloads, :download
8
+
9
+ def load_default_regions_with_download
10
+ load_default_regions_without_download
11
+ @download = load_default_download_regions
12
+ end
13
+
14
+ alias_method_chain :load_default_regions, :download
15
+
16
+ protected
17
+
18
+ def load_default_download_regions
19
+ returning OpenStruct.new do |download|
20
+ download.edit = Radiant::AdminUI::RegionSet.new do |edit|
21
+ edit.main.concat %w{edit_header edit_form}
22
+ edit.form.concat %w{edit_title edit_description edit_document edit_access}
23
+ edit.form_bottom.concat %w{edit_timestamp edit_buttons}
24
+ end
25
+ download.index = Radiant::AdminUI::RegionSet.new do |index|
26
+ index.thead.concat %w{name_header document_header access_header modify_header}
27
+ index.tbody.concat %w{name_cell document_cell access_cell modify_cell}
28
+ index.bottom.concat %w{new_button}
29
+ end
30
+ download.remove = download.index
31
+ download.new = download.edit
32
+ end
33
+ end
34
+
35
+ end
36
+ end
37
+ end
38
+
@@ -0,0 +1,28 @@
1
+ namespace :radiant do
2
+ namespace :extensions do
3
+ namespace :downloads do
4
+
5
+ desc "Runs the migration of the Downloads extension"
6
+ task :migrate => :environment do
7
+ require 'radiant/extension_migrator'
8
+ if ENV["VERSION"]
9
+ DownloadsExtension.migrator.migrate(ENV["VERSION"].to_i)
10
+ else
11
+ DownloadsExtension.migrator.migrate
12
+ end
13
+ end
14
+
15
+ desc "Copies public assets of the Downloads to the instance public/ directory."
16
+ task :update => :environment do
17
+ is_svn_or_dir = proc {|path| path =~ /\.svn/ || File.directory?(path) }
18
+ puts "Copying assets from DownloadsExtension"
19
+ Dir[DownloadsExtension.root + "/public/**/*"].reject(&is_svn_or_dir).each do |file|
20
+ path = file.sub(DownloadsExtension.root, '')
21
+ directory = File.dirname(path)
22
+ mkdir_p RAILS_ROOT + directory
23
+ cp file, RAILS_ROOT + path
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,25 @@
1
+ /* submenu admin */
2
+
3
+ #content table.index .node .download {
4
+ font-size:115%;
5
+ font-weight:bold;
6
+ }
7
+
8
+ #content table.index .node .download a {
9
+ color: black;
10
+ }
11
+
12
+ #content .form-area .user select {
13
+ font-family:Georgia,Palatino,"Times New Roman",Times,serif;
14
+ font-size:150%;
15
+ width:60%;
16
+ }
17
+
18
+ #content .form-area p.description {
19
+ margin-top: 10px;
20
+ }
21
+
22
+ #content .form-area span.formnote {
23
+ color: #7d796c;
24
+ font-size: 85%;
25
+ }
@@ -0,0 +1,73 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe DownloadsController do
4
+ dataset :download_groups
5
+
6
+ before do
7
+ controller.stub!(:request).and_return(request)
8
+ Page.current_site = sites(:test) if defined? Site
9
+ request.env["HTTP_REFERER"] = 'http://test.host/referer!'
10
+ end
11
+
12
+ describe "with a protected download" do
13
+ describe "and no reader" do
14
+ before do
15
+ logout_reader
16
+ get :show, :id => download_id(:grouped)
17
+ end
18
+
19
+ it "should redirect to login" do
20
+ response.should be_redirect
21
+ response.should redirect_to(reader_login_url)
22
+ end
23
+
24
+ it "should set the right return_to url" do
25
+ session[:return_to].should == request.request_uri
26
+ end
27
+ end
28
+
29
+ describe "and a logged-in reader" do
30
+ describe "who is not in a permitted group" do
31
+ before do
32
+ login_as_reader(:ungrouped)
33
+ get :show, :id => download_id(:grouped)
34
+ end
35
+
36
+ it "should redirect to the permission denied page" do
37
+ response.should be_success
38
+ response.should render_template('site/not_allowed')
39
+ end
40
+ end
41
+
42
+ describe "who is in a permitted group" do
43
+ before do
44
+ login_as_reader(:normal)
45
+ get :show, :id => download_id(:grouped)
46
+ end
47
+
48
+ it "should return an internal redirect" do
49
+ dl = downloads(:grouped)
50
+ response.should be_success
51
+ response.headers.should include('X-Accel-Redirect');
52
+ response.headers['X-Accel-Redirect'].should == dl.document.path
53
+ response.headers['Content-Disposition'].should =~ /^attachment/
54
+ end
55
+ end
56
+ end
57
+ end
58
+
59
+ describe "with an ungrouped download" do
60
+ describe "and no reader" do
61
+ before do
62
+ logout_reader
63
+ get :show, :id => download_id(:grouped)
64
+ end
65
+
66
+ it "should refuse access" do
67
+ response.should be_redirect
68
+ response.should redirect_to(reader_login_url)
69
+ end
70
+ end
71
+ end
72
+
73
+ end
@@ -0,0 +1,42 @@
1
+ require 'digest/sha1'
2
+ class DownloadGroupsDataset < Dataset::Base
3
+ datasets = [:downloads, :download_readers]
4
+ datasets << :download_sites if defined? Site
5
+ uses *datasets
6
+
7
+ def load
8
+ create_group "Normal"
9
+ create_group "Busy"
10
+ create_group "Idle"
11
+ add_downloads_to_group :normal, [:grouped]
12
+ add_downloads_to_group :busy, [:grouped, :alsogrouped]
13
+ add_readers_to_group :busy, [:normal, :another]
14
+ end
15
+
16
+ helpers do
17
+ def create_group(name, att={})
18
+ group = create_record Group, name.symbolize, group_attributes(att.update(:name => name))
19
+ end
20
+
21
+ def group_attributes(att={})
22
+ name = att[:name] || "A group"
23
+ attributes = {
24
+ :name => name,
25
+ :description => "Test group"
26
+ }.merge(att)
27
+ attributes[:site_id] ||= site_id(:test) if defined? Site
28
+ attributes
29
+ end
30
+ end
31
+
32
+ def add_readers_to_group(g, rr)
33
+ g = g.is_a?(Group) ? g : groups(g)
34
+ g.readers << rr.map{|r| readers(r)}
35
+ end
36
+
37
+ def add_downloads_to_group(g, dd)
38
+ g = g.is_a?(Group) ? g : groups(g)
39
+ g.downloads << dd.map{|d| downloads(d)}
40
+ end
41
+
42
+ end
@@ -0,0 +1,49 @@
1
+ require "authlogic/test_case"
2
+
3
+ class DownloadReadersDataset < Dataset::Base
4
+ uses :download_sites if defined? Site
5
+
6
+ def load
7
+ create_reader "Normal"
8
+ create_reader "Another"
9
+ create_reader "Ungrouped"
10
+ end
11
+
12
+ helpers do
13
+ def create_reader(name, attributes={})
14
+ attributes = reader_attributes(attributes.update(:name => name))
15
+ reader = create_model Reader, name.symbolize, attributes
16
+ end
17
+
18
+ def reader_attributes(attributes={})
19
+ name = attributes[:name] || "John Doe"
20
+ symbol = name.symbolize
21
+ attributes = {
22
+ :name => name,
23
+ :email => "#{symbol}@spanner.org",
24
+ :login => "#{symbol}@spanner.org",
25
+ :activated_at => Time.now - 1.week,
26
+ :password_salt => "golly",
27
+ :password => 'password',
28
+ :password_confirmation => 'password'
29
+ }.merge(attributes)
30
+ attributes[:site] = sites(:test) if defined? Site
31
+ attributes
32
+ end
33
+
34
+ def login_as_reader(reader)
35
+ activate_authlogic
36
+ login_reader = reader.is_a?(Reader) ? reader : readers(reader)
37
+ ReaderSession.create(login_reader)
38
+ login_reader
39
+ end
40
+
41
+ def logout_reader
42
+ activate_authlogic
43
+ if session = ReaderSession.find
44
+ session.destroy
45
+ end
46
+ end
47
+ end
48
+
49
+ end
@@ -0,0 +1,9 @@
1
+ class DownloadSitesDataset < Dataset::Base
2
+ uses :pages
3
+
4
+ def load
5
+ create_record Site, :test, :name => 'Test Site', :domain => 'test', :base_domain => 'test.host', :position => 1, :mail_from_name => 'test sender', :mail_from_address => 'sender@spanner.org', :homepage_id => page_id(:home)
6
+ Page.current_site = sites(:test)
7
+ end
8
+
9
+ end