timex_datalink_caldav 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.DS_Store +0 -0
- data/CHANGELOG.md +5 -0
- data/Gemfile +20 -0
- data/Gemfile.lock +97 -0
- data/README.md +58 -0
- data/Rakefile +8 -0
- data/bin/timex_datalink_caldav +4 -0
- data/lib/timex_datalink_caldav/client.rb +97 -0
- data/lib/timex_datalink_caldav/version.rb +5 -0
- data/lib/timex_datalink_caldav.rb +43 -0
- data/sig/timex_datalink_caldav.rbs +4 -0
- data/timex_datalink_caldav.gemspec +37 -0
- metadata +61 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 6c7e200c3fbb1011bd0b0b67b98db758f8802b72d8686ceb991b4766cb285860
|
4
|
+
data.tar.gz: e5b0052df0811f4af6f52c34727bd26bd93254903fdc218e9be00d51ae5ac169
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b07bd1855b0b9ffe5a36301c239df18f588bacfd7c1ba6f3e20988057cab7491343dc86072ad43bd5194e0c67e5d25ccb9d4f252214953dd8ed2a793819d9a72
|
7
|
+
data.tar.gz: 529e2275b9207f501414c41131df0e505ae85e46ae8319a4ab0c04a35275b85be393c84b022e0e10890e3072ff4969a351aa55da453a3183b240bc9db19df94f
|
data/.DS_Store
ADDED
Binary file
|
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
source "https://rubygems.org"
|
4
|
+
|
5
|
+
# Specify your gem's dependencies in timex_datalink_caldav.gemspec
|
6
|
+
gemspec
|
7
|
+
|
8
|
+
gem "rake", "~> 13.0"
|
9
|
+
|
10
|
+
gem "rspec", "~> 3.12"
|
11
|
+
|
12
|
+
gem "timex_datalink_client", "~> 0.11.0"
|
13
|
+
|
14
|
+
gem "calendav", "~> 0.4.0"
|
15
|
+
|
16
|
+
gem "icalendar", "~> 2.8"
|
17
|
+
|
18
|
+
gem "icalendar-recurrence", "~> 1.1"
|
19
|
+
|
20
|
+
gem "activesupport", "~> 7.0"
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
timex_datalink_caldav (0.1.0)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: https://rubygems.org/
|
8
|
+
specs:
|
9
|
+
activemodel (7.0.4.3)
|
10
|
+
activesupport (= 7.0.4.3)
|
11
|
+
activesupport (7.0.4.3)
|
12
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
13
|
+
i18n (>= 1.6, < 2)
|
14
|
+
minitest (>= 5.1)
|
15
|
+
tzinfo (~> 2.0)
|
16
|
+
addressable (2.8.4)
|
17
|
+
public_suffix (>= 2.0.2, < 6.0)
|
18
|
+
calendav (0.4.0)
|
19
|
+
http
|
20
|
+
icalendar
|
21
|
+
nokogiri
|
22
|
+
concurrent-ruby (1.2.2)
|
23
|
+
crc (0.4.2)
|
24
|
+
diff-lcs (1.5.0)
|
25
|
+
domain_name (0.5.20190701)
|
26
|
+
unf (>= 0.0.5, < 1.0.0)
|
27
|
+
ffi (1.15.5)
|
28
|
+
ffi-compiler (1.0.1)
|
29
|
+
ffi (>= 1.0.0)
|
30
|
+
rake
|
31
|
+
http (5.1.1)
|
32
|
+
addressable (~> 2.8)
|
33
|
+
http-cookie (~> 1.0)
|
34
|
+
http-form_data (~> 2.2)
|
35
|
+
llhttp-ffi (~> 0.4.0)
|
36
|
+
http-cookie (1.0.5)
|
37
|
+
domain_name (~> 0.5)
|
38
|
+
http-form_data (2.3.0)
|
39
|
+
i18n (1.13.0)
|
40
|
+
concurrent-ruby (~> 1.0)
|
41
|
+
icalendar (2.8.0)
|
42
|
+
ice_cube (~> 0.16)
|
43
|
+
icalendar-recurrence (1.1.3)
|
44
|
+
icalendar (~> 2.0)
|
45
|
+
ice_cube (~> 0.16)
|
46
|
+
ice_cube (0.16.4)
|
47
|
+
llhttp-ffi (0.4.0)
|
48
|
+
ffi-compiler (~> 1.0)
|
49
|
+
rake (~> 13.0)
|
50
|
+
mdb (0.5.0)
|
51
|
+
minitest (5.18.0)
|
52
|
+
nokogiri (1.14.4-arm64-darwin)
|
53
|
+
racc (~> 1.4)
|
54
|
+
public_suffix (5.0.1)
|
55
|
+
racc (1.6.2)
|
56
|
+
rake (13.0.6)
|
57
|
+
rspec (3.12.0)
|
58
|
+
rspec-core (~> 3.12.0)
|
59
|
+
rspec-expectations (~> 3.12.0)
|
60
|
+
rspec-mocks (~> 3.12.0)
|
61
|
+
rspec-core (3.12.2)
|
62
|
+
rspec-support (~> 3.12.0)
|
63
|
+
rspec-expectations (3.12.3)
|
64
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
65
|
+
rspec-support (~> 3.12.0)
|
66
|
+
rspec-mocks (3.12.5)
|
67
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
68
|
+
rspec-support (~> 3.12.0)
|
69
|
+
rspec-support (3.12.0)
|
70
|
+
rubyserial (0.6.0)
|
71
|
+
ffi (~> 1.9, >= 1.9.3)
|
72
|
+
timex_datalink_client (0.11.0)
|
73
|
+
activemodel (~> 7.0.4)
|
74
|
+
crc (~> 0.4.2)
|
75
|
+
mdb (~> 0.5.0)
|
76
|
+
rubyserial (~> 0.6.0)
|
77
|
+
tzinfo (2.0.6)
|
78
|
+
concurrent-ruby (~> 1.0)
|
79
|
+
unf (0.1.4)
|
80
|
+
unf_ext
|
81
|
+
unf_ext (0.0.8.2)
|
82
|
+
|
83
|
+
PLATFORMS
|
84
|
+
arm64-darwin-22
|
85
|
+
|
86
|
+
DEPENDENCIES
|
87
|
+
activesupport (~> 7.0)
|
88
|
+
calendav (~> 0.4.0)
|
89
|
+
icalendar (~> 2.8)
|
90
|
+
icalendar-recurrence (~> 1.1)
|
91
|
+
rake (~> 13.0)
|
92
|
+
rspec (~> 3.12)
|
93
|
+
timex_datalink_caldav!
|
94
|
+
timex_datalink_client (~> 0.11.0)
|
95
|
+
|
96
|
+
BUNDLED WITH
|
97
|
+
2.4.10
|
data/README.md
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
# TimexDatalinkCaldav
|
2
|
+
|
3
|
+
TimexDatalinkCaldav is a simple Ruby gem designed to sync events from a CalDAV server to a Timex Datalink watch. It can also be used as a standalone command-line interface (CLI) tool.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
To install the TimexDatalinkCaldav gem, simply run:
|
8
|
+
|
9
|
+
```sh
|
10
|
+
gem install timex_datalink_caldav
|
11
|
+
```
|
12
|
+
|
13
|
+
Or add this line to your application's Gemfile:
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
source "https://rubygems.pkg.github.com/wjhrdy" do
|
17
|
+
gem "timex_datalink_caldav"
|
18
|
+
end
|
19
|
+
```
|
20
|
+
|
21
|
+
And then execute:
|
22
|
+
|
23
|
+
```sh
|
24
|
+
bundle install
|
25
|
+
```
|
26
|
+
|
27
|
+
## Usage
|
28
|
+
|
29
|
+
### As a Gem
|
30
|
+
|
31
|
+
Here's an example of how to use the tool in your Ruby code:
|
32
|
+
|
33
|
+
```ruby
|
34
|
+
require 'timex_datalink_caldav'
|
35
|
+
|
36
|
+
client = TimexDatalinkCaldav::Client.new(your_username, your_password, your_server_uri, your_device)
|
37
|
+
client.sync_to_watch
|
38
|
+
```
|
39
|
+
|
40
|
+
### As a CLI Tool
|
41
|
+
|
42
|
+
After installing the gem, you can use it as a CLI tool:
|
43
|
+
|
44
|
+
```sh
|
45
|
+
timex_datalink_caldav -u https://caldavendpoint.com -n your_username -p your_password -d your_device
|
46
|
+
```
|
47
|
+
|
48
|
+
Please replace `your_username`, `your_password`, and `your_device` with your actual CalDAV server username, password, and device respectively. In this example, we're using Apple's iCloud CalDAV server. You'll need to replace this with the URI of your own CalDAV server if you're not using iCloud.
|
49
|
+
|
50
|
+
## Note
|
51
|
+
|
52
|
+
Ensure you have the necessary dependencies installed on your system and you have the correct permissions to access the specified device.
|
53
|
+
|
54
|
+
The tool currently works with events that have attendees and converts event times to Eastern Standard Time (EST). Events are sorted by time before syncing to the watch.
|
55
|
+
|
56
|
+
## Resources
|
57
|
+
|
58
|
+
If you want to use this I highly recommend pairing it with the Raspberry Pi Pico and [this project](https://github.com/famiclone6502/DIY_Datalink_Adapter).
|
data/Rakefile
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
require 'calendav'
|
2
|
+
require 'icalendar/recurrence'
|
3
|
+
require 'timex_datalink_client'
|
4
|
+
require 'active_support/time'
|
5
|
+
|
6
|
+
module TimexDatalinkCaldav
|
7
|
+
class Client
|
8
|
+
def initialize(user, password, server_url, serial_device)
|
9
|
+
@user = user
|
10
|
+
@password = password
|
11
|
+
@server_url = server_url
|
12
|
+
@serial_device = serial_device
|
13
|
+
end
|
14
|
+
|
15
|
+
def get_events
|
16
|
+
credentials = Calendav::Credentials::Standard.new(
|
17
|
+
host: @server_url,
|
18
|
+
username: @user,
|
19
|
+
password: @password,
|
20
|
+
authentication: :basic_auth
|
21
|
+
)
|
22
|
+
|
23
|
+
# Create a new client with the credentials
|
24
|
+
client = Calendav.client(credentials)
|
25
|
+
|
26
|
+
# Get events from the calendar for the next day
|
27
|
+
client.events.list(@server_url, from: Time.now, to: Time.now + 24*60*60)
|
28
|
+
end
|
29
|
+
|
30
|
+
def sync_to_watch
|
31
|
+
events = get_events
|
32
|
+
|
33
|
+
appointments = []
|
34
|
+
appointment_map = {} # Used to avoid duplicate appointments
|
35
|
+
|
36
|
+
events.each do |event|
|
37
|
+
ical_events = Icalendar::Event.parse(event.calendar_data)
|
38
|
+
if ical_events.any?
|
39
|
+
ical_event = ical_events.first
|
40
|
+
if ical_event.attendee&.any? # Exclude events without attendees
|
41
|
+
next_occurrence = ical_event.occurrences_between(Time.now, Time.now + 24*60*60).first
|
42
|
+
if next_occurrence
|
43
|
+
est_time = next_occurrence.start_time.in_time_zone('Eastern Time (US & Canada)')
|
44
|
+
key = "#{est_time}_#{ical_event.summary.to_s}"
|
45
|
+
unless appointment_map[key] # Check if the event is already in the map
|
46
|
+
puts "Adding appointment: #{ical_event.summary.to_s} at time #{est_time}"
|
47
|
+
appointment = TimexDatalinkClient::Protocol1::Eeprom::Appointment.new(
|
48
|
+
time: est_time,
|
49
|
+
message: ical_event.summary.to_s
|
50
|
+
)
|
51
|
+
appointments << appointment
|
52
|
+
appointment_map[key] = true
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# Sort the appointments by time
|
60
|
+
appointments.sort_by! { |appointment| appointment.time }
|
61
|
+
write_to_watch(appointments)
|
62
|
+
end
|
63
|
+
|
64
|
+
def write_to_watch(appointments)
|
65
|
+
time1 = Time.now
|
66
|
+
|
67
|
+
models = [
|
68
|
+
TimexDatalinkClient::Protocol1::Sync.new,
|
69
|
+
TimexDatalinkClient::Protocol1::Start.new,
|
70
|
+
TimexDatalinkClient::Protocol1::Time.new(
|
71
|
+
zone: 1,
|
72
|
+
time: time1,
|
73
|
+
is_24h: false
|
74
|
+
),
|
75
|
+
TimexDatalinkClient::Protocol1::TimeName.new(
|
76
|
+
zone: 1,
|
77
|
+
name: time1.zone
|
78
|
+
),
|
79
|
+
TimexDatalinkClient::Protocol1::Eeprom.new(
|
80
|
+
appointments: appointments,
|
81
|
+
appointment_notification_minutes: 5
|
82
|
+
),
|
83
|
+
TimexDatalinkClient::Protocol1::End.new
|
84
|
+
]
|
85
|
+
|
86
|
+
timex_datalink_client = TimexDatalinkClient.new(
|
87
|
+
serial_device: @serial_device,
|
88
|
+
models: models,
|
89
|
+
byte_sleep: 0.008,
|
90
|
+
packet_sleep: 0.06,
|
91
|
+
verbose: true
|
92
|
+
)
|
93
|
+
|
94
|
+
timex_datalink_client.write
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'optparse'
|
3
|
+
|
4
|
+
require_relative "timex_datalink_caldav/client"
|
5
|
+
|
6
|
+
module TimexDatalinkCaldav
|
7
|
+
class CLI
|
8
|
+
def initialize(arguments)
|
9
|
+
@options = parse_options(arguments)
|
10
|
+
end
|
11
|
+
|
12
|
+
def execute
|
13
|
+
client = TimexDatalinkCaldav::Client.new(@options.fetch(:user), @options.fetch(:password), @options.fetch(:uri), @options.fetch(:device))
|
14
|
+
client.sync_to_watch
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def parse_options(arguments)
|
20
|
+
options = {}
|
21
|
+
OptionParser.new do |opts|
|
22
|
+
opts.banner = "Usage: timex_datalink_caldav [options]"
|
23
|
+
|
24
|
+
opts.on("-u", "--uri URI", "CalDAV server URI") do |v|
|
25
|
+
options[:uri] = v
|
26
|
+
end
|
27
|
+
|
28
|
+
opts.on("-n", "--user USERNAME", "Username for CalDAV server") do |v|
|
29
|
+
options[:user] = v
|
30
|
+
end
|
31
|
+
|
32
|
+
opts.on("-p", "--password PASSWORD", "Password for CalDAV server") do |v|
|
33
|
+
options[:password] = v
|
34
|
+
end
|
35
|
+
|
36
|
+
opts.on("-d", "--device DEVICE", "Serial device for Timex Datalink watch") do |v|
|
37
|
+
options[:device] = v
|
38
|
+
end
|
39
|
+
end.parse!(arguments)
|
40
|
+
options
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "lib/timex_datalink_caldav/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "timex_datalink_caldav"
|
7
|
+
spec.version = TimexDatalinkCaldav::VERSION
|
8
|
+
spec.authors = ["Willy Hardy"]
|
9
|
+
spec.email = ["zpga8gbp@mailer.me"]
|
10
|
+
|
11
|
+
spec.summary = "Allows the Timex Datalink watch to sync with a CalDAV server."
|
12
|
+
spec.description = "Adds a CLI and a feature to pull your next day of calendar events into the Timex Datalink watch. Note: Hardcoded protocol1 and EST timezone. At the moment."
|
13
|
+
spec.homepage = "https://github.com/wjhrdy/timex-datalink-caldav"
|
14
|
+
spec.required_ruby_version = ">= 2.6.0"
|
15
|
+
|
16
|
+
spec.license = "MIT"
|
17
|
+
spec.metadata["github_repo"] = "ssh://github.com/wjhrdy/timex-datalink-caldav"
|
18
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
19
|
+
spec.metadata["source_code_uri"] = "https://github.com/wjhrdy/timex-datalink-caldav"
|
20
|
+
spec.metadata["changelog_uri"] = "https://github.com/wjhrdy/timex-datalink-caldav/CHANGELOG.md"
|
21
|
+
|
22
|
+
# Specify which files should be added to the gem when it is released.
|
23
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
24
|
+
spec.files = Dir.chdir(__dir__) do
|
25
|
+
`git ls-files -z`.split("\x0").reject do |f|
|
26
|
+
(File.expand_path(f) == __FILE__) || f.start_with?(*%w[bin/ test/ spec/ features/ .git .circleci appveyor])
|
27
|
+
end
|
28
|
+
end
|
29
|
+
spec.require_paths = ["lib"]
|
30
|
+
spec.executables << 'timex_datalink_caldav'
|
31
|
+
|
32
|
+
# Uncomment to register a new dependency of your gem
|
33
|
+
# spec.add_dependency "example-gem", "~> 1.0"
|
34
|
+
|
35
|
+
# For more information and examples about making a new gem, check out our
|
36
|
+
# guide at: https://bundler.io/guides/creating_gem.html
|
37
|
+
end
|
metadata
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: timex_datalink_caldav
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Willy Hardy
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2023-05-15 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: 'Adds a CLI and a feature to pull your next day of calendar events into
|
14
|
+
the Timex Datalink watch. Note: Hardcoded protocol1 and EST timezone. At the moment.'
|
15
|
+
email:
|
16
|
+
- zpga8gbp@mailer.me
|
17
|
+
executables:
|
18
|
+
- timex_datalink_caldav
|
19
|
+
extensions: []
|
20
|
+
extra_rdoc_files: []
|
21
|
+
files:
|
22
|
+
- ".DS_Store"
|
23
|
+
- CHANGELOG.md
|
24
|
+
- Gemfile
|
25
|
+
- Gemfile.lock
|
26
|
+
- README.md
|
27
|
+
- Rakefile
|
28
|
+
- bin/timex_datalink_caldav
|
29
|
+
- lib/timex_datalink_caldav.rb
|
30
|
+
- lib/timex_datalink_caldav/client.rb
|
31
|
+
- lib/timex_datalink_caldav/version.rb
|
32
|
+
- sig/timex_datalink_caldav.rbs
|
33
|
+
- timex_datalink_caldav.gemspec
|
34
|
+
homepage: https://github.com/wjhrdy/timex-datalink-caldav
|
35
|
+
licenses:
|
36
|
+
- MIT
|
37
|
+
metadata:
|
38
|
+
github_repo: ssh://github.com/wjhrdy/timex-datalink-caldav
|
39
|
+
homepage_uri: https://github.com/wjhrdy/timex-datalink-caldav
|
40
|
+
source_code_uri: https://github.com/wjhrdy/timex-datalink-caldav
|
41
|
+
changelog_uri: https://github.com/wjhrdy/timex-datalink-caldav/CHANGELOG.md
|
42
|
+
post_install_message:
|
43
|
+
rdoc_options: []
|
44
|
+
require_paths:
|
45
|
+
- lib
|
46
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
47
|
+
requirements:
|
48
|
+
- - ">="
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: 2.6.0
|
51
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
56
|
+
requirements: []
|
57
|
+
rubygems_version: 3.4.10
|
58
|
+
signing_key:
|
59
|
+
specification_version: 4
|
60
|
+
summary: Allows the Timex Datalink watch to sync with a CalDAV server.
|
61
|
+
test_files: []
|