Skip to content

Instantly share code, notes, and snippets.

@jsyeo
Forked from jmb/README.md
Last active February 28, 2021 18:32
Show Gist options
  • Save jsyeo/39d3fde3afbffdd31093 to your computer and use it in GitHub Desktop.
Save jsyeo/39d3fde3afbffdd31093 to your computer and use it in GitHub Desktop.

Description

This is a fork of jmb's awesome widget that grabs the events with a private address instead of going through the tiresome process of Google's OAuth authentication.

Dashing widget to display the next and some subsequent Google Calendar events using the Google Calendar's private urls.

See the screenshot below

Installation

dashing install 39d3fde3afbffdd31093

Set up

Grab the private address of your calendar by going to your calendar's settings and look for the ICal button.

The job file defines how many events to get from the calendar and when to start the search. My version gets the next 6 events.

Install Dependencies

  1. icalendar gem
  2. Moment.js

Stick gem 'icalendar' into your Gemfile and run bundle install.

Download the Moment javascript library and add to your javascript assets. Then lastly, make sure you have this at the top of assets/javascripts/application.coffee.

#= require moment.js`

Credits

Thanks @jmb!

class Dashing.GoogleCalendar extends Dashing.Widget
onData: (data) =>
event = rest = null
getEvents = (first, others...) ->
event = first
rest = others
getEvents data.events...
start = moment(event.start)
end = moment(event.end)
@set('event',event)
@set('event_date', start.format('dddd Do MMMM'))
@set('event_times', start.format('HH:mm') + " - " + end.format('HH:mm'))
next_events = []
for next_event in rest
start = moment(next_event.start)
start_date = start.format('Do MMM')
start_time = start.format('HH:mm')
next_events.push { summary: next_event.summary, start_date: start_date, start_time: start_time }
@set('next_events', next_events)
<h1 class="subtitle" >Next event:</h1>
<h3 class="times" data-bind="event_date"></h3>
<h2 class="title" data-bind="event.summary"></h2>
<h3 class="times" data-bind="event_times"></h3>
<h4 data-bind="next_count"></h4>
<table class="next">
<tr data-foreach-e='next_events'>
<td data-bind="e.start_date"></td>
<td data-bind="e.start_time"></td>
<td data-bind="e.summary"></td>
</tr>
</table>
<div class="updated-at" data-bind="updatedAtMessage"></div>
require 'icalendar'
ical_url = 'https://www.google.com/calendar/ical/xxxxxxxx%40group.calendar.google.com/private-xxxxx/basic.ics'
uri = URI ical_url
SCHEDULER.every '15s', :first_in => 4 do |job|
result = Net::HTTP.get uri
calendars = Icalendar.parse(result)
calendar = calendars.first
events = calendar.events.map do |event|
{
start: event.dtstart,
end: event.dtend,
summary: event.summary
}
end.select { |event| event[:start] > DateTime.now }
events = events.sort { |a, b| a[:start] <=> b[:start] }
events = events[0..5]
send_event('google_calendar', { events: events })
end
// ----------------------------------------------------------------------------
// Sass declarations
// ----------------------------------------------------------------------------
$background-color: #47bbb3; //#ec663c;
$title-color: rgba(255, 255, 255, 1);
$subtitle-color: rgba(255, 255, 255, 0.7);
$moreinfo-color: rgba(255, 255, 255, 0.7);
// ----------------------------------------------------------------------------
// Widget-calendar styles
// ----------------------------------------------------------------------------
.widget-google-calendar {
background-color: $background-color;
.subtitle {
color: $subtitle-color;
font-size: 0.75em;
margin: 15px 0;
}
.title {
color: $title-color;
font-size: 1.4em;
}
.times {
font-size: 0.9em;
}
.next {
font-size: 0.75em;
margin-top: 30px;
.tr {
border-bottom: 1px solid $subtitle-color;
.td {
text-align: left;
}
}
}
.more-info {
color: $moreinfo-color;
}
.updated-at {
color: $subtitle-color;
bottom: 5px;
right: 5px;
left: auto;
font-size: 0.5em;
}
&.large h3 {
font-size: 65px;
}
}
Copy link

