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 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
@@ -0,0 +1,5 @@
1
+ ## [Unreleased]
2
+
3
+ ## [0.1.0] - 2023-05-11
4
+
5
+ - Initial release
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,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rubocop/rake_task"
5
+
6
+ RuboCop::RakeTask.new
7
+
8
+ task default: :rubocop
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ require_relative '../lib/timex_datalink_caldav'
3
+
4
+ TimexDatalinkCaldav::CLI.new(ARGV).execute
@@ -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,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TimexDatalinkCaldav
4
+ VERSION = "0.2.0"
5
+ 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,4 @@
1
+ module TimexDatalinkCaldav
2
+ VERSION: String
3
+ # See the writing guide of rbs: https://github.com/ruby/rbs#guides
4
+ 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: []