Giter VIP home page Giter VIP logo

gcalcli's Introduction

gcalcli

Build Status

Google Calendar Command Line Interface

gcalcli is a Python application that allows you to access your Google Calendar(s) from a command line. It's easy to get your agenda, search for events, add new events, delete events, edit events, see recently updated events, and even import those annoying ICS/vCal invites from Microsoft Exchange and/or other sources. Additionally, gcalcli can be used as a reminder service and execute any application you want when an event is coming up.

gcalcli uses the Google Calendar API version 3.

Requirements

Optional packages

  • vobject Python module Used for ics/vcal importing.

Installation

Check your OS distribution for packages.

Debian/Ubuntu

apt-get install gcalcli

Void Linux

xbps-install gcalcli

Install using Nix

nix-env -i gcalcli

Install using Homebrew (MacOS)

brew install gcalcli

Install from PyPI

pip install gcalcli

Install from source

git clone https://github.com/insanum/gcalcli.git
cd gcalcli
python setup.py install

Install optional package

pip install vobject

Features

  • OAuth2 authention with your Google account
  • list your calendars
  • show an agenda using a specified start/end date and time
  • show updates since a specified datetime for events between a start/end date and time
  • find conflicts between events matching search term
  • ascii text graphical calendar display with variable width
  • search for past and/or future events
  • "quick add" new events to a specified calendar
  • "add" a new event to a specified calendar (interactively or automatically)
  • "delete" event(s) from a calendar(s) (interactively or automatically)
  • "edit" event(s) interactively
  • import events from ICS/vCal files to a specified calendar
  • easy integration with your favorite mail client (attachment handler)
  • run as a cron job and execute a command for reminders
  • work against specific calendars (by calendar name w/ regex)
  • flag file support for specifying option defaults
  • colored output and unicode character support
  • super fun hacking with shell scripts, cron, screen, tmux, conky, etc

Screenshots

gcalcli 5

gcalcli 1

gcalcli 2

gcalcli 3

gcalcli 4

HowTo

Usage

gcalcli provides a series of subcommands with the following functionality:

list                list available calendars
edit                edit calendar events
agenda              get an agenda for a time period
updates             get updates since a datetime for a time period
calw                get a week-based agenda in calendar format
calm                get a month agenda in calendar format
quick               quick-add an event to a calendar
add                 add a detailed event to the calendar
import              import an ics/vcal file to a calendar
remind              execute command if event occurs within <mins> time

See the manual (man (1) gcalcli), or run with --help/-h for detailed usage.

Login Information

OAuth2 is used for authenticating with your Google account. The resulting token is placed in the ~/.gcalcli_oauth file. When you first start gcalcli the authentication process will proceed. Simply follow the instructions.

You currently have to use your own Calendar API token. Our Calendar API token is restricted to few users only and waits for Google's approval to be unlocked.

  1. Create a New Project within the Google developer console
    1. Activate the "Create" button.
  2. Enable the Google Calendar API
    1. Activate the "Enable" button.
  3. Create OAuth2 consent screen for an "UI /Desktop Application".
    1. Fill out required App information section
      1. Specify App name. Example: "gcalcli"
      2. Specify User support email. Example: [email protected]
    2. Fill out required Developer contact information
      1. Specify Email addresses. Example: [email protected]
    3. Activate the "Save and continue" button.
    4. Scopes: activate the "Save and continue" button.
    5. Test users
      1. Add [email protected]
      2. Activate the "Save and continue" button.
  4. Create OAuth Client ID
    1. Specify Application type: Desktop app.
    2. Activate the "Create" button.
  5. Grab your newly created Client ID (in the form "xxxxxxxxxxxxxxx.apps.googleusercontent.com") and Client Secret from the Credentials page.
  6. Call gcalcli with your Client ID and Client Secret to login via the OAuth2 Authorization Screen. gcalcli --client-id=xxxxxxxxxxxxxxx.apps.googleusercontent.com --client-secret=xxxxxxxxxxxxxxxxx list. In most shells, putting a space before the command will keep it, and therefore your secrets, out of history. Check with history | tail.
  7. This should automatically open the OAuth2 authorization screen in your default browser.

HTTP Proxy Support

gcalcli will automatically work with an HTTP Proxy simply by setting up some environment variables used by the gdata Python module:

http_proxy
https_proxy
proxy-username or proxy_username
proxy-password or proxy_password

Note that these environment variables must be lowercase.

Flag File

gcalcli is able to read default configuration information from a flag file. This file is located, by default, at '~/.gcalclirc'. The flag file takes one command line parameter per line.

In the current version, the flag file only supports the global options (options against the gcalcli program itself). The plan, longer term, is to support a a configuration formation (probably toml or ini), which will allow for configuration of subcommands (such as add, agenda, calw, etc.)

Example:

--nocache
--nocolor
--default-calendar=CALENDAR_NAME
--client-secret=API_KEY

Note that long options require an equal sign if specifying a parameter. With short options the equal sign is optional.

Configuration Folders

gcalcli is able to store all its necessary information in a specific folder (use the --configFolder option.) Each folder will contain 2 files: oauth and cache. An optional 3rd file, gcalclirc, can be present for specific flags that you only want to apply when using this configuration folder.

Importing VCS/VCAL/ICS Files from Exchange (or other)

Importing events from files is easy with gcalcli. The 'import' command accepts a filename on the command line or can read from standard input. Here is a script that can be used as an attachment handler for Thunderbird or in a mailcap entry with Mutt (or in Mutt you could just use the attachment viewer and pipe command):

#!/bin/bash

TERMINAL=evilvte
CONFIG=~/.gcalclirc

$TERMINAL -e bash -c "echo 'Importing invite...' ; \
                      gcalcli --detail-url=short \
                              --calendar='Eric Davis' \
                              import -v \"$1\" ; \
                      read -p 'press enter to exit: '"

