Skip to content
Browse files

break out from radiant core

  • Loading branch information...
0 parents commit 32e64ff5b0f81666bf3ac00cc23d29effaf272ef @johnmuhl johnmuhl committed Jun 6, 2011
5 README
@@ -0,0 +1,5 @@
+= Exporter
+
+Export your models to YAML at yoursite.com/admin/export
+
+If you want to add models for exporting, add them to the Radiant::Exporter.exportable_models array.
116 Rakefile
@@ -0,0 +1,116 @@
+unless defined? RADIANT_ROOT
+ ENV["RAILS_ENV"] = "test"
+ case
+ when ENV["RADIANT_ENV_FILE"]
+ require File.dirname(ENV["RADIANT_ENV_FILE"]) + "/boot"
+ when File.dirname(__FILE__) =~ %r{vendor/radiant/vendor/extensions}
+ require "#{File.expand_path(File.dirname(__FILE__) + "/../../../../../")}/config/boot"
+ else
+ require "#{File.expand_path(File.dirname(__FILE__) + "/../../../")}/config/boot"
+ end
+end
+
+require 'rake'
+require 'rake/rdoctask'
+require 'rake/testtask'
+
+rspec_base = File.expand_path(RADIANT_ROOT + '/vendor/plugins/rspec/lib')
+$LOAD_PATH.unshift(rspec_base) if File.exist?(rspec_base)
+require 'spec/rake/spectask'
+require 'cucumber'
+require 'cucumber/rake/task'
+
+# Cleanup the RADIANT_ROOT constant so specs will load the environment
+Object.send(:remove_const, :RADIANT_ROOT)
+
+extension_root = File.expand_path(File.dirname(__FILE__))
+
+task :default => :spec
+task :stats => "spec:statsetup"
+
+desc "Run all specs in spec directory"
+Spec::Rake::SpecTask.new(:spec) do |t|
+ t.spec_opts = ['--options', "\"#{extension_root}/spec/spec.opts\""]
+ t.spec_files = FileList['spec/**/*_spec.rb']
+end
+
+task :features => 'spec:integration'
+
+namespace :spec do
+ desc "Run all specs in spec directory with RCov"
+ Spec::Rake::SpecTask.new(:rcov) do |t|
+ t.spec_opts = ['--options', "\"#{extension_root}/spec/spec.opts\""]
+ t.spec_files = FileList['spec/**/*_spec.rb']
+ t.rcov = true
+ t.rcov_opts = ['--exclude', 'spec', '--rails']
+ end
+
+ desc "Print Specdoc for all specs"
+ Spec::Rake::SpecTask.new(:doc) do |t|
+ t.spec_opts = ["--format", "specdoc", "--dry-run"]
+ t.spec_files = FileList['spec/**/*_spec.rb']
+ end
+
+ [:models, :controllers, :views, :helpers].each do |sub|
+ desc "Run the specs under spec/#{sub}"
+ Spec::Rake::SpecTask.new(sub) do |t|
+ t.spec_opts = ['--options', "\"#{extension_root}/spec/spec.opts\""]
+ t.spec_files = FileList["spec/#{sub}/**/*_spec.rb"]
+ end
+ end
+
+ desc "Run the Cucumber features"
+ Cucumber::Rake::Task.new(:integration) do |t|
+ t.fork = true
+ t.cucumber_opts = ['--format', (ENV['CUCUMBER_FORMAT'] || 'pretty')]
+ # t.feature_pattern = "#{extension_root}/features/**/*.feature"
+ t.profile = "default"
+ end
+
+ # Setup specs for stats
+ task :statsetup do
+ require 'code_statistics'
+ ::STATS_DIRECTORIES << %w(Model\ specs spec/models)
+ ::STATS_DIRECTORIES << %w(View\ specs spec/views)
+ ::STATS_DIRECTORIES << %w(Controller\ specs spec/controllers)
+ ::STATS_DIRECTORIES << %w(Helper\ specs spec/views)
+ ::CodeStatistics::TEST_TYPES << "Model specs"
+ ::CodeStatistics::TEST_TYPES << "View specs"
+ ::CodeStatistics::TEST_TYPES << "Controller specs"
+ ::CodeStatistics::TEST_TYPES << "Helper specs"
+ ::STATS_DIRECTORIES.delete_if {|a| a[0] =~ /test/}
+ end
+
+ namespace :db do
+ namespace :fixtures do
+ desc "Load fixtures (from spec/fixtures) into the current environment's database. Load specific fixtures using FIXTURES=x,y"
+ task :load => :environment do
+ require 'active_record/fixtures'
+ ActiveRecord::Base.establish_connection(RAILS_ENV.to_sym)
+ (ENV['FIXTURES'] ? ENV['FIXTURES'].split(/,/) : Dir.glob(File.join(RAILS_ROOT, 'spec', 'fixtures', '*.{yml,csv}'))).each do |fixture_file|
+ Fixtures.create_fixtures('spec/fixtures', File.basename(fixture_file, '.*'))
+ end
+ end
+ end
+ end
+end
+
+desc 'Generate documentation for the exporter extension.'
+Rake::RDocTask.new(:rdoc) do |rdoc|
+ rdoc.rdoc_dir = 'rdoc'
+ rdoc.title = 'ExporterExtension'
+ rdoc.options << '--line-numbers' << '--inline-source'
+ rdoc.rdoc_files.include('README')
+ rdoc.rdoc_files.include('lib/**/*.rb')
+end
+
+# For extensions that are in transition
+desc 'Test the exporter extension.'
+Rake::TestTask.new(:test) do |t|
+ t.libs << 'lib'
+ t.pattern = 'test/**/*_test.rb'
+ t.verbose = true
+end
+
+# Load any custom rakefiles for extension
+Dir[File.dirname(__FILE__) + '/tasks/*.rake'].sort.each { |f| require f }
5 app/controllers/admin/export_controller.rb
@@ -0,0 +1,5 @@
+class Admin::ExportController < ApplicationController
+ def export
+ render :text => Radiant::Exporter.export(params[:type] || 'yaml'), :content_type => "text/yaml"
+ end
+end
41 app/models/radiant/exporter.rb
@@ -0,0 +1,41 @@
+module Radiant
+ class Exporter
+ cattr_accessor :exportable_models
+ @@exportable_models = [Radiant::Config, User, Page, PagePart, PageField, Snippet, Layout]
+ cattr_accessor :template_models
+ @@template_models = [Layout, Snippet, Page, PagePart, PageField]
+ cattr_accessor :ignored_template_attributes
+ @@ignored_template_attributes = [:lock_version, :created_at, :updated_at, :created_by_id, :updated_by_id]
+
+ class << self
+ def export(type='yaml')
+ if self.respond_to?("export_#{type}")
+ self.send("export_#{type}")
+ else
+ ''
+ end
+ end
+
+ def export_yaml
+ hash = ActiveSupport::OrderedHash.new
+ @@exportable_models.each do |klass|
+ hash[klass.name.pluralize] = klass.find(:all).inject(ActiveSupport::OrderedHash.new) { |h, record| h[record.id.to_i] = record.attributes; h }
+ end
+ hash.to_yaml
+ end
+
+ def export_template
+ hash = ActiveSupport::OrderedHash.new
+ hash['name'] = hash['description'] = "Exported Template #{Time.zone.now.to_i}"
+ records = hash['records'] = ActiveSupport::OrderedHash.new
+ @@template_models.each do |klass|
+ records[klass.name.pluralize] = klass.find(:all).inject(ActiveSupport::OrderedHash.new) { |h, record|
+ h[record.id.to_i] = record.attributes.delete_if{|att| @@ignored_template_attributes.include?(att[0].to_sym) };
+ h
+ }
+ end
+ hash.to_yaml
+ end
+ end
+ end
+end
3 config/locales/en.yml
@@ -0,0 +1,3 @@
+---
+en:
+ exporter: Exporter
6 config/routes.rb
@@ -0,0 +1,6 @@
+ActionController::Routing::Routes.draw do |map|
+ map.with_options(:controller => 'admin/export') do |export|
+ export.export 'admin/export', :action => 'export'
+ export.export_type 'admin/export/:type', :action => 'export'
+ end
+end
1 cucumber.yml
@@ -0,0 +1 @@
+default: --format progress features --tags ~@proposed,~@in_progress
8 exporter_extension.rb
@@ -0,0 +1,8 @@
+class ExporterExtension < Radiant::Extension
+ version "1.0"
+ description "Export your models from Radiant"
+ url "http://github.com/radiant/radiant"
+
+ def activate
+ end
+end
16 features/support/env.rb
@@ -0,0 +1,16 @@
+# Sets up the Rails environment for Cucumber
+ENV["RAILS_ENV"] = "test"
+# Extension root
+extension_env = File.expand_path(File.dirname(__FILE__) + '/../../../../../config/environment')
+require extension_env+'.rb'
+
+Dir.glob(File.join(RADIANT_ROOT, "features", "**", "*.rb")).each {|step| require step}
+
+Cucumber::Rails::World.class_eval do
+ include Dataset
+ datasets_directory "#{RADIANT_ROOT}/spec/datasets"
+ Dataset::Resolver.default = Dataset::DirectoryResolver.new("#{RADIANT_ROOT}/spec/datasets", File.dirname(__FILE__) + '/../../spec/datasets', File.dirname(__FILE__) + '/../datasets')
+ self.datasets_database_dump_path = "#{Rails.root}/tmp/dataset"
+
+ # dataset :exporter
+end
14 features/support/paths.rb
@@ -0,0 +1,14 @@
+def path_to(page_name)
+ case page_name
+
+ when /the homepage/i
+ root_path
+
+ when /login/i
+ login_path
+ # Add more page name => path mappings here
+
+ else
+ raise "Can't find mapping from \"#{page_name}\" to a path."
+ end
+end
2 lib/radiant-exporter-extension.rb
@@ -0,0 +1,2 @@
+module RadiantExporterExtension
+end
3 lib/radiant-exporter-extension/version.rb
@@ -0,0 +1,3 @@
+module RadiantExporterExtension
+ VERSION = "1.0.0"
+end
55 lib/tasks/exporter_extension_tasks.rake
@@ -0,0 +1,55 @@
+namespace :radiant do
+ namespace :extensions do
+ namespace :exporter do
+
+ desc "Runs the migration of the Exporter extension"
+ task :migrate => :environment do
+ require 'radiant/extension_migrator'
+ if ENV["VERSION"]
+ ExporterExtension.migrator.migrate(ENV["VERSION"].to_i)
+ Rake::Task['db:schema:dump'].invoke
+ else
+ ExporterExtension.migrator.migrate
+ Rake::Task['db:schema:dump'].invoke
+ end
+ end
+
+ desc "Copies public assets of the Exporter to the instance public/ directory."
+ task :update => :environment do
+ is_svn_or_dir = proc {|path| path =~ /\.svn/ || File.directory?(path) }
+ puts "Copying assets from ExporterExtension"
+ Dir[ExporterExtension.root + "/public/**/*"].reject(&is_svn_or_dir).each do |file|
+ path = file.sub(ExporterExtension.root, '')
+ directory = File.dirname(path)
+ mkdir_p RAILS_ROOT + directory, :verbose => false
+ cp file, RAILS_ROOT + path, :verbose => false
+ end
+ unless ExporterExtension.root.starts_with? RAILS_ROOT # don't need to copy vendored tasks
+ puts "Copying rake tasks from ExporterExtension"
+ local_tasks_path = File.join(RAILS_ROOT, %w(lib tasks))
+ mkdir_p local_tasks_path, :verbose => false
+ Dir[File.join ExporterExtension.root, %w(lib tasks *.rake)].each do |file|
+ cp file, local_tasks_path, :verbose => false
+ end
+ end
+ end
+
+ desc "Syncs all available translations for this ext to the English ext master"
+ task :sync => :environment do
+ # The main translation root, basically where English is kept
+ language_root = ExporterExtension.root + "/config/locales"
+ words = TranslationSupport.get_translation_keys(language_root)
+
+ Dir["#{language_root}/*.yml"].each do |filename|
+ next if filename.match('_available_tags')
+ basename = File.basename(filename, '.yml')
+ puts "Syncing #{basename}"
+ (comments, other) = TranslationSupport.read_file(filename, basename)
+ words.each { |k,v| other[k] ||= words[k] } # Initializing hash variable as empty if it does not exist
+ other.delete_if { |k,v| !words[k] } # Remove if not defined in en.yml
+ TranslationSupport.write_file(filename, basename, comments, other)
+ end
+ end
+ end
+ end
+end
30 radiant-exporter-extension.gemspec
@@ -0,0 +1,30 @@
+# -*- encoding: utf-8 -*-
+$:.push File.expand_path("../lib", __FILE__)
+require "radiant-exporter-extension/version"
+
+Gem::Specification.new do |s|
+ s.name = "radiant-exporter-extension"
+ s.version = RadiantExporterExtension::VERSION
+ s.platform = Gem::Platform::RUBY
+ s.authors = ["Radiant CMS Dev Team"]
+ s.email = ["radiant@radiantcms.org"]
+ s.homepage = "http://radiantcms.org/"
+ s.summary = %q{Export your models from Radiant}
+ s.description = %q{Export your models from Radiant}
+
+ ignores = if File.exist?(".gitignore")
+ File.read(".gitignore").split("\n").inject([]) {|a,p| a + Dir[p] }
+ else
+ []
+ end
+ s.files = Dir["**/*"] - ignores
+ s.test_files = Dir["test/**/*","spec/**/*","features/**/*"] - ignores
+ s.require_paths = ["lib"]
+
+ # s.add_dependency "some_gem", "~> 1.0.0"
+
+ s.post_install_message = %{
+ Add this to your radiant project with:
+ config.gem "radiant-exporter-extension", :version => "~> #{RadiantExporterExtension::VERSION}"
+ }
+end
16 spec/controllers/admin/export_controller_spec.rb
@@ -0,0 +1,16 @@
+require File.dirname(__FILE__) + "/../../spec_helper"
+
+describe Admin::ExportController do
+ dataset :users_and_pages
+
+ before :each do
+ login_as :designer
+ end
+
+ it "should export a YAML file" do
+ get :export
+ response.should be_success
+ response.content_type.should == "text/yaml"
+ YAML.load(response.body).should be_kind_of(Hash)
+ end
+end
29 spec/models/radiant/exporter_spec.rb
@@ -0,0 +1,29 @@
+require File.dirname(__FILE__) + "/../../spec_helper"
+
+describe Radiant::Exporter do
+ dataset :pages_with_layouts, :users_and_pages, :snippets
+
+ let(:exporter){ Radiant::Exporter }
+ let(:exported_content){ exporter.export }
+ let(:exported_hash){ YAML::load(exported_content) }
+ subject { exporter }
+
+ specify{ exported_content.should be_kind_of(String) }
+
+ it "should output all exportable_models with pluralized class names as keys" do
+ exporter.exportable_models.all? { |c| exported_hash.has_key?(c.to_s.pluralize) }.should be_true
+ end
+
+ it "should output the models by id as hashes" do
+ exported_hash['Pages'][page_id(:home)]['title'].should == pages(:home).title
+ exported_hash['Users'][user_id(:admin)]['name'].should == users(:admin).name
+ end
+
+ its(:exportable_models){ should == [Radiant::Config, User, Page, PagePart, PageField, Snippet, Layout] }
+ its(:template_models){ should == [Layout, Snippet, Page, PagePart, PageField] }
+ its(:ignored_template_attributes){ should == [:lock_version, :created_at, :updated_at, :created_by_id, :updated_by_id] }
+ it "should allow setting exportable_models" do
+ exporter.exportable_models = [Page]
+ exporter.exportable_models.should == [Page]
+ end
+end
6 spec/spec.opts
@@ -0,0 +1,6 @@
+--colour
+--format
+progress
+--loadby
+mtime
+--reverse
36 spec/spec_helper.rb
@@ -0,0 +1,36 @@
+unless defined? RADIANT_ROOT
+ ENV["RAILS_ENV"] = "test"
+ case
+ when ENV["RADIANT_ENV_FILE"]
+ require ENV["RADIANT_ENV_FILE"]
+ when File.dirname(__FILE__) =~ %r{vendor/radiant/vendor/extensions}
+ require "#{File.expand_path(File.dirname(__FILE__) + "/../../../../../../")}/config/environment"
+ else
+ require "#{File.expand_path(File.dirname(__FILE__) + "/../../../../")}/config/environment"
+ end
+end
+require "#{RADIANT_ROOT}/spec/spec_helper"
+
+Dataset::Resolver.default << (File.dirname(__FILE__) + "/datasets")
+
+if File.directory?(File.dirname(__FILE__) + "/matchers")
+ Dir[File.dirname(__FILE__) + "/matchers/*.rb"].each {|file| require file }
+end
+
+Spec::Runner.configure do |config|
+ # config.use_transactional_fixtures = true
+ # config.use_instantiated_fixtures = false
+ # config.fixture_path = RAILS_ROOT + '/spec/fixtures'
+
+ # You can declare fixtures for each behaviour like this:
+ # describe "...." do
+ # fixtures :table_a, :table_b
+ #
+ # Alternatively, if you prefer to declare them only once, you can
+ # do so here, like so ...
+ #
+ # config.global_fixtures = :table_a, :table_b
+ #
+ # If you declare global fixtures, be aware that they will be declared
+ # for all of your examples, even those that don't use them.
+end

0 comments on commit 32e64ff

Please sign in to comment.
Something went wrong with that request. Please try again.