Giter Club home page Giter Club logo

touchselfie's Introduction

Thanks to an amazing pull request from @laurentalacoque we now have a ton of new features!

Download and check them out!

News! Now fully compatible with Google Photos API

Original version of TouchSelfie was based on the, now deprecated, PICASA web API. The Picasa Web API is discontinued since January 2019. This version of TouchSelfie handles the new API with the following conditions:

  • You must enable 'Google Photos API' (and 'Gmail' if you want the 'send email' feature) on your google developers console. See this article for help configuring your Google project and downloading your credentials file.
  • You must download your app secret file to the following file : scripts/google_client_id.json
  • You must relaunch the setup

Difference with previous Picasa Web API

  • This new API is safer and better for your privacy!
    • TouchSelfie only asks for the minimum amount of permission: it can only append photos and albums and only can access to items created by the application. This way, it makes it impossible for TouchSelfie to access informations or photos that you uploaded yourself
  • This means that you can't select any album of your photo library, but your MUST create an album using the setup.py script. For this, just use the Select Album button and choose the <Create new> entry. (If you prefer to upload your photos in your photos library instead of an album as your camera does, just select <No Album> instead). Once your album is created, it will be populated with a random color square: don't remove it, otherwise this will delete the album)

TouchSelfie

Open Source Photobooth forked and improved from wyolum/TouchSelfie

For hardware construction, see Make Magazine article

Take a shortcut:

Installing (extracted and adapted from Make Magazine)

Complete Video Howto

For a very nice How-To of how to set up your photobooth, don't miss the video below! Many thanks to Caroline Dunn for her great teaching skills.

Caroline Dunn's TouchSelfie installation howto

Get the necessary packages

# update system
sudo apt-get update

# Install ImageTk, Image from PIL
sudo apt-get install python-imaging
sudo apt-get install python-imaging-tk

# Install google data api and upgrade it
sudo apt-get install python-gdata
sudo pip install --upgrade google-api-python-client
sudo pip install --upgrade oauth2client

# Install ImageMagick for the 'Animation' mode
sudo apt-get install imagemagick

# Install CUPS for the Printing function(optional)
sudo apt-get install cups
sudo apt-get install python-cups

# Setting up  CUPS/printer(optional)
https://www.techradar.com/how-to/computing/how-to-turn-the-raspberry-pi-into-a-wireless-printer-server-1312717
Test device:
Canon Selphy CP1300 with the Canon SELPHY CP900 - CUPS+Gutenprint v5.2.11  driver over USB

If google chrome is not on your system, the following might be necessary:

sudo apt-get install luakit
sudo update-alternatives --config x-www-browser

Optional: create a Google project and enable the APIs

This is only needed if you plan to use the 'send email' or 'upload images to cloud' features of TouchSelfie. Here's an article that will help you creating a project and downloading its credentials

Configure the program

  1. run setup.sh script, this will:
  • guide you through the feature selection (email feature, upload feature)
  • Google Photos album selection
  • and will create a photobooth.sh launcher
  1. setup.sh creates a configuration file scripts/configuration.json, you can edit this file to change configuration parameters, such as:
  • the logo file to put on your pictures
  • email subject and body
  • wether or not to archive snapshots locally
  • where to store pictures locally
  1. Optionally you can change lower-level configuration options in the file scripts/constants.py such as:
  • captured image sizes
  • hardware dependent things

Changes from wyolum/TouchSelfie

Zero password

  • Now integrally based on OAuth2, neither the send-email, nor the upload-pictures will ask for and store a password. You will need to create a Google project if you plan to use these features

Send mails even from protected networks

  • Many faculty/company networks block the sendmail port. By using OAuth2 authentication, photobooth emails are seen as https connection and are not blocked by the network anymore. (Again, create a Google project for this)

Easier setup

  • a new setup.sh assistant will guide you through the configuration of the features you need (send_email, auto-upload) and will help you install the Google credentials.