Note that with Thunderbird you'll have to have the 'Show All Body Parts' extension installed for seeing the calendar attachments when not using 'Lightning'. See this bug report for more details.

Event Popup Reminders

The 'remind' command for gcalcli is used to execute any command as an event notification. This can be a notify-send or an xmessage-like popup or whatever else you can think of. gcalcli does not contain a daemon so you'll have to use some other tool to ensure gcalcli is run in a timely manner for notifications. Two options are using cron or a loop inside a shell script.

Cron:

% crontab -l
*/10 * * * * /usr/bin/gcalcli remind

Shell script like your .xinitrc so notifications only occur when you're logged in via X:

#!/bin/bash

[[ -x /usr/bin/dunst ]] && /usr/bin/dunst -config ~/.dunstrc &

if [ -x /usr/bin/gcalcli ]; then
  while true; do
    /usr/bin/gcalcli --calendar="davis" remind
    sleep 300
  done &
fi

exec herbstluftwm # :-)

By default gcalcli executes the notify-send command for notifications. Most common Linux desktop enviroments already contain a DBUS notification daemon that supports libnotify so it should automagically just work. If you're like me and use nothing that is common I highly recommend the dunst dmenu'ish notification daemon.

Note that each time you run this you will get a reminder if you're still inside the event duration. Also note that due to time slip between machines, gcalcli will give you a ~5 minute margin of error. Plan your cron jobs accordingly.

Agenda On Your Root Desktop

Put your agenda on your desktop using Conky. The '--conky' option causes gcalcli to output Conky color sequences. Note that you need to use the Conky 'execpi' command for the gcalcli output to be parsed for color sequences. Add the following to your .conkyrc:

${execpi 300 gcalcli --conky agenda}

To also get a graphical calendar that shows the next three weeks add:

${execpi 300 gcalcli --conky calw 3}

You may need to increase the text_buffer_size in your conkyrc file. Users have reported that the default of 256 bytes is too small for busy calendars.

Additionaly you need to set --lineart=unicode to output unicode-characters for box drawing. To avoid misaligned borders use a monospace font like 'DejaVu Sans Mono'. On Python2 it might be necessary to set the environment variable PYTHONIOENCODING=utf8 if you are using characters beyond ascii. For example:

${font DejaVu Sans Mono:size=9}${execpi 300 export PYTHONIOENCODING=utf8 && gcalcli --conky --lineart=unicode calw 3}

Agenda Integration With tmux

Put your next event in the left of your 'tmux' status line. Add the following to your tmux.conf file:

set-option -g status-interval 60
set-option -g status-left "#[fg=blue,bright]#(gcalcli agenda | head -2 | tail -1)#[default]"

Agenda Integration With screen

Put your next event in your 'screen' hardstatus line. First add a cron job that will dump you agenda to a text file:

% crontab -e

Then add the following line:

*/5 * * * * gcalcli --nocolor --nostarted agenda "`date`" > /tmp/gcalcli_agenda.txt

Next create a simple shell script that will extract the first agenda line. Let's call this script 'screen_agenda':

#!/bin/bash
head -2 /tmp/gcalcli_agenda.txt | tail -1

Next configure screen's hardstatus line to gather data from a backtick command. Of course your hardstatus line is most likely very different than this (Mine is!):

backtick 1 60 60 screen_agenda
hardstatus "[ %1` ]"

gcalcli's People

Contributors

bdaigle avatar bladtman242 avatar firecat53 avatar flicken avatar grahamking avatar insanum avatar jcmuller avatar jcrowgey avatar lasers avatar mali avatar markgraf avatar matthewdavis avatar maxwell-k avatar mdengler avatar michaelmhoffman avatar mikem23 avatar modxd22 avatar mruwek avatar muness avatar nealmcb avatar semnodime avatar shi2wei3 avatar shigemk2 avatar tresni avatar tschwinge avatar ujjwalsh avatar watersm avatar watho avatar wor avatar yigitkonur avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gcalcli's Issues

Import of ics file only imports first event of a list

From: http://code.google.com/p/gcalcli/issues/detail?id=76

Patch:

*** gcalcli.back        2012-02-12 21:05:30.150085609 +0100
--- gcalcli     2012-02-12 21:06:00.890084273 +0100
***************
*** 1073,1086 ****
                  PrintErrMsg("Error: " + str(e) + "!\n")
                  sys.exit(1)

!         while True:

!             try:
!                 v = vobject.readComponents(f).next()
!             except StopIteration:
!                 break
! 
!             ve = v.vevent
              event = gdata.calendar.CalendarEventEntry()

              if hasattr(ve, 'summary'):
--- 1073,1081 ----
                  PrintErrMsg("Error: " + str(e) + "!\n")
                  sys.exit(1)

!         cal=vobject.readOne(f)

!         for ve in cal.components():
              event = gdata.calendar.CalendarEventEntry()

              if hasattr(ve, 'summary'):

Specify Conky option text_buffer_size in README

I was trying to figure out how to put gcalcli in a conky window on my desktop, but conky kept displaying only a small amount of the calendar and throwing errors. I discovered the default text buffer value conky uses, 256 bytes, was too small and needed increased to something on the order of 9000 via the text_buffer_size option in my conkyrc. It could save others some time by making a quick note of this in the conky section of the README.

Can't add reminder when importing ICS/VCAL event with an RRULE

There is an exception that occurs in gcalcli when importing an ics file with a recurrence and also specifying a reminder time. I poked around, hacked some code, ran some tests and learned that you can't have a gdata When object in an event that contains a Recurrence object. The following error is returned by InsertEvent():

{'status': 400, 'body': 'Entry can not contain both gd:when and gd:recurrence elements.', 'reason': 'Bad Request'}

I then tried to perform and UpdateEvent() with a newly attached When/Reminder object and the same problem occurs. Also looked into added a Reminder object to a Recurrence and that isn't possible.

Anyways, I fixed the initial exception and now only allow reminders to be tacked on to ics events being inserted that don't have a Recurrence.