ghost commented Jan 31, 2017

Hi, the widget show only the upcoming events, not the current one running. Any way to get a list of events including the current event ?

@Smittey
Copy link

Smittey commented Mar 22, 2017

@twpark A somewhat delayed response, and hopefully you've found a solution by now, but in case others find the same issue I fixed this by changing the following:

   onData: (data) =>

      event = rest = null
  
    getEvents = (first, others...) ->
      event = first
      rest = others

    getEvents data.events.items...

    start = moment(event.start.dateTime)
    end = moment(event.end.dateTime)
      
    if event.start.dateTime == undefined
      start = moment(event.start.date)
      end = moment(event.end.date)

    @set('event',event)
    @set('event_date', start.format('dddd Do MMMM'))
    @set('event_times', start.format('HH:mm') + " - " + end.format('HH:mm'))

    next_events = []
    for next_event in rest   
      
      start = moment(next_event.start.dateTime)

      if next_event.start.dateTime == undefined
        start = moment(next_event.start.date)
          
      start_date = start.format('ddd Do MMM')
      start_time = start.format('HH:mm')

      next_events.push { summary: next_event.summary, start_date: start_date, start_time: start_time }
    @set('next_events', next_events)

Basically it boils down to recurring events having a differently named tag than normal events ('date' instead of 'dateTime')

@hornoo
Copy link

hornoo commented Apr 6, 2017

@Smittey with your fix for recurring events did you have some changes in the jobs file to go along with the updated coffee script?

@schuhri
Copy link

schuhri commented May 7, 2017

Hi All,
I am just new at dashing and ran into this problem after I installed this google calendar app:

pi@dashpi:~/dashboard/sweet_dashboard_project $ dashing start
bundler: failed to load command: thin (/usr/local/bin/thin)
LoadError: cannot load such file -- icalendar
/var/lib/gems/2.1.0/gems/backports-3.8.0/lib/backports/std_lib.rb:9:in require' /var/lib/gems/2.1.0/gems/backports-3.8.0/lib/backports/std_lib.rb:9:in require_with_backports'
/home/pi/dashboard/sweet_dashboard_project/jobs/google_calendar.rb:1:in <top (required)>' /var/lib/gems/2.1.0/gems/backports-3.8.0/lib/backports/std_lib.rb:9:in require'
/var/lib/gems/2.1.0/gems/backports-3.8.0/lib/backports/std_lib.rb:9:in require_with_backports' /var/lib/gems/2.1.0/gems/dashing-1.3.7/lib/dashing/app.rb:171:in block in require_glob'
/var/lib/gems/2.1.0/gems/dashing-1.3.7/lib/dashing/app.rb:170:in each' /var/lib/gems/2.1.0/gems/dashing-1.3.7/lib/dashing/app.rb:170:in require_glob'
/var/lib/gems/2.1.0/gems/dashing-1.3.7/lib/dashing/app.rb:181:in <top (required)>' /var/lib/gems/2.1.0/gems/dashing-1.3.7/lib/dashing.rb:3:in require'
/var/lib/gems/2.1.0/gems/dashing-1.3.7/lib/dashing.rb:3:in <top (required)>' config.ru:1:in require'
config.ru:1:in block in <main>' /var/lib/gems/2.1.0/gems/rack-1.5.5/lib/rack/builder.rb:55:in instance_eval'
/var/lib/gems/2.1.0/gems/rack-1.5.5/lib/rack/builder.rb:55:in initialize' config.ru:1:in new'
config.ru:1:in <main>' /var/lib/gems/2.1.0/gems/thin-1.6.4/lib/rack/adapter/loader.rb:33:in eval'
/var/lib/gems/2.1.0/gems/thin-1.6.4/lib/rack/adapter/loader.rb:33:in load' /var/lib/gems/2.1.0/gems/thin-1.6.4/lib/thin/controllers/controller.rb:182:in load_rackup_config'
/var/lib/gems/2.1.0/gems/thin-1.6.4/lib/thin/controllers/controller.rb:72:in start' /var/lib/gems/2.1.0/gems/thin-1.6.4/lib/thin/runner.rb:200:in run_command'
/var/lib/gems/2.1.0/gems/thin-1.6.4/lib/thin/runner.rb:156:in run!' /var/lib/gems/2.1.0/gems/thin-1.6.4/bin/thin:6:in <top (required)>'
/usr/local/bin/thin:23:in load' /usr/local/bin/thin:23:in <top (required)>'