Hardware buttons support

  • Added GPIO hardware interface for three buttons (with connections in hardware/ directory). Each button triggers a different effect. Software buttons are added if GPIO is not available. See scripts/constants.py to enable hardware buttons.

Print selfies immediately

  • A new 'print' button allows you to print selfies on a preconfigured printer (courtesy Pikokosan)

New effects

  • Added "Animation" effect that produces animated gifs (needs imagemagick)

example animation

  • Choose among PiCamera builtin image effects for more creative snapshots

Effects Palette

Higher resolution pictures

  • supports new v2.1 pi camera
  • Supports arbitrary resolution for snapshots (configure it in constants.py)

Better snap preview mode

  • Preview now uses images for countdown: be creative! see constants.py for customizations.
  • Preview is now horizontally flipped which is consistent with cameraphone behaviors and your bathroom mirror. (Previous mode was confusing for users)

User interface improvements

  • Modern "black" userinterface with icon buttons

user interface

  • New skinnable Touchscreen keyboard "mykb.py"

new keyboard

  • Removed configuration button to avoid pranks

    • use setup.sh to setup credentials and setup Google Photo Album
    • tune configuration in constants.py
    • limited runtime configuration (exit, enable/disable email and upload) is still possible via long press)
  • snapshot display now supports animated gifs

  • Mail address logging available in configuration

    • photobooth users can opt-out from the mail logging if activated
  • command line arguments to enable/disable some features:

    • enable/disable fullscreen startup
    • enable/disable email sending
    • enable/disable auto-upload
    • enable/disable hardware buttons support (on-screen buttons displayed instead)
    • Use python user_interface.py --help for a description of command line options

A note on security and confidentiality

  • During setup, you ask me to allow this application to access my email, the original TouchSelfie didn't do this, why?

The Original TouchSelfie script used to store you google account and password in a .credentials file.

Considering it was a security risk, I prefered to code an alternate email-sending procedure that wouldn't require your password to get things done.

This is achieved via OAuth2 mechanism that only requires that you accept (once) that this application can access to your email. This way is safer since there's no way for the application to do anything other than what you accepted it to do.

  • Wait, I don't want email sending, but you still ask me to accept that!

To simplify the setup process, the setup assistant points you to a google credentials download page where email authorization is enabled by default. You can change this.

If you configured TouchSelfie to not send emails, you don't need to authorize access to your mail box, just change this during the credentials download process. This way, the application will only require basic authorization to your account.

  • Will YOU have access to my emails?

No, but don't take my word!

This is the beauty of opensource: everybody can read the source code and check if it's harmfull. Plus, with Github, you can't hide anything: every versions of this code is archived and I can't delete them: you will always be able to verify that I didn't do anything harmfull in the past.

Maybe you don't have the competency to verify the sourcecode, but others have and I trust they will alert the world if they find something nasty (or just file an Issue!).

Hint for future verifyiers: the scripts/oaut2services.py contains all the code that accesses the Google Accounts. As you will see in the __init__ method of the OAuthServices class, the only scope that is requested it the https://www.googleapis.com/auth/gmail.send that restricts the permission of the application to only sending emails on your behalf. (See this official doc)

  • Will YOU have access to my photos?

No, but again, don't take my word for it ;) take a look at scripts/oauth2services.py where all Google account access are done. In the __init__ method of the OAuthServices class, the only scope(s) that are requested for the photo library are:

  • https://www.googleapis.com/auth/photoslibrary.appendonly : can't browse for your photos or directories
  • https://www.googleapis.com/auth/photoslibrary.readonly.appcreateddata: can only access items created by this app

See official doc for the Google Photos API scopes.

  • Why do I need to create a project on Google Developers? Can't you provide one?

Your Security and My Quota.