Authentication hanging

Hi,

I updated to the latest gcalcli version. Now I have to log into my google account in the browser, and select Allow access. But then the browser hangs indefinitely saying Waiting for localhost...

I've tried using different browsers, and I've tried googling for a solution, but I'm totally stuck. I'm sure I'm missing something obvious.

Thanks,
Michael

Calendars display in different time zones

Events are listed in the default time zone of its respective calendar, so if you have multiple calendars in different time zones, it will not show the times correctly with respect to each other.

e.g.
3pm Event 1 (GMT-5)
6pm Event 2 (GMT+0)

Should show (with respect to GMT):
6pm Event 2
8pm Event 1

Rather than showing:
3pm Event 1
6pm Event 2

support for vague dates

It would be cool if you could (for the agenda) have a start time like "now" and an end time like "24h" or "tomorrow." Basically the same kind of functionality as seen in the Linux "date" command.

If someone wants to give it a shot... go for it! :-)

Debian LMDE + Conky + gcalcli = issue

Hello

After switching from LinuxMint to LinuxMint Debian Edition I've got a problem with gcalcli.
After little investigation I've founded cause (copied below).

I'll be much appreciated for any help
Best regards to all.

My error:
Conky: desktop window (10000a5) is subwindow of root window (be)
Conky: window type - override
Conky: drawing to created window (0x2400001)
Conky: drawing to double buffer
Traceback (most recent call last):
File "/usr/bin/gcalcli", line 1529, in
BowChickaWowWow()
File "/usr/bin/gcalcli", line 1474, in BowChickaWowWow
gcal.CalQuery(args[0], count=int(args[1]))
File "/usr/bin/gcalcli", line 1007, in CalQuery
self._GraphEvents(cmd, start, count, eventList)
File "/usr/bin/gcalcli", line 692, in _GraphEvents
PrintMsg(CLR_NRM(), line + "\n")
File "/usr/bin/gcalcli", line 232, in PrintMsg
sys.stdout.write(msg)
UnicodeEncodeError: 'ascii' codec can't encode character u'\u0144' in position 95: ordinal not in range(128)

Unicode characters break script

I originally wrote about it in #2, but the problem still exists:

When I use sys.stdout.write(msg), I get following error:
UnicodeEncodeError: 'ascii' codec can't encode characters in position 129-133: ordinal not in range(128)
Problem doesn't exist when using print msg,.
(Error caused by event called ĄĄĄĘĘ)

PS: I'm new to Python, so I have to ask - why is sys.stdout.write better than print?

add attendees when importing a ICS file

I received the following ICS invite

BEGIN:VCALENDAR
METHOD:REQUEST
PRODID:Microsoft Exchange Server 2010
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Romance Standard Time
BEGIN:STANDARD
DTSTART:16010101T030000
TZOFFSETFROM:+0200
TZOFFSETTO:+0100
RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=10
END:STANDARD
BEGIN:DAYLIGHT
DTSTART:16010101T020000
TZOFFSETFROM:+0100
TZOFFSETTO:+0200
RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=3
END:DAYLIGHT
END:VTIMEZONE
BEGIN:VEVENT
ORGANIZER;CN="Hansen, Sune":MAILTO:[email protected]
ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;CN=tnielse3@c
sc.com:MAILTO:[email protected]
ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;CN=Kent Micha
elsen ([email protected]):MAILTO:[email protected]
ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;CN="Costa, Jor
ge":MAILTO:[email protected]
ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;CN=Martyn K H
olden ([email protected]):MAILTO:[email protected]
DESCRIPTION;LANGUAGE=en-US:All,\n\nThis is a Placeholder for next week’s
TOI –\nWebex and Con Call details will follow.\n\n/Sune\n\n
SUMMARY;LANGUAGE=en-US:SnapCreator TOI
DTSTART;TZID=Romance Standard Time:20121024T113000
DTEND;TZID=Romance Standard Time:20121024T133000
UID:040000008200E00074C5B7101A82E00800000000E082784ADAADCD01000000000000000
01000000078F78DCB98419F4889FE6A4B96A6DAF2
CLASS:PUBLIC
PRIORITY:5
DTSTAMP:20121019T071532Z
TRANSP:OPAQUE
STATUS:CONFIRMED
SEQUENCE:0
LOCATION;LANGUAGE=en-US:Webex and Con Call
X-MICROSOFT-CDO-APPT-SEQUENCE:0
X-MICROSOFT-CDO-OWNERAPPTID:2104731612
X-MICROSOFT-CDO-BUSYSTATUS:TENTATIVE
X-MICROSOFT-CDO-INTENDEDSTATUS:BUSY
X-MICROSOFT-CDO-ALLDAYEVENT:FALSE
X-MICROSOFT-CDO-IMPORTANCE:1
X-MICROSOFT-CDO-INSTTYPE:0
X-MICROSOFT-DISALLOW-COUNTER:FALSE
BEGIN:VALARM
ACTION:DISPLAY
DESCRIPTION:REMINDER
TRIGGER;RELATED=START:-PT15M
END:VALARM
END:VEVENT
END:VCALENDAR

which I imported into google calendar using

[535]$ cat /usr/share/applications/import-ICS-into-google-calendar.desktop
[Desktop Entry]
Name=Import ICS file into Google Calendar
GenericName=Import ICS file into Google Calendar
X-GNOME-FullName=Import ICS file into Google Calendar
Comment=Import ICS file into Google Calendar
Exec=gcalcli --cal "mycalendar" import %U
Icon=chromium-browser
Terminal=false
TryExec=chromium-browser
Type=Application
MimeType=application/x-calendar;x-scheme-handler/ics;
Categories=Network;
X-AppInstall-Keywords=calendar

it shows up with the:

  • WHERE bits:
    Webex and Con Call
  • TEXT bits:

All,

This is a Placeholder for next week’s TOI –
Webex and Con Call details will follow.

