spree_oxygen_pelatologio 1.0.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 37d183e7f183b66f6d87126d0b0cf34a358a25b2b56b0cadbb708a18e5e11cc2
4
+ data.tar.gz: a75437d806c795623c1c645652d0ec592dd0ea3a03dd362fc95f68d9e8a27ee9
5
+ SHA512:
6
+ metadata.gz: 07b968463473dfb11b907291eab80ce997a4f06ed3b5dfb0b57ee0538d8eda2f16b4b972b31b49c72ec8e5b98b2d56a54328cc30e3bf0b37c72036d8c468600e
7
+ data.tar.gz: faa0841cd04899c3f851c7d5cf92c3ad3c9ece75fe1f1162589813ac4ebb06648a1af71db3135e587d0b9ba1d8d25d12ae67e61af825df09505c64e912fa0533
data/LICENSE.md ADDED
@@ -0,0 +1,15 @@
1
+ # LICENSE
2
+
3
+ Copyright (c) 2026 OlympusOne. All rights reserved.
4
+
5
+ This program is free software: you can redistribute it and/or modify it under the terms of the
6
+ GNU Affero General Public License as published by the Free Software Foundation, either
7
+ version 3 of the License, or any later version.
8
+
9
+ This program is distributed in the hope that it will be useful,
10
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ GNU Affero General Public License for more details.
13
+
14
+ You should have received a copy of the GNU Affero General Public License
15
+ along with this program. If not, see [https://www.gnu.org/licenses/](https://www.gnu.org/licenses/).
data/README.md ADDED
@@ -0,0 +1,54 @@
1
+ # Spree Oxygen Pelatologio
2
+
3
+ This is an Oxygen Pelatologio extension for [Spree Commerce](https://spreecommerce.org), an open‑source e-commerce platform built with Ruby on Rails. It adds the ability to sync Oxygen Pelatologio data.
4
+
5
+ [![Gem Version](https://badge.fury.io/rb/spree_oxygen_pelatologio.svg)](https://badge.fury.io/rb/spree_oxygen_pelatologio)
6
+
7
+ ## Installation
8
+
9
+ 1. Add this extension to your Gemfile with this line:
10
+
11
+ ```bash
12
+ bundle add spree_oxygen_pelatologio
13
+ ```
14
+
15
+ ## Developing
16
+
17
+ 1. Create a dummy app
18
+
19
+ ```bash
20
+ bundle update
21
+ bundle exec rake test_app
22
+ ```
23
+
24
+ 2. Add your new code
25
+
26
+ 3. Run tests
27
+
28
+ ```bash
29
+ bundle exec rspec
30
+ ```
31
+
32
+ When testing your applications integration with this extension you may use it's factories.
33
+ Simply add this require statement to your spec_helper:
34
+
35
+ ```ruby
36
+ require 'spree_oxygen_pelatologio/factories'
37
+ ```
38
+
39
+ ## Releasing a new version
40
+
41
+ ```bash
42
+ bundle exec gem bump -p -t
43
+ bundle exec gem release
44
+ ```
45
+
46
+ For more options please see [gem-release README](https://github.com/svenfuchs/gem-release)
47
+
48
+ ## Contributing
49
+
50
+ If you'd like to contribute, please take a look at the
51
+ [instructions](CONTRIBUTING.md) for installing dependencies and crafting a good
52
+ pull request.
53
+
54
+ Copyright (c) 2026 OlympusOne, released under the AGPL-3.0 or later.
data/Rakefile ADDED
@@ -0,0 +1,21 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rspec/core/rake_task'
5
+ require 'spree/testing_support/extension_rake'
6
+
7
+ RSpec::Core::RakeTask.new
8
+
9
+ task :default do
10
+ if Dir['spec/dummy'].empty?
11
+ Rake::Task[:test_app].invoke
12
+ Dir.chdir('../../')
13
+ end
14
+ Rake::Task[:spec].invoke
15
+ end
16
+
17
+ desc 'Generates a dummy app for testing'
18
+ task :test_app do
19
+ ENV['LIB_NAME'] = 'spree_oxygen_pelatologio'
20
+ Rake::Task['extension:test_app'].invoke
21
+ end
@@ -0,0 +1,4 @@
1
+ //= link_tree ../images
2
+ //= link spree_oxygen_pelatologio/application.js
3
+ //= link_tree ../../javascript/spree_oxygen_pelatologio/controllers .js
4
+
@@ -0,0 +1,16 @@
1
+ import '@hotwired/turbo-rails'
2
+ import { Application } from '@hotwired/stimulus'
3
+
4
+ let application
5
+
6
+ if (typeof window.Stimulus === "undefined") {
7
+ application = Application.start()
8
+ application.debug = false
9
+ window.Stimulus = application
10
+ } else {
11
+ application = window.Stimulus
12
+ }
13
+
14
+ import SpreeOxygenPelatologioController from 'spree_oxygen_pelatologio/controllers/spree_oxygen_pelatologio_controller'
15
+
16
+ application.register('spree_oxygen_pelatologio', SpreeOxygenPelatologioController)
@@ -0,0 +1,7 @@
1
+ import { Controller } from '@hotwired/stimulus'
2
+
3
+ export default class extends Controller {
4
+ connect() {
5
+ console.log('Hello, SpreeOxygenPelatologio!')
6
+ }
7
+ }
@@ -0,0 +1,5 @@
1
+ module SpreeOxygenPelatologio
2
+ class BaseJob < Spree::BaseJob
3
+ queue_as SpreeOxygenPelatologio.queue
4
+ end
5
+ end
@@ -0,0 +1,108 @@
1
+ module SpreeOxygenPelatologio
2
+ class Client
3
+ include Spree::IntegrationsConcern
4
+
5
+ SERVICE_ENDPOINTS = {
6
+ sandbox: 'https://sandbox.api.oxygen.gr/v1/',
7
+ production: 'https://api.oxygen.gr/v1/'
8
+ }.freeze
9
+
10
+ attr_reader :client
11
+
12
+ def initialize
13
+ @integration = store_integration('oxygen_pelatologio')
14
+ raise 'Integration not found' unless @integration
15
+
16
+ validate!
17
+ end
18
+
19
+ def call(action, **kwargs, &block)
20
+ case action
21
+ when :pull_products
22
+ pull_products(**kwargs, &block)
23
+ else
24
+ raise ArgumentError, "Unknown action: #{action}"
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ def validate!
31
+ if @integration.preferred_api_key.to_s.strip.empty?
32
+ raise ConfigurationError, "Oxygen api_key is not configured"
33
+ end
34
+ end
35
+
36
+ def pull_products(per_page: 100, &block)
37
+ return enum_for(:pull_products, per_page: per_page) unless block_given?
38
+
39
+ params = {
40
+ per_page: per_page,
41
+ page: 1
42
+ }
43
+
44
+ loop do
45
+ result = get('products', params: params)
46
+
47
+ yield(result['data'])
48
+
49
+ next_link = result.dig('links', 'next')
50
+ break if next_link.nil?
51
+
52
+ params[:page] += 1
53
+ end
54
+ end
55
+
56
+ def get(path, params: {})
57
+ uri = build_uri(path, params)
58
+
59
+ request = Net::HTTP::Get.new(uri)
60
+ apply_headers(request)
61
+
62
+ perform_request(uri, request)
63
+ end
64
+
65
+ def build_uri(path, params)
66
+ base_url = SERVICE_ENDPOINTS[@integration.preferred_environment.to_sym]
67
+ uri = URI.join(base_url, path)
68
+
69
+ if params.any?
70
+ uri.query = URI.encode_www_form(params.compact)
71
+ end
72
+
73
+ uri
74
+ end
75
+
76
+ def apply_headers(request)
77
+ request["Accept"] = "application/json"
78
+ request["User-Agent"] = "SpreeOxygenPelatologio/#{SpreeOxygenPelatologio::VERSION}"
79
+
80
+ api_key = @integration.preferred_api_key.to_s.strip
81
+ request["Authorization"] = "Bearer #{api_key}"
82
+ end
83
+
84
+ def perform_request(uri, request)
85
+ http = Net::HTTP.new(uri.host, uri.port)
86
+ http.use_ssl = uri.scheme == "https"
87
+
88
+ response = http.request(request)
89
+
90
+ unless response.is_a?(Net::HTTPSuccess)
91
+ raise ApiError, "Oxygen API error: #{response.code} #{response.message}"
92
+ end
93
+
94
+ parse_json(response.body)
95
+ rescue Timeout::Error, Errno::ECONNREFUSED, SocketError => e
96
+ raise ApiError, "Oxygen API connection error: #{e.message}"
97
+ end
98
+
99
+ def parse_json(body)
100
+ JSON.parse(body)
101
+ rescue JSON::ParserError => e
102
+ raise ApiError ,"Invalid JSON from Oxygen: #{e.message}"
103
+ end
104
+
105
+ class ConfigurationError < StandardError; end
106
+ class ApiError < StandardError; end
107
+ end
108
+ end
@@ -0,0 +1,11 @@
1
+ module SpreeOxygenPelatologio
2
+ class PullProductsWorker
3
+ include Sidekiq::Worker
4
+
5
+ def perform
6
+ Rails.logger.info "[SpreeOxygenPelatologio] Starting PullProductsWorker..."
7
+ SpreeOxygenPelatologio::PullProducts.new.call
8
+ Rails.logger.info "[SpreeOxygenPelatologio] Finished PullProductsWorker."
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,19 @@
1
+ module Spree
2
+ module Integrations
3
+ class OxygenPelatologio < Spree::Integration
4
+ preference :api_key, :string
5
+ preference :environment, :string, default: 'production'
6
+
7
+ validates :preferred_api_key, presence: true
8
+ validates :preferred_environment, inclusion: { in: %w[production sandbox] }
9
+
10
+ def self.integration_group
11
+ 'other'
12
+ end
13
+
14
+ def self.icon_path
15
+ 'integration_icons/oxygen-pelatologio-logo.png'
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,57 @@
1
+ module SpreeOxygenPelatologio
2
+ class PullProducts
3
+ attr_reader :client
4
+
5
+ def initialize
6
+ @client = SpreeOxygenPelatologio::Client.new
7
+ end
8
+
9
+ def call
10
+ client.call(:pull_products) do |products|
11
+ products.each { |product| update_product(product) }
12
+ end
13
+ end
14
+
15
+ private
16
+
17
+ def update_product(data)
18
+ sku = data['code']
19
+ return if sku.blank?
20
+
21
+ variant = Spree::Variant.find_by(sku: sku)
22
+ return unless variant
23
+
24
+ # Update price
25
+ update_price(variant, data['sale_total_amount'].to_f)
26
+
27
+ # Preload once and build a fast lookup by location name
28
+ stock_items_by_location_name =
29
+ variant.stock_items.includes(:stock_location).index_by { |si| si.stock_location&.name }
30
+
31
+ # Update stock
32
+ data['warehouses'].each do |wh|
33
+ location_name = wh['name']
34
+ qty = wh['quantity'].to_i
35
+
36
+ stock_item = stock_items_by_location_name[location_name]
37
+ next unless stock_item && stock_item.count_on_hand != qty
38
+
39
+ variant.set_stock(qty, nil, stock_item.stock_location)
40
+ end
41
+ end
42
+
43
+ # Update variant price based on new price
44
+ #
45
+ # If new price is lower, set it as the current price and keep compare_at_price
46
+ # If new price is higher, set it as the current price and clear compare_at_price
47
+ def update_price(variant, new_price)
48
+ return if variant.price == new_price
49
+
50
+ if new_price < variant.price
51
+ variant.set_price(variant.currency, new_price, variant.compare_at_price)
52
+ elsif new_price > variant.price
53
+ variant.set_price(variant.currency, new_price)
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,11 @@
1
+ <div class="col-12 col-md-6 p-0">
2
+ <div class="card mb-4">
3
+ <div class="card-body">
4
+ <%= preference_field(@integration, form, 'api_key', i18n_scope: 'admin.integrations.oxygen_pelatologio') %>
5
+
6
+ <div class="form-group">
7
+ <%= form.spree_select :preferred_environment, options_for_select([['Production', 'production'], ['Sandbox', 'sandbox']], @integration.preferred_environment), label: Spree.t('admin.integrations.oxygen_pelatologio.environment') %>
8
+ </div>
9
+ </div>
10
+ </div>
11
+ </div>
@@ -0,0 +1 @@
1
+ <%= javascript_import_module_tag 'application-spree-oxygen-pelatologio' %>
@@ -0,0 +1,6 @@
1
+ pin 'application-spree-oxygen-pelatologio', to: 'spree_oxygen_pelatologio/application.js', preload: false
2
+
3
+ pin_all_from SpreeOxygenPelatologio::Engine.root.join('app/javascript/spree_oxygen_pelatologio/controllers'),
4
+ under: 'spree_oxygen_pelatologio/controllers',
5
+ to: 'spree_oxygen_pelatologio/controllers',
6
+ preload: 'application-spree-oxygen-pelatologio'
@@ -0,0 +1,28 @@
1
+ Sidekiq.configure_server do |config|
2
+ config.on(:startup) do
3
+ puts "[SpreeOxygenPelatologio] Setting up Sidekiq-Cron jobs..."
4
+
5
+ store = Spree::Store.default
6
+
7
+ integration = store.store_integration('oxygen_pelatologio')
8
+
9
+ job_name = "Oxygen Pelatologio Sync - Hourly"
10
+
11
+ if integration
12
+ Sidekiq::Cron::Job.create(
13
+ name: job_name,
14
+ namespace: "SpreeOxygenPelatologio",
15
+ cron: "0 * * * *",
16
+ class: "SpreeOxygenPelatologio::PullProductsWorker",
17
+ queue: SpreeOxygenPelatologio.queue,
18
+ retry: 2
19
+ )
20
+
21
+ Sidekiq.logger.info("[SpreeOxygenPelatologio] Cron job ensured: #{job_name}")
22
+ else
23
+ existing = Sidekiq::Cron::Job.find(job_name)
24
+ existing&.destroy
25
+ Sidekiq.logger.info("[SpreeOxygenPelatologio] Cron job removed (integration disabled): #{job_name}")
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,6 @@
1
+ Rails.application.config.after_initialize do
2
+ Spree.integrations << Spree::Integrations::OxygenPelatologio
3
+
4
+ # Admin partials
5
+ Spree.admin.partials.head << 'spree_oxygen_pelatologio/head'
6
+ end
@@ -0,0 +1,10 @@
1
+ ---
2
+ el:
3
+ spree:
4
+ admin:
5
+ integrations:
6
+ oxygen_pelatologio:
7
+ title: Oxygen Pelatologio
8
+ description: Διασύνδεση με τις υπηρεσίες της Oxygen Pelatologio
9
+ api_key: API Key
10
+ environment: Περιβάλλον
@@ -0,0 +1,10 @@
1
+ ---
2
+ en:
3
+ spree:
4
+ admin:
5
+ integrations:
6
+ oxygen_pelatologio:
7
+ title: Oxygen Pelatologio
8
+ description: Synchronization with Oxygen Pelatologio services
9
+ api_key: API Key
10
+ environment: Environment
data/config/routes.rb ADDED
@@ -0,0 +1,5 @@
1
+ require "sidekiq/cron/web" # require the cron extension
2
+
3
+ Spree::Core::Engine.add_routes do
4
+ # Add your extension routes here
5
+ end
@@ -0,0 +1,13 @@
1
+ module SpreeOxygenPelatologio
2
+ class Configuration < Spree::Preferences::Configuration
3
+
4
+ # Some example preferences are shown below, for more information visit:
5
+ # https://docs.spreecommerce.org/developer/contributing/creating-an-extension
6
+
7
+ # preference :enabled, :boolean, default: true
8
+ # preference :dark_chocolate, :boolean, default: true
9
+ # preference :color, :string, default: 'Red'
10
+ # preference :favorite_number, :integer
11
+ # preference :supported_locales, :array, default: [:en]
12
+ end
13
+ end
@@ -0,0 +1,34 @@
1
+ module SpreeOxygenPelatologio
2
+ class Engine < Rails::Engine
3
+ require 'spree/core'
4
+ isolate_namespace Spree
5
+ engine_name 'spree_oxygen_pelatologio'
6
+
7
+ # use rspec for tests
8
+ config.generators do |g|
9
+ g.test_framework :rspec
10
+ end
11
+
12
+ initializer 'spree_oxygen_pelatologio.environment', before: :load_config_initializers do |_app|
13
+ SpreeOxygenPelatologio::Config = SpreeOxygenPelatologio::Configuration.new
14
+ end
15
+
16
+ initializer 'spree_oxygen_pelatologio.assets' do |app|
17
+ app.config.assets.paths << root.join('app/javascript')
18
+ app.config.assets.precompile += %w[spree_oxygen_pelatologio_manifest]
19
+ end
20
+
21
+ initializer 'spree_oxygen_pelatologio.importmap', before: 'importmap' do |app|
22
+ app.config.importmap.paths << root.join('config/importmap.rb')
23
+ app.config.importmap.cache_sweepers << root.join('app/javascript')
24
+ end
25
+
26
+ def self.activate
27
+ Dir.glob(File.join(File.dirname(__FILE__), '../../app/**/*_decorator*.rb')) do |c|
28
+ Rails.configuration.cache_classes ? require(c) : load(c)
29
+ end
30
+ end
31
+
32
+ config.to_prepare(&method(:activate).to_proc)
33
+ end
34
+ end
@@ -0,0 +1,7 @@
1
+ FactoryBot.define do
2
+ factory :oxygen_pelatologio_integration, class: Spree::Integrations::EltaCourier do
3
+ active { true }
4
+ preferred_api_key { ENV['OXYGEN_PELATOLOGIO_API_KEY'] }
5
+ store { Spree::Store.default }
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ module SpreeOxygenPelatologio
2
+ VERSION = '1.0.0'.freeze
3
+
4
+ def gem_version
5
+ Gem::Version.new(VERSION)
6
+ end
7
+ end
@@ -0,0 +1,13 @@
1
+ require 'spree_core'
2
+ require 'spree_extension'
3
+ require 'spree_oxygen_pelatologio/engine'
4
+ require 'spree_oxygen_pelatologio/version'
5
+ require 'spree_oxygen_pelatologio/configuration'
6
+
7
+ module SpreeOxygenPelatologio
8
+ mattr_accessor :queue
9
+
10
+ def self.queue
11
+ @@queue ||= Spree.queues.default
12
+ end
13
+ end
@@ -0,0 +1,6 @@
1
+ namespace :spree_oxygen_pelatologio do
2
+ desc "Pull products from Oxygen and sync into Spree"
3
+ task pull_products: :environment do
4
+ SpreeOxygenPelatologio::PullProducts.new.call
5
+ end
6
+ end
metadata ADDED
@@ -0,0 +1,155 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: spree_oxygen_pelatologio
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - OlympusOne
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: spree
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: 5.2.5
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: 5.2.5
26
+ - !ruby/object:Gem::Dependency
27
+ name: spree_storefront
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 5.2.5
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: 5.2.5
40
+ - !ruby/object:Gem::Dependency
41
+ name: spree_admin
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: 5.2.5
47
+ type: :runtime
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: 5.2.5
54
+ - !ruby/object:Gem::Dependency
55
+ name: spree_extension
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ type: :runtime
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ - !ruby/object:Gem::Dependency
69
+ name: sidekiq-cron
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '2.3'
75
+ type: :runtime
76
+ prerelease: false
77
+ version_requirements: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '2.3'
82
+ - !ruby/object:Gem::Dependency
83
+ name: spree_dev_tools
84
+ requirement: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ type: :development
90
+ prerelease: false
91
+ version_requirements: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ description: Adds the ability to sync Oxygen Pelatologio data to Spree stores.
97
+ email: info@olympusone.com
98
+ executables: []
99
+ extensions: []
100
+ extra_rdoc_files: []
101
+ files:
102
+ - LICENSE.md
103
+ - README.md
104
+ - Rakefile
105
+ - app/assets/config/spree_oxygen_pelatologio_manifest.js
106
+ - app/assets/images/integration_icons/oxygen-pelatologio-logo.png
107
+ - app/javascript/spree_oxygen_pelatologio/application.js
108
+ - app/javascript/spree_oxygen_pelatologio/controllers/spree_oxygen_pelatologio_controller.js
109
+ - app/jobs/spree_oxygen_pelatologio/base_job.rb
110
+ - app/lib/spree_oxygen_pelatologio/client.rb
111
+ - app/lib/spree_oxygen_pelatologio/pull_products_worker.rb
112
+ - app/models/spree/integrations/oxygen_pelatologio.rb
113
+ - app/services/spree_oxygen_pelatologio/pull_products.rb
114
+ - app/views/spree/admin/integrations/forms/_oxygen_pelatologio.html.erb
115
+ - app/views/spree_oxygen_pelatologio/_head.html.erb
116
+ - config/importmap.rb
117
+ - config/initializers/sidekiq-cron.rb
118
+ - config/initializers/spree.rb
119
+ - config/locales/el.yml
120
+ - config/locales/en.yml
121
+ - config/routes.rb
122
+ - lib/spree_oxygen_pelatologio.rb
123
+ - lib/spree_oxygen_pelatologio/configuration.rb
124
+ - lib/spree_oxygen_pelatologio/engine.rb
125
+ - lib/spree_oxygen_pelatologio/factories.rb
126
+ - lib/spree_oxygen_pelatologio/version.rb
127
+ - lib/tasks/pull_products.rake
128
+ homepage: https://github.com/olympusone/spree_oxygen_pelatologio
129
+ licenses:
130
+ - AGPL-3.0-or-later
131
+ metadata:
132
+ bug_tracker_uri: https://github.com/olympusone/spree_oxygen_pelatologio/issues
133
+ changelog_uri: https://github.com/olympusone/spree_oxygen_pelatologio/releases/tag/v1.0.0
134
+ documentation_uri: https://github.com/olympusone/spree_oxygen_pelatologio
135
+ homepage_uri: https://github.com/olympusone/spree_oxygen_pelatologio
136
+ source_code_uri: https://github.com/olympusone/spree_oxygen_pelatologio/tree/v1.0.0
137
+ rdoc_options: []
138
+ require_paths:
139
+ - lib
140
+ required_ruby_version: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - ">="
143
+ - !ruby/object:Gem::Version
144
+ version: '3.0'
145
+ required_rubygems_version: !ruby/object:Gem::Requirement
146
+ requirements:
147
+ - - ">="
148
+ - !ruby/object:Gem::Version
149
+ version: '0'
150
+ requirements:
151
+ - none
152
+ rubygems_version: 3.6.9
153
+ specification_version: 4
154
+ summary: Spree Commerce Oxygen Pelatologio Extension
155
+ test_files: []