radiant-reader_mailman-extension 0.1.0
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/README.markdown +47 -0
- data/Rakefile +137 -0
- data/VERSION +1 -0
- data/app/models/mailing_list_membership.rb +31 -0
- data/app/views/accounts/_mailing_list.html.haml +24 -0
- data/app/views/admin/reader_configuration/_edit_mailing_list.html.haml +5 -0
- data/app/views/admin/reader_configuration/_mailing_list.html.haml +7 -0
- data/app/views/admin/readers/_mailing_list.html.haml +21 -0
- data/config/initializers/radiant_config.rb +5 -0
- data/config/locales/en.yml +25 -0
- data/db/migrate/20111121160131_mailing_list_preferences.rb +15 -0
- data/lib/mailing_list_reader.rb +8 -0
- data/lib/radiant-reader_mailman-extension.rb +8 -0
- data/lib/tasks/reader_mailman_extension_tasks.rake +28 -0
- data/radiant-reader_mailman-extension.gemspec +32 -0
- data/reader_mailman_extension.rb +15 -0
- data/spec/datasets/download_groups_dataset.rb +42 -0
- data/spec/datasets/download_readers_dataset.rb +49 -0
- data/spec/datasets/download_sites_dataset.rb +9 -0
- data/spec/datasets/downloads_dataset.rb +28 -0
- data/spec/models/group_spec.rb +20 -0
- data/spec/spec.opts +6 -0
- data/spec/spec_helper.rb +36 -0
- metadata +94 -0
    
        data/README.markdown
    ADDED
    
    | @@ -0,0 +1,47 @@ | |
