spree_google_base 0.30.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -0
- data/README.markdown +46 -0
- data/Rakefile +75 -0
- data/app/controllers/admin/google_base_settings_controller.rb +16 -0
- data/app/controllers/admin/taxon_map_controller.rb +26 -0
- data/app/helpers/google_base_helper.rb +21 -0
- data/app/models/product_decorator.rb +40 -0
- data/app/models/taxon_map.rb +3 -0
- data/app/views/admin/_google_base_link.html.erb +1 -0
- data/app/views/admin/google_base_settings/edit.html.erb +21 -0
- data/app/views/admin/google_base_settings/show.html.erb +20 -0
- data/app/views/admin/taxon_map/index.html.erb +24 -0
- data/config/initializers/google_base.rb +15 -0
- data/config/locales/en.yml +11 -0
- data/config/routes.rb +6 -0
- data/db/migrate/20090224211256_create_taxon_maps.rb +14 -0
- data/lib/google_base_configuration.rb +8 -0
- data/lib/spree/google_base/config.rb +22 -0
- data/lib/spree_google_base.rb +20 -0
- data/lib/spree_google_base_hooks.rb +3 -0
- data/lib/tasks/install.rake +25 -0
- data/lib/tasks/spree_google_base.rake +45 -0
- data/public/stylesheets/google_base.css +8 -0
- data/public/template_google_base.xml +14 -0
- data/spec/factories.rb +6 -0
- data/spec/factories/image_factory.rb +3 -0
- data/spec/factories/product_factory.rb +10 -0
- data/spec/models/product_spec.rb +54 -0
- data/spec/models/taxon_spec.rb +9 -0
- data/spec/spec_helper.rb +32 -0
- data/spree_google_base.gemspec +22 -0
- metadata +109 -0
data/.gitignore
ADDED
data/README.markdown
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
SpreeGoogleBase
|
2
|
+
===============
|
3
|
+
|
4
|
+
This extension allows you to use Google Base to list products for free that will appear in Google Product Search (http://www.froogle.com/).
|
5
|
+
|
6
|
+
<a href="http://base.google.com/support/bin/answer.py?answer=25277&topic=2904">Learn more about Google Base</a>
|
7
|
+
|
8
|
+
INSTALLATION
|
9
|
+
------------
|
10
|
+
|
11
|
+
1. Create google base account. Create google base ftp account (if applicable). Create data feed in google base with a type "Products" and name "google_base.xml".
|
12
|
+
|
13
|
+
2. Install the extension with one of the following commands
|
14
|
+
|
15
|
+
Add `gem "spree_google_base"`
|
16
|
+
Run `bundle install`
|
17
|
+
Run `rake db:migrate`
|
18
|
+
Run `rake spree_google_base:install`
|
19
|
+
|
20
|
+
3. Edit product_type, priorities in spree admin (/admin/taxon_map).
|
21
|
+
|
22
|
+
4. Set preferences in spree admin panel (/admin/google_base_settings) for the feed title, public domain, feed description, ftp login and password. FTP login is not required - you may schedule upload from the public directory.
|
23
|
+
|
24
|
+
5. Issue the command 'rake spree_google_base:generate' to generate feed. Verify feed exists (YOUR_APP_ROOT/public/google_base.xml).
|
25
|
+
|
26
|
+
|
27
|
+
ADVANCED CONFIGURATION
|
28
|
+
------------
|
29
|
+
|
30
|
+
You can modify fields set for export and list of 'g:' attributes. Look at config/initializers/google_base.rb
|
31
|
+
You can override values of GOOGLE_BASE_ATTR_MAP and GOOGLE_BASE_FILTERED_ATTRS arrays with help of Array#delete, Array#delete_at, Array#<<, Array#+=, etc.
|
32
|
+
Also you can override methods from product_decorator.rb in your site extension.
|
33
|
+
|
34
|
+
|
35
|
+
CRONJOBS
|
36
|
+
--------
|
37
|
+
|
38
|
+
There are two options to regulate google base product update:
|
39
|
+
|
40
|
+
A) Setup cronjobs to run 'rake spree_google_base:generate' and 'rake spree_google_base:transfer'
|
41
|
+
|
42
|
+
|
43
|
+
Development of this extension is sponsored by [End Point][1] and by [FCP Groton][2].
|
44
|
+
|
45
|
+
[1]: http://www.endpoint.com/
|
46
|
+
[2]: http://www.fcpgroton.com/
|
data/Rakefile
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'rake/testtask'
|
4
|
+
require 'rake/packagetask'
|
5
|
+
require 'rake/gempackagetask'
|
6
|
+
|
7
|
+
gemfile = File.expand_path('../spec/test_app/Gemfile', __FILE__)
|
8
|
+
if File.exists?(gemfile) && (%w(spec cucumber).include?(ARGV.first.to_s) || ARGV.size == 0)
|
9
|
+
require 'bundler'
|
10
|
+
ENV['BUNDLE_GEMFILE'] = gemfile
|
11
|
+
Bundler.setup
|
12
|
+
|
13
|
+
require 'rspec'
|
14
|
+
require 'rspec/core/rake_task'
|
15
|
+
RSpec::Core::RakeTask.new
|
16
|
+
|
17
|
+
require 'cucumber/rake/task'
|
18
|
+
Cucumber::Rake::Task.new do |t|
|
19
|
+
t.cucumber_opts = %w{--format progress}
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
desc "Default Task"
|
24
|
+
task :default => [:spec, :cucumber ]
|
25
|
+
|
26
|
+
spec = eval(File.read('spree_google_base.gemspec'))
|
27
|
+
|
28
|
+
Rake::GemPackageTask.new(spec) do |p|
|
29
|
+
p.gem_spec = spec
|
30
|
+
end
|
31
|
+
|
32
|
+
desc "Release to gemcutter"
|
33
|
+
task :release => :package do
|
34
|
+
require 'rake/gemcutter'
|
35
|
+
Rake::Gemcutter::Tasks.new(spec).define
|
36
|
+
Rake::Task['gem:push'].invoke
|
37
|
+
end
|
38
|
+
|
39
|
+
desc "Default Task"
|
40
|
+
task :default => [ :spec ]
|
41
|
+
|
42
|
+
desc "Regenerates a rails 3 app for testing"
|
43
|
+
task :test_app do
|
44
|
+
require '../spree/lib/generators/spree/test_app_generator'
|
45
|
+
class GoogleBaseTestAppGenerator < Spree::Generators::TestAppGenerator
|
46
|
+
|
47
|
+
def install_gems
|
48
|
+
inside "test_app" do
|
49
|
+
run 'rake spree_core:install'
|
50
|
+
run 'rake spree_google_base:install'
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def migrate_db
|
55
|
+
run_migrations
|
56
|
+
end
|
57
|
+
|
58
|
+
protected
|
59
|
+
def full_path_for_local_gems
|
60
|
+
<<-gems
|
61
|
+
gem 'spree_core', :path => \'#{File.join(File.dirname(__FILE__), "../spree/", "core")}\'
|
62
|
+
gem 'spree_google_base', :path => \'#{File.dirname(__FILE__)}\'
|
63
|
+
gems
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
GoogleBaseTestAppGenerator.start
|
68
|
+
end
|
69
|
+
|
70
|
+
namespace :test_app do
|
71
|
+
desc 'Rebuild test and cucumber databases'
|
72
|
+
task :rebuild_dbs do
|
73
|
+
system("cd spec/test_app && rake db:drop db:migrate RAILS_ENV=test && rake db:drop db:migrate RAILS_ENV=cucumber")
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class Admin::GoogleBaseSettingsController < Admin::BaseController
|
2
|
+
helper :google_base
|
3
|
+
|
4
|
+
def update
|
5
|
+
config = Spree::GoogleBase::Config.instance
|
6
|
+
config.update_attributes(params[:google_base_configuration])
|
7
|
+
Rails.cache.delete("configuration_#{config.id}".to_sym)
|
8
|
+
|
9
|
+
respond_to do |format|
|
10
|
+
format.html {
|
11
|
+
redirect_to admin_google_base_settings_path
|
12
|
+
}
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
class Admin::TaxonMapController < Admin::BaseController
|
2
|
+
resource_controller
|
3
|
+
|
4
|
+
def index
|
5
|
+
@taxons = Taxon.find(:all)
|
6
|
+
@taxons.each do |taxon|
|
7
|
+
if !taxon.taxon_map
|
8
|
+
taxon_map = TaxonMap.new(:product_type => '', :taxon_id => taxon.id, :priority => 0)
|
9
|
+
taxon_map.save
|
10
|
+
taxon.taxon_map = taxon_map
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def create
|
16
|
+
TaxonMap.delete(TaxonMap.find(:all))
|
17
|
+
params[:tax_id].each do |k, v|
|
18
|
+
taxon_map = TaxonMap.new(:product_type => v, :taxon_id => k, :priority => params[:priority][k].to_i || 0)
|
19
|
+
taxon_map.save
|
20
|
+
end
|
21
|
+
if TaxonMap.count == params[:tax_id].size
|
22
|
+
flash[:notice] = "Google Base taxons mapping saved successfully."
|
23
|
+
end
|
24
|
+
redirect_to admin_taxon_map_index_url
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module GoogleBaseHelper
|
2
|
+
def setting_presentation_row(setting, hide_value = false)
|
3
|
+
value = hide_value ? I18n.t(:not_shown) : Spree::GoogleBase::Config[setting].to_s
|
4
|
+
value = "—" if value.blank?
|
5
|
+
%(
|
6
|
+
<tr>
|
7
|
+
<th scope="row">#{I18n.t(setting, :scope => :google_base)}:</th>
|
8
|
+
<td>#{value}</td>
|
9
|
+
</tr>).html_safe
|
10
|
+
end
|
11
|
+
|
12
|
+
def setting_field(form, setting)
|
13
|
+
definition = GoogleBaseConfiguration.preference_definitions[setting.to_s]
|
14
|
+
type = definition.instance_eval('@type').to_sym
|
15
|
+
%(
|
16
|
+
<p>
|
17
|
+
#{form.label("preferred_#{setting}", I18n.t(setting, :scope => :google_base))}:<br />
|
18
|
+
#{preference_field(form, "preferred_#{setting}", :type => type)}
|
19
|
+
</p>).html_safe
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
Product.class_eval do
|
2
|
+
scope :google_base_scope, includes(:taxons, :images)
|
3
|
+
|
4
|
+
protected
|
5
|
+
|
6
|
+
def google_base_description
|
7
|
+
self.description
|
8
|
+
end
|
9
|
+
|
10
|
+
def google_base_condition
|
11
|
+
'new'
|
12
|
+
end
|
13
|
+
|
14
|
+
def google_base_link
|
15
|
+
public_dir = Spree::GoogleBase::Config[:public_domain] || ''
|
16
|
+
[public_dir.sub(/\/$/, ''), 'products', self.permalink].join('/')
|
17
|
+
end
|
18
|
+
|
19
|
+
def google_base_image_link
|
20
|
+
public_dir = Spree::GoogleBase::Config[:public_domain] || ''
|
21
|
+
if self.images.empty?
|
22
|
+
nil
|
23
|
+
else
|
24
|
+
public_dir.sub(/\/$/, '') + self.images.first.attachment.url(:product)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def google_base_product_type
|
29
|
+
return nil unless Spree::GoogleBase::Config[:enable_taxon_mapping]
|
30
|
+
product_type = ''
|
31
|
+
priority = -1000
|
32
|
+
self.taxons.each do |taxon|
|
33
|
+
if taxon.taxon_map && taxon.taxon_map.priority > priority
|
34
|
+
priority = taxon.taxon_map.priority
|
35
|
+
product_type = taxon.taxon_map.product_type
|
36
|
+
end
|
37
|
+
end
|
38
|
+
product_type
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= configurations_menu_item('Google Base', admin_google_base_settings_path, 'Google Base taxonomy management') %>
|
@@ -0,0 +1,21 @@
|
|
1
|
+
<%= render :partial => 'admin/shared/configuration_menu' %>
|
2
|
+
|
3
|
+
<h1><%= t("google_base.export_settings") %></h1>
|
4
|
+
|
5
|
+
<%= form_for(Spree::GoogleBase::Config.instance, :url => admin_google_base_settings_path) do |f| %>
|
6
|
+
<% [:title, :public_domain, :description, :ftp_username,
|
7
|
+
:ftp_password, :enable_taxon_mapping].each do |setting| %>
|
8
|
+
<%= setting_field(f, setting) %>
|
9
|
+
<% end %>
|
10
|
+
|
11
|
+
<p class="form-buttons">
|
12
|
+
<%= button t('update') %>
|
13
|
+
<%= t("or") %> <%= link_to t("cancel"), admin_google_base_settings_url %>
|
14
|
+
</p>
|
15
|
+
<% end %>
|
16
|
+
|
17
|
+
<% content_for :head do %>
|
18
|
+
<style>
|
19
|
+
.edit_google_base_configuration input { width: 250px; }
|
20
|
+
</style>
|
21
|
+
<% end %>
|
@@ -0,0 +1,20 @@
|
|
1
|
+
<%= render :partial => 'admin/shared/configuration_menu' %>
|
2
|
+
|
3
|
+
<h1><%= t("google_base.export_settings") %></h1>
|
4
|
+
|
5
|
+
<table>
|
6
|
+
<% [:title, :public_domain, :description, :ftp_username].each do |setting| %>
|
7
|
+
<%= setting_presentation_row(setting) %>
|
8
|
+
<% end %>
|
9
|
+
<%= setting_presentation_row(:ftp_password, true) %>
|
10
|
+
<%= setting_presentation_row(:enable_taxon_mapping) %>
|
11
|
+
</table>
|
12
|
+
|
13
|
+
<p>
|
14
|
+
<%= link_to_with_icon 'edit', t("edit"), edit_admin_google_base_settings_path %>
|
15
|
+
<% if Spree::GoogleBase::Config[:enable_taxon_mapping] %>
|
16
|
+
<%= link_to_with_icon 'edit', t("google_base.manage_taxon_mapping"), admin_taxon_map_index_path %>
|
17
|
+
<% end %>
|
18
|
+
</p>
|
19
|
+
|
20
|
+
|
@@ -0,0 +1,24 @@
|
|
1
|
+
<% content_for :head do -%>
|
2
|
+
<%= stylesheet_link_tag 'google_base.css' %>
|
3
|
+
<% end -%>
|
4
|
+
|
5
|
+
<div id="google_base_map">
|
6
|
+
<h1>Google Base Taxonomy Mapping</h1>
|
7
|
+
<a href="http://www.google.com/support/merchants/bin/answer.py?hl=en&answer=160081" target="_blank">Google Taxonomy Listings</a>
|
8
|
+
|
9
|
+
<% form_for :taxon_maper do |f| %>
|
10
|
+
<div class="headers">
|
11
|
+
<label for="header">Taxon</label>
|
12
|
+
<div class="priority">Priority</div>
|
13
|
+
<div class="category">Category</div>
|
14
|
+
</div>
|
15
|
+
<% @taxons.each do |taxon| -%>
|
16
|
+
<p>
|
17
|
+
<label><%= taxon.name %></label>
|
18
|
+
<%= text_field(:priority, taxon.id, :value => taxon.taxon_map.priority.to_s, :class => 'priority') %>
|
19
|
+
<%= text_field(:tax_id, taxon.id, :value => taxon.taxon_map.product_type, :class => 'category') %>
|
20
|
+
</p>
|
21
|
+
<% end -%>
|
22
|
+
<%= submit_tag 'Update' %>
|
23
|
+
<% end %>
|
24
|
+
</div>
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# See http://base.google.com/support/bin/answer.py?hl=en&answer=78170 for all other fields
|
2
|
+
GOOGLE_BASE_ATTR_MAP = [
|
3
|
+
['id', 'id'],
|
4
|
+
['mpn', 'sku'],
|
5
|
+
['title', 'name'],
|
6
|
+
['link', 'google_base_link'],
|
7
|
+
['description', 'google_base_description'],
|
8
|
+
['price', 'master_price'],
|
9
|
+
['condition', 'google_base_condition'],
|
10
|
+
['image_link', 'google_base_image_link'],
|
11
|
+
['product_type', 'google_base_product_type']
|
12
|
+
]
|
13
|
+
|
14
|
+
|
15
|
+
GOOGLE_BASE_FILTERED_ATTRS = ["brand", "condition", "id", "image_link", "mpn", "price", "product_type", "quantity"]
|
@@ -0,0 +1,11 @@
|
|
1
|
+
en:
|
2
|
+
google_base:
|
3
|
+
export_settings: "Google Base Export Settings"
|
4
|
+
title: "Title"
|
5
|
+
public_domain: "Public Domain"
|
6
|
+
description: "Description"
|
7
|
+
ftp_username: "FTP user name"
|
8
|
+
ftp_password: "FTP password"
|
9
|
+
manage_taxon_mapping: "Manage taxon mapping"
|
10
|
+
enable_taxon_mapping: "Enable taxon mapping"
|
11
|
+
|
data/config/routes.rb
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
class GoogleBaseConfiguration < Configuration
|
2
|
+
preference :title, :string, :default => 'My Site'
|
3
|
+
preference :public_domain, :string, :default => 'http://www.mysite.com/'
|
4
|
+
preference :description, :text, :default => 'My Description'
|
5
|
+
preference :ftp_username, :string, :default => ''
|
6
|
+
preference :ftp_password, :password, :default => ''
|
7
|
+
preference :enable_taxon_mapping, :boolean, :default => false
|
8
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Spree
|
2
|
+
module GoogleBase
|
3
|
+
# Singleton class to access the google base configuration object (GoogleBaseConfiguration.first by default) and it's preferences.
|
4
|
+
#
|
5
|
+
# Usage:
|
6
|
+
# Spree::GoogleBase::Config[:foo] # Returns the foo preference
|
7
|
+
# Spree::GoogleBase::Config[] # Returns a Hash with all the google base preferences
|
8
|
+
# Spree::GoogleBase::Config.instance # Returns the configuration object (GoogleBaseConfiguration.first)
|
9
|
+
# Spree::GoogleBase::Config.set(preferences_hash) # Set the google base preferences as especified in +preference_hash+
|
10
|
+
class Config
|
11
|
+
include Singleton
|
12
|
+
include PreferenceAccess
|
13
|
+
|
14
|
+
class << self
|
15
|
+
def instance
|
16
|
+
return nil unless ActiveRecord::Base.connection.tables.include?('configurations')
|
17
|
+
GoogleBaseConfiguration.find_or_create_by_name("Google Base configuration")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'spree_core'
|
2
|
+
require 'spree_google_base_hooks'
|
3
|
+
|
4
|
+
module SpreeGoogleBase
|
5
|
+
class Engine < Rails::Engine
|
6
|
+
|
7
|
+
config.autoload_paths += %W(#{config.root}/lib)
|
8
|
+
|
9
|
+
def self.activate
|
10
|
+
Dir.glob(File.join(File.dirname(__FILE__), "../app/**/*_decorator*.rb")) do |c|
|
11
|
+
Rails.env.production? ? require(c) : load(c)
|
12
|
+
end
|
13
|
+
if Spree::Config.instance
|
14
|
+
Taxon.has_one :taxon_map
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
config.to_prepare &method(:activate).to_proc
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
namespace :spree_google_base do
|
2
|
+
desc "Copies all migrations and assets (NOTE: This will be obsolete with Rails 3.1)"
|
3
|
+
task :install do
|
4
|
+
Rake::Task['spree_google_base:install:migrations'].invoke
|
5
|
+
Rake::Task['spree_google_base:install:assets'].invoke
|
6
|
+
end
|
7
|
+
|
8
|
+
namespace :install do
|
9
|
+
desc "Copies all migrations (NOTE: This will be obsolete with Rails 3.1)"
|
10
|
+
task :migrations do
|
11
|
+
source = File.join(File.dirname(__FILE__), '..', '..', 'db')
|
12
|
+
destination = File.join(Rails.root, 'db')
|
13
|
+
Spree::FileUtilz.mirror_files(source, destination)
|
14
|
+
end
|
15
|
+
|
16
|
+
desc "Copies all assets (NOTE: This will be obsolete with Rails 3.1)"
|
17
|
+
task :assets do
|
18
|
+
source = File.join(File.dirname(__FILE__), '..', '..', 'public')
|
19
|
+
destination = File.join(Rails.root, 'public')
|
20
|
+
puts "INFO: Mirroring assets from #{source} to #{destination}"
|
21
|
+
Spree::FileUtilz.mirror_files(source, destination)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'net/ftp'
|
2
|
+
|
3
|
+
namespace :spree_google_base do
|
4
|
+
|
5
|
+
task :generate => :environment do
|
6
|
+
results = '<?xml version="1.0"?>' + "\n" + '<rss version="2.0" xmlns:g="http://base.google.com/ns/1.0">' + "\n" + _filter_xml(_build_xml) + '</rss>'
|
7
|
+
File.open("#{RAILS_ROOT}/public/google_base.xml", "w") do |io|
|
8
|
+
io.puts(results)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
task :transfer => :environment do
|
13
|
+
ftp = Net::FTP.new('uploads.google.com')
|
14
|
+
ftp.login(Spree::GoogleBase::Config[:ftp_username], Spree::GoogleBase::Config[:ftp_password])
|
15
|
+
ftp.put("#{RAILS_ROOT}/public/google_base.xml", 'google_base.xml')
|
16
|
+
ftp.quit()
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
def _filter_xml(output)
|
22
|
+
fields = GOOGLE_BASE_FILTERED_ATTRS
|
23
|
+
0.upto(fields.length - 1) { |i| output = output.gsub(fields[i] + '>', 'g:' + fields[i] + '>') }
|
24
|
+
output
|
25
|
+
end
|
26
|
+
|
27
|
+
def _build_xml
|
28
|
+
returning '' do |output|
|
29
|
+
@public_dir = Spree::GoogleBase::Config[:public_domain] || ''
|
30
|
+
xml = Builder::XmlMarkup.new(:target => output, :indent => 2, :margin => 1)
|
31
|
+
xml.channel {
|
32
|
+
xml.title Spree::GoogleBase::Config[:title] || ''
|
33
|
+
xml.link @public_dir
|
34
|
+
xml.description Spree::GoogleBase::Config[:description] || ''
|
35
|
+
Product.google_base_scope.each do |product|
|
36
|
+
xml.item {
|
37
|
+
GOOGLE_BASE_ATTR_MAP.each do |k, v|
|
38
|
+
value = product.send(v)
|
39
|
+
xml.tag!(k, CGI.escapeHTML(value.to_s)) unless value.nil?
|
40
|
+
end
|
41
|
+
}
|
42
|
+
end
|
43
|
+
}
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
div#google_base_map h1 { margin: 10px 0px; }
|
2
|
+
div#google_base_map div.headers { font-size: 1.2em; font-weight: bold; }
|
3
|
+
div#google_base_map p { margin: 5px 0px; clear: both; }
|
4
|
+
div#google_base_map label { float: left; width: 150px; }
|
5
|
+
div#google_base_map input.category { margin: 0px 10px; width: 400px; }
|
6
|
+
div#google_base_map input.priority { margin: 0px 40px 0px 10px; width: 30px; }
|
7
|
+
div#google_base_map div.category { margin: 0px 10px; width: 400px; float: left; }
|
8
|
+
div#google_base_map div.priority { margin: 0px 40px 0px 10px; width: 30px; float: left; }
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<?xml version="1.0"?>
|
2
|
+
<rss version="2.0" xmlns:g="http://base.google.com/ns/1.0">
|
3
|
+
<channel>
|
4
|
+
<title>Spree Demo Site</title>
|
5
|
+
<link>http://demo.spreehq.org/</link>
|
6
|
+
<description>Spree Demo</description>
|
7
|
+
<item>
|
8
|
+
<title>Ruby on Rails Ringer T-Shirt</title>
|
9
|
+
<link>http://demo.spreehq.org/products/ruby-on-rails-ringer-t-shirt</link>
|
10
|
+
<description>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nulla nonummy aliquet mi. Proin lacus. Ut placerat. Proin consequat, justo sit amet tempus consequat, elit est adipiscing odio, ut egestas pede eros in diam. Proin varius, lacus vitae suscipit varius, ipsum eros convallis nisi, sit amet sodales lectus pede non est. Duis augue. Suspendisse hendrerit pharetra metus. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur nec pede. Quisque volutpat, neque ac porttitor sodales, sem lacus rutrum nulla, ullamcorper placerat ante tortor ac odio. Suspendisse vel libero. Nullam volutpat magna vel ligula. Suspendisse sit amet metus. Nunc quis massa. Nulla facilisi. In enim. In venenatis nisi id eros. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nunc sit amet felis sed lectus tincidunt egestas. Mauris nibh.</description>
|
11
|
+
<g:price>17.99</g:price>
|
12
|
+
</item>
|
13
|
+
</channel>
|
14
|
+
</rss>
|
data/spec/factories.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
Factory.sequence(:product_sequence) {|n| "Product ##{n} - #{rand(9999)}"}
|
2
|
+
|
3
|
+
Factory.define :product do |f|
|
4
|
+
f.name { Factory.next(:product_sequence) }
|
5
|
+
f.description { Faker::Lorem.paragraphs(rand(5)+1).join("\n") }
|
6
|
+
|
7
|
+
f.price 19.99
|
8
|
+
f.cost_price 17.00
|
9
|
+
f.sku "ABC"
|
10
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe Product do
|
4
|
+
|
5
|
+
context "shoulda validations" do
|
6
|
+
it { should have_many(:images) }
|
7
|
+
it { should have_and_belong_to_many(:taxons) }
|
8
|
+
it { should validate_presence_of(:price) }
|
9
|
+
it { should validate_presence_of(:permalink) }
|
10
|
+
end
|
11
|
+
|
12
|
+
context "with GoogleBase support" do
|
13
|
+
let(:product) { Factory(:product) }
|
14
|
+
it 'should have a saved product record' do
|
15
|
+
product.new_record?.should be_false
|
16
|
+
end
|
17
|
+
it 'should have google_base_condition' do
|
18
|
+
product.send(:google_base_condition).should_not be_nil
|
19
|
+
end
|
20
|
+
it 'should have google_base_description' do
|
21
|
+
product.send(:google_base_description).should_not be_nil
|
22
|
+
end
|
23
|
+
it 'should have google_base_link' do
|
24
|
+
product.send(:google_base_link).should_not be_nil
|
25
|
+
end
|
26
|
+
context 'with enabled taxon mapping' do
|
27
|
+
before do
|
28
|
+
Spree::GoogleBase::Config.set :enable_taxon_mapping => true
|
29
|
+
end
|
30
|
+
specify { product.send(:google_base_product_type).should_not be_nil }
|
31
|
+
end
|
32
|
+
context 'with disabled taxon mapping' do
|
33
|
+
before do
|
34
|
+
Spree::GoogleBase::Config.set :enable_taxon_mapping => false
|
35
|
+
end
|
36
|
+
specify { product.send(:google_base_product_type).should be_nil }
|
37
|
+
end
|
38
|
+
context 'without images' do
|
39
|
+
before do
|
40
|
+
product.images.clear
|
41
|
+
end
|
42
|
+
specify { product.send(:google_base_image_link).should be_nil }
|
43
|
+
end
|
44
|
+
context 'with images' do
|
45
|
+
before do
|
46
|
+
Factory(:image, :viewable => product)
|
47
|
+
product.reload
|
48
|
+
end
|
49
|
+
specify { product.send(:google_base_image_link).should_not be_nil }
|
50
|
+
specify { product.send(:google_base_image_link).should == [Spree::GoogleBase::Config[:public_domain], "attachments/product/missing.png"].join }
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# This file is copied to ~/spec when you run 'ruby script/generate rspec'
|
2
|
+
# from the project root directory.
|
3
|
+
ENV["RAILS_ENV"] ||= 'test'
|
4
|
+
require File.expand_path("../test_app/config/environment", __FILE__)
|
5
|
+
require 'rspec/rails'
|
6
|
+
|
7
|
+
# Requires supporting files with custom matchers and macros, etc,
|
8
|
+
# in ./support/ and its subdirectories.
|
9
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
10
|
+
|
11
|
+
require 'factories'
|
12
|
+
|
13
|
+
RSpec.configure do |config|
|
14
|
+
# == Mock Framework
|
15
|
+
#
|
16
|
+
# If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
|
17
|
+
#
|
18
|
+
# config.mock_with :mocha
|
19
|
+
# config.mock_with :flexmock
|
20
|
+
# config.mock_with :rr
|
21
|
+
config.mock_with :rspec
|
22
|
+
|
23
|
+
config.fixture_path = "#{::Rails.root}/spec/fixtures"
|
24
|
+
|
25
|
+
#config.include Devise::TestHelpers, :type => :controller
|
26
|
+
# If you're not using ActiveRecord, or you'd prefer not to run each of your
|
27
|
+
# examples within a transaction, comment the following line or assign false
|
28
|
+
# instead of true.
|
29
|
+
config.use_transactional_fixtures = true
|
30
|
+
end
|
31
|
+
|
32
|
+
@configuration ||= AppConfiguration.find_or_create_by_name("Default configuration")
|
@@ -0,0 +1,22 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.platform = Gem::Platform::RUBY
|
3
|
+
s.name = 'spree_google_base'
|
4
|
+
s.version = '0.30.1'
|
5
|
+
s.summary = 'Google Base for Spree'
|
6
|
+
s.description = 'Provide rake task to generate XML for Google Base and so on.'
|
7
|
+
s.required_ruby_version = '>= 1.8.7'
|
8
|
+
|
9
|
+
s.authors = ['Steph Skardal', 'Ryan Siddle', 'Roman Smirnov']
|
10
|
+
# s.email = 'david@loudthinking.com'
|
11
|
+
s.homepage = 'http://github.com/romul/spree-google-base'
|
12
|
+
# s.rubyforge_project = 'actionmailer'
|
13
|
+
|
14
|
+
s.files = `git ls-files`.split("\n")
|
15
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
16
|
+
s.require_path = 'lib'
|
17
|
+
s.requirements << 'none'
|
18
|
+
|
19
|
+
s.has_rdoc = true
|
20
|
+
|
21
|
+
s.add_dependency('spree_core', '>= 0.30.1')
|
22
|
+
end
|
metadata
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: spree_google_base
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 30
|
8
|
+
- 1
|
9
|
+
version: 0.30.1
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Steph Skardal
|
13
|
+
- Ryan Siddle
|
14
|
+
- Roman Smirnov
|
15
|
+
autorequire:
|
16
|
+
bindir: bin
|
17
|
+
cert_chain: []
|
18
|
+
|
19
|
+
date: 2011-02-20 00:00:00 +03:00
|
20
|
+
default_executable:
|
21
|
+
dependencies:
|
22
|
+
- !ruby/object:Gem::Dependency
|
23
|
+
name: spree_core
|
24
|
+
prerelease: false
|
25
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
segments:
|
30
|
+
- 0
|
31
|
+
- 30
|
32
|
+
- 1
|
33
|
+
version: 0.30.1
|
34
|
+
type: :runtime
|
35
|
+
version_requirements: *id001
|
36
|
+
description: Provide rake task to generate XML for Google Base and so on.
|
37
|
+
email:
|
38
|
+
executables: []
|
39
|
+
|
40
|
+
extensions: []
|
41
|
+
|
42
|
+
extra_rdoc_files: []
|
43
|
+
|
44
|
+
files:
|
45
|
+
- .gitignore
|
46
|
+
- README.markdown
|
47
|
+
- Rakefile
|
48
|
+
- app/controllers/admin/google_base_settings_controller.rb
|
49
|
+
- app/controllers/admin/taxon_map_controller.rb
|
50
|
+
- app/helpers/google_base_helper.rb
|
51
|
+
- app/models/product_decorator.rb
|
52
|
+
- app/models/taxon_map.rb
|
53
|
+
- app/views/admin/_google_base_link.html.erb
|
54
|
+
- app/views/admin/google_base_settings/edit.html.erb
|
55
|
+
- app/views/admin/google_base_settings/show.html.erb
|
56
|
+
- app/views/admin/taxon_map/index.html.erb
|
57
|
+
- config/initializers/google_base.rb
|
58
|
+
- config/locales/en.yml
|
59
|
+
- config/routes.rb
|
60
|
+
- db/migrate/20090224211256_create_taxon_maps.rb
|
61
|
+
- lib/google_base_configuration.rb
|
62
|
+
- lib/spree/google_base/config.rb
|
63
|
+
- lib/spree_google_base.rb
|
64
|
+
- lib/spree_google_base_hooks.rb
|
65
|
+
- lib/tasks/install.rake
|
66
|
+
- lib/tasks/spree_google_base.rake
|
67
|
+
- public/stylesheets/google_base.css
|
68
|
+
- public/template_google_base.xml
|
69
|
+
- spec/factories.rb
|
70
|
+
- spec/factories/image_factory.rb
|
71
|
+
- spec/factories/product_factory.rb
|
72
|
+
- spec/models/product_spec.rb
|
73
|
+
- spec/models/taxon_spec.rb
|
74
|
+
- spec/spec_helper.rb
|
75
|
+
- spree_google_base.gemspec
|
76
|
+
has_rdoc: true
|
77
|
+
homepage: http://github.com/romul/spree-google-base
|
78
|
+
licenses: []
|
79
|
+
|
80
|
+
post_install_message:
|
81
|
+
rdoc_options: []
|
82
|
+
|
83
|
+
require_paths:
|
84
|
+
- lib
|
85
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
segments:
|
90
|
+
- 1
|
91
|
+
- 8
|
92
|
+
- 7
|
93
|
+
version: 1.8.7
|
94
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
95
|
+
requirements:
|
96
|
+
- - ">="
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
segments:
|
99
|
+
- 0
|
100
|
+
version: "0"
|
101
|
+
requirements:
|
102
|
+
- none
|
103
|
+
rubyforge_project:
|
104
|
+
rubygems_version: 1.3.6
|
105
|
+
signing_key:
|
106
|
+
specification_version: 3
|
107
|
+
summary: Google Base for Spree
|
108
|
+
test_files: []
|
109
|
+
|