Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support weekly aggregation #226

Merged
merged 6 commits into from Jan 4, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
74 changes: 53 additions & 21 deletions lib/statistics/aggregation.rb
@@ -1,24 +1,42 @@
module Statistics
class Aggregation
class << self
def run(date:)
cnps_dojos = Dojo.eager_load(:dojo_event_services).where(dojo_event_services: { name: :connpass }).to_a
drkp_dojos = Dojo.eager_load(:dojo_event_services).where(dojo_event_services: { name: :doorkeeper }).to_a
fsbk_dojos = Dojo.eager_load(:dojo_event_services).where(dojo_event_services: { name: :facebook }).to_a
def run(date:, weekly:)
cnps_dojos, drkp_dojos, fsbk_dojos = fetch_dojos

Connpass.run(cnps_dojos, date)
Doorkeeper.run(drkp_dojos, date)
Facebook.run(fsbk_dojos, date)
Connpass.run(cnps_dojos, date, weekly)
Doorkeeper.run(drkp_dojos, date, weekly)
Facebook.run(fsbk_dojos, date, weekly)
end

def fetch_dojos
[
Dojo.eager_load(:dojo_event_services).where(dojo_event_services: { name: :connpass }).to_a,
Dojo.eager_load(:dojo_event_services).where(dojo_event_services: { name: :doorkeeper }).to_a,
Dojo.eager_load(:dojo_event_services).where(dojo_event_services: { name: :facebook }).to_a
]
end
end

class Connpass
class << self
def run(dojos, date)
def run(dojos, date, weekly)
cnps = Client::Connpass.new
params = {
yyyymm: "#{date.year}#{date.month}"
}
params = if weekly
week_days = loop.with_object([date]) { |_, list|
nd = list.last.next_day
raise StopIteration if nd > date.end_of_week
list << nd
}.map { |date| date.strftime('%Y%m%d') }

{
yyyymmdd: week_days.join(',')
}
else
{
yyyymm: "#{date.year}#{date.month}"
}
end

dojos.each do |dojo|
dojo.dojo_event_services.each do |dojo_event_service|
Expand All @@ -42,12 +60,19 @@ def run(dojos, date)

class Doorkeeper
class << self
def run(dojos, date)
def run(dojos, date, weekly)
drkp = Client::Doorkeeper.new
params = {
since_at: date.beginning_of_month,
until_at: date.end_of_month
}
params = if weekly
{
since_at: date.beginning_of_week,
until_at: date.end_of_week
}
else
{
since_at: date.beginning_of_month,
until_at: date.end_of_month
}
end

dojos.each do |dojo|
dojo.dojo_event_services.each do |dojo_event_service|
Expand All @@ -71,12 +96,19 @@ def run(dojos, date)

class Facebook
class << self
def run(dojos, date)
def run(dojos, date, weekly)
fsbk = Client::Facebook.new
params = {
since_at: date.beginning_of_month,
until_at: date.end_of_month
}
params = if weekly
{
since_at: date.beginning_of_week,
until_at: date.end_of_week
}
else
{
since_at: date.beginning_of_month,
until_at: date.end_of_month
}
end

dojos.each do |dojo|
dojo.dojo_event_services.each do |dojo_event_service|
Expand Down
3 changes: 2 additions & 1 deletion lib/statistics/client.rb
Expand Up @@ -36,13 +36,14 @@ def search(keyword:)
@client.get('event/', { keyword: keyword, count: 100 })
end

def fetch_events(series_id:, yyyymm: nil)
def fetch_events(series_id:, yyyymm: nil, yyyymmdd: nil)
params = {
series_id: series_id,
start: 1,
count: 100
}
params[:ym] = yyyymm if yyyymm
params[:ymd] = yyyymmdd if yyyymmdd
events = []

loop do
Expand Down
65 changes: 49 additions & 16 deletions lib/tasks/statistics.rake
@@ -1,10 +1,10 @@
require_relative '../statistics.rb'

