Code Monkey home page Code Monkey logo

spotty's People

Contributors

mherger avatar michaelherger 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

Watchers

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

spotty's Issues

Error: Failed to lookup address information

Hi there,

i just installed Logitech Media Server on an Ubuntu 18.04 vps, using Spotty 2.6.6.
After entering my Spotify username and password, and clicking "Apply" i saw this error on top of the screen:

Authorization failed: called Result::unwrap()on anErrvalue: Error { repr: Custom(Custom { kind: Other, error: StringError("failed to lookup address information: Try again") }) }

It took me some time to figure out that unbound (which i had installed as this ubuntu servers dns resolver by following this guide ) also listens on port 5353 udp, which appeared to be the same port Spotty was listening on, resulting in breaking dns resolving for the entire server... and also preventing Spotty itself from working:
Spotty crashed with this command: /var/lib/squeezeboxserver/cache/InstalledPlugins/Plugins/Spotty/Bin/i386-linux/spotty-x86_64 -c /var/lib/squeezeboxserver/cache/spotty/__AUTHENTICATE__ -n Spotify\ Authorization\ (servername) -u myusername -p mypassword -a --disable-discovery).

unbound was listening on: UDP 127.0.0.1:5353
spotty was listening on: UDP *:5353

Stopping unbound and temporarily setting 1.1.1.1 as a dns resolver solved the problem. After entering the spotty username & password, and disabling "Spotify Connect", Spotty stops listening on 5353 and everything works fine again.

  • Just posting as FYI and also in case others stumble upon the same issue (Pi-Hole is quite popular these days) they can then find it here... :-)

After upgrade of the plugin clients can no longer connect

I updated the plugin to version 2.1.11 and the spotty helper application to version 0.9.1. I run on freenas. When I specify a connect player on the Spotify client is tries to connect but fails. On console of the lms server I see the following error each time a client tries to connect:

thread 'main' panicked at 'called Result::unwrap() on an Err value: WireError(InvalidEnumValue(13))', /checkout/src/libcore/result.rs:906:4
note: Run with RUST_BACKTRACE=1 for a backtrace.

I tried with the old version of the helper application, 0.8.1, same results.

It used to work before the upgrade of the plugin.

Got a crash on the first login

When using plugin.audio.spotify.
I didn't have problems afterwards, but the exception code worried me enough to post.

Response.type=4
Sig[0].Name=Application Name
Sig[0].Value=spotty.exe
Sig[1].Name=Application Version
Sig[1].Value=0.0.0.0
Sig[2].Name=Application Timestamp
Sig[2].Value=5aff361f
Sig[3].Name=Fault Module Name
Sig[3].Value=spotty.exe
Sig[4].Name=Fault Module Version
Sig[4].Value=0.0.0.0
Sig[5].Name=Fault Module Timestamp
Sig[5].Value=5aff361f
Sig[6].Name=Exception Code
Sig[6].Value=c000001d
Sig[7].Name=Exception Offset
Sig[7].Value=0029ac0d

Why would your executable return an illegal instruction? (I have a core 2 quad if it can help)
EDIT: wtf

Spotty helper fails to load

I'm running LMS v8.2.0 on a Windows 10 server. Spotty always used to work fine but earlier this year it stopped working. I now get this warning coming up on the settings page:

There has been a problem running the Spotty helper application. Please make sure you have the Microsoft Visual C++ Runtime (64-bit!) installed on your system.

Unfortunately, I'm only running a 32-bit operating system so I can't install the 64-bit libraries. Is there another way around this other than upgrading Windows 10 to 64-bit?

Thanks, Andy.

spotty-custom periodically dumps core (FreeBSD)

I'm using spotty on FreeBSD (11.2). It generally works well, the only issue is that it occasionally stops playing music and resyncs. I've never been sure whether it's a spotty problem, or a sync-ing-among-my-players problem, or a network problem, or bad karma.

Periodically my FreeBSD daily reports mention that spotty-custom has dumped a core file. I found the time to go take a look at it today, but it seems that spotty custom isn't built with debugging info:

# gdb /var/db/logitechmediaserver/cache/InstalledPlugins/Plugins/SpottyBinFreeBSD/Bin/spotty-custom /var/tmp/spotty-custom.core
GNU gdb 6.1.1 [FreeBSD]
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "amd64-marcel-freebsd"...Dwarf Error: wrong version in compilation unit header (is 4, should be 2) [in module /var/db/logitechmediaserver/cache/InstalledPlugins/Plugins/SpottyBinFreeBSD/Bin/spotty-custom]

