cloudxls 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ Gemfile.lock
2
+ *.gem
data/cloudxls.gemspec CHANGED
@@ -20,5 +20,5 @@ Gem::Specification.new do |gem|
20
20
 
21
21
  gem.add_development_dependency "minitest"
22
22
  gem.add_development_dependency "rake"
23
- gem.add_development_dependency "webmock"
23
+ gem.add_development_dependency "rspec"
24
24
  end
@@ -0,0 +1,108 @@
1
+ require 'csv'
2
+
3
+ module CloudXLS
4
+ class CSVWriter
5
+ DATETIME_FORMAT = "%FT%T.%L%z".freeze
6
+ DATE_FORMAT = "%F".freeze
7
+
8
+ # Generates CSV string.
9
+ #
10
+ # @param [Array<String/Symbol>] columns
11
+ # Method/attribute keys to for the export.
12
+ #
13
+ # @return [String]
14
+ # The full CSV as a string. Titleizes *columns* for the header.
15
+ #
16
+ def self.text(scope, options = {})
17
+ columns = options[:columns]
18
+
19
+ str = ::CSV.generate do |csv|
20
+
21
+ if options[:skip_headers] != true
22
+ if scope.respond_to?(:column_names)
23
+ columns ||= scope.column_names
24
+ end
25
+ if columns
26
+ csv << csv_titles(columns, :titleize)
27
+ end
28
+ end
29
+
30
+ enum = scope_enumerator(scope)
31
+ scope.send(enum) do |record|
32
+ csv << csv_row(record, columns)
33
+ end
34
+ end
35
+ str.strip!
36
+ end
37
+
38
+ # Example
39
+ #
40
+ # Post.csv_enumerator(Post.all, [:title, :author, :published_at])
41
+ #
42
+ # @param [ActiveRecord::Scope] scope
43
+ # An activerecord scope object for the records to be exported.
44
+ # Example: Post.all.limit(500).where(author: "foo")
45
+ #
46
+ # @return [Enumerator] enumerator to use for streaming response.
47
+ #
48
+ def self.enumerator(scope, options = {})
49
+ columns = options[:columns]
50
+
51
+ Enumerator.new do |row|
52
+ if options[:skip_headers] != true
53
+ if scope.respond_to?(:column_names)
54
+ columns ||= scope.column_names
55
+ end
56
+ if columns
57
+ row << csv_titles(columns, :titleize).to_csv
58
+ end
59
+ end
60
+
61
+ enum = scope_enumerator(scope)
62
+ scope.send(enum) do |record|
63
+ row << csv_row(record, columns).to_csv
64
+ end
65
+ end
66
+ end
67
+
68
+ private
69
+
70
+
71
+ def self.csv_row(obj, columns = [])
72
+ if obj.is_a?(Array)
73
+ obj.map{ |el| encode_for_csv(el) }
74
+ else
75
+ columns.map do |key|
76
+ encode_for_csv(obj.send(key))
77
+ end
78
+ end
79
+ end
80
+
81
+
82
+ def self.encode_for_csv(val)
83
+ case val
84
+ when DateTime,Time then val.strftime(DATETIME_FORMAT)
85
+ when Date then val.strftime(DATE_FORMAT)
86
+ else
87
+ val
88
+ end
89
+ end
90
+
91
+ def self.csv_titles(column_names, strategy = :titleize)
92
+ column_names.map do |c|
93
+ title = c.to_s
94
+ title = title.send(strategy) if title.respond_to?(strategy)
95
+ title
96
+ end
97
+ end
98
+
99
+
100
+ def self.scope_enumerator(scope)
101
+ if scope.respond_to?(:find_each)
102
+ :find_each
103
+ else
104
+ :each
105
+ end
106
+ end
107
+ end
108
+ end
@@ -1,3 +1,3 @@
1
1
  module CloudXLS