/Sune

but the atendee list is missing

Intermittent fault when importing ics file

When running: 'gcalcli import CalendarEvent.ics' i get an error
some of the time (maybe 1/3 or 1/5 or 1/10 of the time), and the events are not imported. The other times i get no error, and the events are imported.

Version: gcalcli v2.2 (Eric Davis) - from debian testing
The CalendarEvent.ics file: https://gist.github.com/4279685

The error:

/x/d> gcalcli import CalendarEvent.ics
Traceback (most recent call last):
File "/usr/bin/gcalcli", line 1579, in
BowChickaWowWow()
File "/usr/bin/gcalcli", line 1568, in BowChickaWowWow
gcal.ImportICS(verbose, args[0])
File "/usr/bin/gcalcli", line 1188, in ImportICS
PrintErrMsg("Error: " + e["reason"] + "\n")
TypeError: sequence index must be integer, not 'str'

dateutil bug

Old version worked, but new version of gcalcli on opensuse 12.2 generates following error.
for any command (eg gcalcli list). I changes the set default for python to utf-8 but that did not help (that was necessary in previous version).
File "/home/wbmacleod/bin/gcalcli", line 2242, in
BowChickaWowWow()
File "/home/wbmacleod/bin/gcalcli", line 2091, in BowChickaWowWow
configFolder=FLAGS.configFolder
File "/home/wbmacleod/bin/gcalcli", line 461, in init
self._GetCached()
File "/home/wbmacleod/bin/gcalcli", line 591, in _GetCached
event['s'] = parse(event['start']['dateTime'])
File "/usr/lib/python2.7/site-packages/dateutil/parser.py", line 720, in parse
return DEFAULTPARSER.parse(timestr, **kwargs)
File "/usr/lib/python2.7/site-packages/dateutil/parser.py", line 310, in parse
raise ValueError("unknown string format")
ValueError: unknown string format

indent and wrap description text in agenda output

When the --detail-all or --detail-descr option is used for the 'agenda' command the resulting text can be downright ugly. I'd like to see the description text indented properly, word wrapped to a specified width (even wrapped text is indented), and for extra credit optionally boxed with ascii text (i.e. '-' and '|').

Importing ics Events with Comma in SUMMARY/DESCRIPTION fields

I'm trying to import a .ics file. The SUMMARY and DESCRIPTION fields contain commas. The event is imported successfully, but SUMMARY and DESCRIPTION are only parsed until the first comma.

This is my .ics file I try to import:

[beni@lilobster:~]$ cat Downloads/SBBVerbindung\ \(9\).ics
BEGIN:VCALENDAR
VERSION:2.0
PRODID:http://www.hacon.de
METHOD:PUBLISH
BEGIN:VTIMEZONE
TZID:Europe/Berlin
X-LIC-LOCATION:Europe/Berlin
BEGIN:DAYLIGHT
TZOFFSETFROM:+0100
TZOFFSETTO:+0200
TZNAME:CEST
DTSTART:19700329T020000
RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=3
END:DAYLIGHT
BEGIN:STANDARD
TZOFFSETFROM:+0200
TZOFFSETTO:+0100
TZNAME:CET
DTSTART:19701025T030000
RRULE:FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=10
END:STANDARD
END:VTIMEZONE
BEGIN:VEVENT
UID:hafas1747939549
CLASS:PUBLIC
SUMMARY:Zürich, Kalkbreite -> Trimmis, Churweg
DTSTART;TZID=Europe/Berlin:20130208T191800
DTEND;TZID=Europe/Berlin:20130208T205800
DTSTAMP:20130208T121500Z
URL:http://fahrplan.sbb.ch/bin/query.exe/dn?S=Z%FCrich,%20Kalkbreite&Z=Trimmis,%20Churweg&date=08.02.13&time=19%3A18&
DESCRIPTION:Reise: Zürich, Kalkbreite nach Trimmis, Churweg\nDatum: 08.02.13\n-\nab 19:18 Zürich, Kalkbreite  (Tram 2, Richtung: Zürich Tiefenbrunnen, Bahnhof)\nan 19:20 Zürich, Stauffacher \n\nab 19:22 Zürich, Stauffacher  (Tram 14, Richtung: Zürich, Seebach)\nan 19:27 Zürich, Bahnhofplatz/HB \n\nab Zürich, Bahnhofplatz/HB  (Fussweg)\nan Zürich HB \n\nab 19:37 Zürich HB - Gleis 7 (IC 587)\nan 20:41 Landquart - Gleis 2ABC\n\nab Landquart  (Fussweg)\nan Landquart, Bahnhof \n\nab 20:45 Landquart, Bahnhof  (BUS 3571)\nan 20:58 Trimmis, Churweg \n-\nDauer 1:40, Umsteigevorgänge 3\n\n\nFahrplan:\nhttp://fahrplan.sbb.ch/bin/query.exe/dn?S=Z%FCrich,%20Kalkbreite&Z=Trimmis,%20Churweg&date=08.02.13&time=19%3A18&\n \nÄnderungen vorbehalten. Alle Angaben, Anschlüsse und Einhaltung des Fahrplans ohne Gewähr.\nhttp://www.sbb.ch 
END:VEVENT
END:VCALENDAR

And then the output from gcalcli:

[beni@lilobster:~]$ gcalcli import -v Downloads/SBBVerbindung\ \(9\).ics
Event........Zürich
Start........2013-02-08 19:18:00+01:00
End..........2013-02-08 20:58:00+01:00
Local Start..2013-02-08 19:18:00+01:00
Local End....2013-02-08 20:58:00+01:00
Description:
Reise: Zürich

[S]kip [i]mport [q]uit: q

As you can see, the "Event" is only "Zürich" but really should be "Zürich, Kalkbreite -> Trimmis, Churweg", and Description is only "Reise: Zürich" without the following stuff.

I'm using gcalcli master, rev 8262bf9.

