vgcal 0.1.0
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/.github/workflows/ruby.yml +23 -0
- data/.gitignore +10 -0
- data/.rspec +3 -0
- data/.ruby-version +1 -0
- data/Gemfile +7 -0
- data/Gemfile.lock +141 -0
- data/README.md +105 -0
- data/Rakefile +8 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/exe/vgcal +3 -0
- data/images/google-calendar.png +0 -0
- data/lib/vgcal.rb +9 -0
- data/lib/vgcal/google/authorizer.rb +36 -0
- data/lib/vgcal/handlers/describer.rb +111 -0
- data/lib/vgcal/my_calendar.rb +95 -0
- data/lib/vgcal/version.rb +5 -0
- data/template-credentials.json +14 -0
- data/template.env +1 -0
- data/vgcal.gemspec +33 -0
- metadata +162 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 07d0a87b75c94b40ea313deb0529af9b0bc77b18eec1d40b64a4fb8abc03e0de
|
|
4
|
+
data.tar.gz: eb3ce8c7b2d4100b4fe54aba45e6ce719c8401c174673fb1ff7fd9486c92972b
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: a839a9e7ca345f8ea4278bcd516cd8e9f9ef6b7f51bffbfb4dcfea2519f43ada3b334148d7248856a09157f07d641b242eaf4b77bfe33dc3b18b6746ab98a82a
|
|
7
|
+
data.tar.gz: b3541703db6cc78f5ee2c0f65a82974f43887a8125b84951e966644ea098533d69335b89e3edbf698b6747ec9cddd0e4e358c09eb98763a2eb98086e5041777a
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
name: Ruby
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
- push
|
|
5
|
+
- pull_request
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
test:
|
|
9
|
+
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v2
|
|
14
|
+
- name: Set up Ruby
|
|
15
|
+
# To automatically get bug fixes and new Ruby versions for ruby/setup-ruby,
|
|
16
|
+
# change this to (see https://github.com/ruby/setup-ruby#versioning):
|
|
17
|
+
uses: ruby/setup-ruby@v1
|
|
18
|
+
with:
|
|
19
|
+
ruby-version: 3.0
|
|
20
|
+
- name: Install dependencies
|
|
21
|
+
run: bundle install
|
|
22
|
+
- name: Run tests
|
|
23
|
+
run: bundle exec rake spec
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.ruby-version
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.0.1
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
PATH
|
|
2
|
+
remote: .
|
|
3
|
+
specs:
|
|
4
|
+
vgcal (0.1.0)
|
|
5
|
+
dotenv
|
|
6
|
+
google-api-client
|
|
7
|
+
thor (~> 1.1)
|
|
8
|
+
|
|
9
|
+
GEM
|
|
10
|
+
remote: https://rubygems.org/
|
|
11
|
+
specs:
|
|
12
|
+
activesupport (6.1.3.2)
|
|
13
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
14
|
+
i18n (>= 1.6, < 2)
|
|
15
|
+
minitest (>= 5.1)
|
|
16
|
+
tzinfo (~> 2.0)
|
|
17
|
+
zeitwerk (~> 2.3)
|
|
18
|
+
addressable (2.7.0)
|
|
19
|
+
public_suffix (>= 2.0.2, < 5.0)
|
|
20
|
+
ast (2.4.2)
|
|
21
|
+
concurrent-ruby (1.1.9)
|
|
22
|
+
declarative (0.0.20)
|
|
23
|
+
diff-lcs (1.4.4)
|
|
24
|
+
dotenv (2.7.6)
|
|
25
|
+
faraday (1.4.2)
|
|
26
|
+
faraday-em_http (~> 1.0)
|
|
27
|
+
faraday-em_synchrony (~> 1.0)
|
|
28
|
+
faraday-excon (~> 1.1)
|
|
29
|
+
faraday-net_http (~> 1.0)
|
|
30
|
+
faraday-net_http_persistent (~> 1.1)
|
|
31
|
+
multipart-post (>= 1.2, < 3)
|
|
32
|
+
ruby2_keywords (>= 0.0.4)
|
|
33
|
+
faraday-em_http (1.0.0)
|
|
34
|
+
faraday-em_synchrony (1.0.0)
|
|
35
|
+
faraday-excon (1.1.0)
|
|
36
|
+
faraday-net_http (1.0.1)
|
|
37
|
+
faraday-net_http_persistent (1.1.0)
|
|
38
|
+
gems (1.2.0)
|
|
39
|
+
google-api-client (0.53.0)
|
|
40
|
+
google-apis-core (~> 0.1)
|
|
41
|
+
google-apis-generator (~> 0.1)
|
|
42
|
+
google-apis-core (0.3.0)
|
|
43
|
+
addressable (~> 2.5, >= 2.5.1)
|
|
44
|
+
googleauth (~> 0.14)
|
|
45
|
+
httpclient (>= 2.8.1, < 3.0)
|
|
46
|
+
mini_mime (~> 1.0)
|
|
47
|
+
representable (~> 3.0)
|
|
48
|
+
retriable (>= 2.0, < 4.0)
|
|
49
|
+
rexml
|
|
50
|
+
signet (~> 0.14)
|
|
51
|
+
webrick
|
|
52
|
+
google-apis-discovery_v1 (0.4.0)
|
|
53
|
+
google-apis-core (~> 0.1)
|
|
54
|
+
google-apis-generator (0.3.0)
|
|
55
|
+
activesupport (>= 5.0)
|
|
56
|
+
gems (~> 1.2)
|
|
57
|
+
google-apis-core (~> 0.1)
|
|
58
|
+
google-apis-discovery_v1 (~> 0.0)
|
|
59
|
+
thor (>= 0.20, < 2.a)
|
|
60
|
+
googleauth (0.16.2)
|
|
61
|
+
faraday (>= 0.17.3, < 2.0)
|
|
62
|
+
jwt (>= 1.4, < 3.0)
|
|
63
|
+
memoist (~> 0.16)
|
|
64
|
+
multi_json (~> 1.11)
|
|
65
|
+
os (>= 0.9, < 2.0)
|
|
66
|
+
signet (~> 0.14)
|
|
67
|
+
httpclient (2.8.3)
|
|
68
|
+
i18n (1.8.10)
|
|
69
|
+
concurrent-ruby (~> 1.0)
|
|
70
|
+
jwt (2.2.3)
|
|
71
|
+
memoist (0.16.2)
|
|
72
|
+
mini_mime (1.1.0)
|
|
73
|
+
minitest (5.14.4)
|
|
74
|
+
multi_json (1.15.0)
|
|
75
|
+
multipart-post (2.1.1)
|
|
76
|
+
os (1.1.1)
|
|
77
|
+
parallel (1.20.1)
|
|
78
|
+
parser (3.0.2.0)
|
|
79
|
+
ast (~> 2.4.1)
|
|
80
|
+
public_suffix (4.0.6)
|
|
81
|
+
rainbow (3.0.0)
|
|
82
|
+
rake (13.0.3)
|
|
83
|
+
regexp_parser (2.1.1)
|
|
84
|
+
representable (3.1.1)
|
|
85
|
+
declarative (< 0.1.0)
|
|
86
|
+
trailblazer-option (>= 0.1.1, < 0.2.0)
|
|
87
|
+
uber (< 0.2.0)
|
|
88
|
+
retriable (3.1.2)
|
|
89
|
+
rexml (3.2.5)
|
|
90
|
+
rspec (3.10.0)
|
|
91
|
+
rspec-core (~> 3.10.0)
|
|
92
|
+
rspec-expectations (~> 3.10.0)
|
|
93
|
+
rspec-mocks (~> 3.10.0)
|
|
94
|
+
rspec-core (3.10.1)
|
|
95
|
+
rspec-support (~> 3.10.0)
|
|
96
|
+
rspec-expectations (3.10.1)
|
|
97
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
98
|
+
rspec-support (~> 3.10.0)
|
|
99
|
+
rspec-mocks (3.10.2)
|
|
100
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
101
|
+
rspec-support (~> 3.10.0)
|
|
102
|
+
rspec-support (3.10.2)
|
|
103
|
+
rubocop (1.18.4)
|
|
104
|
+
parallel (~> 1.10)
|
|
105
|
+
parser (>= 3.0.0.0)
|
|
106
|
+
rainbow (>= 2.2.2, < 4.0)
|
|
107
|
+
regexp_parser (>= 1.8, < 3.0)
|
|
108
|
+
rexml
|
|
109
|
+
rubocop-ast (>= 1.8.0, < 2.0)
|
|
110
|
+
ruby-progressbar (~> 1.7)
|
|
111
|
+
unicode-display_width (>= 1.4.0, < 3.0)
|
|
112
|
+
rubocop-ast (1.8.0)
|
|
113
|
+
parser (>= 3.0.1.1)
|
|
114
|
+
ruby-progressbar (1.11.0)
|
|
115
|
+
ruby2_keywords (0.0.4)
|
|
116
|
+
signet (0.15.0)
|
|
117
|
+
addressable (~> 2.3)
|
|
118
|
+
faraday (>= 0.17.3, < 2.0)
|
|
119
|
+
jwt (>= 1.5, < 3.0)
|
|
120
|
+
multi_json (~> 1.10)
|
|
121
|
+
thor (1.1.0)
|
|
122
|
+
trailblazer-option (0.1.1)
|
|
123
|
+
tzinfo (2.0.4)
|
|
124
|
+
concurrent-ruby (~> 1.0)
|
|
125
|
+
uber (0.1.0)
|
|
126
|
+
unicode-display_width (2.0.0)
|
|
127
|
+
webrick (1.7.0)
|
|
128
|
+
zeitwerk (2.4.2)
|
|
129
|
+
|
|
130
|
+
PLATFORMS
|
|
131
|
+
x86_64-darwin-19
|
|
132
|
+
|
|
133
|
+
DEPENDENCIES
|
|
134
|
+
bundler (~> 2.2)
|
|
135
|
+
rake (~> 13.0)
|
|
136
|
+
rspec (~> 3.10)
|
|
137
|
+
rubocop
|
|
138
|
+
vgcal!
|
|
139
|
+
|
|
140
|
+
BUNDLED WITH
|
|
141
|
+
2.2.15
|
data/README.md
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+