2
- VERSION = '0.3.0'
2
+ VERSION = '0.4.0'
3
3
  end
data/lib/cloudxls.rb CHANGED
@@ -6,12 +6,13 @@ require 'rest_client'
6
6
  require 'multi_json'
7
7
 
8
8
  require 'cloudxls/version'
9
+ require 'cloudxls/csv_writer'
9
10
 
10
11
  module CloudXLS
11
12
  @https = true
12
13
  @api_base = 'cloudxls.com'.freeze
13
14
  @api_key = ENV["CLOUDXLS_API_KEY"]
14
- @ssl_bundle_path = File.dirname(__FILE__) + '/data/ca-certificates.crt'
15
+ # @ssl_bundle_path = File.dirname(__FILE__) + '/data/ca-certificates.crt'
15
16
  @verify_ssl_certs = true
16
17
 
17
18
  class << self
@@ -0,0 +1,86 @@
1
+ require 'spec_helper'
2
+
3
+ describe "CloudXLS::CSVWriter" do
4
+ before do
5
+ @writer = CloudXLS::CSVWriter
6
+ end
7
+
8
+ describe "with array" do
9
+ it "should not titleize" do
10
+ expect( @writer.text([['foo','bar'],[1,2]]) ).to eq("foo,bar\n1,2")
11
+ end
12
+
13
+ it "should escape titles" do
14
+ expect( @writer.text([['bar"baz']]) ).to eq("\"bar\"\"baz\"")
15
+ end
16
+
17
+ it "should escape rows" do
18
+ expect( @writer.text([['title'],['bar"baz']]) ).to eq("title\n\"bar\"\"baz\"")
19
+ end
20
+
21
+ it "should write YYYY-MM-DD for Date" do
22
+ expect( @writer.text([[Date.new(2012,12,24)]]) ).to eq("2012-12-24")
23
+ end
24
+
25
+ it "should write xmlschema for DateTime" do
26
+ # TODO: make UTC consistent
27
+ expect( @writer.text([[DateTime.new(2012,12,24,18,30,5,'+0000')]]) ).to eq("2012-12-24T18:30:05.000+0000")
28
+ expect( @writer.text([[DateTime.new(2012,12,24,18,30,5,'+0000').to_time.utc]]) ).to eq("2012-12-24T18:30:05.000+0000")
29
+ end
30
+
31
+ it "should write nothing for nil" do
32
+ expect( @writer.text([[nil,nil]]) ).to eq(",")
33
+ end
34
+
35
+ it "should write \"\" for empty string" do
36
+ expect( @writer.text([["",""]]) ).to eq('"",""')
37
+ end
38
+
39
+ it "should write integers" do
40
+ expect( @writer.text([[-1,0,1,1_000_000]]) ).to eq('-1,0,1,1000000')
41
+ end
42
+
43
+ it "should write floats" do
44
+ expect( @writer.text([[-1.0,0.0,1.0,1_000_000.0,1.234567]]) ).to eq('-1.0,0.0,1.0,1000000.0,1.234567')
45
+ end
46
+ end
47
+
48
+ # describe "#text with AR" do
49
+ # before do
50
+ # Post.delete_all
51
+ # @post = Post.create(
52
+ # :title => "hello world",
53
+ # :visits => 12_032,
54
+ # :conversion_rate => 0.24,
55
+ # :published_on => Date.new(2013,12,24),
56
+ # :expired_at => DateTime.new(2013,12,25,12,30,30),
57
+ # :unix_timestamp => DateTime.new(2013,12,25,12,30,30),
58
+ # :published => false)
59
+ # end
60
+
61
+ # it "given no records should just return titles" do
62
+ # Post.delete_all
63
+ # expect( @writer.text(Post.all, :columns => [:title, :visits]) ).to eq("Title,Visits")
64
+ # end
65
+
66
+ # it "should work with a Post.all" do
67
+ # expect( @writer.text(Post.all, :columns => [:title, :visits]) ).to eq("Title,Visits\nhello world,12032")
68
+ # end
69
+
70
+ # it "should work with a Post.limit" do
71
+ # expect( @writer.text(Post.limit(10), :columns => [:title, :visits]) ).to eq("Title,Visits\nhello world,12032")
72
+ # end
73
+
74
+ # it "should work with a Post.all.to_a" do
75
+ # expect( @writer.text(Post.all.to_a, :columns => [:title, :visits]) ).to eq("Title,Visits\nhello world,12032")
76
+ # end
77
+
78
+ # it "should write xmlschema for DateTime" do
79
+ # expect( @writer.text(Post.all, :columns => [:expired_at]) ).to eq("Expired At\n2013-12-25T12:30:30.000+0000")
80
+ # end
81
+
82
+ # it "should write YYYY-MM-DD for Date" do
83
+ # expect( @writer.text(Post.all, :columns => [:published_on]) ).to eq("Published On\n2013-12-24")
84
+ # end
85
+ # end
86
+ end
@@ -0,0 +1,10 @@
1
+ ENV["RAILS_ENV"] = 'test'
2
+ require 'bundler'
3
+ require 'bundler/setup'
4
+ require 'cloudxls'
5
+
6
+
7
+ RSpec.configure do |config|
8
+ config.color_enabled = true
9
+ config.order = "random"
10
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cloudxls
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-11-19 00:00:00.000000000 Z
12
+ date: 2013-11-20 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rest-client
@@ -82,7 +82,7 @@ dependencies:
82
82
  - !ruby/object:Gem::Version