Anyone any idea?
Thank you

@7k50
Copy link

7k50 commented Jul 15, 2017

@notmyrealcode: I seem to be having a similar issue:

scheduler caught exception:
undefined method `events' for nil:NilClass
/Users/me/Smashing/test01/jobs/google_calendar.rb:11:in `block in <top (required)>'
/usr/local/lib/ruby/gems/2.4.0/gems/rufus-scheduler-2.0.24/lib/rufus/sc/jobs.rb:230:in `trigger_block'
/usr/local/lib/ruby/gems/2.4.0/gems/rufus-scheduler-2.0.24/lib/rufus/sc/jobs.rb:204:in `block in trigger'
/usr/local/lib/ruby/gems/2.4.0/gems/rufus-scheduler-2.0.24/lib/rufus/sc/scheduler.rb:430:in `block in trigger_job'

BTW: I also need to use Scandinavian letters, but I don't have any of them in the daily calendar events I'm currently testing. Are they retrieved from future (non-intraday) events?

@manifolded
Copy link

I get this error, repeating.
**** DEPRECATION WARNING ****
Icalendar.parse will be removed. Please switch to Icalendar::Calendar.parse.

@borisv1979
Copy link

@manifolded:
Just edit file google_calendar.rb and replace line (if you are using Icalendar version 2.0 and above):

calendars = Icalendar.parse(result)

WITH

calendars = Icalendar::Calendar.parse(result)

@Burrro
Copy link

Burrro commented Feb 21, 2018

Hello there,
Is there a way to get the data of multiple icals?
I think this widget does it, but I could not get it to work with this one here.
Is anyone able to help me? :)

@Dr-Bone
Copy link

Dr-Bone commented Jul 6, 2019

Hi There
Could somebody please help me with that? When I try to load this widget I get:
69970458660820 rufus-scheduler intercepted an error:
69970458660820 job:
69970458660820 Rufus::Scheduler::EveryJob "15s" {:first_in=>4}
69970458660820 error:
69970458660820 69970458660820
69970458660820 ArgumentError
69970458660820 comparison of Time with DateTime failed
69970458660820 /usr/lib/ruby/2.5.0/delegate.rb:83:in >' 69970458660820 /usr/lib/ruby/2.5.0/delegate.rb:83:in method_missing'
69970458660820 /root/sweet_dashboard_project/jobs/google_calendar.rb:17:in block (2 levels) in <top (required)>' 69970458660820 /root/sweet_dashboard_project/jobs/google_calendar.rb:17:in select'
69970458660820 /root/sweet_dashboard_project/jobs/google_calendar.rb:17:in `block in <top (required)>'
69970458660820 ...........

@mostofthetime
Copy link

@Dr-Bone: Add

require 'date'

at top of the google_calendar.rb

@louismillette
Copy link

I had the same issue. Managed to hack around it by casting the event date to a string, then converting to a DateTime. In google_calendar.rb:
replace
end.select { |event| event[:start] > DateTime.now }
with
end.select { |event| DateTime.parse(event[:start].to_s) > DateTime.now }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment