plausible_api 0.1.3 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 61ec37015a39b48b8ef1a5ff88f98452a87c590232ee527f03591d9fe3928a8d
4
- data.tar.gz: d8a7df06ccea331230058b18a900b41c850a55ca18d9e850d1cc2fbf7fa7bbcc
3
+ metadata.gz: 22016ef4c32d7f1d0470a619111b0134134e3c272ed62a6630f3f81184e7cd50
4
+ data.tar.gz: ef9f7efae941960ca78dca62b4b5f02207ddfb6ebeffb174120edcc0c14b7eec
5
5
  SHA512:
6
- metadata.gz: a0ce1d1dc380b44136fc38f193e307ee7b84872e6835043c02ebe89497c702daaf404efafe855c9b11f867569c612fe260ac0f1c79c959b30359d39df192d08c
7
- data.tar.gz: 0b28a11d857c1b2a9b83f5336fc833abb722e9492d602172f829c0bb12956c9aba7c426649ed01428a65f88d4c49ea421d44b09a808c639aa43c83b8453f8ada
6
+ metadata.gz: dfa7ec056c52894e489838410ec922d90544e80dca6525718c5c8629fa9fb9faece1fb76dd28f0fc8c6f455187ab46d5bd00e5d60ad7f7a8458c38e77ef60a5e
7
+ data.tar.gz: c858040b75e37e69c5d50813b78cf1ccf6708d24982ad865727adeb1a501839ed3b2a0244e8128fb99919dc97b41176c78bf870b1130be332bbfd07b27ee49bc
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- plausible_api (0.1.3)
4
+ plausible_api (0.1.5)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -27,6 +27,7 @@ c.aggregate
27
27
  c.aggregate({ period: '30d' })
28
28
  c.aggregate({ period: '30d', metrics: 'visitors,pageviews' })
29
29
  c.aggregate({ period: '30d', metrics: 'visitors,pageviews', filters: 'event:page==/order/confirmation' })
30
+ c.aggregate({ period: 'custom', date: '2021-01-01,2021-02-10' })
30
31
 
31
32
  # You'll get something like this:
32
33
  => {"bounce_rate"=>{"value"=>81.0}, "pageviews"=>{"value"=>29}, "visit_duration"=>{"value"=>247.0}, "visitors"=>{"value"=>14}}
@@ -42,11 +43,27 @@ c.timeseries
42
43
  # Set parameters (period, filters, interval)
43
44
  c.timeseries({ period: '7d' })
44
45
  c.timeseries({ period: '7d', filters: 'event:page==/order/confirmation' })
46
+ c.timeseries({ period: 'custom', date: '2021-01-01,2021-02-15' })
45
47
 
46
48
  # You'll get something like this:
47
49
  => [{"date"=>"2021-01-11", "value"=>100}, {"date"=>"2021-01-12", "value"=>120}, {"date"=>"2021-01-13", "value"=>80}...]
48
50
  ```
49
51
 
52
+ ### Stats > Breakdown
53
+ ```rb
54
+ # Use the default parameters (30d, event:page)
55
+ c.breakdown
56
+
57
+ # Set parameters (property, period, metrics, limit, page, filters, date)
58
+ c.breakdown({ property: 'visit:source' })
59
+ c.breakdown({ property: 'visit:source', metrics: 'visitors,pageviews' })
60
+ c.breakdown({ property: 'visit:source', metrics: 'visitors,pageviews', period: '30d' })
61
+ c.breakdown({ property: 'visit:source', metrics: 'visitors,pageviews', period: 'custom', date: '2021-01-01,2021-02-01' })
62
+
63
+ # You'll get something like this:
64
+ => [{"page"=>"/", "visitors"=>41}, {"page"=>"/plans/", "visitors"=>14}, {"page"=>"/agencies/", "visitors"=>8}, {"page"=>"/features/", "visitors"=>8}, {"page"=>"/ready/", "visitors"=>5}, {"page"=>"/contact/", "visitors"=>4}, {"page"=>"/about/", "visitors"=>3}, {"page"=>"/donate/", "visitors"=>3}]
65
+ ```
66
+
50
67
  ### Realtime > Visitors
51
68
 
52
69
  It's as simple as:
@@ -1,8 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'plausible_api/stats/base'
3
4
  require 'plausible_api/stats/realtime/visitors'
4
5
  require 'plausible_api/stats/aggregate'
5
6
  require 'plausible_api/stats/timeseries'
7
+ require 'plausible_api/stats/breakdown'
6
8
 
7
9
  require 'json'
8
10
  require "net/http"
@@ -27,6 +29,10 @@ module PlausibleApi
27
29
  call PlausibleApi::Stats::Timeseries.new(options)
28
30
  end
29
31
 
32
+ def breakdown(options = {})
33
+ call PlausibleApi::Stats::Breakdown.new(options)
34
+ end
35
+
30
36
  def realtime_visitors
31
37
  call PlausibleApi::Stats::Realtime::Visitors.new
32
38
  end
@@ -37,6 +43,8 @@ module PlausibleApi
37
43
 
38
44
  private
39
45
  def call(api)
46
+ raise StandardError.new "There is some invalid parameters." unless api.valid?
47
+
40
48
  url = "#{BASE_URL}#{api.request_url.gsub('$SITE_ID', @site_id)}"
41
49
  uri = URI.parse(url)
42
50
 
@@ -46,7 +54,7 @@ module PlausibleApi
46
54
  http = Net::HTTP.new(uri.host, uri.port)
47
55
  http.use_ssl = true
48
56
 
49
- JSON.parse http.request(req).body
57
+ api.parse_response http.request(req).body
50
58
  end
51
59
  end
52
60
  end
@@ -2,21 +2,22 @@
2
2
 
3
3
  module PlausibleApi
4
4
  module Stats
5
- class Aggregate
5
+ class Aggregate < Base
6
6
  def initialize(options = {})
7
7
  @period = options[:period] || '30d'
8
8
  @metrics = options[:metrics] || 'visitors,pageviews,bounce_rate,visit_duration'
9
9
  @filters = options[:filters]
10
10
  @compare = options[:compare]
11
+ @date = options[:date]
12
+ @period = 'custom' if @date
11
13
  end
12
14
 
13
- def request_url
14
- url = "/api/v1/stats/aggregate?site_id=$SITE_ID"
15
- url += "&period=#{@period}" if @period
16
- url += "&metrics=#{@metrics}" if @metrics
17
- url += "&filters=#{CGI.escape(@filters)}" if @filters
18
- url += "&compare=#{@compare}" if @compare
19
- url
15
+ def request_url_base
16
+ "/api/v1/stats/aggregate?site_id=$SITE_ID"
17
+ end
18
+
19
+ def parse_response(body)
20
+ JSON.parse body
20
21
  end
21
22
  end
22
23
  end
@@ -0,0 +1,89 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PlausibleApi
4
+ module Stats
5
+ class Base
6
+ def initialize(options = {})
7
+ raise NotImplementedError
8
+ end
9
+
10
+ def request_url_base
11
+ raise NotImplementedError
12
+ end
13
+
14
+ def request_url
15
+ url = request_url_base
16
+ url += "&period=#{@period}" if defined?(@period) && @period
17
+ url += "&metrics=#{@metrics}" if defined?(@metrics) && @metrics
18
+ url += "&filters=#{CGI.escape(@filters)}" if defined?(@filters) && @filters
19
+ url += "&compare=#{@compare}" if defined?(@compare) && @compare
20
+ url += "&interval=#{@interval}" if defined?(@interval) && @interval
21
+ url += "&property=#{@property}" if defined?(@property) && @property
22
+ url += "&limit=#{@limit}" if defined?(@limit) && @limit
23
+ url += "&page=#{@page}" if defined?(@page) && @page
24
+ url += "&date=#{@date}" if defined?(@date) && @date
25
+ url
26
+ end
27
+
28
+ def parse_response(body)
29
+ raise NotImplementedError
30
+ end
31
+
32
+ def valid?
33
+ errors.empty?
34
+ end
35
+
36
+ def errors
37
+ allowed_period = %w(12mo 6mo month 30d 7d day custom)
38
+ allowed_metrics = %w(visitors pageviews bounce_rate visit_duration)
39
+ allowed_compare = %w(previous_period)
40
+ allowed_interval = %w(date month)
41
+ allowed_property = %w(event:page event:source event:referrer event:utm_medium
42
+ event:utm_source event:utm_campaign event:device event:browser event:browser_version
43
+ event:os event:os_version event:country)
44
+ e = 'Not a valid parameter. Allowed parameters are: '
45
+
46
+ errors = []
47
+ if defined?(@period) && @period
48
+ errors.push({ period: "#{e}#{allowed_period.join(', ')}" }) unless allowed_period.include? @period
49
+ end
50
+ if defined?(@metrics) && @metrics
51
+ metrics_array = @metrics.split(',')
52
+ errors.push({ metrics: "#{e}#{allowed_metrics.join(', ')}" }) unless metrics_array & allowed_metrics == metrics_array
53
+ end
54
+ if defined?(@compare) && @compare
55
+ errors.push({ compare: "#{e}#{allowed_compare.join(', ')}" }) unless allowed_compare.include? @compare
56
+ end
57
+ if defined?(@interval) && @interval
58
+ errors.push({ interval: "#{e}#{allowed_interval.join(', ')}" }) unless allowed_interval.include? @interval
59
+ end
60
+ if defined?(@property) && @property
61
+ errors.push({ property: "#{e}#{allowed_property.join(', ')}" }) unless allowed_property.include? @property
62
+ end
63
+ if defined?(@filters) && @filters
64
+ filters_array = @filters.to_s.split(';')
65
+ filters_array.each do |f|
66
+ parts = f.split("==")
67
+ errors.push({ filters: "Unrecognized filter: #{f}" }) unless parts.length == 2
68
+ errors.push({ filters: "Unknown metric for filter: #{parts[0]}" }) unless allowed_property.include? parts[0]
69
+ end
70
+ end
71
+ if defined?(@limit) && @limit
72
+ errors.push({ limit: "Limit param must be a positive number" }) unless @limit.is_a? Integer and @limit > 0
73
+ end
74
+ if defined?(@page) && @page
75
+ errors.push({ page: "Page param must be a positive number" }) unless @page.is_a? Integer and @page > 0
76
+ end
77
+ if defined?(@date) && @date
78
+ errors.push({ date: 'You must define the period parameter as custom' }) unless @period == 'custom'
79
+ date_array = @date.split(",")
80
+ errors.push({ date: 'You must define start and end dates divided by comma' }) unless date_array.length == 2
81
+ regex = /\d{4}\-\d{2}\-\d{2}/
82
+ errors.push({ date: 'Wrong format for the start date' }) unless date_array[0] =~ regex
83
+ errors.push({ date: 'Wrong format for the end date' }) unless date_array[1] =~ regex
84
+ end
85
+ errors
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PlausibleApi
4
+ module Stats
5
+ class Breakdown < Base
6
+ def initialize(options = {})
7
+ @property = options[:property] || 'event:page' # required
8
+ @period = options[:period] || '30d' # required
9
+ @metrics = options[:metrics]
10
+ @limit = options[:limit]
11
+ @page = options[:page]
12
+ @filters = options[:filters]
13
+ @date = options[:date]
14
+ @period = 'custom' if @date
15
+
16
+ end
17
+
18
+ def request_url_base
19
+ "/api/v1/stats/breakdown?site_id=$SITE_ID"
20
+ end
21
+
22
+ def parse_response(body)
23
+ JSON.parse(body)['results']
24
+ end
25
+ end
26
+ end
27
+ end
@@ -3,13 +3,17 @@
3
3
  module PlausibleApi
4
4
  module Stats
5
5
  module Realtime
6
- class Visitors
6
+ class Visitors < PlausibleApi::Stats::Base
7
7
  def initialize
8
8
  end
9
9
 
10
- def request_url
10
+ def request_url_base
11
11
  "/api/v1/stats/realtime/visitors?site_id=$SITE_ID"
12
12
  end
13
+
14
+ def parse_response(body)
15
+ body.to_i
16
+ end
13
17
  end
14
18
  end
15
19
  end
@@ -2,19 +2,21 @@
2
2
 
3
3
  module PlausibleApi
4
4
  module Stats
5
- class Timeseries
5
+ class Timeseries < Base
6
6
  def initialize(options = {})
7
7
  @period = options[:period] || '30d'
8
8
  @filters = options[:filters]
9
9
  @interval = options[:interval]
10
+ @date = options[:date]
11
+ @period = 'custom' if @date
10
12
  end
11
13
 
12
- def request_url
13
- url = "/api/v1/stats/timeseries?site_id=$SITE_ID"
14
- url += "&period=#{@period}" if @period
15
- url += "&filters=#{CGI.escape(@filters)}" if @filters
16
- url += "&interval=#{@interval}" if @interval
17
- url
14
+ def request_url_base
15
+ "/api/v1/stats/timeseries?site_id=$SITE_ID"
16
+ end
17
+
18
+ def parse_response(body)
19
+ JSON.parse(body)['results']
18
20
  end
19
21
  end
20
22
  end
@@ -1,3 +1,3 @@
1
1
  module PlausibleApi
2
- VERSION = "0.1.3"
2
+ VERSION = "0.1.5"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: plausible_api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gustavo Garcia
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-02-15 00:00:00.000000000 Z
11
+ date: 2021-02-23 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: A very humble wrapper for the new API by Plausible
14
14
  email:
@@ -29,6 +29,8 @@ files:
29
29
  - lib/plausible_api.rb
30
30
  - lib/plausible_api/client.rb
31
31
  - lib/plausible_api/stats/aggregate.rb
32
+ - lib/plausible_api/stats/base.rb
33
+ - lib/plausible_api/stats/breakdown.rb
32
34
  - lib/plausible_api/stats/realtime/visitors.rb
33
35
  - lib/plausible_api/stats/timeseries.rb
34
36
  - lib/plausible_api/version.rb