83
83
  version: '0'
84
84
  - !ruby/object:Gem::Dependency
85
- name: webmock
85
+ name: rspec
86
86
  requirement: !ruby/object:Gem::Requirement
87
87
  none: false
88
88
  requirements:
@@ -104,14 +104,17 @@ executables: []
104
104
  extensions: []
105
105
  extra_rdoc_files: []
106
106
  files:
107
+ - .gitignore
107
108
  - Gemfile
108
- - Gemfile.lock
109
109
  - README.md
110
110
  - Rakefile
111
111
  - cloudxls.gemspec
112
112
  - lib/cloudxls.rb
113
+ - lib/cloudxls/csv_writer.rb
113
114
  - lib/cloudxls/version.rb
114
115
  - lib/data/ca-certificates.txt
116
+ - spec/csv_writer_spec.rb
117
+ - spec/spec_helper.rb
115
118
  homepage: https://cloudxls.com
116
119
  licenses: []
117
120
  post_install_message:
@@ -136,4 +139,6 @@ rubygems_version: 1.8.23
136
139
  signing_key:
137
140
  specification_version: 3
138
141
  summary: Ruby wrapper for the CloudXLS xpipe API
139
- test_files: []
142
+ test_files:
143
+ - spec/csv_writer_spec.rb
144
+ - spec/spec_helper.rb
data/Gemfile.lock DELETED
@@ -1,32 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- cloudxls (0.1.0)
5
- multi_json (>= 1.0.4, < 2)
6
- rest-client (~> 1.4)
7
-
8
- GEM
9
- remote: https://rubygems.org/
10
- specs:
11
- addressable (2.3.5)
12
- crack (0.4.1)
13
- safe_yaml (~> 0.9.0)
14
- mime-types (1.25)
15
- minitest (5.0.8)
16
- multi_json (1.8.0)
17
- rake (10.1.0)
18
- rest-client (1.6.7)
19
- mime-types (>= 1.16)
20
- safe_yaml (0.9.7)
21
- webmock (1.13.0)
22
- addressable (>= 2.2.7)
23
- crack (>= 0.3.2)
24
-
25
- PLATFORMS
26
- ruby
27
-
28
- DEPENDENCIES
29
- cloudxls!
30
- minitest
31
- rake
32
- webmock