Regards
Benedikt

support multi-day events

gcalcli should show multi-day events across each day for agenda, calw, and calm outputs.

If someone wants to give it a shot... go for it! :-)

Error: Event being modified contains too many reminders.

gcalcli can't add reminder when quick add event to calendar.


./gcalcli --user USERNAME --pw PASSWORD --reminder 1 quick 'test 121'
New event added: https://www.google.com/calendar/event?eid=cDRFwerfAzcGdFKmskdiVlisejmAoFZ0BnYWxpFSsrwraXkSDFrwerldi51YQ
Update error: Forbidden
Error: Event being modified contains too many reminders.
Update error: Forbidden
Error: Event being modified contains too many reminders.
Update error: Forbidden
Error: Event being modified contains too many reminders.
Update error: Forbidden
Error: Event being modified contains too many reminders.
Update error: Forbidden
Error: Event being modified contains too many reminders.
Update error: Forbidden
Error: Event being modified contains too many reminders.
Failed to update event!


Please fix it.

Thanks.

timezone calculation wrong for some events

The old bug #70 from the googlecode tracker is still around. The workaround still applies. Copied from the googlecode tracker (with updated line number):


My calendar setting seems to already be set to the proper time zone, "(GMT-5) Eastern" (although with the current state of daylight saving time it should be GMT-4).

It appears that the issue is that Google sends some events in local time and some events in UTC time, and gcalcli doesn't convert to local time. I fixed it by adding the following after the times are parsed on line 801:

            event.s = event.s.astimezone(tzlocal())
            event.e = event.e.astimezone(tzlocal())

This seems to work, but I don't know enough about the code to know if changes also need to be made elsewhere.

can't find config file

Hi there, I can't find the config file. Also, how can I display my calendars without having to enter my username and password everytime?

Can add events, but agenda reports "no events found"

Great concept guys, I love it!

Just installed gcalcli 2.1 using apt-get on Unbuntu 12.04, running on an x86 machine with a 3.0Ghz processor and 2GB of RAM. I set up the gcalclirc file with my username and password, it connects just fine.

I can add events - "gcalcli quick 'meet joe 7pm'", and they appear in Google Calendar and on my phone!

Awesome stuff, so simple, you guys rock!

But "gcalcli agenda", "gcalcli --cals=all agenda" and "gcalcli calw" all report "No events found" (or just show nothing but the dates in calw's case), even though I added said events through gcalcli, and they are displayed correctly on Google website and on my mobile.

I've tried manually specifying times "gcalcli agenda 2pm 9pm", but I still get "No events found".

Any idea what I'm doing wrong? :-(

I thought my firewall might be disrupting something, but one "sudo ufw disable" later I'm still getting "No events found".

gcalcli & geektool : just the beginning displayed in week view

Hello,

I'm trying to use gcalcli with geektool (Mountain Lion, MBPr 2013).
With this command :
/usr/local/bin/gcalcli --nc calw 1
and with only one or all or a part of my calendars, it will only show between 6AM and 11AM, sometimes more.

I have no problem in a normal shell in OS X ( zsh)

Yann

BOOM!!! Daily limit reached...

gcalcli from 'master' seems to be popular! We've easily reached the daily 10K request limit. This quota is tied to the gcalcli client application key which is in turn tied to my Google account. There are two temporary solutions and one long term solution...

Short term:

  1. Increase the daily quota limit.
  2. Change gcalcli so each user has to create their own client application key tied to their own Google account.

Long term:

  1. Caching.

I don't like the idea of each user having to create their own client application key. This is a hassle and something you don't have to do for any other application using the various Google APIs.

Today I put in a request to Google to raise the daily quota to 1M requests per day. Hopefully this will be enough until we fully support caching. Btw, see the 'caching' branch for that work.

Traceback (most recent call last):
  File "/mnt/raid/insanum/src/gcalcli/gcalcli", line 2427, in <module>
    BowChickaWowWow()
  File "/mnt/raid/insanum/src/gcalcli/gcalcli", line 2257, in BowChickaWowWow
    useCache=useCache)
  File "/mnt/raid/insanum/src/gcalcli/gcalcli", line 539, in __init__
    self._GetCached()
  File "/mnt/raid/insanum/src/gcalcli/gcalcli", line 623, in _GetCached
    calList = self._CalService().calendarList().list().execute()
  File "/usr/lib/python2.7/site-packages/oauth2client/util.py", line 120, in positional_wrapper
    return wrapped(*args, **kwargs)
  File "/usr/lib/python2.7/site-packages/apiclient/http.py", line 678, in execute
    raise HttpError(resp, content, uri=self.uri)
apiclient.errors.HttpError: <HttpError 403 when requesting https://www.googleapis.com/calendar/v3/users/me/calendarList?alt=json&key=AIzaSyA6qJCdEnUiOX7Y79Ro5eA2toInxwWCikc returned "Daily Limit Exceeded">

configFolder doesn't work

Have you even tried to use it? You check for gcalcli and read gcalclirc:

    if os.path.exists(os.path.expanduser("%s/gcalcli" % FLAGS.configFolder)):
        if not FLAGS.includeRc:
            tmpArgv = argv + ["--flagfile=~%s/gcalclirc" % FLAGS.configFolder, ]
        else:
            tmpArgv += ["--flagfile=~%s/gcalclirc" % FLAGS.configFolder, ]

And "~%s" should be "%s".

Also, it would be nice to check for a default configFolder without having to specify it (.config/gcalcli is a good default).

calendar names

I've noticed yesterday that gcalcli doesnt like calendar names like:

  • someCalendar
  • another.Calendar
  • yet-another-Calendar

It only wanted to work with all lowercase names, like "imacalendar".
Issue showed up on ubuntu 12.04 server

Can you reproduce this error or is it just me?

needs caching

gcalcli needs to support caching by being able to download a specified range of events and use that cache for the various viewing mode commands used by gcalcli. This would speed up anything that uses gcalcli for visibility (i.e. scripts, conky, screen, tmux, reminders, etc) and still work in an offline mode.