|
|
2
|
+
|
|
3
|
+
# Vgcal
|
|
4
|
+
|
|
5
|
+
The vgcal command was created to simplify the display of my Google calendar schedules.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```shell
|
|
10
|
+
$ gem install vgcal
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## First run
|
|
14
|
+
|
|
15
|
+
- Setup Google API
|
|
16
|
+
- [Create a project and enable the API](https://developers.google.com/workspace/guides/create-project)
|
|
17
|
+
- [Create credentials](https://developers.google.com/workspace/guides/create-credentials)
|
|
18
|
+
- [When creating an OAuth client ID, the application type will be a desktop application](https://developers.google.com/workspace/guides/create-credentials#desktop)
|
|
19
|
+
- [Enable Google Calendar API](https://console.cloud.google.com/apis/library/calendar-json.googleapis.com)
|
|
20
|
+
|
|
21
|
+
```shell
|
|
22
|
+
$ gem install vgcal
|
|
23
|
+
$ vgcal init
|
|
24
|
+
Fix the __FIX_ME__ in /Users/ito.shota/.vgcal/credentials.json
|
|
25
|
+
$
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Usage
|
|
29
|
+
|
|
30
|
+
```shell
|
|
31
|
+
# help
|
|
32
|
+
$ vgcal
|
|
33
|
+
Commands:
|
|
34
|
+
vgcal help [COMMAND] # Describe available commands or one specific command
|
|
35
|
+
vgcal init # Make directory and template credentials.json for Google authentication
|
|
36
|
+
vgcal show # Show google calendar
|
|
37
|
+
vgcal version # View vgcal version
|
|
38
|
+
$
|
|
39
|
+
$ vgcal help show
|
|
40
|
+
Usage:
|
|
41
|
+
vgcal show
|
|
42
|
+
|
|
43
|
+
Options:
|
|
44
|
+
-d, [--date=DATE] # Show relative date. ex.-1, +10
|
|
45
|
+
-c, [--current-week=CURRENT-WEEK] # Show current week tasks
|
|
46
|
+
-s, [--start-date=N] # Start date. ex.20210701
|
|
47
|
+
-e, [--end-date=N] # End date. ex.20210728
|
|
48
|
+
|
|
49
|
+
Show google calendar
|
|
50
|
+
$
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### example
|
|
54
|
+
|
|
55
|
+

|
|
56
|
+
|
|
57
|
+
```shell
|
|
58
|
+
# Today's schedule
|
|
59
|
+
$ vgcal show
|
|
60
|
+
Period: 2021-07-24T00:00:00+09:00 - 2021-07-24T23:59:59+09:00
|
|
61
|
+
|
|
62
|
+
My tasks: 5.25h(0.66day)
|
|
63
|
+
・all day task 1: all day
|
|
64
|
+
・all day task2: all day
|
|
65
|
+
・meeting1: 2.0h
|
|
66
|
+
・meeting2: 0.25h
|
|
67
|
+
・meeting3: 3.0h
|
|
68
|
+
|
|
69
|
+
Invited meetings: 0h(0day)
|
|
70
|
+
|
|
71
|
+
# This week's schedule (starting on Sunday)
|
|
72
|
+
$ vgcal show -c
|
|
73
|
+
|
|
74
|
+
# Schedule for 5 days ago
|
|
75
|
+
$ vgcal show -d -5
|
|
76
|
+
|
|
77
|
+
# 1 day later
|
|
78
|
+
$ vgcal show -d +1
|
|
79
|
+
|
|
80
|
+
# Schedule for 2021/07/01 - 2021/07/28
|
|
81
|
+
$ vgcal show -s 20210701 -e 20210728
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Development
|
|
85
|
+
|
|
86
|
+
```shell
|
|
87
|
+
$ git clone git@github.com:st1t/vgcal.git
|
|
88
|
+
$ cd vgcal/
|
|
89
|
+
$ bundle install
|
|
90
|
+
$ bundle exec ruby exe/vgcal show -d -5
|
|
91
|
+
$ rake spec
|
|
92
|
+
|
|
93
|
+
Vgcal
|
|
94
|
+
has a version number
|
|
95
|
+
|
|
96
|
+
Vgcal::MyCalendar
|
|
97
|
+
my_task
|
|
98
|
+
my_task_hidden
|
|
99
|
+
invitation_task
|
|
100
|
+
|
|
101
|
+
Finished in 0.01492 seconds (files took 0.75345 seconds to load)
|
|
102
|
+
4 examples, 0 failures
|
|
103
|
+
|
|
104
|
+
$
|
|
105
|
+
```
|
data/Rakefile
ADDED
data/bin/console
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require "bundler/setup"
|
|
5
|
+
require "vgcal"
|
|
6
|
+
|
|
7
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
|
8
|
+
# with your gem easier. You can also use a different console, if you like.
|
|
9
|
+
|
|
10
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
|
11
|
+
# require "pry"
|
|
12
|
+
# Pry.start
|
|
13
|
+
|
|
14
|
+
require "irb"
|
|
15
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
data/exe/vgcal
ADDED
|
Binary file
|
data/lib/vgcal.rb
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'googleauth'
|
|
4
|
+
require 'googleauth/stores/file_token_store'
|
|
5
|
+
require 'google/apis/calendar_v3'
|
|
6
|
+
require 'fileutils'
|
|
7
|
+
|
|
8
|
+
module Vgcal
|
|
9
|
+
# for Google authorization
|
|
10
|
+
class Authorizer
|
|
11
|
+
def initialize
|
|
12
|
+
@oob_uri = 'urn:ietf:wg:oauth:2.0:oob'
|
|
13
|
+
@credentials_path = "#{Dir.home}/.vgcal/credentials.json"
|
|
14
|
+
@token_path = "#{Dir.home}/.vgcal/token.yaml"
|
|
15
|
+
@scope = Google::Apis::CalendarV3::AUTH_CALENDAR_READONLY
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def credentials
|
|
19
|
+
client_id = Google::Auth::ClientId.from_file @credentials_path
|
|
20
|
+
token_store = Google::Auth::Stores::FileTokenStore.new file: @token_path
|
|
21
|
+
authorizer = Google::Auth::UserAuthorizer.new client_id, @scope, token_store
|
|
22
|
+
user_id = 'default'
|
|
23
|
+
credentials = authorizer.get_credentials user_id
|
|
24
|
+
if credentials.nil?
|
|
25
|
+
url = authorizer.get_authorization_url base_url: @oob_uri
|
|
26
|
+
puts 'Open the following URL in the browser and enter the ' \
|
|
27
|
+
"resulting code after authorization:\n" + url
|
|
28
|
+
code = $stdin.gets
|
|
29
|
+
credentials = authorizer.get_and_store_credentials_from_code(
|
|
30
|
+
user_id: user_id, code: code, base_url: @oob_uri
|
|
31
|
+
)
|
|
32
|
+
end
|
|
33
|
+
credentials
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'thor'
|
|
4
|
+
require 'vgcal/my_calendar'
|
|
5
|
+
require 'fileutils'
|
|
6
|
+
|
|
7
|
+
module Vgcal
|
|
8
|
+
module Handlers
|
|
9
|
+
# Describer
|
|
10
|
+
class Describer < Thor
|
|
11
|
+
desc 'init', 'Make directory and template credentials.json for Google authentication'
|
|
12
|
+
|
|
13
|
+
def init
|
|
14
|
+
vgcal_dir = "#{Dir.home}/.vgcal"
|
|
15
|
+
cred_json = "#{vgcal_dir}/credentials.json"
|
|
16
|
+
dot_env = "#{vgcal_dir}/.env"
|
|
17
|
+
Dir.mkdir(vgcal_dir, 0o755) unless Dir.exist?(vgcal_dir)
|
|
18
|
+
FileUtils.cp('template-credentials.json', cred_json) unless File.exist?(cred_json)
|
|
19
|
+
FileUtils.cp('template.env', dot_env) unless File.exist?(dot_env)
|
|
20
|
+
puts "Fix the __FIX_ME__ in #{cred_json} and #{dot_env}"
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
option :date, type: :string, aliases: '-d', desc: 'Show relative date. ex.-1, +10'
|
|
24
|
+
option :'current-week', type: :string, aliases: '-c', desc: 'Show current week tasks'
|
|
25
|
+
option :'start-date', type: :numeric, aliases: '-s', desc: 'Start date. ex.20210701'
|
|
26
|
+
option :'end-date', type: :numeric, aliases: '-e', desc: 'End date. ex.20210728'
|
|
27
|
+
|
|
28
|
+
desc 'show', 'Show google calendar'
|
|
29
|
+
|
|
30
|
+
def show
|
|
31
|
+
Dotenv.load("#{Dir.home}/.vgcal/.env")
|
|
32
|
+
puts "Period: #{start_date} - #{end_date}"
|
|
33
|
+
puts
|
|
34
|
+
mcal = MyCalendar.new(start_date, end_date)
|
|
35
|
+
events = mcal.events
|
|
36
|
+
tasks = mcal.tasks(events)
|
|
37
|
+
puts "My tasks: #{tasks[0]}h(#{(tasks[0] / 8).round(2)}day)"
|
|
38
|
+
tasks[1].each do |task|
|
|
39
|
+
if task[1].is_a?(String)
|
|
40
|
+
puts " ・#{task[0]}: #{task[1]}"
|
|
41
|
+
else
|
|
42
|
+
puts " ・#{task[0]}: #{task[1]}h"
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
meetings = mcal.invited_meetings(events)
|
|
46
|
+
puts "Invited meetings: #{meetings[0]}h(#{(meetings[0] / 8).round(2)}day)"
|
|
47
|
+
meetings[1].each do |meeting|
|
|
48
|
+
puts " ・#{meeting[0]}: #{meeting[1]}h"
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
desc 'version', 'View vgcal version'
|
|
53
|
+
|
|
54
|
+
def version
|
|
55
|
+
puts VERSION
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
private
|
|
59
|
+
|
|
60
|
+
def start_date
|
|
61
|
+
s_date = if options[:'current-week']
|
|
62
|
+
if Date.today.sunday?
|
|
63
|
+
Date.today.to_s
|
|
64
|
+
else
|
|
65
|
+
(Date.today - Date.today.wday - 1).to_s
|
|
66
|
+
end
|
|
67
|
+
elsif options[:date]
|
|
68
|
+
case options[:date][0]
|
|
69
|
+
when '+'
|
|
70
|
+
(Date.today + options[:date].delete('+').to_i).to_s
|
|
71
|
+
when '-'
|
|
72
|
+
(Date.today - options[:date].delete('-').to_i).to_s
|
|
73
|
+
else
|
|
74
|
+
(Date.today + options[:date].to_i).to_s
|
|
75
|
+
end
|
|
76
|
+
elsif options['start-date'] && options['end-date']
|
|
77
|
+
Date.parse(options['start-date']).to_s
|
|
78
|
+
else
|
|
79
|
+
Date.today.to_s
|
|
80
|
+
end
|
|
81
|
+
"#{s_date}T00:00:00+09:00"
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def end_date
|
|
85
|
+
e_date = if options[:'current-week']
|
|
86
|
+
if Date.today.sunday?
|
|
87
|
+
(Date.today + 6).to_s
|
|
88
|
+
else
|
|
89
|
+
(Date.today + (6 - Date.today.wday)).to_s
|
|
90
|
+
end
|
|
91
|
+
elsif options[:date]
|
|
92
|
+
case options[:date][0]
|
|
93
|
+
when '+'
|
|
94
|
+
(Date.today + options[:date].delete('+').to_i).to_s
|
|
95
|
+
when '-'
|
|
96
|
+
(Date.today - options[:date].delete('-').to_i).to_s
|
|
97
|
+
else
|
|
98
|
+
(Date.today + options[:date].to_i).to_s
|
|
99
|
+
end
|
|
100
|
+
elsif options['start-date'] && options['end-date']
|
|
101
|
+
Date.parse(options['end-date']).to_s
|
|
102
|
+
else
|
|
103
|
+
Date.today.to_s
|
|
104
|
+
end
|
|
105
|
+
"#{e_date}T23:59:59+09:00"
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
Vgcal::Handlers::Describer.start(ARGV)
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'vgcal/google/authorizer'
|
|
4
|
+
require 'dotenv'
|
|
5
|
+
|
|
6
|
+
# MyCalendar
|
|
7
|
+
module Vgcal
|
|
8
|
+
class MyCalendar
|
|
9
|
+
def initialize(start_date, end_date)
|
|
10
|
+
@start_date = start_date
|
|
11
|
+
@end_date = end_date
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def events
|
|
15
|
+
service = Google::Apis::CalendarV3::CalendarService.new
|
|
16
|
+
service.authorization = Vgcal::Authorizer.new.credentials
|
|
17
|
+
calendar_id = 'primary'
|
|
18
|
+
service.list_events(calendar_id,
|
|
19
|
+
max_results: 100,
|
|
20
|
+
single_events: true,
|
|
21
|
+
order_by: 'startTime',
|
|
22
|
+
time_min: @start_date,
|
|
23
|
+
time_max: @end_date)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# return: [4.25, [["daily scrum", 0.25], ["SRE定例", 1.0], ["test", 2.0], ["task2", 1.0]]]
|
|
27
|
+
def tasks(events)
|
|
28
|
+
total_meeting_times = 0
|
|
29
|
+
tasks_hash = {}
|
|
30
|
+
events.items.each do |e|
|
|
31
|
+
if e.organizer.email.include?(my_email_address) && !e.summary.start_with?(*hide_words)
|
|
32
|
+
if all_day_event?(e.start.date)
|
|
33
|
+
tasks_hash[e.summary] = 'all day'
|
|
34
|
+
else
|
|
35
|
+
task_time = (e.end.date_time - e.start.date_time).to_f * 24
|
|
36
|
+
# 1日の中で同じタスク名が複数あったら時間を集計する。例.午前と午後それぞれでAプロジェクトに1時間スケジュール
|
|
37
|
+
if tasks_hash[e.summary]
|
|
38
|
+
tasks_hash[e.summary] += task_time
|
|
39
|
+
else
|
|
40
|
+
tasks_hash[e.summary] = task_time
|
|
41
|
+
end
|
|
42
|
+
total_meeting_times = 0
|
|
43
|
+
tasks_hash.each do |h|
|
|
44
|
+
total_meeting_times += h.to_ary[1] unless h.to_ary[1].is_a?(String)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
[total_meeting_times, tasks_hash.sort.to_a]
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# return: [2.25, [["朝会", 0.5], ["daily scrum", 0.25], ["SRE朝会", 0.5], ["定例", 1.0]]]
|
|
53
|
+
def invited_meetings(events)
|
|
54
|
+
total_meeting_times = 0
|
|
55
|
+
tasks_hash = {}
|
|
56
|
+
events.items.each do |e|
|
|
57
|
+
next if e.organizer.email.include?(my_email_address) || e.summary.start_with?(*hide_words)
|
|
58
|
+
|
|
59
|
+
# 単一のカレンダー内から自分が出席返答したイベントを探して計算
|
|
60
|
+
e.attendees.each do |a|
|
|
61
|
+
# next unless a.email == my_email_address && (a.email != my_email_address && a.response_status == 'accepted')
|
|
62
|
+
next if a.email != my_email_address || (a.email == my_email_address && a.response_status != 'accepted')
|
|
63
|
+
|
|
64
|
+
task_time = (e.end.date_time - e.start.date_time).to_f * 24
|
|
65
|
+
if tasks_hash[e.summary]
|
|
66
|
+
tasks_hash[e.summary] += task_time
|
|
67
|
+
else
|
|
68
|
+
tasks_hash[e.summary] = task_time
|
|
69
|
+
end
|
|
70
|
+
total_meeting_times = 0
|
|
71
|
+
tasks_hash.each do |h|
|
|
72
|
+
total_meeting_times += h.to_ary[1]
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
[total_meeting_times, tasks_hash.sort.to_a]
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
private
|
|
80
|
+
|
|
81
|
+
def my_email_address
|
|
82
|
+
ENV['MY_EMAIL_ADDRESS']
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def hide_words
|
|
86
|
+
['__']
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def all_day_event?(date)
|
|
90
|
+
# The date, in the format "yyyy-mm-dd", if this is an all-day event.
|
|
91
|
+
# https://developers.google.com/calendar/api/v3/reference/events
|
|
92
|
+
!!/[0-9]...-[0-9].-[0-9]./.match(date.to_s)
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"installed": {
|
|
3
|
+
"client_id": "__FIX_ME__.apps.googleusercontent.com",
|
|
4
|
+
"project_id": "__FIX_ME__",
|
|
5
|
+
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
|
|
6
|
+
"token_uri": "https://oauth2.googleapis.com/token",
|
|
7
|
+
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
|
|
8
|
+
"client_secret": "__FIX_ME__",
|
|
9
|
+
"redirect_uris": [
|
|
10
|
+
"urn:ietf:wg:oauth:2.0:oob",
|
|
11
|
+
"http://localhost"
|
|
12
|
+
]
|
|
13
|
+
}
|
|
14
|
+
}
|
data/template.env
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
MY_EMAIL_ADDRESS=__FIX__ME__
|
data/vgcal.gemspec
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
lib = File.expand_path("../lib", __FILE__)
|
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
5
|
+
require "vgcal/version"
|
|
6
|
+
|
|
7
|
+
Gem::Specification.new do |spec|
|
|
8
|
+
spec.name = "vgcal"
|
|
9
|
+
spec.version = Vgcal::VERSION
|
|
10
|
+
spec.authors = ["Shota Ito"]
|
|
11
|
+
spec.email = ["shota.ito.jp@gmail.com"]
|
|
12
|
+
|
|
13
|
+
spec.summary = "%q{The vgcal command simplifies the display of Google Calendar events.}"
|
|
14
|
+
spec.description = "%q{The vgcal command simplifies the display of Google Calendar events.}"
|
|
15
|
+
spec.homepage = "https://github.com/st1t/vgcal"
|
|
16
|
+
spec.license = "MIT"
|
|
17
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 3.0.1")
|
|
18
|
+
|
|
19
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
|
20
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features)/}) }
|
|
21
|
+
end
|
|
22
|
+
spec.bindir = "exe"
|
|
23
|
+
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
|
24
|
+
spec.require_paths = ["lib"]
|
|
25
|
+
|
|
26
|
+
spec.add_development_dependency "bundler", "~> 2.2"
|
|
27
|
+
spec.add_development_dependency "rake", "~> 13.0"
|
|
28
|
+
spec.add_development_dependency "rspec", "~> 3.10"
|
|
29
|
+
spec.add_development_dependency "rubocop"
|
|
30
|
+
spec.add_runtime_dependency "thor", "~> 1.1"
|
|
31
|
+
spec.add_runtime_dependency "google-api-client"
|
|
32
|
+
spec.add_runtime_dependency "dotenv"
|
|
33
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: vgcal
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Shota Ito
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: exe
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2021-07-25 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: bundler
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '2.2'
|
|
20
|
+
type: :development
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '2.2'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: rake
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - "~>"
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '13.0'
|
|
34
|
+
type: :development
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - "~>"
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '13.0'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: rspec
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - "~>"
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '3.10'
|
|
48
|
+
type: :development
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - "~>"
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '3.10'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: rubocop
|
|
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: thor
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - "~>"
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: '1.1'
|
|
76
|
+
type: :runtime
|
|
77
|
+
prerelease: false
|
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - "~>"
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: '1.1'
|
|
83
|
+
- !ruby/object:Gem::Dependency
|
|
84
|
+
name: google-api-client
|
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
|
86
|
+
requirements:
|
|
87
|
+
- - ">="
|
|
88
|
+
- !ruby/object:Gem::Version
|
|
89
|
+
version: '0'
|
|
90
|
+
type: :runtime
|
|
91
|
+
prerelease: false
|
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
+
requirements:
|
|
94
|
+
- - ">="
|
|
95
|
+
- !ruby/object:Gem::Version
|
|
96
|
+
version: '0'
|
|
97
|
+
- !ruby/object:Gem::Dependency
|
|
98
|
+
name: dotenv
|
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
|
100
|
+
requirements:
|
|
101
|
+
- - ">="
|
|
102
|
+
- !ruby/object:Gem::Version
|
|
103
|
+
version: '0'
|
|
104
|
+
type: :runtime
|
|
105
|
+
prerelease: false
|
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
107
|
+
requirements:
|
|
108
|
+
- - ">="
|
|
109
|
+
- !ruby/object:Gem::Version
|
|
110
|
+
version: '0'
|
|
111
|
+
description: "%q{The vgcal command simplifies the display of Google Calendar events.}"
|
|
112
|
+
email:
|
|
113
|
+
- shota.ito.jp@gmail.com
|
|
114
|
+
executables:
|
|
115
|
+
- vgcal
|
|
116
|
+
extensions: []
|
|
117
|
+
extra_rdoc_files: []
|
|
118
|
+
files:
|
|
119
|
+
- ".github/workflows/ruby.yml"
|
|
120
|
+
- ".gitignore"
|
|
121
|
+
- ".rspec"
|
|
122
|
+
- ".ruby-version"
|
|
123
|
+
- Gemfile
|
|
124
|
+
- Gemfile.lock
|
|
125
|
+
- README.md
|
|
126
|
+
- Rakefile
|
|
127
|
+
- bin/console
|
|
128
|
+
- bin/setup
|
|
129
|
+
- exe/vgcal
|
|
130
|
+
- images/google-calendar.png
|
|
131
|
+
- lib/vgcal.rb
|
|
132
|
+
- lib/vgcal/google/authorizer.rb
|
|
133
|
+
- lib/vgcal/handlers/describer.rb
|
|
134
|
+
- lib/vgcal/my_calendar.rb
|
|
135
|
+
- lib/vgcal/version.rb
|
|
136
|
+
- template-credentials.json
|
|
137
|
+
- template.env
|
|
138
|
+
- vgcal.gemspec
|
|
139
|
+
homepage: https://github.com/st1t/vgcal
|
|
140
|
+
licenses:
|
|
141
|
+
- MIT
|
|
142
|
+
metadata: {}
|
|
143
|
+
post_install_message:
|
|
144
|
+
rdoc_options: []
|
|
145
|
+
require_paths:
|
|
146
|
+
- lib
|
|
147
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
148
|
+
requirements:
|
|
149
|
+
- - ">="
|
|
150
|
+
- !ruby/object:Gem::Version
|
|
151
|
+
version: 3.0.1
|
|
152
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
153
|
+
requirements:
|
|
154
|
+
- - ">="
|
|
155
|
+
- !ruby/object:Gem::Version
|
|
156
|
+
version: '0'
|
|
157
|
+
requirements: []
|
|
158
|
+
rubygems_version: 3.2.15
|
|
159
|
+
signing_key:
|
|
160
|
+
specification_version: 4
|
|
161
|
+
summary: "%q{The vgcal command simplifies the display of Google Calendar events.}"
|
|
162
|
+
test_files: []
|