By retrieving yourself application credentials, you basically authorize yourself to access your own google account and you can revoke this whenever you want. Also, Application Credentials have a daily limit of free use, If I were to provide you my own credentials, a group of users would consume this quota in no time, leaving everybody with a bad experience.

touchselfie's People

Contributors

anool avatar ghislainjo avatar jephilosoraptor avatar koljatm-edeka avatar laurentalacoque avatar osbock avatar pikokosan avatar wyojustin 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

Watchers

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

touchselfie's Issues

“No hardware buttons found”

Hi!
Thank you for a great project.

However I can for the love of my life not get the hardware buttons to work.
I am using this button from adafruit: [https://learn.adafruit.com/press-your-button-for-raspberry-pi/assembly] with the same suggested wiring.

I have tried putting the wire on both 8, 10 and 12 pins. I have also tried changing them to 11, 13 and 15 in without any difference. Tried different wires and different switches. I have tried both pull_up and pull_down and changed active state in constants.py.
The led on the button is working but upon quitting photo booth, I am presented with: “No hardware buttons found, generating software buttons” every time.

Anyone have some input on what I am doing wrong?
Cheers

Google hasn't verified this app

Hello,

When I enable the upload of the pictures to a Google Photo album, I get this error message :
Google hasn't verified this app

I click on 'Show advanced' and then on the hyperlink redirecting me to https://accounts.google.com/#

Have I misconfigured something ?

Thanks

Offline Usage

What I have found is that in the setting I wish to use it (a camp), there is not always reliable internet and so while the online upload feature is nice is it possible to disable it so that the system can work offline as the system basically goes back and forth between working perfectly to not working at all due to not great internet.

Print photos from smartphone?

Hi,

I am wondering if your nice project is also able to download photos from bluetooth-connected smartphone and print them.
Is it restricted to only print the selfie that it takes?

Thanks
Fabio

Alexa integration

Hello
I'm wondering if this wonderful project can be integrated someway with Alexa in order to control the shoots with the voice
Thanks a lot!

Camera Ringlicht - Camera with WS2812 LED lighting

Hi all,

I've been trying to integrate with the Ringlicht - it's a little board that has 12 WS2812 LEDs - perfect for lighting up the scene before a shot.

https://github.com/watterott/RPi-Camera-RingLicht

Altough my experiments with the WS2812 leds and python2 are successful, I fail to integrate both. Maybe someone with a bit more python knowledge (mine is really low) could help here.

Right now I am using this libary and the examples for python of this GithHub repo work nicely, also my own examples based on these:

https://github.com/rpi-ws281x

My example code alone looks similar to this:

import time
from rpi_ws281x import PixelStrip, Color

LED_COUNT = 12        # Number of LED pixels.
LED_PIN = 18          # GPIO pin connected to the pixels (18 uses PWM!).
# LED_PIN = 10        # GPIO pin connected to the pixels (10 uses SPI /dev/spidev0.0).
LED_FREQ_HZ = 800000  # LED signal frequency in hertz (usually 800khz)
LED_DMA = 10          # DMA channel to use for generating signal (try 10)
LED_BRIGHTNESS = 255  # Set to 0 for darkest and 255 for brightest
LED_INVERT = False    # True to invert the signal (when using NPN transistor level shift)
LED_CHANNEL = 0       # set to '1' for GPIOs 13, 19, 41, 45 or 53


# Define functions which animate LEDs in various ways.
def color(strip, color, wait_ms=50):
    """Wipe color across display a pixel at a time."""
    for i in range(strip.numPixels()):
        strip.setPixelColor(i, color)
        strip.show()
        time.sleep(wait_ms / 1000.0)



# Main program logic follows:
if __name__ == '__main__':

    strip = PixelStrip(LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA, LED_INVERT, LED_BRIGHTNESS, LED_CHANNEL)
    strip.begin()
    color(strip, Color(255, 0, 0))  # Red wipe
    strip.show()

    

I've been trying to integrate it into user_interface.py (also I hacked the startup script as the led driver requires sudo, so the photobooth.sh script now does a sudo python), but I get a weird error telling me that strip.setSetPixelColor is being called with 4 arguments. I am only passing three, I am assuming that "self" from the python class system somehow gets passed. Problem is, it's a method from the pixel library, so how can I call it with only the three variables?

Sorry, I realize it is a bit confusing. Maybe someone could let me know what would be the best place to initialize the LED strip and then call the led strip functions. Ideally I want to start the led strip if someone has clicked the single/multiple/animation buttons and then turn it off again after the pics are taken.

Thx to all, this is a great project. It saved me a ton of time...

logos and splash screens

First part figured out....

Second part: Is there a way to put a splash screen or text on the black background when i open TouchSelfie? and can there be a refresh after a certain amount of time to go back to that splash screen after a photo is taken?

Displaying a Message During Printing

It would be very helpful if after you have pressed Print you get a message that will be printed. Since nothing is displayed at the moment, it is pressed so often until a photo comes, which takes about 10-15 seconds and then often the same photos come out multiple times.

Picasa API is dead

Hey guys,

I followed the great writeup in Make magazine to create my photobooth. Everything worked perfectly until Friday Jan 27th. I , as well as a few commenters on the Make article, started to get [Erno 32] Broken pipe upload failed. After a long night of poking the API and reading the (Picasa forums)[https://productforums.google.com/forum/#!category-topic/picasa/-6qGYNiNXKA] it looks like the Picasa API may finally be dead.

I forked your repo and and changed out the backend to use Google Drive via the PyDrive library. The great news is it's a pretty seamless transition and the install process is exactly the same (with the addition of pip install PyDrive)

I also created a photobooth_gui_user.py script that removes the customize button so users don't mess with the settings.

Long story short... Would you be interested in a PR of my fork?

Error while parsing configuration.json

(Edited Issue)

I can launch the script within the TouchSelfie folder with this command: sudo ./photobooth.sh

  1. When it launches and I press (using the 7" touchscreen) one of the options (https://prnt.sc/ukpis5) I do not get the countdown although it is in the config file. https://prnt.sc/ukpjk0

  2. Also, I had to flip the touchscreen 180 degrees so the script is now shooting upsidedown. I did not see where I can edit that?

  3. How do I set this to run on boot?

Update: This error below was because I was SSHing into the pi. Running the command via vnc worked.

pi@raspberrypi:-/TouchSelfie/scripts $ python user_interface.py

Traceback (most recent call last):

File "user_interface.py", line 1152, in ui = User Interface(config,window_size=(SCREEN SCREEN_H),

log_level = logging. DEBUG)

File "user_interface.py", line 140, in init self.root = TKO

File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1828, in init self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk, sync, use)

_tkinter.TclError: no display name and no $DISPLAY environment

E-mailing Photo

Hi, I've been working on this project for school and have gotten everything to work fine except the only problem that I keep stumbling upon is when I try to e-mail myself the picture that I take. In terminal it reads "sending photo by email to 'email address' " at first. However, during this time it freezes the application and it takes a while for it to load but when it does, terminal reads "Send Failed: [Error 101] Network is unreachable" I was wondering if you could help me solve this issue. I don't know if it's simply my network that won't let it work since it's a school network or if it's an issue deriving from when I was setting everything up in the beginning.

Several issues

I just tried to install this with the instructions I found from makezine.com.

First, I also have the login issues like some other peoples too.

Google Username:*[email protected]
App Specific Password
/usr/local/lib/python2.7/dist-packages/oauth2client/_helpers.py:255: UserWarning: Cannot access ./credentials.dat: No such file or directory
warnings.warn(_MISSING_FILE_MESSAGE.format(filename))
could not login to Google, check .credential file
('Error opening file', './OpenSelfie.json', 'No such file or directory', 2)

OpenSelfie.json file is missing

Exception in Tkinter callback
Traceback (most recent call last):
File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1545, in call
return self.func(*args)
File "/home/pi/git/TouchSelfie/scripts/custom.py", line 271, in launch_album_select
self.albums = listalbums.getAlbums(" **NOTE: THIS HAD HARD CODED SOME KEVIN'S GMAIL")
File "/home/pi/git/TouchSelfie/scripts/listalbums.py", line 127, in getAlbums
gd_client = OAuth2Login(client_secrets, credential_store, email)
File "/home/pi/git/TouchSelfie/scripts/credentials.py", line 21, in OAuth2Login
flow = flow_from_clientsecrets(client_secrets, scope=scope, redirect_uri='urn:ietf:wg:oauth:2.0:oob')
File "/usr/local/lib/python2.7/dist-packages/oauth2client/_helpers.py", line 133, in positional_wrapper
return wrapped(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/oauth2client/client.py", line 2135, in flow_from_clientsecrets
cache=cache)
File "/usr/local/lib/python2.7/dist-packages/oauth2client/clientsecrets.py", line 165, in loadfile
return _loadfile(filename)
File "/usr/local/lib/python2.7/dist-packages/oauth2client/clientsecrets.py", line 125, in _loadfile
exc.strerror, exc.errno)
InvalidClientSecretsError: ('Error opening file', './OpenSelfie.json', 'No such file or directory', 2)

Again OpenSelfie.json missing

it will be amazing if i could use my DSLR

as photographer I loved your project it's brilliant how you can send the pic using the API's to my album and the user on his email it will be even cooler if I could use my Canon DSLR I searched about how to connect the DSLR and I have found gphoto2: gPhoto is a set of software applications and libraries for use in digital photography I don't wanna use any other photo booth project because the email feature is gold to me

camera support

Really interested in this project and will download at some point over the next few days!

I was wondering what support this had for cameras like use cameras and DSLR tethering?

Preview is black

I am using a camera connected via the camera connector. When the picture is about to be taken, the preview is shown, however, when in preview mode the camera view is black.

Preview is not visible

Hi!
I have several problems.
First, I cannot see the preview : I have the countdown, but no image. No problem to get the pictures.
Second, I would like to change the size of the image to use this app on a bigger screen.
Anyone to help me ? Thank you in advance guys !

No module named oauth2client.client

raceback (most recent call last):
File "./photobooth_gui.py", line 15, in
import custom
File "/home/pi/git/TouchSelfie/scripts/custom.py", line 1, in
import listalbums
File "/home/pi/git/TouchSelfie/scripts/listalbums.py", line 3, in
from credentials import OAuth2Login
File "/home/pi/git/TouchSelfie/scripts/credentials.py", line 10, in
from oauth2client.client import flow_from_clientsecrets
ImportError: No module named oauth2client.client

Raspberry 4

Hi,

Do you think it should be easy to do this project with a Raspberry 4 instead of 3 ?

Thanks !!!

I suck at pull requests!

Hey, I tried to make a pull request, but failed. Thanks for your pull request, I've accepted all your changes and have made some updates myself. This "issue" is just a way to say thanks and offer the changes back.

Justin

Changes:
added email validation so we don't attempt to send to mal-formed email addresses
mykb: added cancel key (send turns to cancel when email is not valid)
mykb: added keyboard shortcuts for escape and send
added Nine collage feature.
added software button "order" attribute so you can arrange buttons on bottom of screen.

Permanent preview?

Would it be possible to have the preview open up with the program and display permanently, rather than only once a photo mode has been selected?

Preview

Hi!
Been testing out this code for a while and its working great exept for one problem.
The problem is the camera preview is zoomed when taking a picture. The finished picture is at the right resolution. I have tried changing every parameters in all the scripts I can find, but nothing changes the zoomed preview. I use a v2 pi camera.
Any one have a work around this problem?

OpenCV2 integration not working

I am not sure to understand how this is supposed to work but I can’t see any preview method implemented on the opencv wrapper.
Whenever I try to use it, the image is not showing.

400 'Bad Request'

Hello,

I followed all the steps multiple times but when I take a picture I get (400, 'Bad Request', Invalid Request URI')
Upload failed:(400, 'Bad Request', 'Invalid request URI)')

Thanks for the help!

Quality configuration

Trying to figure out how to config quality on the photos being taken. I'm using the v2 camera module which has a 8MP but its only uploading 1366x768 px images (1MP).

What is the best way to maximize quality on the images?

Unknown pull_up_down mode 0

After following standard install setup, I get this error when running ./photobooth.sh
Error included a Traceback, but the issue was in hardware_buttons.py Line 35

ValueError: Unknown pull_up_down mode 0

I don't have any hardware buttons connected at the moment, but if I put an actual value for the mode somewhere in hardware_buttons.py (eg mode = "pull_down" added around line 45) everything works fine so I'm not sure at the moment why it isn't pulling this from constants.py - it is correct in there, but is set to a default of 0 in hardware_buttons.py... hence the error.

I'll have a look at this more when I have added some hardware buttons at some stage - I guess I could have equally set RPI_GPIO_EXISTS = False in the mean time.

bad transparency mask

Hi,

I generated a new logo file in PNG format, 1366×235 pixels, with transparency.
After loading in, I have bad transparency mask error.
May I know what are the settings I missed?
Thank you.

Screen turns black after 1st countdown overlay - on snap_None ONLY

Not really sure what the issue is, but when using the snap_None mode (just the single photo mode) my count down will start, and after the first number appears the screen turns black and remains black until the countdown finishes. The collage ("snap_four") mode works as expected

Nothing is jumping out at me in the code, both the "none" (single) mode and "four"(collage) mode call the __show_countdown() method and then capture an image immediately thereafter but for whatever reason "none" (single) mode just drops the overlay until the count down finishes.

I should note - my build is a little different than this repo. The latest raspbian version (buster) does not have access to python-imaging or python-imaging-tk so I have to update things to use python-pil and python-pil.imagetk.

Directory Not found. Not Archiving

I'm working on a photo booth right now following the Makezine tutorial. I can't seem to get past Authentication though. I am able to enter my google user name and app specific password, but nothing else. I can allow it access to my google account and I can get the authentication code with ease. But when I return to the terminal to type it in, I get a screen loaded with errors. Starting with:

Directory Not Found. Not Archiving
/usr/local/lib/python2.7/dist-packages/oau2client/_helpers.py:255: Userwarning: Cannot Access./credentials.dat: No such file or directory
warnings.warn(_MISSING_FILE_MESSAGE.format(filename))

The worst part is that some of the errors pop up after the Authentication Code prompt, so it blocks off my ability to type in the code. I'd enter more of the error code but it seems to show somewhat different errors each time, so that seems like it wouldn't help that much to put it here. I'm convinced if I can get the .credentials.dat and get it to find the right directory, it'll work though.

I'd also like to mention that while I have luakit as my default browser, it always seems to open in Chromium. Still trying to figure out why that's happening

I saw a previous poster have a very similar problem, posted as a reply in another issue, but it never got answered.

UnboundLocalError

Thanks for the hard work!

Selecting no email and no auto-upload photos during installation results on service variable not having been created when called on line 1016. Check wether the user wants to use either/both of the two options above before calling test_connection().

2 questions

Hello from France,
Is it a module that can be installed on a magic mirror?
Can we use a USB camera?
best regards
Adel

Google API Issue

I am having trouble with the google API. I think I have the project set up correctly but when I try to add the Oauth credentials, I do not see the "other" option and can not get past that part.

Keyboard Issue

The virtual keyboard doesn't have a "Send" button but instead it's "cancel" in place of the send button if it's a ".au" email address.

2019-03-12 21_58_19-Window

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.