Man page

gcalcli --help gives useful information but it would be really convenient to access this information as a man page.

gcalcli screws up timezone conversion

Here's my calendar viewed from Google Calendar:

Google Calendar

Here's the same calendar viewed from gcalcli:

mfag@mfag-tpad:~:$ gcalcli calw

+----------+----------+----------+----------+----------+----------+----------+
|Sunday    |Monday    |Tuesday   |Wednesday |Thursday  |Friday    |Saturday  |
+----------+----------+----------+----------+----------+----------+----------+
|17 Feb ** |18 Feb    |19 Feb    |20 Feb    |21 Feb    |22 Feb    |23 Feb    |
|          |          |          |          |          |          |          |
|          |10:00 Пм  |          |15:30     |          |16:00 ЧГК |12:00     |
|          |          |          |Codeforces|          |          |Личная    |
|          |          |          |Round     |          |          |олимпиада |
|          |          |          |#168      |          |          |школьников|
|          |          |          |(Div. 2)  |          |          |          |
|          |          |          |          |          |          |          |
|          |          |          |15:30     |          |          |          |
|          |          |          |Codeforces|          |          |          |
|          |          |          |Round     |          |          |          |
|          |          |          |#168      |          |          |          |
|          |          |          |(Div. 1)  |          |          |          |
+----------+----------+----------+----------+----------+----------+----------+

Note the incorrect start time for events "Codeforces Round #168 (Div. 2)" and "<...> (Div. 1)". I guess that the reason for this is that these events are imported from a public calendar, where they are presumably stored in UTC or some other timezone, but my home timezone is Europe/Riga (UTC+2 normally, UTC+3 during DST). Can this be fixed?

gcalcli - location is not appearing with agenda

Good Morning,

Problem: the location does not show up on an agenda call, either in the normal or --tsv format. I am running version 2.3.

Example: I have added an event with a location. In the online Google calendar, I can see the location, but I don't get the location when I run the gcalcli command.

Thank you for your time and consideration.

fred@P3200:~/Documents/SearchesAndTempLogs$ gcalcli --config /home/fred/scripts/vars/fgcalclirc.txt --title 'This should be the Title' --where 'This should be the location' --when '02/01/2013 21:30' --duration 60 --descr 'This is the description' --reminder 240 add
New event added: https://www.google.com/calendar/event?eid=NzQ1MmJtcW9pa3Q3czJodnNyczR1NGN1NWMgY29udHJhY29ybmVyc0Bt

fred@P3200:~/Documents/SearchesAndTempLogs$ /usr/bin/gcalcli --detail-all --config /home/fred/scripts/vars/fgcalclirc.txt agenda
Fri Feb 01 9:30pm This should be the Title
Length: 1:00:00
Description:
-----------------------------------------------------------
This is the description
-----------------------------------------------------------

fred@P3200:~/Documents/SearchesAndTempLogs$ /usr/bin/gcalcli --detail-all --tsv --config /home/fred/scripts/vars/fgcalclirc.txt agenda
2013-02-01 21:30 22:30 This should be the Title This is the description

fred@P3200:/Documents/SearchesAndTempLogs$ /usr/bin/gcalcli --version --config /home/fred/scripts/vars/fgcalclirc.txt
gcalcli v2.3 (Eric Davis)
fred@P3200:
/Documents/SearchesAndTempLogs$

Additional API Usage (e.g. event notes)

Currently gcalcli only does quick add and doesn't use the APIs createEvent function. Quick add doesn't allow users to add notes about an event.

Perhaps some syntax like:

gcalcli -chstv add [title] [start/when] [end]

where:
-c is --content
accepts a string for event content (--content="Some special notes about this event")
-h is --html
sets the contents mime-type as HTML
-s is --status
sets the event status as confirmed=1, tentative=0, or canceled=-1
-t is --transparency
can be set to 0 or 1 (--transparency=0)
-v is --visibility
can be set to 0 or 1 (--visibility=0)

https://developers.google.com/google-apps/calendar/v1/developers_guide_php#CreatingEvents

I would like to see some traction ;-) especially content.

add a detailed event to a calendar - gflags.py error

Hi.
I try add event by:

./gcalcli --cal 'my calendar' --title 'test' --descr '' --reminder 0 --where '' --when '03/08/2013 10:00' --duration 60 add

and I get an error:

File "./gcalcli", line 2242, in
BowChickaWowWow()
File "./gcalcli", line 2182, in BowChickaWowWow
if FLAGS.descr == None and FLAGS.prompt:
File "/usr/local/lib/python2.6/dist-packages/python_gflags-2.0-py2.6.egg/gflags.py", line 1059, in getattr
raise AttributeError(name)
AttributeError: descr

use python-keyring for password management

python keyring1 provides a interface for multiple password manager such as OSXKeychain,KDEKWallet or GnomeKeyring.

I wrote a small patch for gcalcli which support usage of python-keyring

--- gcalcli 2012-12-12 12:52:23.000000000 +0100
+++ gcalcli 2012-12-12 12:32:53.000000000 +0100
@@ -1379,7 +1379,15 @@

     try:
         if pwd == None:
-            pwd = getpass.getpass("Password: ")
+            try:
+                import keyring
+                pwd = keyring.get_password('www.google.com/calendar', usr)
+            except ImportError:
+                PrintErrMsg("keyring library not found")
+            if pwd == None:
+                pwd = getpass.getpass("Password: ")
+                # TODO check password?
+                keyring.set_password('www.google.com/calendar', usr, pwd)
     except Exception, e:
         PrintErrMsg("Error: " + str(e) + "!\n")
         sys.exit(1)

Support updated/moved/cancelled events from ics/vcal files when importing

gcalcli needs to support importing events from ics/vcal files (i.e. from Exchange) that have previously been entered and are now updated, moved, or cancelled.

