dech 0.0.1
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 +7 -0
- data/.gitignore +17 -0
- data/.rspec +1 -0
- data/.travis.yml +5 -0
- data/Gemfile +4 -0
- data/Guardfile +6 -0
- data/README.md +29 -0
- data/Rakefile +6 -0
- data/dech.gemspec +27 -0
- data/lib/dech.rb +7 -0
- data/lib/dech/price_uploader.rb +8 -0
- data/lib/dech/price_uploader/ponpare.rb +10 -0
- data/lib/dech/price_uploader/ponpare/ftps.rb +70 -0
- data/lib/dech/version.rb +5 -0
- data/spec/dech/price_uploader/ponpare/ftps_spec.rb +141 -0
- data/spec/dech_spec.rb +6 -0
- data/spec/spec_helper.rb +8 -0
- metadata +133 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: aa970fe74fc171b20d2e05ad1f4fcd19dbda7c6c
|
4
|
+
data.tar.gz: bcdc45225d298201caf2130388f93e63f35b12e1
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 825291cf53ba0ceb4d77dc8188114a54e98c69fb1be3683bcda1d5c85b060fcdd0a22bda2c3c9aadc5ed8a2e811647d5ee629c0df56f8051c8713128d7b3cdc3
|
7
|
+
data.tar.gz: 042ce66ab9b37ef1e52c41af435f61c8511598cb63da065663c2d3314f5976bdaebdc029248cc7ba710941f125ef179596485c3581ea920dc5c555c429955b96
|
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Guardfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# Dech
|
2
|
+
|
3
|
+

