embulk-input-mixpanel 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +9 -0
- data/CHANGELOG.md +8 -0
- data/README.md +9 -3
- data/Rakefile +5 -51
- data/embulk-input-mixpanel.gemspec +2 -1
- data/gemfiles/embulk-0.6.18 +4 -0
- data/gemfiles/embulk-0.6.19 +4 -0
- data/gemfiles/embulk-0.6.20 +4 -0
- data/gemfiles/embulk-0.6.21 +4 -0
- data/gemfiles/embulk-0.6.22 +4 -0
- data/gemfiles/embulk-0.6.23 +4 -0
- data/gemfiles/embulk-latest +2 -0
- data/gemfiles/template.erb +4 -0
- data/lib/embulk/input/mixpanel.rb +28 -7
- data/lib/embulk/input/mixpanel_api/client.rb +4 -3
- data/test/embulk/input/mixpanel_api/test_client.rb +28 -13
- data/test/embulk/input/test_mixpanel.rb +174 -23
- metadata +23 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5fca90578e059bd058fa52d1d8283afbd85a58a1
|
4
|
+
data.tar.gz: 09305de32323e4284f33a005330d522f2afc98e7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8a200ccc100c2baa7552e933846648253bace0b944a7cefa8bfcc87198ab0e5dfe2a8a754a3195ac2aeca096114a92defc74c3d7e35176a2d8475bcac830cf83
|
7
|
+
data.tar.gz: 91c0591f7bf83a14dc5bdb7f56f2915c97ba8e3d3b81cac8f37ac411541c0ae5302bf2712c6f4e6347a542955c5278a085cab67925a8da6559ce0195dc12edaf
|
data/.travis.yml
CHANGED
@@ -13,4 +13,13 @@ jdk:
|
|
13
13
|
gemfile:
|
14
14
|
- gemfiles/embulk-0.6.16
|
15
15
|
- gemfiles/embulk-0.6.17
|
16
|
+
- gemfiles/embulk-0.6.18
|
17
|
+
- gemfiles/embulk-0.6.19
|
18
|
+
- gemfiles/embulk-0.6.20
|
19
|
+
- gemfiles/embulk-0.6.21
|
20
|
+
- gemfiles/embulk-0.6.22
|
21
|
+
- gemfiles/embulk-0.6.23
|
16
22
|
- gemfiles/embulk-latest
|
23
|
+
matrix:
|
24
|
+
allow_failures:
|
25
|
+
- gemfile: gemfiles/embulk-0.6.22
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
## 0.2.0 - 2015-08-17
|
2
|
+
|
3
|
+
* [enhanement] Raise config error for unretryable [#15](https://github.com/treasure-data/embulk-input-mixpanel/pull/15) [[Reported by @muga](https://github.com/treasure-data/embulk-input-mixpanel/issues/11). Thanks!!]
|
4
|
+
* [maintenance] Use everyleaf-embulk_helper [#14](https://github.com/treasure-data/embulk-input-mixpanel/pull/14)
|
5
|
+
* [enhancement] Support scheduled execution [#13](https://github.com/treasure-data/embulk-input-mixpanel/pull/13) [[Reported by @muga](https://github.com/treasure-data/embulk-input-mixpanel/issues/12). Thanks!!]
|
6
|
+
* [maintenance] Improve coverage [#10](https://github.com/treasure-data/embulk-input-mixpanel/pull/10)
|
7
|
+
* [fixed] README: Add description for how to get project's timezone [#9](https://github.com/treasure-data/embulk-input-mixpanel/pull/9)
|
8
|
+
|
1
9
|
## 0.1.0 - 2015-07-28
|
2
10
|
|
3
11
|
The first release!!
|
data/README.md
CHANGED
@@ -23,13 +23,19 @@ This plugin uses API key and API secret for target project. Before you make your
|
|
23
23
|
|
24
24
|
For API configuration, you should log in mixpanel website, and click "Account" at the header. When you select "Projects" panel, you can get "API Key" and "API Secret" for each project.
|
25
25
|
|
26
|
+
### How to get project's timezone
|
27
|
+
|
28
|
+
This plugin uses project's timezone to adjust timestamp to UTC.
|
29
|
+
|
30
|
+
To get it, you should log in mixpanel website, and click gear icon at the lower left. Then an opened dialog shows timezone at "Timezone" column in "Management" tab.
|
31
|
+
|
26
32
|
### Configuration
|
27
33
|
|
28
34
|
- **api_key**: project API Key (string, required)
|
29
35
|
- **api_secret**: project API Secret (string, required)
|
30
36
|
- **timezone**: project timezone(string, required)
|
31
|
-
- **from_date**: From date to export (string,
|
32
|
-
- **
|
37
|
+
- **from_date**: From date to export (string, optional, default: today - 2)
|
38
|
+
- **days**: Count of days range for exporting (integer, optional, default: (today - 1) - from_date)
|
33
39
|
- **event**: The event or events to filter data (array, optional, default: nil)
|
34
40
|
- **where**: Expression to filter data (c.f. https://mixpanel.com/docs/api-documentation/data-export-api#segmentation-expressions) (string, optional, default: nil)
|
35
41
|
- **bucket**:The data backet to filter data (string, optional, default: nil)
|
@@ -43,7 +49,7 @@ in:
|
|
43
49
|
api_secret: "API_SECRET"
|
44
50
|
timezone: "US/Pacific"
|
45
51
|
from_date: "2015-07-19"
|
46
|
-
|
52
|
+
days: 5
|
47
53
|
```
|
48
54
|
|
49
55
|
## Run test
|
data/Rakefile
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require "bundler/gem_tasks"
|
2
|
+
require "everyleaf/embulk_helper/tasks"
|
2
3
|
|
3
4
|
task default: :test
|
4
5
|
|
@@ -7,54 +8,7 @@ task :test do
|
|
7
8
|
ruby("test/run-test.rb", "--use-color=yes", "--collector=dir")
|
8
9
|
end
|
9
10
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
changelog_file = root_dir.join("CHANGELOG.md")
|
15
|
-
gemspec_file = root_dir.join("embulk-input-mixpanel.gemspec")
|
16
|
-
|
17
|
-
system("git fetch origin")
|
18
|
-
|
19
|
-
# detect merged PR
|
20
|
-
old_version = gemspec_file.read[/spec\.version += *"([0-9]+\.[0-9]+\.[0-9]+)"/, 1]
|
21
|
-
pr_numbers = `git log v#{old_version}..origin/master --oneline`.scan(/#[0-9]+/)
|
22
|
-
|
23
|
-
if !$?.success? || pr_numbers.empty?
|
24
|
-
puts "Detecting PR failed. Please confirm if any PR were merged after the latest release."
|
25
|
-
exit(false)
|
26
|
-
end
|
27
|
-
|
28
|
-
# Generate new version
|
29
|
-
major, minor, patch = old_version.split(".").map(&:to_i)
|
30
|
-
new_version = "#{major}.#{minor}.#{patch + 1}"
|
31
|
-
|
32
|
-
# Update ChangeLog
|
33
|
-
pr_descriptions = pr_numbers.map do |number|
|
34
|
-
body = open("https://api.github.com/repos/treasure-data/embulk-input-mixpanel/issues/#{number.gsub("#", "")}").read
|
35
|
-
payload = JSON.parse(body)
|
36
|
-
"* [] #{payload["title"]} [#{number}](https://github.com/treasure-data/embulk-input-mixpanel/pull/#{number.gsub('#', '')})"
|
37
|
-
end.join("\n")
|
38
|
-
|
39
|
-
new_changelog = <<-HEADER
|
40
|
-
## #{new_version} - #{Time.now.strftime("%Y-%m-%d")}
|
41
|
-
#{pr_descriptions}
|
42
|
-
|
43
|
-
#{changelog_file.read.chomp}
|
44
|
-
HEADER
|
45
|
-
|
46
|
-
File.open(changelog_file, "w") {|f| f.write(new_changelog) }
|
47
|
-
|
48
|
-
# Update version.rb
|
49
|
-
old_content = gemspec_file.read
|
50
|
-
File.open(gemspec_file, "w") do |f|
|
51
|
-
f.write old_content.gsub(/(spec\.version += *)".*?"/, %Q!\\1"#{new_version}"!)
|
52
|
-
end
|
53
|
-
|
54
|
-
# Update Gemfile.lock
|
55
|
-
system("bundle install")
|
56
|
-
|
57
|
-
puts "ChangeLog, version and Gemfile.lock were updated. New version is #{new_version}."
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
11
|
+
Everyleaf::EmbulkHelper::Tasks.install(
|
12
|
+
gemspec: "./embulk-input-mixpanel.gemspec",
|
13
|
+
github_name: "treasure-data/embulk-input-mixpanel",
|
14
|
+
)
|
@@ -1,7 +1,7 @@
|
|
1
1
|
|
2
2
|
Gem::Specification.new do |spec|
|
3
3
|
spec.name = "embulk-input-mixpanel"
|
4
|
-
spec.version = "0.
|
4
|
+
spec.version = "0.2.0"
|
5
5
|
spec.authors = ["yoshihara", "uu59"]
|
6
6
|
spec.summary = "Mixpanel input plugin for Embulk"
|
7
7
|
spec.description = "Loads records from Mixpanel."
|
@@ -22,4 +22,5 @@ Gem::Specification.new do |spec|
|
|
22
22
|
spec.add_development_dependency 'test-unit'
|
23
23
|
spec.add_development_dependency 'test-unit-rr'
|
24
24
|
spec.add_development_dependency 'codeclimate-test-reporter'
|
25
|
+
spec.add_development_dependency 'everyleaf-embulk_helper'
|
25
26
|
end
|
data/gemfiles/embulk-latest
CHANGED
@@ -3,7 +3,6 @@ require "embulk/input/mixpanel_api/client"
|
|
3
3
|
|
4
4
|
module Embulk
|
5
5
|
module Input
|
6
|
-
|
7
6
|
class Mixpanel < InputPlugin
|
8
7
|
Plugin.register_input("mixpanel", self)
|
9
8
|
|
@@ -19,9 +18,7 @@ module Embulk
|
|
19
18
|
|
20
19
|
task[:params] = export_params(config)
|
21
20
|
|
22
|
-
|
23
|
-
to_date = config.param(:to_date, :string)
|
24
|
-
dates = Date.parse(from_date)..Date.parse(to_date)
|
21
|
+
dates = generate_dates(config)
|
25
22
|
task[:dates] = dates.map {|date| date.to_s}
|
26
23
|
|
27
24
|
task[:api_key] = config.param(:api_key, :string)
|
@@ -33,7 +30,7 @@ module Embulk
|
|
33
30
|
TZInfo::Timezone.get(task[:timezone])
|
34
31
|
rescue => e
|
35
32
|
Embulk.logger.error "'#{task[:timezone]}' is invalid timezone"
|
36
|
-
raise e
|
33
|
+
raise ConfigError, e.message
|
37
34
|
end
|
38
35
|
|
39
36
|
columns = []
|
@@ -51,7 +48,12 @@ module Embulk
|
|
51
48
|
def self.resume(task, columns, count, &control)
|
52
49
|
commit_reports = yield(task, columns, count)
|
53
50
|
|
54
|
-
|
51
|
+
# NOTE: If this plugin supports to run by multi threads, this
|
52
|
+
# implementation is terrible.
|
53
|
+
commit_report = commit_reports.first
|
54
|
+
next_to_date = Date.parse(commit_report[:to_date]).next
|
55
|
+
|
56
|
+
next_config_diff = {from_date: next_to_date.to_s}
|
55
57
|
return next_config_diff
|
56
58
|
end
|
57
59
|
|
@@ -83,6 +85,25 @@ module Embulk
|
|
83
85
|
return {"columns" => columns}
|
84
86
|
end
|
85
87
|
|
88
|
+
def self.generate_dates(config)
|
89
|
+
default_from_date = (Date.today - 2).to_s
|
90
|
+
|
91
|
+
begin
|
92
|
+
from_date = Date.parse(config.param(:from_date, :string, default: default_from_date))
|
93
|
+
rescue ArgumentError # invalid date
|
94
|
+
raise ConfigError, "from_date '#{from_date}' is invalid date"
|
95
|
+
end
|
96
|
+
|
97
|
+
default_days = ((Date.today - 1) - from_date).to_i
|
98
|
+
days = config.param(:days, :integer, default: default_days)
|
99
|
+
|
100
|
+
if days < 1
|
101
|
+
raise ConfigError, "days '#{days}' is invalid. Please spcify bigger number than 0."
|
102
|
+
end
|
103
|
+
|
104
|
+
from_date..(from_date + days)
|
105
|
+
end
|
106
|
+
|
86
107
|
def init
|
87
108
|
@api_key = task[:api_key]
|
88
109
|
@api_secret = task[:api_secret]
|
@@ -126,7 +147,7 @@ module Embulk
|
|
126
147
|
|
127
148
|
page_builder.finish
|
128
149
|
|
129
|
-
commit_report = {}
|
150
|
+
commit_report = {to_date: @dates.last}
|
130
151
|
return commit_report
|
131
152
|
end
|
132
153
|
|
@@ -21,9 +21,10 @@ module Embulk
|
|
21
21
|
params[:sig] = signature(params)
|
22
22
|
response = httpclient.get(ENDPOINT_EXPORT, params)
|
23
23
|
|
24
|
-
if response.code
|
25
|
-
|
26
|
-
|
24
|
+
if (400..499).include?(response.code)
|
25
|
+
raise ConfigError, response.body
|
26
|
+
elsif response.code >= 500
|
27
|
+
raise RuntimeError, response.body
|
27
28
|
end
|
28
29
|
|
29
30
|
Enumerator.new do |y|
|
@@ -31,10 +31,17 @@ module Embulk
|
|
31
31
|
super
|
32
32
|
|
33
33
|
@httpclient = HTTPClient.new
|
34
|
-
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_httpclient
|
37
|
+
stub_response(success_response)
|
38
|
+
mock(@client).httpclient { @httpclient }
|
39
|
+
|
40
|
+
@client.export(params)
|
35
41
|
end
|
36
42
|
|
37
43
|
def test_response_class
|
44
|
+
stub_client
|
38
45
|
stub_response(success_response)
|
39
46
|
|
40
47
|
actual = @client.export(params)
|
@@ -43,6 +50,7 @@ module Embulk
|
|
43
50
|
end
|
44
51
|
|
45
52
|
def test_http_request
|
53
|
+
stub_client
|
46
54
|
mock(@httpclient).get(Client::ENDPOINT_EXPORT, params) do
|
47
55
|
success_response
|
48
56
|
end
|
@@ -51,6 +59,7 @@ module Embulk
|
|
51
59
|
end
|
52
60
|
|
53
61
|
def test_success
|
62
|
+
stub_client
|
54
63
|
stub_response(success_response)
|
55
64
|
|
56
65
|
actual = @client.export(params)
|
@@ -58,24 +67,30 @@ module Embulk
|
|
58
67
|
assert_equal(dummy_responses, actual.to_a)
|
59
68
|
end
|
60
69
|
|
61
|
-
def
|
62
|
-
|
63
|
-
|
64
|
-
stub(Embulk.logger).error(failure_response.body) {}
|
65
|
-
actual = @client.export(params)
|
70
|
+
def test_failure_with_400
|
71
|
+
stub_client
|
72
|
+
stub_response(failure_response(400))
|
66
73
|
|
67
|
-
|
74
|
+
assert_raise(Embulk::ConfigError) do
|
75
|
+
@client.export(params)
|
76
|
+
end
|
68
77
|
end
|
69
78
|
|
70
|
-
def
|
71
|
-
|
79
|
+
def test_failure_with_500
|
80
|
+
stub_client
|
81
|
+
stub_response(failure_response(500))
|
72
82
|
|
73
|
-
|
74
|
-
|
83
|
+
assert_raise(RuntimeError) do
|
84
|
+
@client.export(params)
|
85
|
+
end
|
75
86
|
end
|
76
87
|
|
77
88
|
private
|
78
89
|
|
90
|
+
def stub_client
|
91
|
+
stub(@client).httpclient { @httpclient }
|
92
|
+
end
|
93
|
+
|
79
94
|
def stub_response(response)
|
80
95
|
stub(@httpclient).get(Client::ENDPOINT_EXPORT, params) do
|
81
96
|
response
|
@@ -86,8 +101,8 @@ module Embulk
|
|
86
101
|
Struct.new(:code, :body).new(200, jsonl_dummy_responses)
|
87
102
|
end
|
88
103
|
|
89
|
-
def failure_response
|
90
|
-
Struct.new(:code, :body).new(
|
104
|
+
def failure_response(code)
|
105
|
+
Struct.new(:code, :body).new(code, "{'error': 'invalid'}")
|
91
106
|
end
|
92
107
|
|
93
108
|
def params
|
@@ -9,6 +9,9 @@ module Embulk
|
|
9
9
|
API_SECRET = "api_secret".freeze
|
10
10
|
FROM_DATE = "2015-02-22".freeze
|
11
11
|
TO_DATE = "2015-03-02".freeze
|
12
|
+
DAYS = 8
|
13
|
+
DATES = Date.parse(FROM_DATE)..(Date.parse(FROM_DATE) + DAYS)
|
14
|
+
TIMEZONE = "Asia/Tokyo".freeze
|
12
15
|
|
13
16
|
DURATIONS = [
|
14
17
|
{from_date: FROM_DATE, to_date: "2015-02-28"}, # It has 7 days between 2015-02-22 and 2015-02-28
|
@@ -56,6 +59,144 @@ module Embulk
|
|
56
59
|
assert_equal(expected, actual)
|
57
60
|
end
|
58
61
|
|
62
|
+
class GenerateDatesTest < self
|
63
|
+
def test_valid_from_date
|
64
|
+
from_date = "2015-08-14"
|
65
|
+
parsed_date = Date.parse(from_date)
|
66
|
+
|
67
|
+
expected = (parsed_date..(parsed_date + DAYS))
|
68
|
+
actual = Mixpanel.generate_dates(transaction_config(from_date))
|
69
|
+
assert_equal(expected, actual)
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_invalid_from_date
|
73
|
+
from_date = "2015-08-41"
|
74
|
+
|
75
|
+
assert_raise(Embulk::ConfigError) do
|
76
|
+
Mixpanel.generate_dates(transaction_config(from_date))
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
def transaction_config(from_date)
|
83
|
+
_config = config.merge(
|
84
|
+
from_date: from_date,
|
85
|
+
timezone: TIMEZONE,
|
86
|
+
columns: schema,
|
87
|
+
)
|
88
|
+
DataSource[*_config.to_a.flatten(1)]
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
class TransactionTest < self
|
93
|
+
class FromDateTest < self
|
94
|
+
end
|
95
|
+
|
96
|
+
class TimezoneTest < self
|
97
|
+
def test_valid_timezone
|
98
|
+
timezone = TIMEZONE
|
99
|
+
mock(Mixpanel).resume(transaction_task(timezone), columns, 1, &control)
|
100
|
+
|
101
|
+
Mixpanel.transaction(transaction_config(timezone), &control)
|
102
|
+
end
|
103
|
+
|
104
|
+
def test_invalid_timezone
|
105
|
+
timezone = "#{TIMEZONE}ooooo"
|
106
|
+
|
107
|
+
assert_raise(Embulk::ConfigError) do
|
108
|
+
Mixpanel.transaction(transaction_config(timezone), &control)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
private
|
113
|
+
|
114
|
+
def transaction_task(timezone)
|
115
|
+
task.merge(
|
116
|
+
dates: DATES.map {|date| date.to_s},
|
117
|
+
api_key: API_KEY,
|
118
|
+
api_secret: API_SECRET,
|
119
|
+
timezone: timezone,
|
120
|
+
schema: schema
|
121
|
+
)
|
122
|
+
end
|
123
|
+
|
124
|
+
def transaction_config(timezone)
|
125
|
+
_config = config.merge(
|
126
|
+
timezone: timezone,
|
127
|
+
columns: schema,
|
128
|
+
)
|
129
|
+
DataSource[*_config.to_a.flatten(1)]
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
class DaysTest < self
|
134
|
+
def test_valid_days
|
135
|
+
days = 5
|
136
|
+
|
137
|
+
mock(Mixpanel).resume(transaction_task(days), columns, 1, &control)
|
138
|
+
Mixpanel.transaction(transaction_config(days), &control)
|
139
|
+
end
|
140
|
+
|
141
|
+
def test_invalid_days
|
142
|
+
days = 0
|
143
|
+
|
144
|
+
assert_raise(Embulk::ConfigError) do
|
145
|
+
Mixpanel.transaction(transaction_config(days), &control)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
private
|
150
|
+
|
151
|
+
def transaction_task(days)
|
152
|
+
from_date = Date.parse(FROM_DATE)
|
153
|
+
task.merge(
|
154
|
+
dates: (from_date..(from_date + days)).map {|date| date.to_s},
|
155
|
+
api_key: API_KEY,
|
156
|
+
api_secret: API_SECRET,
|
157
|
+
timezone: TIMEZONE,
|
158
|
+
schema: schema
|
159
|
+
)
|
160
|
+
end
|
161
|
+
|
162
|
+
def transaction_config(days)
|
163
|
+
_config = config.merge(
|
164
|
+
days: days,
|
165
|
+
columns: schema,
|
166
|
+
timezone: TIMEZONE,
|
167
|
+
)
|
168
|
+
DataSource[*_config.to_a.flatten(1)]
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
def test_resume
|
173
|
+
today = Date.today
|
174
|
+
control = proc { [{to_date: today.to_s}] }
|
175
|
+
actual = Mixpanel.resume(transaction_task, columns, 1, &control)
|
176
|
+
assert_equal({from_date: today.next.to_s}, actual)
|
177
|
+
end
|
178
|
+
|
179
|
+
def control
|
180
|
+
proc {} # dummy
|
181
|
+
end
|
182
|
+
|
183
|
+
def transaction_task
|
184
|
+
task.merge(
|
185
|
+
dates: DATES.map {|date| date.to_s},
|
186
|
+
api_key: API_KEY,
|
187
|
+
api_secret: API_SECRET,
|
188
|
+
timezone: TIMEZONE,
|
189
|
+
schema: schema
|
190
|
+
)
|
191
|
+
end
|
192
|
+
|
193
|
+
def columns
|
194
|
+
schema.map do |col|
|
195
|
+
Column.new(nil, col["name"], col["type"].to_sym)
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
59
200
|
def test_export_params
|
60
201
|
config_params = [
|
61
202
|
:type, "mixpanel",
|
@@ -89,6 +230,14 @@ module Embulk
|
|
89
230
|
@plugin = Mixpanel.new(task, nil, nil, @page_builder)
|
90
231
|
end
|
91
232
|
|
233
|
+
def test_preview_check
|
234
|
+
mock(@plugin).preview? { true }
|
235
|
+
stub(@page_builder).add(anything)
|
236
|
+
stub(@page_builder).finish
|
237
|
+
|
238
|
+
@plugin.run
|
239
|
+
end
|
240
|
+
|
92
241
|
def test_preview
|
93
242
|
stub(@plugin).preview? { true }
|
94
243
|
mock(@page_builder).add(anything).times(records.length)
|
@@ -114,28 +263,8 @@ module Embulk
|
|
114
263
|
@plugin.run
|
115
264
|
end
|
116
265
|
|
117
|
-
def test_invalid_timezone
|
118
|
-
assert_raise(TZInfo::InvalidTimezoneIdentifier) do
|
119
|
-
Mixpanel.new(task.merge(timezone: "Asia/Tokyooooooooo"), nil, nil, @page_builder).run
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
266
|
private
|
124
267
|
|
125
|
-
def task
|
126
|
-
{
|
127
|
-
api_key: API_KEY,
|
128
|
-
api_secret: API_SECRET,
|
129
|
-
timezone: "Asia/Tokyo",
|
130
|
-
schema: [
|
131
|
-
{"name" => "foo", "type" => "long"},
|
132
|
-
{"name" => "time", "type" => "long"},
|
133
|
-
],
|
134
|
-
dates: (Date.parse(FROM_DATE)..Date.parse(TO_DATE)).to_a,
|
135
|
-
params: Mixpanel.export_params(embulk_config),
|
136
|
-
}
|
137
|
-
end
|
138
|
-
|
139
268
|
def timezone_offset_seconds
|
140
269
|
60 * 60 * 9 # Asia/Tokyo
|
141
270
|
end
|
@@ -143,6 +272,25 @@ module Embulk
|
|
143
272
|
|
144
273
|
private
|
145
274
|
|
275
|
+
def schema
|
276
|
+
[
|
277
|
+
{"name" => "foo", "type" => "long"},
|
278
|
+
{"name" => "time", "type" => "long"},
|
279
|
+
{"name" => "event", "type" => "string"},
|
280
|
+
]
|
281
|
+
end
|
282
|
+
|
283
|
+
def task
|
284
|
+
{
|
285
|
+
api_key: API_KEY,
|
286
|
+
api_secret: API_SECRET,
|
287
|
+
timezone: TIMEZONE,
|
288
|
+
schema: schema,
|
289
|
+
dates: DATES.to_a,
|
290
|
+
params: Mixpanel.export_params(embulk_config),
|
291
|
+
}
|
292
|
+
end
|
293
|
+
|
146
294
|
def records
|
147
295
|
[
|
148
296
|
{
|
@@ -160,14 +308,17 @@ module Embulk
|
|
160
308
|
1234567890
|
161
309
|
end
|
162
310
|
|
163
|
-
def
|
164
|
-
|
311
|
+
def config
|
312
|
+
{
|
165
313
|
type: "mixpanel",
|
166
314
|
api_key: API_KEY,
|
167
315
|
api_secret: API_SECRET,
|
168
316
|
from_date: FROM_DATE,
|
169
|
-
|
317
|
+
days: DAYS,
|
170
318
|
}
|
319
|
+
end
|
320
|
+
|
321
|
+
def embulk_config
|
171
322
|
DataSource[*config.to_a.flatten(1)]
|
172
323
|
end
|
173
324
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: embulk-input-mixpanel
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- yoshihara
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2015-
|
12
|
+
date: 2015-08-17 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
@@ -143,6 +143,20 @@ dependencies:
|
|
143
143
|
- - '>='
|
144
144
|
- !ruby/object:Gem::Version
|
145
145
|
version: '0'
|
146
|
+
- !ruby/object:Gem::Dependency
|
147
|
+
requirement: !ruby/object:Gem::Requirement
|
148
|
+
requirements:
|
149
|
+
- - '>='
|
150
|
+
- !ruby/object:Gem::Version
|
151
|
+
version: '0'
|
152
|
+
name: everyleaf-embulk_helper
|
153
|
+
prerelease: false
|
154
|
+
type: :development
|
155
|
+
version_requirements: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - '>='
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0'
|
146
160
|
description: Loads records from Mixpanel.
|
147
161
|
email:
|
148
162
|
- h.yoshihara@everyleaf.com
|
@@ -161,7 +175,14 @@ files:
|
|
161
175
|
- embulk-input-mixpanel.gemspec
|
162
176
|
- gemfiles/embulk-0.6.16
|
163
177
|
- gemfiles/embulk-0.6.17
|
178
|
+
- gemfiles/embulk-0.6.18
|
179
|
+
- gemfiles/embulk-0.6.19
|
180
|
+
- gemfiles/embulk-0.6.20
|
181
|
+
- gemfiles/embulk-0.6.21
|
182
|
+
- gemfiles/embulk-0.6.22
|
183
|
+
- gemfiles/embulk-0.6.23
|
164
184
|
- gemfiles/embulk-latest
|
185
|
+
- gemfiles/template.erb
|
165
186
|
- lib/embulk/input/mixpanel.rb
|
166
187
|
- lib/embulk/input/mixpanel_api/client.rb
|
167
188
|
- test/embulk/input/mixpanel_api/test_client.rb
|