I haven't looked closely at the ICS spec but I think there is a UID field in there which is used for tracking individual meetings which can be tagged onto a Google Calendar event.

Switch arg parsing library

argparse should allow more versatility so that we don't have commands (like add) where the options come before the commands themselves. Also may allow us to clean up the current initialization code.

gflags is used by the google-api module already.

syntax error on ";", doesn't compile.

I downloaded gcalcli.py, tried 'gcalci --help' and it gives me:

File "/usr/bin/gcalcli", line 610
    if event['s'].year &gt;= 2038 or event['e'].year &gt;= 2038:
                          ^
SyntaxError: invalid syntax

I tried to comment that section out (I'll probably be dead by 2038 : D) and it gives me:

File "/usr/bin/gcalcli", line 674
    if self.now &lt; startDateTime or self.now &gt; endDateTime:
                   ^
SyntaxError: invalid syntax

Tried to uncomment line 674 and folowing if clause and get:

File "/usr/bin/gcalcli", line 686
    if dayNum &lt; 0:
                 ^
SyntaxError: invalid syntax

so i immagine it's a problem with ";"
I've installed parsedatetime, am using archlinux (had to change the shebang to /usr/bin/env python2 since standard python is python3) and I have no gcalcli configuration

Request error on valid calendar item

After issuing

$ gcalcli quick '06/09/12 6pm unix kurs (PVV)'

I receive a gdata.service.RequestError. And the entire stack trace is:

Traceback (most recent call last):
File "/usr/bin/gcalcli", line 1512, in
BowChickaWowWow()
File "/usr/bin/gcalcli", line 1487, in BowChickaWowWow
gcal.QuickAdd(unicode(args[1], locale.getpreferredencoding()))
File "/usr/bin/gcalcli", line 1011, in QuickAdd
self.gcal.InsertEvent(quickEvent, self._TargetCalendar())
File "/usr/lib/python2.7/site-packages/gdata/calendar/service.py", line 159, in InsertEvent
converter=gdata.calendar.CalendarEventEntryFromString)
File "/usr/lib/python2.7/site-packages/gdata/service.py", line 1236, in Post
media_source=media_source, converter=converter)
File "/usr/lib/python2.7/site-packages/gdata/service.py", line 1347, in PostOrPut
redirects_remaining - 1, media_source, converter=converter)
File "/usr/lib/python2.7/site-packages/gdata/service.py", line 1347, in PostOrPut
redirects_remaining - 1, media_source, converter=converter)
File "/usr/lib/python2.7/site-packages/gdata/service.py", line 1347, in PostOrPut
redirects_remaining - 1, media_source, converter=converter)
File "/usr/lib/python2.7/site-packages/gdata/service.py", line 1347, in PostOrPut
redirects_remaining - 1, media_source, converter=converter)
File "/usr/lib/python2.7/site-packages/gdata/service.py", line 1355, in PostOrPut
'body': result_body}
gdata.service.RequestError: {'status': 302, 'body': '\n\n<TITLE>Moved Temporarily</TITLE>\n\n\n

Moved Temporarily

\nThe document has moved here.\n\n\n', 'reason': 'Redirect received, but redirects_remaining <= 0'}

After immediately issing the same command, there is no error and the item is inserted in my calendar.

An other issue is that the date is wrong. The item is inserted for today, and not 6. september as I wrote it.

Error: [gcalcli] is an invalid command

Previous version (2.1, installed 28 Dec 2012) works, but current HEAD returns "Error: [gcalcli] is an invalid command" regardless of command. I know that's not very helpful; is there a way to get a more verbose error?

Add feature to locally view ICS/VCAL files

I assume currently gcalcli parses ICS/VCAL files locally then imports them into the Google Calender account? It would be great to have a feature to just output the converted ICS/VCAL information and exit, without logging into the Google account (which takes a few seconds).

I'd like to use this feature for better handling viewing ICS attachment in Mutt. Currently I use the following in my mailcap file:

text/calendar; echo q | PYTHONIOENCODING=utf-8 gcalcli import -v %s; copiousoutput;

It works great, but it's just slow. I know there are other scripts available I could use to do this, but it would be good to have this feature in gcalcli, since that's what I'm ultimately using to import the ICS file into my Calender, and if the code already exists to convert and display the ICS file in gcalcli, it makes sense to use that.

Thanks,
Michael

Stripping of unicode/Emoji possible?

Some calendars that I share with friends/family tend to use Emoji characters (see http://www.unicode.org/charts/PDF/U1F300.pdf). These are correctly displayed (albeit with a light background on an otherwise dark terminal for non-standard emojis) but overlapping with the next character, rendering the beginning of calendar entries illegible (see http://cl.ly/1T0j2Z2v2i0t3J203E3Y)

Is it somehow possible to strip these characters from the text that gcalcli displays?

Current master broken?

Hi,
first - thanx for Your great work! It is incredibly helpful tool.

Is it just me or is current master branch broken? I have problem with args list (agrs[0] is first line from my config file, not action as it should?).

Thank you!

Leszek

Allow different Start- and End-Timezones

In the Google Calendar web interface, it's possible to create events with different start and end time zones:

  1. Create Event
  2. Click "Time zone" link
  3. Enable "Use separate start and end time zones"

I would like to specify start- and end-timezones through gcalcli. For example. the 'add' option could take '--starttime' and '--endtime' parameters with a zone specifier (e.g. "-0400", or "UTC").

Regards
Benedikt

--cal command line parameter doesn't overwrite the config file parameter

Hi,

I'm not sure what the intended behaviour is supposed to be, but when I specify a calender on the command line, it is added to the calendars already specified in the config file, rather than replacing them.

So it's not possible to only look at a specific calender, without removing any others from the config file. When I use the import option, I notice the event is imported to the first calender I've specified in the config file, and not the one I specify with --cal in the import command.

Thanks,
Michael

can't add to non-default calendar

The documentation implies that with the use of --cal you can specify a different calendar to add your event to. This does not work.

  1. add new calendar called "playground"
  2. gcalcli --cal playground quick 'kickball at 3pm'
  3. event is added to your default/Personal calendar, not the one called "playground"

I've experimented with the syntax for nearly an hour with no success....

conky, only first date shown

I put the line ${execi 300 gcalcli --nc agenda} into .conkyrc, and only the first line is shown, or actually only the date of the first line is shown: "Wed Jun 20".

A similar (probably related) problem occurs in the terminal when i try 'gcalcli --nc agenda > file', only the first date is streamed to the file, and i get a bunch of errors:

Traceback (most recent call last):
File "/usr/bin/gcalcli", line 1524, in
BowChickaWowWow()
File "/usr/bin/gcalcli", line 1447, in BowChickaWowWow
gcal.AgendaQuery()
File "/usr/bin/gcalcli", line 960, in AgendaQuery
self._PrintEvents(start, eventList)
File "/usr/bin/gcalcli", line 751, in _PrintEvents
('', self._ValidTitle(event.title.text).strip()))
File "/usr/bin/gcalcli", line 236, in PrintMsg
sys.stdout.write(cunicode(msg))
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe5' in position 10: ordinal not in range(128)

Tag a release

Any chance you could tag a numbered release?

If 2.2 was meant to be released with the changes last July, I'd recommend using d4f058d .

git tag 2.2 d4f058dfe45b9bf1136b9269170b2b7ee92b094e
git push origin 2.2

And the for the stuff being worked on now on now, maybe some tags for snapshot/dev releases?

git tag 2.3a1
git push origin 2.3a1

Honestly I just want to update the MacPort's PortFile and they didn't seem to like my idea of using git commit hashes. But looking at Debian, Ubuntu, and other distros, many are still using the 2.1 release from Google Code.

Unicode issues again

Hi to all,

It shows:
BowChickaWowWow()
File "/usr/bin/gcalcli", line 1500, in BowChickaWowWow
gcal.AgendaQuery()
File "/usr/bin/gcalcli", line 965, in AgendaQuery
self._PrintEvents(start, eventList)
File "/usr/bin/gcalcli", line 757, in _PrintEvents
(tmpTimeStr, self._ValidTitle(event.title.text).strip()))
File "/usr/bin/gcalcli", line 242, in PrintMsg
sys.stdout.write(unicode(msg, 'UTF-8'))
UnicodeEncodeError: 'ascii' codec can't encode character u'\xf3' in position 40: ordinal not in range(128)