Core was generated by `/var/db/logitechmediaserver/cache/InstalledPlugins/Plugins/SpottyBinFreeBSD/Bin/'.
Program terminated with signal 6, Aborted.
#0  0x000000080196847a in ?? ()
(gdb) where
#0  0x000000080196847a in ?? ()
#1  0x0000000801968444 in ?? ()
#2  0x00000000000188cf in ?? ()
#3  0xb60cd4abe43ff4b5 in ?? ()
#4  0x00007fffffffcb24 in ?? ()
#5  0x0000000000000000 in ?? ()
(gdb)

I'm not a rustacean; I'm not sure how easy it would be to provide a version with debugging symbols and/or whether it'd be likely to tell us anything useful.

If you could and if it would, I'd be game to run it for a while to see where it's giving up the ghost.

Spotty crashing LMS

I've been running spotty on my Squeezebox network for a long time with no problems. Yesterday the LMS would not connect to my players. I tried to restart LMS but it kept stopping. I managed to open it in safe mode. It will only run in full mode if Spotty is turned off. All other plugins work, including Tidal. As soon as turn Spotty back on the LMS stops.
Any ideas?

thread 'main' panicked at 'called `Result::unwrap()`

I just wanted to leave this here. Happens every week or so using Spotty v4.6.2. I have enabled debug logging for plugin.spotty now.

Nov 24 12:42:46 nasty squeezeboxserver[3917482]: thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: IoError(Custom { kind: UnexpectedEof, error: "early eof" })', src/spotty.rs:113:26
Nov 24 12:42:46 nasty squeezeboxserver[3917482]: stack backtrace:
Nov 24 12:42:46 nasty squeezeboxserver[3917482]:    0:           0x6cbd0a - <unknown>
Nov 24 12:42:46 nasty squeezeboxserver[3917482]:    1:           0x44966f - <unknown>
Nov 24 12:42:46 nasty squeezeboxserver[3917482]:    2:           0x6cb491 - <unknown>
Nov 24 12:42:46 nasty squeezeboxserver[3917482]:    3:           0x6caed0 - <unknown>
Nov 24 12:42:46 nasty squeezeboxserver[3917482]:    4:           0x6ca497 - <unknown>
Nov 24 12:42:46 nasty squeezeboxserver[3917482]:    5:           0x6e683d - <unknown>
Nov 24 12:42:46 nasty squeezeboxserver[3917482]:    6:           0x6e67ac - <unknown>
Nov 24 12:42:46 nasty squeezeboxserver[3917482]:    7:           0x6e675d - <unknown>
Nov 24 12:42:46 nasty squeezeboxserver[3917482]:    8:           0x4005f0 - <unknown>
Nov 24 12:42:46 nasty squeezeboxserver[3917482]:    9:           0x400ce2 - <unknown>
Nov 24 12:42:46 nasty squeezeboxserver[3917482]:   10:           0x43cf77 - <unknown>
Nov 24 12:42:46 nasty squeezeboxserver[3917482]:   11:           0x6b050c - <unknown>
Nov 24 12:42:46 nasty squeezeboxserver[3917482]:   12:           0x6beab3 - <unknown>
Nov 24 12:42:46 nasty squeezeboxserver[3917482]:   13:           0x6af930 - <unknown>

Playlist radio repeats same songs but does not load new

spotty version according to squeezebox server (7.9.1): 2.7.5

Unfortunately, spotty does not work properly when using spotify connect together with the playlist-radio function ("more songs load as you listen"). spotty keeps repeating the same songs instead of loading new ones.

The original librespot implementation has this issue as well. The issue has been fixed, e.g., in the librespot-java fork (librespot-org/librespot-java@e4d80fc).
Could you please have a look at this? It's the basic feature for me and I would totally regret, if I could not use it.

Thanks in advance!
Wolfi

Error during initial Spotify Account setup

I am running the lms on an rasperry pi running raspian os, latest version.I enabled the Spotty Plugin, restarted the lms and now I get the following error, when I try to access the config page for the plugin:

404 Not Found: plugins/Extensions/settings/plugins/Spotty/settings/basic.html

Do you know how to solve this?

Librespot changes

Hi I see in your readme it states that you had to modify librespot for it to integrate with spotty. I was just wandering what changes did you have to make and why?

How to use --get-token

I'm finding it hard how to get a Web API token using spotty.

I've successfully authenticated and streamed a track, so I know connecting isn't the problem.

I'm using something like this:

./spotty --authenticate --cache ./ --name MyDevice --get-token --client-id MyApp

The response is:

error getting token MercuryError

This is running spotty compiled from the dev branch. The master branch error is similar, but with an unhandled unwrap() error as well.

I've also tried with supplying a username and password, and the error is the same.

Have I misunderstood some part of this process?

Error in spotty helper

Hi,

I am running LMS in a docker container form here:

https://github.com/larsks/docker-image-logitech-media-server

which works with no issues up to the point in which I try to install the spotty plugin.

when entering the configuration page in order to setup my spotify account I see the error message below.

Is it true, that spotty doesn't work on x64 systems ? or might it be related to the docker installation ?

Beim Ausführen der Spotty Helfer-Anwendung ist ein Fehler aufgetreten. Vermutlich wird diese auf ihrem System nicht unterstützt. Bitte wenden Sie sich an mich, unter Angabe der folgenden Plattform-Informationen:

Betriebssystem: Debian / x86_64-linux

Ordner für Hilfsprogramme:
/usr/share/squeezeboxserver/Bin/x86_64-linux
/usr/share/squeezeboxserver/Bin
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
/srv/squeezebox/cache/InstalledPlugins/Plugins/Spotty/Bin/i386-linux
/srv/squeezebox/cache/InstalledPlugins/Plugins/Spotty/Bin
ldd (Ubuntu GLIBC 2.23-0ubuntu10) 2.23

Song is skipped after few seconds and make players out of sync.

Hi @mherger,

After upgrading squeezebox server and spotty, I have this issue described in title.
When I ask to play the whole album, first song plays for 4-5 seconds and it skips to next one. But players don't start the second one at the same time, so all others songs are played out of sync on the players.
If I do skip it the first one manually before the errors occurs, all other songs play just fine on each player.
It can be reproduced with this album: L'étrange pays, artist:  Jean Leloup

Logitech Media Server Version: 7.9.2 - 1565967976
Spotty: 2.8.4
3 players:

  • Odroid C1 with Max2Play / SqueezeLite
  • Raspberry Pi with Max2Play / SqueezeLite
  • Old Atom desktop with Ubuntu / SqueezeLite

Spotify Connect: checked for all players.

Before the upgrade I had
Logitech Media Server Version: 7.9.0
Spotty: 2.2.x

Spotty can't play from Spotify, won't even open in LMS web or app

Spotty has worked great for a year or so, but a couple of weeks ago, music wouldn't play anymore though we could still browse. Assuming some protocol change was the cause, I updated the plugin on LMS and re-added the account. The account add process worked fine, but as soon as I attempt to switch playback to one of the LMS clients, the Spotify display flashes and the client disappears from the "connected devices" list.
Trying the Spotty menu in LMS is worse, it won't display anything.
I have removed, rebooted and re-installed several times to no avail. Looking in the logs shows that there is some kind of connection problem, but not being very familiar with the LMS code, I am at a loss for what the problem might be. Here is a snippet:

[20-04-01 18:01:21.0531] Plugins::Spotty::API::Token::_killTokenHelper (164) Timed out waiting for a token
[20-04-01 18:02:01.0984] Slim::Networking::IO::Select::__ANON__ (147) Error: Select task failed calling Slim::Web::HTTP::processHTTP: Not a SCALAR reference at /volume1/@appstore/SqueezeCenter/Slim/Web/HTTP.pm line 1770.
; fh=Slim::Web::HTTP::ClientConn=GLOB(0xa5b4d10)

I'm running LMS 7.7.6 - 1452060463 on a Synology DS412+
Spotty version 3.1.3
the old Spotify official plugin is NOT installed. Should it be?

thread 'main' panicked at 'cannot poll Result twice', /checkout/src/libcore/option.rs:839:4

I build the 0.7.0 on Freebsd 11 (actually Freenas 11). When not authenticated it appears as a Spotify Connect endpoint in the Spotify Client, however as soon as you connect it quits with the following error in the Squeezebox logs:

thread 'main' panicked at 'cannot poll Result twice', /checkout/src/libcore/option.rs:839:4

When I start it from the command line the same error is thrown.

LMS Transport

Hi Michael, are the transport controls on LMS able to control a Spotify Connect stream?

I've realised when I press next track it looks like it's only going through the playlist (not what's on the phone) which of course there isn't one and my device gets confused. Anything you're able to do or is this just one of these LMS limitations? Thanks

The account list can show the wrong names after spotify "overload"

I have a spotify family account and have four accounts registered in spotty. These are registered through passwords as using the spotify app authentication did not seem to work. Maybe firewall issues on my fedora box? But that is not the issue here, it works fine for me with passwords.

Part of the problem is that when clicking around in the web interface it is quite easy to "overload" spotify. When this happens the account list will show the same name multiple times. I guess this is because when iterating over the account list and it fails to fetch the "DisplayName" from spotify it will re-use the name from the previous account in the list. Or something like that. (I found the name-mapping in spotty.prefs and after a while i realized that there was no point in editing the file as name changes was overwritten.)

The result is quite confusing as the names in the list depend on which account(s) are overloaded at the moment. And the order of the accounts. So the list changes depending on if you triggering the overload or not.

Thank you VERY much for your continued support to keep my squeezeboxes alive!!!

/Bengt

Multi Account Support

I would like to configure more than one Spotify account at the same time. This was possible using the original Spotify plugin for Squeezebox but seems to be impossible using spotty.

Do you have any plans to support more than one account in the future?

Stream Spotify podcast

I am not able to stream Spotify podcasts from your application.

Is this a feature you are planning to implement?

Great work on the software.
Thanks,
Paul

Mac desktop app and mobile app sync problem w/ LMS

Mac desktop app and mobile app don't show currently playing song on LMS after selecting it as a source. Good news is I see LMS as a source (which disappears form time to time unexpectedly but haven't caught the pattern yet).

Will the sync of currently playing song be available in the future?

Proper respect for maintaining this repo,
Alen

Failed to get access token

When i try to go to Spotify at the web page, it show :

Failed to get access token
Please check Settings/Advanced/Spotty Spotify for Squeezebox in the web interface

How can i fix it
log:
21-02-27 00:43:25.8146] Plugins::Spotty::API::ANON (1424) API call: me
[21-02-27 00:43:25.8148] Plugins::Spotty::API::ANON (1428) error: 400 Bad Request
[21-02-27 00:43:25.8176] Plugins::Spotty::API::ANON (1424) API call: browse/featured-playlists?country=US&limit=50&locale=zh×tamp=2021-02-27T00%3A40%3A00
[21-02-27 00:43:25.8176] Plugins::Spotty::API::ANON (1428) error: 400 Bad Request
[21-02-27 00:43:25.8177] Plugins::Spotty::OPML::ANON (191) Failed to get featured playlists and/or token - do not continue
[21-02-27 00:43:27.4496] Plugins::Spotty::API::ANON (1424) API call: browse/featured-playlists?country=US&limit=50&locale=zh×tamp=2021-02-27T00%3A40%3A00
[21-02-27 00:43:27.4497] Plugins::Spotty::API::ANON (1428) error: 400 Bad Request
[21-02-27 00:43:27.4498] Plugins::Spotty::OPML::ANON (191) Failed to get featured playlists and/or token - do not continue
[21-02-27 00:43:27.5009] Plugins::Spotty::API::ANON (1424) API call: browse/featured-playlists?country=US&limit=50&locale=zh×tamp=2021-02-27T00%3A40%3A00
[21-02-27 00:43:27.5010] Plugins::Spotty::API::ANON (1428) error: 400 Bad Request
[21-02-27 00:43:27.5010] Plugins::Spotty::OPML::ANON (191) Failed to get featured playlists and/or token - do not continue
[21-02-27 00:46:45.0970] Plugins::Spotty::API::ANON (1424) API call: users/joe2006121/playlists?limit=50
[21-02-27 00:46:45.0971] Plugins::Spotty::API::ANON (1428) error: 400 Bad Request
[21-02-27 00:46:45.1215] Plugins::Spotty::API::ANON (1424) API call: me
[21-02-27 00:46:45.1216] Plugins::Spotty::API::ANON (1428) error: 400 Bad Request
[21-02-27 00:46:45.1734] Plugins::Spotty::API::ANON (1424) API call: me/albums?limit=1
[21-02-27 00:46:45.1735] Plugins::Spotty::API::ANON (1428) error: 400 Bad Request
[21-02-27 00:46:45.3166] Plugins::Spotty::API::ANON (1424) API call: me/following?limit=50&type=artist
[21-02-27 00:46:45.3168] Plugins::Spotty::API::ANON (1428) error: 400 Bad Request
[21-02-27 00:47:51.4343] Plugins::Spotty::API::ANON (1424) API call: browse/featured-playlists?country=US&limit=50&locale=zh×tamp=2021-02-27T00%3A40%3A00
[21-02-27 00:47:51.4344] Plugins::Spotty::API::ANON (1428) error: 400 Bad Request
[21-02-27 00:47:51.4345] Plugins::Spotty::OPML::ANON (191) Failed to get featured playlists and/or token - do not continue

It seems that the URL is wrong?

LMS v.8.1.1 Windows
Spotty v.4.4.7

zombie processes

hey there

thank you so much for this plugin, it is awesome!

I have noticed that whenever I stop playing from Spotty and go back to my local libraries or just when I turn off my squeezebox, Spotty will leave behind a zombie process. these processes can't be killed until LMS is completely restartet (then they are removed without further interaction)
since my "server" is not that powerful, I do not have the option on to always have a spotty service for my squeezebox started but rather only when needed

anyway to fix that behavior or is this something entirely new?

thanks again and br

Spotify helper app not found

I used Spotty for several weeks but it stopped working. I tried to activate my Spotify account in Spotty again but I get this error:

Konnte die Spotify Connect Helferanwendung nicht finden oder nicht ausführen. Ist ihr Betriebssystem unterstützt?
/var/lib/squeezeboxserver/cache/InstalledPlugins/Plugins/Spotty/Bin/arm-linux/spotty-muslhf

I am running the logitechmediaserver on the current Rasbian OS version on a RaspberryPi.

Any idea how to get it working again?

No podcast playback from playlists

If a playlist contains podcasts, the podcasts are not played back. If playing a mixed playlist, the music is played back correctly but the podcasts are skipped.

Weird buffering issue after wlan-update

Spotty shows a weird buffering issue after the wlan hotspot was updated to a google wifi ap. Music stops repeatedly every 20 to 40 seconds.

  • This happens while streaming to a single squeezebox as well when several are synchronized.
  • Other network streaming plugins like soundcloud or bbc iplayer work flawlessly, streaming of local music to one or several synchronized SBS works flawlessly as well.
  • The squeezebox server is hosted on an odroid u8 via ethernet, all squeezeboxes are wirelessly connected.
  • cable was changed, network throughput to the SB server seems okay (70-80 MBit)
  • the cache in spotty configuration was set to 500 MB
  • CPU-Load seems okayish
  • logs are empty :(

Failed to get access token

When trying to access Spotty via the LMS webpage or thru iPeng I get

Failed to get access token
Please check Settings/Advanced/Spotty Spotify for Squeezebox in the web interface

I tried taking it off and putting it back on, and re-authorising but still the same

Log
frame 0: Slim::Utils::Log::logBacktrace (/usr/local/slimserver/Slim/Schema/Storage.pm line 121)
frame 1: Slim::Schema::Storage::throw_exception (/usr/local/slimserver/CPAN/DBIx/Class/Storage/DBI.pm line 1007)
frame 2: DBIx::Class::Storage::DBI::ANON (/usr/local/slimserver/Slim/Plugin/FullTextSearch/Plugin.pm line 568)
frame 3: Slim::Plugin::FullTextSearch::Plugin::_initPopularTerms (/usr/local/slimserver/Slim/Plugin/FullTextSearch/Plugin.pm line 137)
frame 4: Slim::Plugin::FullTextSearch::Plugin::ANON (/usr/local/slimserver/Slim/Control/Request.pm line 2058)
frame 5: (eval) (/usr/local/slimserver/Slim/Control/Request.pm line 2058)
frame 6: Slim::Control::Request::notify (/usr/local/slimserver/Slim/Control/Request.pm line 859)
frame 7: Slim::Control::Request::checkNotifications (/usr/local/slimserver/slimserver.pl line 711)
frame 8: main::idle (/usr/local/slimserver/slimserver.pl line 680)
frame 9: main::main (/usr/local/slimserver/slimserver.pl line 1224)

[22-01-08 13:07:40.0062] Slim::Control::Request::notify (2060) Error: Failed notify: Carp::Clan::ANON(): DBI Exception: DBD::SQLite::db selectcol_arrayref failed: no such table: fulltext_terms [for Statement "
SELECT term, d FROM (
SELECT term, SUM(documents) d
FROM fulltext_terms
WHERE NOT col IN ('*', 1, 0) AND LENGTH(term) > 1
GROUP BY term
ORDER BY d DESC
)
WHERE d > 500
"] at /usr/local/slimserver/Slim/Schema/Storage.pm line 125
[22-01-08 13:10:21.1993] Plugins::Spotty::API::Token::_killTokenHelper (182) Token refresh call helper has closed unexpectedly? - Please consider re-setting your Spotify credentials should this happen all the time.
[22-01-08 13:10:21.2005] Plugins::Spotty::OPML::ANON (198) Failed to get featured playlists and/or token - do not continue

LMS 8.2.0

Can't add individual songs

Hi There,

I use spotty for ~2 years now. I was never able to add individual songs from the search results.
Anything I can try / do ?

build on windows

Great work on this!

I was looking for this exact same thing to replace libspotify in my Kodi addon and only need the raw audio pipe. If I may ask, how did you manage to build this on windows ?

Got it working on my mac within a few minutes but windows keeps complaining about mdns and portaudio.

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.