| 1 | 
            +
            # reader_mailman extension
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            This is a very simple radiant extension that lets your readership populate a mailman mailing lists, opt in and out and set their message-receipt preferences. It will soon include the ability to assign a different list to each reader-group but right now it's just a single global list.
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            ## Requirements
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            * The [reader extension](https://github.com/spanner/radiant-reader-extension) to provide for your user-management and access-control needs.
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            * A Mailman installation [configured to use MySQL for membership data](http://loeki.tv/log/archives/81-Setting-up-Mailman-to-store-members-in-a-MySQL-database.html), at least for the lists you want to populate. Note that the database must be set up in the 'wide' configuration, ie. one table per list.
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            ## Configuration
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            We access the mailman table through activerecord using a separate database connection called `mailman_#{RAILS_ENV}`. Add definitions like these to your database.yml:
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                mailman_development:
         | 
| 16 | 
            +
                  adapter: mysql2
         | 
| 17 | 
            +
                  database: mailman
         | 
| 18 | 
            +
                  username: somebody
         | 
| 19 | 
            +
                  password: whatever
         | 
| 20 | 
            +
                  host: 127.0.0.1
         | 
| 21 | 
            +
                
         | 
| 22 | 
            +
                mailman_production:
         | 
| 23 | 
            +
                  adapter: mysql2
         | 
| 24 | 
            +
                  database: mailman
         | 
| 25 | 
            +
                  username: somebody
         | 
| 26 | 
            +
                  password: whatever
         | 
| 27 | 
            +
                  host: mail.server.com
         | 
| 28 | 
            +
             | 
| 29 | 
            +
            You store the name of the mailing list (which is also the name of the data table) in:
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                reader.mailman.list_name
         | 
| 32 | 
            +
                
         | 
| 33 | 
            +
            You can do that through the usual reader-settings interface.
         | 
| 34 | 
            +
             | 
| 35 | 
            +
            ## Status
         | 
| 36 | 
            +
             | 
| 37 | 
            +
            New but reasonably simple. The legacy interface involves some subversion of ActiveRecord so bugs are possible there.
         | 
| 38 | 
            +
             | 
| 39 | 
            +
            ## Bugs and comments
         | 
| 40 | 
            +
             | 
| 41 | 
            +
            Issues in github, please, or for little things an email or github message is fine.
         | 
| 42 | 
            +
             | 
| 43 | 
            +
            ## Author and copyright
         | 
| 44 | 
            +
             | 
| 45 | 
            +
            * Copyright Spanner Ltd 2011.
         | 
| 46 | 
            +
            * Released under the same terms as Rails and/or Radiant.
         | 
| 47 | 
            +
            * Contact will at spanner.org
         | 
    
        data/Rakefile
    ADDED
    
    | @@ -0,0 +1,137 @@ | |
| 1 | 
            +
            begin
         | 
| 2 | 
            +
              require 'jeweler'
         | 
| 3 | 
            +
              Jeweler::Tasks.new do |gem|
         | 
| 4 | 
            +
                gem.name = "radiant-downloads-extension"
         | 
| 5 | 
            +
                gem.summary = %Q{Controlled, secure file access for Radiant CMS with group-based access control.}
         | 
| 6 | 
            +
                gem.description = %Q{Controlled, secure file access with group-based access control.}
         | 
| 7 | 
            +
                gem.email = "will@spanner.org"
         | 
| 8 | 
            +
                gem.homepage = "http://github.com/spanner/radiant-downloads-extension"
         | 
| 9 | 
            +
                gem.authors = ["spanner"]
         | 
| 10 | 
            +
                gem.add_dependency "radiant", ">= 0.9.0"
         | 
| 11 | 
            +
                gem.add_dependency 'radiant-reader_group-extension'
         | 
| 12 | 
            +
              end
         | 
| 13 | 
            +
            rescue LoadError
         | 
| 14 | 
            +
              puts "Jeweler (or a dependency) not available. This is only required if you plan to package downloads as a gem."
         | 
| 15 | 
            +
            end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            # In rails 1.2, plugins aren't available in the path until they're loaded.
         | 
| 18 | 
            +
            # Check to see if the rspec plugin is installed first and require
         | 
| 19 | 
            +
            # it if it is.  If not, use the gem version.
         | 
| 20 | 
            +
             | 
| 21 | 
            +
            # Determine where the RSpec plugin is by loading the boot
         | 
| 22 | 
            +
            unless defined? RADIANT_ROOT
         | 
| 23 | 
            +
              ENV["RAILS_ENV"] = "test"
         | 
| 24 | 
            +
              case
         | 
| 25 | 
            +
              when ENV["RADIANT_ENV_FILE"]
         | 
| 26 | 
            +
                require File.dirname(ENV["RADIANT_ENV_FILE"]) + "/boot"
         | 
| 27 | 
            +
              when File.dirname(__FILE__) =~ %r{vendor/radiant/vendor/extensions}
         | 
| 28 | 
            +
                require "#{File.expand_path(File.dirname(__FILE__) + "/../../../../../")}/config/boot"
         | 
| 29 | 
            +
              else
         | 
| 30 | 
            +
                require "#{File.expand_path(File.dirname(__FILE__) + "/../../../")}/config/boot"
         | 
| 31 | 
            +
              end
         | 
| 32 | 
            +
            end
         | 
| 33 | 
            +
             | 
| 34 | 
            +
            require 'rake'
         | 
| 35 | 
            +
            require 'rake/rdoctask'
         | 
| 36 | 
            +
            require 'rake/testtask'
         | 
| 37 | 
            +
             | 
| 38 | 
            +
            rspec_base = File.expand_path(RADIANT_ROOT + '/vendor/plugins/rspec/lib')
         | 
| 39 | 
            +
            $LOAD_PATH.unshift(rspec_base) if File.exist?(rspec_base)
         | 
| 40 | 
            +
            require 'spec/rake/spectask'
         | 
| 41 | 
            +
            require 'cucumber'
         | 
| 42 | 
            +
            require 'cucumber/rake/task'
         | 
| 43 | 
            +
             | 
| 44 | 
            +
            # Cleanup the RADIANT_ROOT constant so specs will load the environment
         | 
| 45 | 
            +
            Object.send(:remove_const, :RADIANT_ROOT)
         | 
| 46 | 
            +
             | 
| 47 | 
            +
            extension_root = File.expand_path(File.dirname(__FILE__))
         | 
| 48 | 
            +
             | 
| 49 | 
            +
            task :default => :spec
         | 
| 50 | 
            +
            task :stats => "spec:statsetup"
         | 
| 51 | 
            +
             | 
| 52 | 
            +
            desc "Run all specs in spec directory"
         | 
| 53 | 
            +
            Spec::Rake::SpecTask.new(:spec) do |t|
         | 
| 54 | 
            +
              t.spec_opts = ['--options', "\"#{extension_root}/spec/spec.opts\""]
         | 
| 55 | 
            +
              t.spec_files = FileList['spec/**/*_spec.rb']
         | 
| 56 | 
            +
            end
         | 
| 57 | 
            +
             | 
| 58 | 
            +
            task :features => 'spec:integration'
         | 
| 59 | 
            +
             | 
| 60 | 
            +
            namespace :spec do
         | 
| 61 | 
            +
              desc "Run all specs in spec directory with RCov"
         | 
| 62 | 
            +
              Spec::Rake::SpecTask.new(:rcov) do |t|
         | 
| 63 | 
            +
                t.spec_opts = ['--options', "\"#{extension_root}/spec/spec.opts\""]
         | 
| 64 | 
            +
                t.spec_files = FileList['spec/**/*_spec.rb']
         | 
| 65 | 
            +
                t.rcov = true
         | 
| 66 | 
            +
                t.rcov_opts = ['--exclude', 'spec', '--rails']
         | 
| 67 | 
            +
              end
         | 
| 68 | 
            +
              
         | 
| 69 | 
            +
              desc "Print Specdoc for all specs"
         | 
| 70 | 
            +
              Spec::Rake::SpecTask.new(:doc) do |t|
         | 
| 71 | 
            +
                t.spec_opts = ["--format", "specdoc", "--dry-run"]
         | 
| 72 | 
            +
                t.spec_files = FileList['spec/**/*_spec.rb']
         | 
| 73 | 
            +
              end
         | 
| 74 | 
            +
             | 
| 75 | 
            +
              [:models, :controllers, :views, :helpers].each do |sub|
         | 
| 76 | 
            +
                desc "Run the specs under spec/#{sub}"
         | 
| 77 | 
            +
                Spec::Rake::SpecTask.new(sub) do |t|
         | 
| 78 | 
            +
                  t.spec_opts = ['--options', "\"#{extension_root}/spec/spec.opts\""]
         | 
| 79 | 
            +
                  t.spec_files = FileList["spec/#{sub}/**/*_spec.rb"]
         | 
| 80 | 
            +
                end
         | 
| 81 | 
            +
              end
         | 
| 82 | 
            +
              
         | 
| 83 | 
            +
              desc "Run the Cucumber features"
         | 
| 84 | 
            +
              Cucumber::Rake::Task.new(:integration) do |t|
         | 
| 85 | 
            +
                t.fork = true
         | 
| 86 | 
            +
                t.cucumber_opts = ['--format', (ENV['CUCUMBER_FORMAT'] || 'pretty')]
         | 
| 87 | 
            +
                # t.feature_pattern = "#{extension_root}/features/**/*.feature"
         | 
| 88 | 
            +
                t.profile = "default"
         | 
| 89 | 
            +
              end
         | 
| 90 | 
            +
             | 
| 91 | 
            +
              # Setup specs for stats
         | 
| 92 | 
            +
              task :statsetup do
         | 
| 93 | 
            +
                require 'code_statistics'
         | 
| 94 | 
            +
                ::STATS_DIRECTORIES << %w(Model\ specs spec/models)
         | 
| 95 | 
            +
                ::STATS_DIRECTORIES << %w(View\ specs spec/views)
         | 
| 96 | 
            +
                ::STATS_DIRECTORIES << %w(Controller\ specs spec/controllers)
         | 
| 97 | 
            +
                ::STATS_DIRECTORIES << %w(Helper\ specs spec/views)
         | 
| 98 | 
            +
                ::CodeStatistics::TEST_TYPES << "Model specs"
         | 
| 99 | 
            +
                ::CodeStatistics::TEST_TYPES << "View specs"
         | 
| 100 | 
            +
                ::CodeStatistics::TEST_TYPES << "Controller specs"
         | 
| 101 | 
            +
                ::CodeStatistics::TEST_TYPES << "Helper specs"
         | 
| 102 | 
            +
                ::STATS_DIRECTORIES.delete_if {|a| a[0] =~ /test/}
         | 
| 103 | 
            +
              end
         | 
| 104 | 
            +
             | 
| 105 | 
            +
              namespace :db do
         | 
| 106 | 
            +
                namespace :fixtures do
         | 
| 107 | 
            +
                  desc "Load fixtures (from spec/fixtures) into the current environment's database.  Load specific fixtures using FIXTURES=x,y"
         | 
| 108 | 
            +
                  task :load => :environment do
         | 
| 109 | 
            +
                    require 'active_record/fixtures'
         | 
| 110 | 
            +
                    ActiveRecord::Base.establish_connection(RAILS_ENV.to_sym)
         | 
| 111 | 
            +
                    (ENV['FIXTURES'] ? ENV['FIXTURES'].split(/,/) : Dir.glob(File.join(RAILS_ROOT, 'spec', 'fixtures', '*.{yml,csv}'))).each do |fixture_file|
         | 
| 112 | 
            +
                      Fixtures.create_fixtures('spec/fixtures', File.basename(fixture_file, '.*'))
         | 
| 113 | 
            +
                    end
         | 
| 114 | 
            +
                  end
         | 
| 115 | 
            +
                end
         | 
| 116 | 
            +
              end
         | 
| 117 | 
            +
            end
         | 
| 118 | 
            +
             | 
| 119 | 
            +
            desc 'Generate documentation for the downloads extension.'
         | 
| 120 | 
            +
            Rake::RDocTask.new(:rdoc) do |rdoc|
         | 
| 121 | 
            +
              rdoc.rdoc_dir = 'rdoc'
         | 
| 122 | 
            +
              rdoc.title    = 'DownloadsExtension'
         | 
| 123 | 
            +
              rdoc.options << '--line-numbers' << '--inline-source'
         | 
| 124 | 
            +
              rdoc.rdoc_files.include('README')
         | 
| 125 | 
            +
              rdoc.rdoc_files.include('lib/**/*.rb')
         | 
| 126 | 
            +
            end
         | 
| 127 | 
            +
             | 
| 128 | 
            +
            # For extensions that are in transition
         | 
| 129 | 
            +
            desc 'Test the downloads extension.'
         | 
| 130 | 
            +
            Rake::TestTask.new(:test) do |t|
         | 
| 131 | 
            +
              t.libs << 'lib'
         | 
| 132 | 
            +
              t.pattern = 'test/**/*_test.rb'
         | 
| 133 | 
            +
              t.verbose = true
         | 
| 134 | 
            +
            end
         | 
| 135 | 
            +
             | 
| 136 | 
            +
            # Load any custom rakefiles for extension
         | 
| 137 | 
            +
            Dir[File.dirname(__FILE__) + '/tasks/*.rake'].sort.each { |f| require f }
         | 
    
        data/VERSION
    ADDED
    
    | @@ -0,0 +1 @@ | |
| 1 | 
            +
            0.5.2
         | 
| @@ -0,0 +1,31 @@ | |
| 1 | 
            +
            class MailingListMembership < ActiveRecord::Base
         | 
| 2 | 
            +
              establish_connection "mailman_#{RAILS_ENV}"
         | 
| 3 | 
            +
              set_table_name Radiant.config['reader.mailman.list_name']
         | 
| 4 | 
            +
              set_primary_key "address"
         | 
| 5 | 
            +
              
         | 
| 6 | 
            +
              def self.of_list(listname)
         | 
| 7 | 
            +
                old_table_name = self.table_name
         | 
| 8 | 
            +
                set_table_name listname
         | 
| 9 | 
            +
                reset_column_information
         | 
| 10 | 
            +
                self
         | 
| 11 | 
            +
              end
         | 
| 12 | 
            +
              
         | 
| 13 | 
            +
              [:digest, :not_metoo, :nomail, :plain].each do |col|
         | 
| 14 | 
            +
                define_method(col) do
         | 
| 15 | 
            +
                  read_attribute(col) == 'Y'
         | 
| 16 | 
            +
                end
         | 
| 17 | 
            +
                define_method("#{col}=") do |value|
         | 
| 18 | 
            +
                  write_attribute(col, to_yesno(value))
         | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
                define_method("#{col}_before_type_cast") do
         | 
| 21 | 
            +
                  read_attribute(col) == 'Y' ? 1 : 0
         | 
| 22 | 
            +
                end
         | 
| 23 | 
            +
              end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
            private
         | 
| 26 | 
            +
             | 
| 27 | 
            +
              def to_yesno(value)
         | 
| 28 | 
            +
                (value && value.to_i != 0) ? 'Y' : 'N'
         | 
| 29 | 
            +
              end
         | 
| 30 | 
            +
              
         | 
| 31 | 
            +
            end
         | 
| @@ -0,0 +1,24 @@ | |
| 1 | 
            +
            - fields_for @reader do |rf|
         | 
| 2 | 
            +
              - @reader.build_mailing_list_membership unless @reader.mailing_list_membership
         | 
| 3 | 
            +
              - rf.fields_for :mailing_list_membership do |mf|
         | 
| 4 | 
            +
                #mailing_list
         | 
| 5 | 
            +
                  %h3
         | 
| 6 | 
            +
                    = t('mailing_list_preferences')
         | 
| 7 | 
            +
                  %p
         | 
| 8 | 
            +
                    = t('control_your_subscription', :list_name => "#{Radiant.config['reader.mailman.list_name']}@")
         | 
| 9 | 
            +
                    %br
         | 
| 10 | 
            +
                    = mf.check_box :nomail
         | 
| 11 | 
            +
                    = mf.label :nomail
         | 
| 12 | 
            +
                    %br
         | 
| 13 | 
            +
                    %span#more_mailing_list_options.hidden
         | 
| 14 | 
            +
                      = mf.check_box :digest
         | 
| 15 | 
            +
                      = mf.label :digest
         | 
| 16 | 
            +
                      %br
         | 
| 17 | 
            +
                      = mf.check_box :plain
         | 
| 18 | 
            +
                      = mf.label :plain
         | 
| 19 | 
            +
                      %br
         | 
| 20 | 
            +
                      = mf.check_box :not_metoo
         | 
| 21 | 
            +
                      = mf.label :not_metoo
         | 
| 22 | 
            +
                      %br
         | 
| 23 | 
            +
                    %a.toggle.small{:href => '#', :rel => '#more_mailing_list_options'}
         | 
| 24 | 
            +
                      =t('more_options')
         | 
| @@ -0,0 +1,21 @@ | |
| 1 | 
            +
            - fields_for @reader do |rf|
         | 
| 2 | 
            +
              #mailing_list
         | 
| 3 | 
            +
                %h3
         | 
| 4 | 
            +
                  = t('mailing_list_preferences')
         | 
| 5 | 
            +
                %p
         | 
| 6 | 
            +
                  = rf.check_box :opt_out_of_mailing_list
         | 
| 7 | 
            +
                  = rf.label :opt_out_of_mailing_list
         | 
| 8 | 
            +
                  %br
         | 
| 9 | 
            +
                  - @reader.build_mailing_list_membership
         | 
| 10 | 
            +
                  - rf.fields_for :mailing_list_membership do |mf|
         | 
| 11 | 
            +
                    = mf.check_box :nomail
         | 
| 12 | 
            +
                    = mf.label :nomail
         | 
| 13 | 
            +
                    %br
         | 
| 14 | 
            +
                    = mf.check_box :digest
         | 
| 15 | 
            +
                    = mf.label :digest
         | 
| 16 | 
            +
                    %br
         | 
| 17 | 
            +
                    = mf.check_box :plain
         | 
| 18 | 
            +
                    = mf.label :plain
         | 
| 19 | 
            +
                    %br
         | 
| 20 | 
            +
                    = mf.check_box :not_metoo
         | 
| 21 | 
            +
                    = mf.label :not_metoo
         | 
| @@ -0,0 +1,25 @@ | |
| 1 | 
            +
            en:
         | 
| 2 | 
            +
              activerecord:
         | 
| 3 | 
            +
                attributes:
         | 
| 4 | 
            +
                  mailing_list_membership:
         | 
| 5 | 
            +
                    nomail: "Tick this box if you <strong>do not</strong> want to receive mailing list messages"
         | 
| 6 | 
            +
                    digest: "Get the mailing list as a daily digest instead of individual messages"
         | 
| 7 | 
            +
                    plain: "Get digest messages in plain text rather than HTML"
         | 
| 8 | 
            +
                    not_metoo: "Don't receive an echo of your own messages to the mailing list"
         | 
| 9 | 
            +
                errors:
         | 
| 10 | 
            +
                  models:
         | 
| 11 | 
            +
                    download:
         | 
| 12 | 
            +
                      attributes:
         | 
| 13 | 
            +
              config:
         | 
| 14 | 
            +
                reader:
         | 
| 15 | 
            +
                  mailman:
         | 
| 16 | 
            +
                    list_name: mailing list name
         | 
| 17 | 
            +
                    host: database host
         | 
| 18 | 
            +
                    port: database port
         | 
| 19 | 
            +
                    username: db username
         | 
| 20 | 
            +
                    password: db password
         | 
| 21 | 
            +
              control_your_subscription: "You can also control your membership of the %{list_name} mailing list from here."
         | 
| 22 | 
            +
              mailing_list: "Mailing list"
         | 
| 23 | 
            +
              mailing_list_configuration: "Mailing list configuration"
         | 
| 24 | 
            +
              mailing_list_preferences: "Mailing list preferences"
         | 
| 25 | 
            +
              more_options: "Show more options"
         | 
| @@ -0,0 +1,15 @@ | |
| 1 | 
            +
            class MailingListPreferences < ActiveRecord::Migration
         | 
| 2 | 
            +
              def self.up
         | 
| 3 | 
            +
                add_column :readers, :opt_out_of_mailing_list, :boolean
         | 
| 4 | 
            +
                add_column :readers, :mailing_list_digested, :boolean
         | 
| 5 | 
            +
                add_column :readers, :mailing_list_notmetoo, :boolean
         | 
| 6 | 
            +
                add_column :readers, :mailing_list_nomail, :boolean
         | 
| 7 | 
            +
              end
         | 
| 8 | 
            +
             | 
| 9 | 
            +
              def self.down
         | 
| 10 | 
            +
                remove_column :readers, :opt_out_of_mailing_list
         | 
| 11 | 
            +
                remove_column :readers, :mailing_list_digested
         | 
| 12 | 
            +
                remove_column :readers, :mailing_list_notmetoo
         | 
| 13 | 
            +
                remove_column :readers, :mailing_list_nomail
         | 
| 14 | 
            +
              end
         | 
| 15 | 
            +
            end
         | 
| @@ -0,0 +1,8 @@ | |
| 1 | 
            +
            module MailingListReader  # for inclusion into Reader
         | 
| 2 | 
            +
              def self.included(base)
         | 
| 3 | 
            +
                base.class_eval do
         | 
| 4 | 
            +
                  has_one :mailing_list_membership, :primary_key => 'email', :foreign_key => 'address', :dependent => :destroy
         | 
| 5 | 
            +
                  accepts_nested_attributes_for :mailing_list_membership
         | 
| 6 | 
            +
                end
         | 
| 7 | 
            +
              end
         | 
| 8 | 
            +
            end
         | 
| @@ -0,0 +1,8 @@ | |
| 1 | 
            +
            module RadiantReaderMailmanExtension
         | 
| 2 | 
            +
              VERSION = '0.1.0'
         | 
| 3 | 
            +
              SUMMARY = %q{Basic integration of reader groups with mailman mailing lists}
         | 
| 4 | 
            +
              DESCRIPTION = %q{Allows you to specify and configure a mailman mailing list for your readers. Group lists will follow.}
         | 
| 5 | 
            +
              URL = "http://radiant.spanner.org/reader_mailman"
         | 
| 6 | 
            +
              AUTHORS = ["William Ross"]
         | 
| 7 | 
            +
              EMAIL = ["radiant@spanner.org"]
         | 
| 8 | 
            +
            end
         | 
| @@ -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,32 @@ | |
| 1 | 
            +
            # -*- encoding: utf-8 -*-
         | 
| 2 | 
            +
            $:.push File.expand_path("../lib", __FILE__)
         | 
| 3 | 
            +
            require "radiant-reader_mailman-extension"
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            Gem::Specification.new do |s|
         | 
| 6 | 
            +
              s.name        = "radiant-reader_mailman-extension"
         | 
| 7 | 
            +
              s.version     = RadiantReaderMailmanExtension::VERSION
         | 
| 8 | 
            +
              s.platform    = Gem::Platform::RUBY
         | 
| 9 | 
            +
              s.authors     = RadiantReaderMailmanExtension::AUTHORS
         | 
| 10 | 
            +
              s.email       = RadiantReaderMailmanExtension::EMAIL
         | 
| 11 | 
            +
              s.homepage    = RadiantReaderMailmanExtension::URL
         | 
| 12 | 
            +
              s.summary     = RadiantReaderMailmanExtension::SUMMARY
         | 
| 13 | 
            +
              s.description = RadiantReaderMailmanExtension::DESCRIPTION
         | 
| 14 | 
            +
             | 
| 15 | 
            +
              ignores = if File.exist?('.gitignore')
         | 
| 16 | 
            +
                File.read('.gitignore').split("\n").inject([]) {|a,p| a + Dir[p] }
         | 
| 17 | 
            +
              else
         | 
| 18 | 
            +
                []
         | 
| 19 | 
            +
              end
         | 
| 20 | 
            +
              s.files         = Dir['**/*'] - ignores
         | 
| 21 | 
            +
              s.test_files    = Dir['test/**/*','spec/**/*','features/**/*'] - ignores
         | 
| 22 | 
            +
              # s.executables   = Dir['bin/*'] - ignores
         | 
| 23 | 
            +
              s.require_paths = ["lib"]
         | 
| 24 | 
            +
             | 
| 25 | 
            +
              s.post_install_message = %{
         | 
| 26 | 
            +
              Add this to your radiant project with a line in your Gemfile:
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                gem 'radiant-reader_mailman-extension', '~> #{RadiantReaderMailmanExtension::VERSION}'
         | 
| 29 | 
            +
             | 
| 30 | 
            +
              }
         | 
| 31 | 
            +
             | 
| 32 | 
            +
            end
         | 
| @@ -0,0 +1,15 @@ | |
| 1 | 
            +
            class ReaderMailmanExtension < Radiant::Extension
         | 
| 2 | 
            +
              version RadiantReaderMailmanExtension::VERSION
         | 
| 3 | 
            +
              description RadiantReaderMailmanExtension::DESCRIPTION
         | 
| 4 | 
            +
              url RadiantReaderMailmanExtension::URL
         | 
| 5 | 
            +
                
         | 
| 6 | 
            +
              def activate
         | 
| 7 | 
            +
                Reader.send :include, MailingListReader
         | 
| 8 | 
            +
                
         | 
| 9 | 
            +
                admin.account.edit.add :form, "accounts/mailing_list", :after => 'edit_password'
         | 
| 10 | 
            +
                admin.reader.edit.add :form, "admin/readers/mailing_list", :after => 'edit_group'
         | 
| 11 | 
            +
                admin.reader_configuration.show.add :settings, "admin/reader_configuration/mailing_list", :after => "administration"
         | 
| 12 | 
            +
                admin.reader_configuration.edit.add :form, "admin/reader_configuration/edit_mailing_list", :after => "administration"
         | 
| 13 | 
            +
              end
         | 
| 14 | 
            +
              
         | 
| 15 | 
            +
            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
         | 
| @@ -0,0 +1,28 @@ | |
| 1 | 
            +
            class DownloadsDataset < Dataset::Base
         | 
| 2 | 
            +
              uses :download_sites if defined? Site
         | 
| 3 | 
            +
              
         | 
| 4 | 
            +
              def load
         | 
| 5 | 
            +
                create_download "grouped"
         | 
| 6 | 
            +
                create_download "alsogrouped"
         | 
| 7 | 
            +
                create_download "ungrouped"
         | 
| 8 | 
            +
              end
         | 
| 9 | 
            +
             | 
| 10 | 
            +
              helpers do
         | 
| 11 | 
            +
                def create_download(name, attributes={})
         | 
| 12 | 
            +
                  attributes[:site] ||= sites(:test) if defined? Site
         | 
| 13 | 
            +
                  create_model :download, name.symbolize, download_attributes(attributes.update(:name => name))
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
                
         | 
| 16 | 
            +
                def download_attributes(att={})
         | 
| 17 | 
            +
                  name = att[:name] || "A download"
         | 
| 18 | 
            +
                  attributes = { 
         | 
| 19 | 
            +
                    :name => name,
         | 
| 20 | 
            +
                    :description => "Test download"
         | 
| 21 | 
            +
                  }.merge(att)
         | 
| 22 | 
            +
                  attributes[:site_id] ||= site_id(:test) if defined? Site
         | 
| 23 | 
            +
                  attributes[:document] ||= File.new(File.dirname(__FILE__) + "/../files/test.pdf")
         | 
| 24 | 
            +
                  attributes
         | 
| 25 | 
            +
                end
         | 
| 26 | 
            +
                
         | 
| 27 | 
            +
              end
         | 
| 28 | 
            +
            end
         | 
| @@ -0,0 +1,20 @@ | |
| 1 | 
            +
            require File.dirname(__FILE__) + '/../spec_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe Group do
         | 
| 4 | 
            +
              dataset :download_groups
         | 
| 5 | 
            +
              
         | 
| 6 | 
            +
              before do
         | 
| 7 | 
            +
                @site = Page.current_site = sites(:test) if defined? Site
         | 
| 8 | 
            +
              end
         | 
| 9 | 
            +
              
         | 
| 10 | 
            +
              it "should have a downloads association" do
         | 
| 11 | 
            +
                Group.reflect_on_association(:downloads).should_not be_nil
         | 
| 12 | 
            +
              end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
              it "should have a group of downloads" do
         | 
| 15 | 
            +
                group = groups(:busy)
         | 
| 16 | 
            +
                group.downloads.any?.should be_true
         | 
| 17 | 
            +
                group.downloads.size.should == 2
         | 
| 18 | 
            +
              end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
            end
         | 
    
        data/spec/spec.opts
    ADDED
    
    
    
        data/spec/spec_helper.rb
    ADDED
    
    | @@ -0,0 +1,36 @@ | |
| 1 | 
            +
            unless defined? RADIANT_ROOT
         | 
| 2 | 
            +
              ENV["RAILS_ENV"] = "test"
         | 
| 3 | 
            +
              case
         | 
| 4 | 
            +
              when ENV["RADIANT_ENV_FILE"]
         | 
| 5 | 
            +
                require ENV["RADIANT_ENV_FILE"]
         | 
| 6 | 
            +
              when File.dirname(__FILE__) =~ %r{vendor/radiant/vendor/extensions}
         | 
| 7 | 
            +
                require "#{File.expand_path(File.dirname(__FILE__) + "/../../../../../../")}/config/environment"
         | 
| 8 | 
            +
              else
         | 
| 9 | 
            +
                require "#{File.expand_path(File.dirname(__FILE__) + "/../../../../")}/config/environment"
         | 
| 10 | 
            +
              end
         | 
| 11 | 
            +
            end
         | 
| 12 | 
            +
            require "#{RADIANT_ROOT}/spec/spec_helper"
         | 
| 13 | 
            +
             | 
| 14 | 
            +
            Dataset::Resolver.default << (File.dirname(__FILE__) + "/datasets")
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            if File.directory?(File.dirname(__FILE__) + "/matchers")
         | 
| 17 | 
            +
              Dir[File.dirname(__FILE__) + "/matchers/*.rb"].each {|file| require file }
         | 
| 18 | 
            +
            end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
            Spec::Runner.configure do |config|
         | 
| 21 | 
            +
              # config.use_transactional_fixtures = true
         | 
| 22 | 
            +
              # config.use_instantiated_fixtures  = false
         | 
| 23 | 
            +
              # config.fixture_path = RAILS_ROOT + '/spec/fixtures'
         | 
| 24 | 
            +
             | 
| 25 | 
            +
              # You can declare fixtures for each behaviour like this:
         | 
| 26 | 
            +
              #   describe "...." do
         | 
| 27 | 
            +
              #     fixtures :table_a, :table_b
         | 
| 28 | 
            +
              #
         | 
| 29 | 
            +
              # Alternatively, if you prefer to declare them only once, you can
         | 
| 30 | 
            +
              # do so here, like so ...
         | 
| 31 | 
            +
              #
         | 
| 32 | 
            +
              #   config.global_fixtures = :table_a, :table_b
         | 
| 33 | 
            +
              #
         | 
| 34 | 
            +
              # If you declare global fixtures, be aware that they will be declared
         | 
| 35 | 
            +
              # for all of your examples, even those that don't use them.
         | 
| 36 | 
            +
            end
         | 
    
        metadata
    ADDED
    
    | @@ -0,0 +1,94 @@ | |
| 1 | 
            +
            --- !ruby/object:Gem::Specification 
         | 
| 2 | 
            +
            name: radiant-reader_mailman-extension
         | 
| 3 | 
            +
            version: !ruby/object:Gem::Version 
         | 
| 4 | 
            +
              hash: 27
         | 
| 5 | 
            +
              prerelease: 
         | 
| 6 | 
            +
              segments: 
         | 
| 7 | 
            +
              - 0
         | 
| 8 | 
            +
              - 1
         | 
| 9 | 
            +
              - 0
         | 
| 10 | 
            +
              version: 0.1.0
         | 
| 11 | 
            +
            platform: ruby
         | 
| 12 | 
            +
            authors: 
         | 
| 13 | 
            +
            - William Ross
         | 
| 14 | 
            +
            autorequire: 
         | 
| 15 | 
            +
            bindir: bin
         | 
| 16 | 
            +
            cert_chain: []
         | 
| 17 | 
            +
             | 
| 18 | 
            +
            date: 2011-11-22 00:00:00 Z
         | 
| 19 | 
            +
            dependencies: []
         | 
| 20 | 
            +
             | 
| 21 | 
            +
            description: Allows you to specify and configure a mailman mailing list for your readers. Group lists will follow.
         | 
| 22 | 
            +
            email: 
         | 
| 23 | 
            +
            - radiant@spanner.org
         | 
| 24 | 
            +
            executables: []
         | 
| 25 | 
            +
             | 
| 26 | 
            +
            extensions: []
         | 
| 27 | 
            +
             | 
| 28 | 
            +
            extra_rdoc_files: []
         | 
| 29 | 
            +
             | 
| 30 | 
            +
            files: 
         | 
| 31 | 
            +
            - app/models/mailing_list_membership.rb
         | 
| 32 | 
            +
            - app/views/accounts/_mailing_list.html.haml
         | 
| 33 | 
            +
            - app/views/admin/reader_configuration/_edit_mailing_list.html.haml
         | 
| 34 | 
            +
            - app/views/admin/reader_configuration/_mailing_list.html.haml
         | 
| 35 | 
            +
            - app/views/admin/readers/_mailing_list.html.haml
         | 
| 36 | 
            +
            - config/initializers/radiant_config.rb
         | 
| 37 | 
            +
            - config/locales/en.yml
         | 
| 38 | 
            +
            - db/migrate/20111121160131_mailing_list_preferences.rb
         | 
| 39 | 
            +
            - lib/mailing_list_reader.rb
         | 
| 40 | 
            +
            - lib/radiant-reader_mailman-extension.rb
         | 
| 41 | 
            +
            - lib/tasks/reader_mailman_extension_tasks.rake
         | 
| 42 | 
            +
            - radiant-reader_mailman-extension.gemspec
         | 
| 43 | 
            +
            - Rakefile
         | 
| 44 | 
            +
            - reader_mailman_extension.rb
         | 
| 45 | 
            +
            - README.markdown
         | 
| 46 | 
            +
            - spec/datasets/download_groups_dataset.rb
         | 
| 47 | 
            +
            - spec/datasets/download_readers_dataset.rb
         | 
| 48 | 
            +
            - spec/datasets/download_sites_dataset.rb
         | 
| 49 | 
            +
            - spec/datasets/downloads_dataset.rb
         | 
| 50 | 
            +
            - spec/models/group_spec.rb
         | 
| 51 | 
            +
            - spec/spec.opts
         | 
| 52 | 
            +
            - spec/spec_helper.rb
         | 
| 53 | 
            +
            - VERSION
         | 
| 54 | 
            +
            homepage: http://radiant.spanner.org/reader_mailman
         | 
| 55 | 
            +
            licenses: []
         | 
| 56 | 
            +
             | 
| 57 | 
            +
            post_install_message: "\n  Add this to your radiant project with a line in your Gemfile:\n\n    gem 'radiant-reader_mailman-extension', '~> 0.1.0'\n\n  "
         | 
| 58 | 
            +
            rdoc_options: []
         | 
| 59 | 
            +
             | 
| 60 | 
            +
            require_paths: 
         | 
| 61 | 
            +
            - lib
         | 
| 62 | 
            +
            required_ruby_version: !ruby/object:Gem::Requirement 
         | 
| 63 | 
            +
              none: false
         | 
| 64 | 
            +
              requirements: 
         | 
| 65 | 
            +
              - - ">="
         | 
| 66 | 
            +
                - !ruby/object:Gem::Version 
         | 
| 67 | 
            +
                  hash: 3
         | 
| 68 | 
            +
                  segments: 
         | 
| 69 | 
            +
                  - 0
         | 
| 70 | 
            +
                  version: "0"
         | 
| 71 | 
            +
            required_rubygems_version: !ruby/object:Gem::Requirement 
         | 
| 72 | 
            +
              none: false
         | 
| 73 | 
            +
              requirements: 
         | 
| 74 | 
            +
              - - ">="
         | 
| 75 | 
            +
                - !ruby/object:Gem::Version 
         | 
| 76 | 
            +
                  hash: 3
         | 
| 77 | 
            +
                  segments: 
         | 
| 78 | 
            +
                  - 0
         | 
| 79 | 
            +
                  version: "0"
         | 
| 80 | 
            +
            requirements: []
         | 
| 81 | 
            +
             | 
| 82 | 
            +
            rubyforge_project: 
         | 
| 83 | 
            +
            rubygems_version: 1.8.10
         | 
| 84 | 
            +
            signing_key: 
         | 
| 85 | 
            +
            specification_version: 3
         | 
| 86 | 
            +
            summary: Basic integration of reader groups with mailman mailing lists
         | 
| 87 | 
            +
            test_files: 
         | 
| 88 | 
            +
            - spec/datasets/download_groups_dataset.rb
         | 
| 89 | 
            +
            - spec/datasets/download_readers_dataset.rb
         | 
| 90 | 
            +
            - spec/datasets/download_sites_dataset.rb
         | 
| 91 | 
            +
            - spec/datasets/downloads_dataset.rb
         | 
| 92 | 
            +
            - spec/models/group_spec.rb
         | 
| 93 | 
            +
            - spec/spec.opts
         | 
| 94 | 
            +
            - spec/spec_helper.rb
         |