When I try this:
gcalcli --24h --cals owner --nc agenda | tee -i ~/.gcal/gcal

or this:

gcalcli --24h --cals owner --nc agenda -> ~/.gcal/gcal

oauth2 failing

I'm attempting to authenticate with the --noauth_local_webserver switch. After I enter the verification code from Google, I receive the following traceback. I get that the issue is somehow related to SSL, but beyond that, I'm not sure what's going...

Are there additional dependencies which I'm missing?

Traceback (most recent call last):
File "gcalcli", line 2242, in
BowChickaWowWow()
File "gcalcli", line 2091, in BowChickaWowWow
configFolder=FLAGS.configFolder
File "gcalcli", line 461, in init
self._GetCached()
File "gcalcli", line 551, in _GetCached
calList = self._CalService().calendarList().list().execute()
File "gcalcli", line 502, in _CalService
http=self._GoogleAuth(),
File "gcalcli", line 490, in _GoogleAuth
storage)
File "/usr/local/lib/python2.7/site-packages/google_api_python_client-1.1-py2.7.egg/oauth2client/util.py", line 128, in positional_wrapper
return wrapped(_args, *_kwargs)
File "/usr/local/lib/python2.7/site-packages/google_api_python_client-1.1-py2.7.egg/oauth2client/tools.py", line 197, in run
credential = flow.step2_exchange(code, http=http)
File "/usr/local/lib/python2.7/site-packages/google_api_python_client-1.1-py2.7.egg/oauth2client/util.py", line 128, in positional_wrapper
return wrapped(_args, *_kwargs)
File "/usr/local/lib/python2.7/site-packages/google_api_python_client-1.1-py2.7.egg/oauth2client/client.py", line 1283, in step2_exchange
headers=headers)
File "/usr/local/lib/python2.7/site-packages/httplib2-0.8-py2.7.egg/httplib2/init.py", line 1570, in request
(response, content) = self._request(conn, authority, uri, request_uri, method, body, headers, redirections, cachekey)
File "/usr/local/lib/python2.7/site-packages/httplib2-0.8-py2.7.egg/httplib2/init.py", line 1317, in _request
(response, content) = self._conn_request(conn, request_uri, method, body, headers)
File "/usr/local/lib/python2.7/site-packages/httplib2-0.8-py2.7.egg/httplib2/init.py", line 1252, in _conn_request
conn.connect()
File "/usr/local/lib/python2.7/site-packages/httplib2-0.8-py2.7.egg/httplib2/init.py", line 1021, in connect
self.disable_ssl_certificate_validation, self.ca_certs)
File "/usr/local/lib/python2.7/site-packages/httplib2-0.8-py2.7.egg/httplib2/init.py", line 80, in _ssl_wrap_socket
cert_reqs=cert_reqs, ca_certs=ca_certs)
File "/usr/local/lib/python2.7/ssl.py", line 381, in wrap_socket
ciphers=ciphers)
File "/usr/local/lib/python2.7/ssl.py", line 141, in init
ciphers)
ssl.SSLError: [Errno 185090050] _ssl.c:340: error:0B084002:x509 certificate routines:X509_load_cert_crl_file:system lib

Set custom locale

It should be possible to set a custom locale maybe via:
--locale=en_EN.UTF-8

I hard coded my locale this way:
locale.setlocale(locale.LC_ALL, 'de_DE.UTF-8')

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.