|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'dech'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install dech
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
TODO: Write usage instructions here
|
22
|
+
|
23
|
+
## Contributing
|
24
|
+
|
25
|
+
1. Fork it ( http://github.com/<my-github-username>/dech/fork )
|
26
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
28
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/dech.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'dech/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "dech"
|
8
|
+
spec.version = Dech::VERSION
|
9
|
+
spec.authors = ["OSA Shunsuke"]
|
10
|
+
spec.email = ["hhelibebcnofnenamg@gmail.com"]
|
11
|
+
spec.summary = %q{Utilities gem for e-commerce mall in Japan.}
|
12
|
+
spec.description = %q{Dech enables you to upload price change easily.}
|
13
|
+
spec.homepage = "https://github.com/e-maido/dech"
|
14
|
+
spec.license = ""
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency "double-bag-ftps"
|
22
|
+
|
23
|
+
spec.add_development_dependency "bundler", "~> 1.5"
|
24
|
+
spec.add_development_dependency "rake"
|
25
|
+
spec.add_development_dependency "rspec"
|
26
|
+
spec.add_development_dependency "guard-rspec"
|
27
|
+
end
|
data/lib/dech.rb
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require "net/ftp"
|
4
|
+
require "double_bag_ftps"
|
5
|
+
require "csv"
|
6
|
+
|
7
|
+
module Dech
|
8
|
+
module PriceUploader
|
9
|
+
module Ponpare
|
10
|
+
class FTPS
|
11
|
+
HEADERS = %w(コントロールカラム 商品管理ID(商品URL) 販売価格)
|
12
|
+
|
13
|
+
attr_accessor :username, :host, :path
|
14
|
+
|
15
|
+
def initialize(args={})
|
16
|
+
@products = args[:products] || []
|
17
|
+
@username = args[:username]
|
18
|
+
@password = args[:password]
|
19
|
+
@host = args[:host] || "ftps.ponparemall.com"
|
20
|
+
@path = args[:path] || "/item.csv"
|
21
|
+
end
|
22
|
+
|
23
|
+
def ready?
|
24
|
+
ftps_connection{|ftps| !ftps.nlst(File.dirname(@path)).include?(@path) }
|
25
|
+
end
|
26
|
+
|
27
|
+
def csv
|
28
|
+
csv_string = CSV.generate do |csv|
|
29
|
+
csv << HEADERS
|
30
|
+
@products.each do |product|
|
31
|
+
csv << ["u", product[:id].to_s.downcase, product[:price]]
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
StringIO.new(csv_string.encode(Encoding::Windows_31J))
|
36
|
+
end
|
37
|
+
|
38
|
+
def save_csv_as(filename)
|
39
|
+
FileUtils.mkdir_p(File.dirname(filename))
|
40
|
+
File.open(filename, "w:windows-31j") do |file|
|
41
|
+
file << csv.string
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def upload!
|
46
|
+
ftps_connection{|ftps| ftps.storlines("STOR #{@path}", csv) }
|
47
|
+
true
|
48
|
+
end
|
49
|
+
|
50
|
+
def upload
|
51
|
+
ready? && upload!
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def ftps_connection(&block)
|
57
|
+
ftps = DoubleBagFTPS.new
|
58
|
+
ftps.passive = true
|
59
|
+
ftps.ssl_context = DoubleBagFTPS.create_ssl_context(verify_mode: OpenSSL::SSL::VERIFY_NONE)
|
60
|
+
ftps.connect(@host)
|
61
|
+
ftps.login(@username, @password)
|
62
|
+
|
63
|
+
yield(ftps)
|
64
|
+
ensure
|
65
|
+
ftps.close
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
data/lib/dech/version.rb
ADDED
@@ -0,0 +1,141 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
describe Dech::PriceUploader::Ponpare::FTPS do
|
6
|
+
let(:dech) {
|
7
|
+
Dech::PriceUploader::Ponpare::FTPS.new(
|
8
|
+
products: [{id: "PRODUCT-CODE", price: 9800}],
|
9
|
+
username: "username",
|
10
|
+
password: "password",
|
11
|
+
host: "example.com"
|
12
|
+
)
|
13
|
+
}
|
14
|
+
|
15
|
+
let(:ftps) {
|
16
|
+
ftps = double("ftps")
|
17
|
+
allow(ftps).to receive(:passive=)
|
18
|
+
allow(ftps).to receive(:ssl_context=)
|
19
|
+
allow(ftps).to receive(:connect)
|
20
|
+
allow(ftps).to receive(:login)
|
21
|
+
allow(ftps).to receive(:close)
|
22
|
+
ftps
|
23
|
+
}
|
24
|
+
|
25
|
+
describe "initialize" do
|
26
|
+
context "given no args" do
|
27
|
+
it "should create an instance successfully" do
|
28
|
+
expect(dech).to be_an_instance_of(Dech::PriceUploader::Ponpare::FTPS)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context "given some args" do
|
33
|
+
it "should create an instance successfully" do
|
34
|
+
expect(dech).to be_an_instance_of(Dech::PriceUploader::Ponpare::FTPS)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "#ready?" do
|
40
|
+
context "some files in the server" do
|
41
|
+
before do
|
42
|
+
expect(ftps).to receive(:nlst).and_return([dech.path])
|
43
|
+
expect(DoubleBagFTPS).to receive(:new).and_return(ftps)
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should be false" do
|
47
|
+
expect(dech.ready?).to be false
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context "any files in the server" do
|
52
|
+
before do
|
53
|
+
expect(ftps).to receive(:nlst).and_return([])
|
54
|
+
expect(DoubleBagFTPS).to receive(:new).and_return(ftps)
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should be true" do
|
58
|
+
expect(dech.ready?).to be true
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe "#csv" do
|
64
|
+
headers = {
|
65
|
+
"コントロールカラム" => /\Au\Z/,
|
66
|
+
"商品管理ID(商品URL)" => String,
|
67
|
+
"販売価格" => /\d+/
|
68
|
+
}
|
69
|
+
|
70
|
+
describe "headers" do
|
71
|
+
let(:csv){ CSV.new(dech.csv, headers: true) }
|
72
|
+
|
73
|
+
headers.each_key.map{|h| h.encode(Encoding::Windows_31J) }.each do |header|
|
74
|
+
it "should have '#{header}' header" do
|
75
|
+
csv.readlines
|
76
|
+
expect(csv.headers).to be_include(header)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
describe "columns" do
|
82
|
+
let(:csv){ CSV.new(dech.csv, headers: true).read }
|
83
|
+
|
84
|
+
headers.each do |header, type|
|
85
|
+
it "should have #{type} in '#{header}'" do
|
86
|
+
expect(csv[header.encode(Encoding::Windows_31J)]).to be_all{|c| type === c }
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
describe "encoding" do
|
92
|
+
let(:io){ dech.csv }
|
93
|
+
|
94
|
+
it "should have windows-31j as external_encoding" do
|
95
|
+
expect(io.external_encoding).to eq(Encoding::Windows_31J)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
describe "#save_csv_as" do
|
101
|
+
let(:filename){ "tmp/#{Time.now.strftime("%Y%m%d_%H%M%S_%N")}.csv" }
|
102
|
+
|
103
|
+
it "should save CSV file as given name" do
|
104
|
+
dech.save_csv_as(filename)
|
105
|
+
expect(Dir.glob("tmp/*")).to be_include(filename)
|
106
|
+
end
|
107
|
+
|
108
|
+
it "should save CSV file in Shift_JIS" do
|
109
|
+
dech.save_csv_as(filename)
|
110
|
+
CSV.open(filename, "r:windows-31j:utf-8", headers: true) do |csv|
|
111
|
+
expect{csv.readlines}.not_to raise_error
|
112
|
+
expect(csv.headers).to eq(Dech::PriceUploader::Ponpare::FTPS::HEADERS)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
describe "#upload" do
|
118
|
+
context "server is ready" do
|
119
|
+
before do
|
120
|
+
allow(ftps).to receive(:nlst).and_return([])
|
121
|
+
expect(ftps).to receive(:storlines)
|
122
|
+
expect(DoubleBagFTPS).to receive(:new).and_return(ftps).at_least(:once)
|
123
|
+
end
|
124
|
+
|
125
|
+
it "should upload CSV file to the path on FTPS server" do
|
126
|
+
expect(dech.upload).to be true
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
context "server is not ready" do
|
131
|
+
before do
|
132
|
+
allow(ftps).to receive(:nlst).and_return([dech.path])
|
133
|
+
expect(DoubleBagFTPS).to receive(:new).and_return(ftps)
|
134
|
+
end
|
135
|
+
|
136
|
+
it "should not upload CSV file to the path on FTPS server" do
|
137
|
+
expect(dech.upload).to be false
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
data/spec/dech_spec.rb
ADDED
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,133 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: dech
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- OSA Shunsuke
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-07-21 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: double-bag-ftps
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.5'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.5'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: guard-rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
description: Dech enables you to upload price change easily.
|
84
|
+
email:
|
85
|
+
- hhelibebcnofnenamg@gmail.com
|
86
|
+
executables: []
|
87
|
+
extensions: []
|
88
|
+
extra_rdoc_files: []
|
89
|
+
files:
|
90
|
+
- ".gitignore"
|
91
|
+
- ".rspec"
|
92
|
+
- ".travis.yml"
|
93
|
+
- Gemfile
|
94
|
+
- Guardfile
|
95
|
+
- README.md
|
96
|
+
- Rakefile
|
97
|
+
- dech.gemspec
|
98
|
+
- lib/dech.rb
|
99
|
+
- lib/dech/price_uploader.rb
|
100
|
+
- lib/dech/price_uploader/ponpare.rb
|
101
|
+
- lib/dech/price_uploader/ponpare/ftps.rb
|
102
|
+
- lib/dech/version.rb
|
103
|
+
- spec/dech/price_uploader/ponpare/ftps_spec.rb
|
104
|
+
- spec/dech_spec.rb
|
105
|
+
- spec/spec_helper.rb
|
106
|
+
homepage: https://github.com/e-maido/dech
|
107
|
+
licenses:
|
108
|
+
- ''
|
109
|
+
metadata: {}
|
110
|
+
post_install_message:
|
111
|
+
rdoc_options: []
|
112
|
+
require_paths:
|
113
|
+
- lib
|
114
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
115
|
+
requirements:
|
116
|
+
- - ">="
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '0'
|
119
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
120
|
+
requirements:
|
121
|
+
- - ">="
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: '0'
|
124
|
+
requirements: []
|
125
|
+
rubyforge_project:
|
126
|
+
rubygems_version: 2.2.2
|
127
|
+
signing_key:
|
128
|
+
specification_version: 4
|
129
|
+
summary: Utilities gem for e-commerce mall in Japan.
|
130
|
+
test_files:
|
131
|
+
- spec/dech/price_uploader/ponpare/ftps_spec.rb
|
132
|
+
- spec/dech_spec.rb
|
133
|
+
- spec/spec_helper.rb
|