flycal-cli 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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 8efca78d1d82f9e3310cbd90a29a95ad52fbf9fff714d3aada8321c999bfaa71
4
+ data.tar.gz: 749f5417dfd3cc780c78e55524aa0acabea9b8fc28f07614d8faa25e7920253b
5
+ SHA512:
6
+ metadata.gz: be1d24bae7776ca94842c9edd5116544b750846ccc169bd57ba6720dc1b63904eaad92fb2f33ace8f668a8580352ea2ff530532c5262bbc83d44f4f92521b324
7
+ data.tar.gz: 2d89f80c2b486f102b8ad6edf178dd71126fd78549a49caecc17a5bc0254827f2d0ed07cb727e2cbc18c0b3bf19cc64bbca04846f8a72a00b82d7cb77495273c
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 flycal-cli
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,139 @@
1
+ # flycal-cli
2
+
3
+ CLI per accedere ai calendari Google da riga di comando.
4
+
5
+ ## Installazione
6
+
7
+ ```bash
8
+ gem install flycal-cli
9
+ ```
10
+
11
+ Oppure aggiungi al tuo Gemfile:
12
+
13
+ ```ruby
14
+ gem "flycal-cli"
15
+ ```
16
+
17
+ ## Configurazione iniziale
18
+
19
+ Prima di usare flycal, devi creare credenziali OAuth nel Google Cloud Console:
20
+
21
+ 1. Vai su [Google Cloud Console - Credenziali](https://console.cloud.google.com/apis/credentials)
22
+ 2. Crea un progetto (o usa uno esistente)
23
+ 3. Abilita l'**API Google Calendar** (API e servizi → Libreria → Cerca "Google Calendar API")
24
+ 4. Crea credenziali **Applicazione desktop** (OAuth 2.0 Client IDs)
25
+ 5. Aggiungi questo URI come redirect autorizzato:
26
+ ```
27
+ http://127.0.0.1:9292/oauth2callback
28
+ ```
29
+ 6. Scarica il file JSON e salvalo come `~/.flycal/credentials.json`
30
+
31
+ ## Comandi
32
+
33
+ ### `flycal login`
34
+
35
+ Connetti al tuo account Google. Se non sei connesso, verrà generato un link da aprire nel browser per completare l'autenticazione OAuth.
36
+
37
+ ```bash
38
+ flycal login
39
+ ```
40
+
41
+ ### `flycal calendars`
42
+
43
+ Mostra la lista dei calendari disponibili e permette di selezionare il calendario di default. La selezione è scorrevole (usa le frecce per navigare).
44
+
45
+ ```bash
46
+ flycal calendars
47
+ ```
48
+
49
+ ### `flycal logout`
50
+
51
+ Disconnetti dall'account Google.
52
+
53
+ ```bash
54
+ flycal logout
55
+ ```
56
+
57
+ ### `flycal search`
58
+
59
+ Cerca eventi nei calendari.
60
+
61
+ ```bash
62
+ flycal search --from 2025-02-01 --to 2025-02-28
63
+ flycal search -f 2025-02-01 -t 2025-02-28 --description "riunione"
64
+ flycal search -f 2025-02-01T09:00 -t 2025-02-28T18:00 -c "Lavoro"
65
+ ```
66
+
67
+ Opzioni:
68
+ - `-f, --from`: Data/ora inizio (es. `2025-01-01` o `2025-01-01T09:00`)
69
+ - `-t, --to`: Data/ora fine
70
+ - `-c, --calendar`: Nome o ID del calendario (default: calendario impostato con `flycal calendars`)
71
+ - `-d, --description`: Filtra eventi per testo nella descrizione
72
+
73
+ ## File di configurazione
74
+
75
+ I dati vengono salvati in `~/.flycal/`:
76
+
77
+ - `config.yml` - calendario di default (`calendar_default`)
78
+ - `credentials.json` - credenziali OAuth (da creare manualmente)
79
+ - `tokens.yml` - token di accesso (gestito automaticamente)
80
+
81
+ ## Pubblicazione su RubyGems
82
+
83
+ ### Primo caricamento
84
+
85
+ 1. Crea un account su [rubygems.org](https://rubygems.org) se non ce l'hai
86
+ 2. Aggiorna `flycal-cli.gemspec` con i tuoi dati (autori, email, homepage)
87
+ 3. Build e push:
88
+
89
+ ```bash
90
+ # Build della gem
91
+ gem build flycal-cli.gemspec
92
+
93
+ # Push (ti chiederà email e password RubyGems)
94
+ gem push flycal-cli-0.1.0.gem
95
+ ```
96
+
97
+ ### Versioni successive
98
+
99
+ 1. Aggiorna la versione in `lib/flycal_cli/version.rb`
100
+ 2. Commit e tag:
101
+
102
+ ```bash
103
+ git add .
104
+ git commit -m "Release v0.2.0"
105
+ git tag v0.2.0
106
+ git push origin main
107
+ git push origin v0.2.0
108
+ ```
109
+
110
+ 3. Build e push:
111
+
112
+ ```bash
113
+ gem build flycal-cli.gemspec
114
+ gem push flycal-cli-0.2.0.gem
115
+ ```
116
+
117
+ ### Usando `rake release` (raccomandato)
118
+
119
+ Aggiungi al Rakefile:
120
+
121
+ ```ruby
122
+ require "bundler/gem_tasks"
123
+ ```
124
+
125
+ Poi:
126
+
127
+ ```bash
128
+ # Per la prima release
129
+ bundle exec rake release
130
+
131
+ # Per release successive: aggiorna VERSION e poi
132
+ bundle exec rake release
133
+ ```
134
+
135
+ `rake release` esegue: build, push su RubyGems, commit, tag e push su git.
136
+
137
+ ## Licenza
138
+
139
+ MIT
data/exe/flycal ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "flycal_cli"
5
+
6
+ FlycalCli::Cli.start(ARGV)
@@ -0,0 +1,132 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "webrick"
4
+ require "googleauth"
5
+ require "googleauth/stores/file_token_store"
6
+ require "fileutils"
7
+
8
+ module FlycalCli
9
+ class Auth
10
+ SCOPE = "https://www.googleapis.com/auth/calendar.readonly"
11
+ REDIRECT_PORT = 9292
12
+ REDIRECT_URI = "http://127.0.0.1:#{REDIRECT_PORT}/oauth2callback"
13
+
14
+ class << self
15
+ def credentials
16
+ return nil unless Config.credentials_exist?
17
+
18
+ token_store = Google::Auth::Stores::FileTokenStore.new(file: Config.tokens_path)
19
+ client_id = Google::Auth::ClientId.from_file(Config.credentials_path)
20
+ authorizer = Google::Auth::UserAuthorizer.new(
21
+ client_id,
22
+ SCOPE,
23
+ token_store,
24
+ "/oauth2callback"
25
+ )
26
+
27
+ creds = authorizer.get_credentials("flycal_user")
28
+ return creds if creds
29
+
30
+ nil
31
+ end
32
+
33
+ def logged_in?
34
+ creds = credentials
35
+ return false unless creds
36
+
37
+ creds.fetch_access_token!
38
+ true
39
+ rescue Signet::AuthorizationError
40
+ false
41
+ end
42
+
43
+ def login
44
+ unless Config.credentials_exist?
45
+ raise FlycalCli::Error,
46
+ "File credentials non trovato. Crea #{Config.credentials_path} con le credenziali OAuth dal Google Cloud Console.\n" \
47
+ "Vai su: https://console.cloud.google.com/apis/credentials\n" \
48
+ "Crea credenziali 'Desktop app' e scarica il JSON come credentials.json"
49
+ end
50
+
51
+ token_store = Google::Auth::Stores::FileTokenStore.new(file: Config.tokens_path)
52
+ client_id = Google::Auth::ClientId.from_file(Config.credentials_path)
53
+ authorizer = Google::Auth::UserAuthorizer.new(
54
+ client_id,
55
+ SCOPE,
56
+ token_store,
57
+ "/oauth2callback"
58
+ )
59
+
60
+ creds = authorizer.get_credentials("flycal_user")
61
+ if creds
62
+ creds.fetch_access_token!
63
+ return creds
64
+ end
65
+
66
+ # Avvia server locale per ricevere il codice
67
+ code = start_redirect_server(authorizer)
68
+ raise FlycalCli::Error, "Autenticazione annullata o fallita" if code.nil? || code.empty?
69
+
70
+ authorizer.get_and_store_credentials_from_code(
71
+ user_id: "flycal_user",
72
+ code: code,
73
+ base_url: "http://127.0.0.1:#{REDIRECT_PORT}"
74
+ )
75
+ end
76
+
77
+ def logout
78
+ return true unless File.exist?(Config.tokens_path)
79
+
80
+ token_store = Google::Auth::Stores::FileTokenStore.new(file: Config.tokens_path)
81
+ token_store.delete("flycal_user")
82
+ File.delete(Config.tokens_path) if File.exist?(Config.tokens_path)
83
+ true
84
+ end
85
+
86
+ private
87
+
88
+ def start_redirect_server(authorizer)
89
+ auth_code = nil
90
+ state = SecureRandom.hex(16)
91
+ code_verifier = Google::Auth::UserAuthorizer.generate_code_verifier
92
+ authorizer.code_verifier = code_verifier
93
+
94
+ server = WEBrick::HTTPServer.new(
95
+ Port: REDIRECT_PORT,
96
+ BindAddress: "127.0.0.1",
97
+ Logger: WEBrick::Log.new($stderr, WEBrick::Log::FATAL),
98
+ AccessLog: []
99
+ )
100
+
101
+ server.mount_proc("/oauth2callback") do |req, res|
102
+ query = req.request_uri.query
103
+ params = query ? URI.decode_www_form(query).to_h : {}
104
+
105
+ if params["error"]
106
+ res.status = 400
107
+ res.body = "<h1>Errore</h1><p>#{params['error']}: #{params['error_description']}</p>"
108
+ auth_code = nil
109
+ elsif params["code"]
110
+ auth_code = params["code"]
111
+ res.status = 200
112
+ res.body = "<h1>Autenticazione completata!</h1><p>Puoi chiudere questa finestra e tornare al terminale.</p>"
113
+ end
114
+
115
+ Thread.new { server.shutdown }
116
+ end
117
+
118
+ url = authorizer.get_authorization_url(
119
+ base_url: REDIRECT_URI.sub("/oauth2callback", ""),
120
+ state: state
121
+ )
122
+
123
+ puts "\nApri questo link nel browser per autenticarti:\n\n"
124
+ puts " #{url}\n\n"
125
+ puts "Dopo l'autenticazione, tornerai qui automaticamente.\n\n"
126
+
127
+ server.start
128
+ auth_code
129
+ end
130
+ end
131
+ end
132
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "google/apis/calendar_v3"
4
+
5
+ module FlycalCli
6
+ class CalendarService
7
+ def initialize(credentials)
8
+ @service = Google::Apis::CalendarV3::CalendarService.new
9
+ @service.authorization = credentials
10
+ end
11
+
12
+ def list_calendars
13
+ result = @service.list_calendar_lists
14
+ result.items || []
15
+ end
16
+
17
+ def get_calendar(calendar_id)
18
+ @service.get_calendar(calendar_id)
19
+ end
20
+
21
+ def list_events(calendar_id, time_min:, time_max:, query: nil)
22
+ events = []
23
+ page_token = nil
24
+
25
+ loop do
26
+ result = @service.list_events(
27
+ calendar_id,
28
+ time_min: time_min.iso8601,
29
+ time_max: time_max.iso8601,
30
+ q: query,
31
+ single_events: true,
32
+ order_by: "startTime",
33
+ page_token: page_token
34
+ )
35
+
36
+ events.concat(result.items || [])
37
+
38
+ page_token = result.next_page_token
39
+ break if page_token.nil? || page_token.empty?
40
+ end
41
+
42
+ events
43
+ end
44
+
45
+ def list_all_events(calendar_ids, time_min:, time_max:, query: nil)
46
+ all_events = []
47
+
48
+ calendar_ids.each do |cal_id|
49
+ begin
50
+ events = list_events(cal_id, time_min: time_min, time_max: time_max, query: query)
51
+ events.each { |e| all_events << { calendar_id: cal_id, event: e } }
52
+ rescue Google::Apis::Errors::Error => e
53
+ warn "Errore nel calendario #{cal_id}: #{e.message}"
54
+ end
55
+ end
56
+
57
+ all_events
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,236 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "thor"
4
+ require "time"
5
+ require "tty-prompt"
6
+ require "tty-spinner"
7
+
8
+ module FlycalCli
9
+ class Cli < Thor
10
+ package_name "flycal"
11
+
12
+ def self.exit_on_failure?
13
+ true
14
+ end
15
+
16
+ desc "login", "Connetti al tuo account Google"
17
+ def login
18
+ if Auth.logged_in?
19
+ puts "✓ Sei già connesso al tuo account Google."
20
+ puts "\nEsegui 'flycal calendars' per impostare il calendario di default."
21
+ return
22
+ end
23
+
24
+ unless Config.credentials_exist?
25
+ puts "Errore: File credentials non trovato."
26
+ puts "\nPer configurare flycal:"
27
+ puts "1. Vai su https://console.cloud.google.com/apis/credentials"
28
+ puts "2. Crea credenziali 'Applicazione desktop' (Desktop app)"
29
+ puts "3. Scarica il JSON e salvalo come: #{Config.credentials_path}"
30
+ puts "\nAggiungi anche questo URI come redirect autorizzato:"
31
+ puts " http://127.0.0.1:9292/oauth2callback"
32
+ return
33
+ end
34
+
35
+ begin
36
+ Auth.login
37
+ puts "\n✓ Autenticazione completata con successo!"
38
+ puts "\nEsegui 'flycal calendars' per impostare il calendario di default."
39
+ rescue FlycalCli::Error => e
40
+ puts "Errore: #{e.message}"
41
+ exit 1
42
+ end
43
+ end
44
+
45
+ desc "logout", "Disconnetti dall'account Google"
46
+ def logout
47
+ unless Auth.logged_in?
48
+ puts "Non sei connesso a nessun account Google."
49
+ return
50
+ end
51
+
52
+ Auth.logout
53
+ puts "✓ Disconnesso con successo."
54
+ end
55
+
56
+ desc "calendars", "Mostra i calendari disponibili e imposta quello di default"
57
+ def calendars
58
+ unless Auth.logged_in?
59
+ puts "Non sei connesso. Esegui prima 'flycal login'."
60
+ exit 1
61
+ end
62
+
63
+ creds = Auth.credentials
64
+ service = CalendarService.new(creds)
65
+
66
+ spinner = TTY::Spinner.new("Caricamento calendari... ", format: :dots)
67
+ spinner.auto_spin
68
+ calendars = service.list_calendars
69
+ spinner.stop("✓")
70
+
71
+ if calendars.empty?
72
+ puts "Nessun calendario trovato."
73
+ return
74
+ end
75
+
76
+ # Costruisci lista per selezione (display => calendar_id)
77
+ default_id = Config.calendar_default
78
+ choices = calendars.to_h do |cal|
79
+ primary = cal.primary ? " (principale)" : ""
80
+ default = (cal.id == default_id) ? " [default]" : ""
81
+ summary = cal.summary || cal.id
82
+ label = "#{summary}#{primary}#{default}"
83
+ [label, cal.id]
84
+ end
85
+
86
+ prompt = TTY::Prompt.new
87
+ selected_id = prompt.select(
88
+ "Scegli il calendario di default:",
89
+ choices,
90
+ per_page: 15,
91
+ filter: true
92
+ )
93
+
94
+ calendar = calendars.find { |c| c.id == selected_id }
95
+ if calendar
96
+ Config.calendar_default = calendar.id
97
+ puts "\n✓ Calendario di default impostato: #{calendar.summary}"
98
+ end
99
+ end
100
+
101
+ desc "search", "Cerca eventi nei calendari"
102
+ option :calendar, type: :string, aliases: "-c", desc: "Nome o ID del calendario (default: calendario default)"
103
+ option :from, type: :string, aliases: "-f", required: true, desc: "Data/ora inizio (es. 2025-01-01 o 2025-01-01T09:00)"
104
+ option :to, type: :string, aliases: "-t", required: true, desc: "Data/ora fine (es. 2025-01-31 o 2025-01-31T18:00)"
105
+ option :description, type: :string, aliases: "-d", desc: "Filtra per descrizione (testo)"
106
+ def search
107
+ unless Auth.logged_in?
108
+ puts "Non sei connesso. Esegui prima 'flycal login'."
109
+ exit 1
110
+ end
111
+
112
+ time_min = parse_datetime(options[:from])
113
+ time_max = parse_datetime(options[:to], end_of_day: true)
114
+
115
+ if time_min > time_max
116
+ puts "Errore: la data 'from' deve essere prima della data 'to'."
117
+ exit 1
118
+ end
119
+
120
+ creds = Auth.credentials
121
+ service = CalendarService.new(creds)
122
+
123
+ calendar_ids = resolve_calendar_ids(service, options[:calendar])
124
+ if calendar_ids.empty?
125
+ puts "Nessun calendario trovato."
126
+ exit 1
127
+ end
128
+
129
+ events = service.list_all_events(
130
+ calendar_ids,
131
+ time_min: time_min,
132
+ time_max: time_max,
133
+ query: options[:description]
134
+ )
135
+
136
+ print_events(service, events)
137
+ print_summary(events)
138
+ end
139
+
140
+ default_task :help
141
+
142
+ private
143
+
144
+ def parse_datetime(str, end_of_day: false)
145
+ return nil if str.nil? || str.empty?
146
+
147
+ if str.include?("T")
148
+ Time.parse(str)
149
+ else
150
+ d = Date.parse(str)
151
+ t = d.to_time
152
+ end_of_day ? t + 86400 - 1 : t # 23:59:59 per --to quando è solo data
153
+ end
154
+ end
155
+
156
+ def resolve_calendar_ids(service, calendar_name)
157
+ calendar_lists = service.list_calendars
158
+
159
+ if calendar_name.nil? || calendar_name.empty?
160
+ default_id = Config.calendar_default
161
+ if default_id
162
+ return [default_id]
163
+ end
164
+ # Usa calendario principale se disponibile
165
+ primary = calendar_lists.find(&:primary)
166
+ return [primary.id] if primary
167
+ # Altrimenti primo calendario
168
+ return [calendar_lists.first.id] if calendar_lists.any?
169
+ return []
170
+ end
171
+
172
+ # Cerca per nome o ID
173
+ matches = calendar_lists.select do |cal|
174
+ cal.id == calendar_name ||
175
+ (cal.summary && cal.summary.downcase.include?(calendar_name.downcase))
176
+ end
177
+
178
+ matches.map(&:id)
179
+ end
180
+
181
+ def print_events(service, events)
182
+ # Usa lista calendari per i nomi (evita chiamate API extra)
183
+ calendar_list = service.list_calendars
184
+ calendar_names = calendar_list.to_h { |c| [c.id, c.summary || c.id] }
185
+
186
+ events.each do |item|
187
+ cal_id = item[:calendar_id]
188
+ event = item[:event]
189
+ cal_name = calendar_names[cal_id] || cal_id
190
+
191
+ start_time = event.start&.date_time || event.start&.date
192
+ end_time = event.end&.date_time || event.end&.date
193
+
194
+ start_str = format_datetime(start_time)
195
+ end_str = format_datetime(end_time)
196
+ desc = event.summary || "(senza titolo)"
197
+ desc = event.description&.slice(0, 80) if event.summary.nil? && event.description
198
+
199
+ puts "#{cal_name} | #{start_str} | #{end_str} | #{desc}"
200
+ end
201
+ end
202
+
203
+ def format_datetime(dt)
204
+ return "-" if dt.nil?
205
+
206
+ if dt.is_a?(String)
207
+ dt
208
+ else
209
+ dt.strftime("%Y-%m-%d %H:%M")
210
+ end
211
+ end
212
+
213
+ def print_summary(events)
214
+ total_minutes = 0
215
+
216
+ events.each do |item|
217
+ event = item[:event]
218
+ start = event.start&.date_time || event.start&.date
219
+ end_dt = event.end&.date_time || event.end&.date
220
+
221
+ next if start.nil? || end_dt.nil?
222
+
223
+ start = start.to_time if start.respond_to?(:to_time)
224
+ end_dt = end_dt.to_time if end_dt.respond_to?(:to_time)
225
+ total_minutes += (end_dt - start) / 60
226
+ end
227
+
228
+ hours = (total_minutes / 60).floor
229
+ mins = (total_minutes % 60).round
230
+
231
+ puts "\n---"
232
+ puts "Eventi trovati: #{events.size}"
233
+ puts "Tempo totale occupato: #{hours}h #{mins}min"
234
+ end
235
+ end
236
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "yaml"
4
+ require "fileutils"
5
+
6
+ module FlycalCli
7
+ class Config
8
+ CONFIG_DIR = File.expand_path("~/.flycal")
9
+ CONFIG_FILE = File.join(CONFIG_DIR, "config.yml")
10
+ CREDENTIALS_FILE = File.join(CONFIG_DIR, "credentials.json")
11
+ TOKENS_FILE = File.join(CONFIG_DIR, "tokens.yml")
12
+
13
+ class << self
14
+ def load
15
+ return {} unless File.exist?(CONFIG_FILE)
16
+
17
+ YAML.load_file(CONFIG_FILE) || {}
18
+ end
19
+
20
+ def save(data)
21
+ FileUtils.mkdir_p(CONFIG_DIR)
22
+ File.write(CONFIG_FILE, data.to_yaml)
23
+ end
24
+
25
+ def calendar_default
26
+ load["calendar_default"]
27
+ end
28
+
29
+ def calendar_default=(calendar_id)
30
+ data = load
31
+ data["calendar_default"] = calendar_id
32
+ save(data)
33
+ end
34
+
35
+ def credentials_path
36
+ CREDENTIALS_FILE
37
+ end
38
+
39
+ def credentials_exist?
40
+ File.exist?(CREDENTIALS_FILE)
41
+ end
42
+
43
+ def tokens_path
44
+ TOKENS_FILE
45
+ end
46
+
47
+ def config_dir
48
+ CONFIG_DIR
49
+ end
50
+
51
+ def clear_all
52
+ FileUtils.rm_rf(CONFIG_DIR)
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FlycalCli
4
+ VERSION = "0.1.0"
5
+ end
data/lib/flycal_cli.rb ADDED
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "flycal_cli/version"
4
+ require "flycal_cli/config"
5
+ require "flycal_cli/auth"
6
+ require "flycal_cli/calendar_service"
7
+ require "flycal_cli/cli"
8
+
9
+ module FlycalCli
10
+ class Error < StandardError; end
11
+ end
metadata ADDED
@@ -0,0 +1,138 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: flycal-cli
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - flycal-cli
8
+ bindir: exe
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: google-apis-calendar_v3
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: '0.51'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - "~>"
24
+ - !ruby/object:Gem::Version
25
+ version: '0.51'
26
+ - !ruby/object:Gem::Dependency
27
+ name: googleauth
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - "~>"
31
+ - !ruby/object:Gem::Version
32
+ version: '1.8'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '1.8'
40
+ - !ruby/object:Gem::Dependency
41
+ name: thor
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '1.3'
47
+ type: :runtime
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '1.3'
54
+ - !ruby/object:Gem::Dependency
55
+ name: tty-prompt
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '0.23'
61
+ type: :runtime
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '0.23'
68
+ - !ruby/object:Gem::Dependency
69
+ name: tty-spinner
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '0.9'
75
+ type: :runtime
76
+ prerelease: false
77
+ version_requirements: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '0.9'
82
+ - !ruby/object:Gem::Dependency
83
+ name: webrick
84
+ requirement: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '1.8'
89
+ type: :runtime
90
+ prerelease: false
91
+ version_requirements: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: '1.8'
96
+ description: flycal-cli permette di connettersi al proprio account Google e gestire
97
+ i calendari da riga di comando
98
+ email:
99
+ - ''
100
+ executables:
101
+ - flycal
102
+ extensions: []
103
+ extra_rdoc_files: []
104
+ files:
105
+ - LICENSE
106
+ - README.md
107
+ - exe/flycal
108
+ - lib/flycal_cli.rb
109
+ - lib/flycal_cli/auth.rb
110
+ - lib/flycal_cli/calendar_service.rb
111
+ - lib/flycal_cli/cli.rb
112
+ - lib/flycal_cli/config.rb
113
+ - lib/flycal_cli/version.rb
114
+ homepage: https://github.com/your-username/flycal-cli
115
+ licenses:
116
+ - MIT
117
+ metadata:
118
+ homepage_uri: https://github.com/your-username/flycal-cli
119
+ source_code_uri: https://github.com/your-username/flycal-cli
120
+ changelog_uri: https://github.com/your-username/flycal-cli/blob/main/CHANGELOG.md
121
+ rdoc_options: []
122
+ require_paths:
123
+ - lib
124
+ required_ruby_version: !ruby/object:Gem::Requirement
125
+ requirements:
126
+ - - ">="
127
+ - !ruby/object:Gem::Version
128
+ version: 3.1.0
129
+ required_rubygems_version: !ruby/object:Gem::Requirement
130
+ requirements:
131
+ - - ">="
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
134
+ requirements: []
135
+ rubygems_version: 4.0.6
136
+ specification_version: 4
137
+ summary: CLI per accedere ai calendari Google
138
+ test_files: []