namespace :statistics do
desc '月次のイベント履歴を集計します'
desc '月次/週次のイベント履歴を集計します'
task :aggregation, [:from, :to] => :environment do |tasks, args|
date_from_str = -> (str) {
formats = %w(%Y%m %Y/%m %Y-%m)
formats = %w(%Y%m%d %Y/%m/%d %Y-%m-%d %Y%m %Y/%m %Y-%m)
d = formats.map { |fmt|
begin
Time.zone.strptime(str, fmt)
Expand All @@ -20,42 +20,75 @@ namespace :statistics do
puts `curl --data-urlencode "source=#{msg}" -s #{ENV['IDOBATA_HOOK_URL']} -o /dev/null -w "idobata: %{http_code}"` if ENV.key?('IDOBATA_HOOK_URL')
}

ym_format = -> (date) { date.strftime('%Y/%m') }
ymd_format = -> (date) { date.strftime('%Y/%m/%d') }

montly_aggregation = -> (from, to) {
loop.with_object([from]) { |_, list|
nm = list.last.next_month
raise StopIteration if nm > to
list << nm
}.each { |date|
puts "Aggregate for #{ym_format.call(date)}"
Statistics::Aggregation.run(date: date, weekly: false)
}
}

weekly_aggregation = -> (from, to) {
loop.with_object([from]) { |_, list|
nw = list.last.next_week
raise StopIteration if nw > to
list << nw
}.each { |date|
puts "Aggregate for #{ymd_format.call(date)}~#{ymd_format.call(date.end_of_week)}"
Statistics::Aggregation.run(date: date, weekly: true)
}
}

weekly = true

from = if args[:from]
if args[:from].length == 4
weekly = false
date_from_str.call(args[:from]).beginning_of_year
else
elsif args[:from].length == 6
weekly = false
date_from_str.call(args[:from]).beginning_of_month
else
date_from_str.call(args[:from]).beginning_of_week
end
else
Time.current.prev_month.beginning_of_month
Time.current.prev_week.beginning_of_week
end
to = if args[:to]
if args[:to].length == 4
date_from_str.call(args[:to]).end_of_year
else
elsif args[:to].length == 6
date_from_str.call(args[:to]).end_of_month
else
date_from_str.call(args[:to]).end_of_week
end
else
Time.current.prev_month.end_of_month
Time.current.prev_week.end_of_week
end

Statistics::Client::Facebook.access_token = Koala::Facebook::OAuth.new(ENV['FACEBOOK_APP_ID'], ENV['FACEBOOK_APP_SECRET']).get_app_access_token

EventHistory.where(evented_at: from..to).delete_all

from_str = weekly ? ym_format.call(from) : ymd_format.call(from)
to_str = weekly ? ym_format.call(to) : ymd_format.call(to)

begin
loop.with_object([from]) { |_, list|
nm = list.last.next_month
raise StopIteration if nm > to
list << nm
}.each { |date|
puts "Aggregate for #{date.strftime('%Y/%m')}"
Statistics::Aggregation.run(date: date)
}
if weekly
weekly_aggregation.call(from, to)
else
montly_aggregation.call(from, to)
end

notify_idobata.call("#{from.strftime('%Y/%m')}~#{to.strftime('%Y/%m')}のイベント履歴の集計を行いました")
notify_idobata.call("#{from_str}~#{to_str}のイベント履歴の集計を行いました")
rescue => e
notify_idobata.call("#{from.strftime('%Y/%m')}~#{to.strftime('%Y/%m')}のイベント履歴の集計でエラーが発生しました\n#{e.message}")
notify_idobata.call("#{from_str}~#{to_str}のイベント履歴の集計でエラーが発生しました\n#{e.message}")
raise e
end
end
Expand Down
2 changes: 1 addition & 1 deletion spec/lib/statistics/aggregation_spec.rb
Expand Up @@ -24,7 +24,7 @@
DojoEventService.create(dojo_id: d3.id, name: :facebook, group_id: 123451234512345)
end

subject { Statistics::Aggregation.run(date: Time.current) }
subject { Statistics::Aggregation.run(date: Time.current, weekly: false) }

it do
expect{ subject }.to change{EventHistory.count}.from(0).to(3)
Expand Down