GithubHelp home page GithubHelp logo

mbleigh / subdomain-fu Goto Github PK

View Code? Open in Web Editor NEW
587.0 13.0 122.0 327 KB

A new plugin approach to attempting to solve the usage of subdomains in linking and routing in Rails projects.

Home Page: http://rdoc.info/projects/mbleigh/subdomain-fu

License: Other

Ruby 100.00%

subdomain-fu's People

Contributors

ajn avatar arctickiwi avatar danielmorrison avatar eric avatar etaque avatar gix avatar jcoby avatar joslynesser avatar leehambley avatar lerrua avatar loe avatar morhekil avatar nhowell avatar pboling avatar ramontayag avatar rishav avatar rykov avatar ryland avatar technicalpickles avatar zachhale 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

subdomain-fu's Issues

NoMethodError (undefined method `+' for nil:NilClass)

I get this exception when using:
thin (1.2.7)
subdomain-fu (0.5.4)
Karmic 9.10

NoMethodError (undefined method +' for nil:NilClass): /usr/lib/ruby/gems/1.8/gems/subdomain-fu-0.5.4/lib/subdomain-fu.rb:132:incurrent_subdomain'
/usr/lib/ruby/gems/1.8/gems/subdomain-fu-0.5.4/lib/subdomain_fu/routing_extensions.rb:27:in extract_request_environment' thin (1.2.7) lib/thin/connection.rb:76:inpre_process'
thin (1.2.7) lib/thin/connection.rb:74:in catch' thin (1.2.7) lib/thin/connection.rb:74:inpre_process'
thin (1.2.7) lib/thin/connection.rb:57:in process' thin (1.2.7) lib/thin/connection.rb:42:inreceive_data'
eventmachine (0.12.10) lib/eventmachine.rb:256:in run_machine' eventmachine (0.12.10) lib/eventmachine.rb:256:inrun'
thin (1.2.7) lib/thin/backends/base.rb:57:in start' thin (1.2.7) lib/thin/server.rb:156:instart'
thin (1.2.7) lib/thin/controllers/controller.rb:80:in start' thin (1.2.7) lib/thin/runner.rb:177:insend'
thin (1.2.7) lib/thin/runner.rb:177:in run_command' thin (1.2.7) lib/thin/runner.rb:143:inrun!'
thin (1.2.7) bin/thin:6
/usr/bin/thin:19:in `load'
/usr/bin/thin:19

Link generation in Snow Leopard

Since i upgraded to Snow Leopard and reinstalled all the gems, rails doesn't generate proper URLs with the :subdomain option set. It ignores the subdomain option completely.
The routing works correctly though.

Release 1.0.0

It would be great to finally push 1.0.0 to RubyGems ;)

current_domain returns wrong domain

Hi!

Helper current_domain returns wrong domain. Ex.:
We have 'sub.domain.com.local'. For this case we, of course, set TLD to 2. and expect that current_domain will return 'domain.com.local', but it returns 'com.local' instead.

The cause is here:

diff --git a/vendor/plugins/subdomain-fu/lib/subdomain-fu.rb b/vendor/plugins/subdomain-fu/lib/subdomain-fu.rb
index 7b4a9da..9c8d7d4 100644
--- a/vendor/plugins/subdomain-fu/lib/subdomain-fu.rb
+++ b/vendor/plugins/subdomain-fu/lib/subdomain-fu.rb
@@ -140,8 +140,10 @@ module SubdomainFu
   #Enables subdomain-fu to more completely replace DHH's account_location plugin
   def self.current_domain(request)
     domain = ""
-    domain << request.subdomains[1..-1].join(".") + "." if request.subdomains.length > 1
-    domain << request.domain + request.port_string
+    subdomains = request.subdomains(SubdomainFu.tld_size)
+    domain << subdomains[1..-1].join(".") + "." if subdomains.length > 1
+    domain << request.domain(SubdomainFu.tld_size) + request.port_string
+    domain
   end
 
   module Controller

Here you used request.subdomains and request.domain w/o TLD param. By default it is set to 1. So, if tld_size is set to 1 in development.rb, for instance, everything works fine. But for example mentioned below this doesn't work as expected. I've just defined TLD param for calling request.subdomains and request.domain.

P.S. SubdomainFu.tld_size = X doesn't work for me. I get

undefined method `tld_size=' for SubdomainFu:Module

Get error when trying to start server

I get this error when I try to start my server:

Users/alfner/.gem/ruby/1.8/gems/activesupport-2.3.5/lib/active_support/core_ext/object/misc.rb:78:in `with_options': no block given (LocalJumpError)
from /Library/Ruby/Gems/1.8/gems/subdomain-fu-0.5.4/lib/subdomain_fu/routing_extensions.rb:38:in `quick_map'
from /Library/Ruby/Gems/1.8/gems/subdomain-fu-0.5.4/lib/subdomain_fu/routing_extensions.rb:45:in `subdomain'
from /Users/alfner/Rails/project_name/config/routes.rb:22
from /Users/alfner/.gem/ruby/1.8/gems/activesupport-2.3.5/lib/active_support/core_ext/object/misc.rb:78:in `with_options'
from /Users/alfner/Rails/project_name/config/routes.rb:21
from /Users/alfner/.gem/ruby/1.8/gems/actionpack-2.3.5/lib/action_controller/routing/route_set.rb:226:in `draw'
from /Users/alfner/Rails/project_name/config/routes.rb:1
from /Users/alfner/.gem/ruby/1.8/gems/activesupport-2.3.5/lib/active_support/dependencies.rb:145:in `load_without_new_constant_marking'
 ... 17 levels...
from /Users/alfner/.gem/ruby/1.8/gems/rails-2.3.5/lib/commands/server.rb:84
from /Library/Ruby/Site/1.8/rubygems/custom_require.rb:31:in `gem_original_require'
from /Library/Ruby/Site/1.8/rubygems/custom_require.rb:31:in `require'
from script/server:3

README.rdoc formating

Some of the formating is skewed, because rdoc is special. Also, it includes instructions for now defunct github gems, when it is available on gemcutter.

default to :subdomain => false for all routes

Is there a way to default to :subdomain => false for all routes? I already have a bunch of named routes, and if I never specified a subdomain for them in the routes file, I would like my_named_route_url to equal my_named_route_url(:subdomain => false) even if current_subdomain is "foo"

miss routing ajax request

XMLHttpRequests are being miss routing, any idea way?

GET http://sd.mydomain.com/categories/1 routed properly.
(SD::CategoriesController < SDApplicationController)

new Ajax.Request('http://sd.mydomain.com/categories/1', {asynchronous:true, evalScripts:true, method:'get'...
routed to ApplicationController#index

Also I got

ActionController::MethodNotAllowed (Only get, put, and delete requests are allowed.):
which does not make much sense since its set as get request.

My routes

map.subdomain :sd do |sd|
sd.resources :categories, :controller => "sd/categories"
end
map.resource :categories

Am i doing something wrong, is it a bug or a constraint?

I appreciate any insights

subdomain-fu 0.5.4
rails 2.3.8
ruby 1.8.7

Subdomain conditions not passed to generated named routes generated by resources.

I'm new to subdomain-fu. So I might be mistaking the desired behaviour for a defect.

The named route helpers generated by the following resource declaration do not add the subdomain option to the underlying url_for calls.

map.resources :foos, :conditions => {:subdomain => :bar}

foos_url produces http://current_subdomain.example.com/foos.
I'm expecting http://bar.example.com/foos. regardless of what the current subdomain is.

I understand that this behaviour ensures that subdomains are not changed unless explicitly stated. It's not very DRY to require an explicitly supplied subdomain for routes that are only valid under specific subdomains.

map.with_options root controller

Hello,
I defined the following route:

map.with_options :conditions => {:subdomain => 'foo'} do |bar|
bar.resources :users
end

How can I define a root route for this subdomain? so that if anybody visits foo.example.com, they'll be automatically redirected to that controller?

I tried the following two rules with no luck:

  1. bar.root :controller => 'abc'
  2. bar.connect '/', :controller => 'abc'

Any ideas?

Rails3 - no such file to load -- action_controller/url_rewriter

I'd post it on the intridea repo, but issues is disabled.
Basically I added the beta2 gem of subdomain-fu and it won't let the environment load as it tries to require url_rewriter which apparently no longer exists.

Let me know if I can be more useful than this...

boggling comment in subdomain_fu/routing_extensions.rb

I was looking over the router extension stuff to see if I could add some logic for poking at the full domain name... then I came across this comment at the top:

# This is not yet a working part of SubdomainFu.

I'm guessing this is no longer true, since (I think) I've use the functionality it provides.

:subdomain not working

Hi! I install subdomain-fu successfully and read the documentation. I was used "url_for" method in my layout file with :subdomain option. But I not get result :(

url_for(:controller => "main", :action => "index", :subdomain => "bar")

I have development version on Webrick. url_for return "lvh.me" without subdomain
What's the problem?

Incompatible with Rails 4.2

The latest version, 3752799, is incompatible with rails 4.2.

lib/subdomain_fu/url_rewriter.rb monkey-patches ActionDispatch::Routing::RouteSet#url_for. The 1..2 argument method signature of the monkey patch:

def url_for_with_subdomains(options, path_segments=nil)
  # ...
end
alias_method_chain :url_for, :subdomains

is incompatible with the 1..3 argument method signature in rails 4.2.

See rails/rails@212057b, the commit which changes the method signature in rails.

:conditions are not inherited by nested resources

Given the following routes:
map.subdomain :api do |api|
api.resources :projects do |project|
project.resources :tasks
end
end

When I look at the conditions of api_project_tasks_path()
Then I should see { :subdomain => /api/ }

fails.

api_projects_path() has the conditions. This seems to be because the :conditions option is not inherited in nested resources. I could fix this by adding:
ActionController::Resources::INHERITABLE_OPTIONS << :conditions
to an initializer.

Routing a controller only to a subdomain

I've been reading through the source and i still don't understand how to do this. I'm wondering if someone can help me out with this.

I'm launching a mobile version of a site, and i want everything that goes to m.foo.com to be redirected to the m. controller, and then create a namespace and have other controllers under there.

I don't know of a restful way of doing this. It seems like this module wants to create m.foo.com/m, but that's not what i need.

Am i missing something?

url_for unexpected behaviour

This behavior by default

url_for(controller: :payment, action: :error, subdomain: :secure) => /payment_error

And I get expected result when add option only_path: false

url_for(controller: :payment, action: :error, subdomain: :secure, only_path: false) => http://secure.my.office/payment_error

It's a bug?

session store issue

Hi

I am using old application which running ruby 1.8.7 and rails 2.3.14

In my application after login its revert to login panel, problem is not
storing session values during development mode.(Ruby 1.8.7 and Rails
2.3.14)

URL : http://localhost:3000/-- works fine(after login)
URL : http://test.prospectus.com:3000 - works fine(after login)
URL: http://prospectus.com:3000 NOT WORKING every time redirect to
login page, when I looked at log file session/create stores the
session values but next control session values lost, see the log file
for your reference.

Here is the host.ini file details

127.0.0.1 localhost
127.0.0.1 prospectus.com
127.0.0.1 www.prospectus.com
127.0.0.1 test.prospectus.com

Processing SessionController#create (for 127.0.0.1 at 2013-11-28
19:18:47) [POST]
Parameters: {"commit"=>"Log in", "login"=>"admin", "password"=>"1234"}
[4;36;1mUser Load (15.6ms) [0m [0;1mSELECT * FROM users WHERE
(users.login = 'admin') ORDER BY users.last_name LIMIT 1 [0m
session[:user_id] ------1
pp:---current_user----1
Redirected to http://prospectus.com:3000/clients
pp:--LAST session[:user_id]----1
Completed in 188ms (DB: 16) | 302 Found [http://prospectus.com/session]

Processing ClientsController#index (for 127.0.0.1 at 2013-11-28 19:18:48) [GET]
login_from_session session[:user_id] ------
Redirected to http://prospectus.com:3000/session/new
Filter chain halted as [:login_required] rendered_or_redirected.
Completed in 0ms (DB: 0) | 302 Found [http://prospectus.com/clients]

Failure when generating links in background jobs

I have some emails which are generated with delayed jobs, so there is no actual request at the time the emails are created. However they have many calls to generate links such as new_user_url(...), etc. All of these fails because there is no request.

It would be nice to be able to set a "fake" subdomain which is used during the processing of these jobs so any calls to url_for functions will work. Any ideas for this?

current_subdomain in test alway is "test"

Hi everyone, I test with rspec , when call :

login (@customer)
get :show

and in function :

...
@customer=Customer.find_by_user_name(current_subdomain)
...

but current_subdomain alway return => 'test'
need your helps :D

Gem won't load in with Bundler 1.1.2, Ruby 1.9.3

I keep getting the following error when I try to include the 1.0.0-beta2 Rails 3 re-write:

cannot load such file -- subdomain/fu

There appears to have been a change to bundler which requires namespaced files and the hyphen in the gem name is causing this to not load properly:

rubygems/bundler@653e1ea

How do we work around this?

Server won't load; rails/init

After installing the plugin on 1.9.2 with 3.1.3 I cannot get the server to restart. This is a brand new project with an empty routes.rb file. If I remove the plugin directory it starts up again without trouble.

```/Users/Chris/.rvm/gems/ruby-1.9.2-p290/gems/activesupport-3.1.3/lib/active_support/dependencies.rb:240:inrequire': no such file to load -- rails/init (LoadError) from /Users/Chris/.rvm/gems/ruby-1.9.2-p290/gems/activesupport-3.1.3/lib/active_support/dependencies.rb:240:in block in require'
from /Users/Chris/.rvm/gems/ruby-1.9.2-p290/gems/activesupport-3.1.3/lib/active_support/dependencies.rb:223:in`block in load_dependency'
from /Users/Chris/.rvm/gems/ruby-1.9.2-p290/gems/activesupport-3.1.3/lib/active_support/dependencies.rb:640:in `new_constants_in'
from /Users/Chris/.rvm/gems/ruby-1.9.2-p290/gems/activesupport-3.1.3/lib/active_support/dependencies.rb:223:in`load_dependency'
from /Users/Chris/.rvm/gems/ruby-1.9.2-p290/gems/activesupport-3.1.3/lib/active_support/dependencies.rb:240:in `require'
from /Users/Chris/Documents/projects/Roster/vendor/plugins/subdomain-fu/init.rb:1:in`block in class:Plugin'
from /Users/Chris/.rvm/gems/ruby-1.9.2-p290/gems/railties-3.1.3/lib/rails/plugin.rb:81:in `eval'
from /Users/Chris/.rvm/gems/ruby-1.9.2-p290/gems/railties-3.1.3/lib/rails/plugin.rb:81:in`block in class:Plugin'
from /Users/Chris/.rvm/gems/ruby-1.9.2-p290/gems/railties-3.1.3/lib/rails/initializable.rb:30:in `instance_exec'
from /Users/Chris/.rvm/gems/ruby-1.9.2-p290/gems/railties-3.1.3/lib/rails/initializable.rb:30:in`run'
from /Users/Chris/.rvm/gems/ruby-1.9.2-p290/gems/railties-3.1.3/lib/rails/initializable.rb:55:in `block in run_initializers'
from /Users/Chris/.rvm/gems/ruby-1.9.2-p290/gems/railties-3.1.3/lib/rails/initializable.rb:54:in`each'
from /Users/Chris/.rvm/gems/ruby-1.9.2-p290/gems/railties-3.1.3/lib/rails/initializable.rb:54:in `run_initializers'
from /Users/Chris/.rvm/gems/ruby-1.9.2-p290/gems/railties-3.1.3/lib/rails/application.rb:96:in`initialize!'
from /Users/Chris/.rvm/gems/ruby-1.9.2-p290/gems/railties-3.1.3/lib/rails/railtie/configurable.rb:30:in `method_missing'
from /Users/Chris/Documents/projects/Roster/config/environment.rb:5:in`<top (required)>'
from /Users/Chris/Documents/projects/Roster/config.ru:4:in `require'
from /Users/Chris/Documents/projects/Roster/config.ru:4:in`block in

'
from /Users/Chris/.rvm/gems/ruby-1.9.2-p290/gems/rack-1.3.5/lib/rack/builder.rb:51:in `instance_eval'
from /Users/Chris/.rvm/gems/ruby-1.9.2-p290/gems/rack-1.3.5/lib/rack/builder.rb:51:in`initialize'
from /Users/Chris/Documents/projects/Roster/config.ru:1:in `new'
from /Users/Chris/Documents/projects/Roster/config.ru:1:in`'
from /Users/Chris/.rvm/gems/ruby-1.9.2-p290/gems/rack-1.3.5/lib/rack/builder.rb:40:in `eval'
from /Users/Chris/.rvm/gems/ruby-1.9.2-p290/gems/rack-1.3.5/lib/rack/builder.rb:40:in`parse_file'
from /Users/Chris/.rvm/gems/ruby-1.9.2-p290/gems/rack-1.3.5/lib/rack/server.rb:200:in `app'
from /Users/Chris/.rvm/gems/ruby-1.9.2-p290/gems/railties-3.1.3/lib/rails/commands/server.rb:46:in`app'
from /Users/Chris/.rvm/gems/ruby-1.9.2-p290/gems/rack-1.3.5/lib/rack/server.rb:301:in `wrapped_app'
from /Users/Chris/.rvm/gems/ruby-1.9.2-p290/gems/rack-1.3.5/lib/rack/server.rb:252:in`start'
from /Users/Chris/.rvm/gems/ruby-1.9.2-p290/gems/railties-3.1.3/lib/rails/commands/server.rb:70:in `start'
from /Users/Chris/.rvm/gems/ruby-1.9.2-p290/gems/railties-3.1.3/lib/rails/commands.rb:54:in`block in <top (required)>'
from /Users/Chris/.rvm/gems/ruby-1.9.2-p290/gems/railties-3.1.3/lib/rails/commands.rb:49:in `tap'
from /Users/Chris/.rvm/gems/ruby-1.9.2-p290/gems/railties-3.1.3/lib/rails/commands.rb:49:in`<top (required)>'
from script/rails:6:in `require'
from script/rails:6:in`'

current_domain includes port

current_domain returns "foo.com:3000" when the port is 3000 (not 80). For reference, request.domain returns "foo.com" so I think current_domain should be just the domain too. For my purposes (the domain attribute of a cookie) the port is not considered part of the domain name, and is not allowed to be included.

The request object also has request.host and request.host_with_port, so perhaps a new variable current_domain_with_port could be added if someone needs it.

Crash when requesting URL with tld_size different than expected

With a tld_size=1, requesting a url with the host 'localhost' will crash rails url_helpers. This is probably an edge case but was unavoidable for me as Monit (old version) would only use 'localhost' as a host so this made monit monitoring impossible.

The offending code

def self.host_without_subdomain(host)
parts = host.split('.')
parts[-(SubdomainFu.tld_size+1)..-1].join(".")
end

could be replaced with

def self.host_without_subdomain(host)
parts = host.split('.')
host_without_sub = parts[-(SubdomainFu.tld_size+1)..-1]
host_without_sub.blank? ? host : host_without_sub.join(".")
end

rspec redirect_to matcher fails if route only exists for a subdomain

I was running into a problem with rspec's redirect_to matcher in my controller specs. If a controller was redirecting to a url that only exists in a subdomain, redirect_to would fail because it ignores the host part of the 302 response. I saw this with rails 2.3.8, rspec-rails 1.3.2 and subdomain-fu 0.5.4. Here's an example, followed by a workaround.

# routes
map.with_options :conditions => {:subdomain => 'mobile'} do |mobile|
  mobile.resources :phone_numbers
end

# a controller
class PhoneNumbersController < ActionController::Base
  def new; end
  def edit; redirect_to new_phone_number_url; end
end

# and a spec
describe '#edit' do
  it "should redirect" do
    request.host = 'mobile.test.host'
    get 'edit'
    puts response.body # prints the correct url of http://mobile.test.host/phone_numbers/new
    response.should redirect_to(edit_phone_number_url) # this raises ActionController::RoutingError
  end
end

I traced the problem to the rspec-rails file lib/spec/rails/matchers/redirect_to.rb where the url from the 302 response gets converted into a route hash. But it ignores the host part of the url so the hash wouldn't have :subdomain => 'mobile'. This would cause the route not to be found, raising the error. I monkey patched rspec-rails like this which solved my problem:

module Spec
  module Rails
    module Matchers
      class RedirectTo  #:nodoc:
        # a monkey patch to make rspec aware of subdomains when using the redirect_to matcher
        def path_hash(url)
          uri = URI.parse(url)
          ActionController::Routing::Routes.recognize_path uri.path, {
            :method => :get,   
            :subdomain => SubdomainFu.subdomain_from(uri.host),
          }     
        end
      end
    end
  end
end

I'm not sure whether subdomain-fu should try to patch rspec like above, or if rspec could be doing something better to avoid the issue. It seems like rspec is taking a shortcut converting the url to a hash which bypasses the route extensions applied by subdomain-fu.

Exceptions thrown when someone requests without Host: HTTP header

http://apidock.com/rails/ActionController/Request/domain

ActionController::Request.domain() will return nil if someone comes to a site using subdomain-fu using only the server's IP address, such as http://10.2.3.4/zomg-haxor.php . In the real world, this sort of thing will happen fairly frequently thanks to security probes, ill-written bots, and crummy HTTP clients. This causes an error, attempting to apply '+' to nil:

gems/subdomain-fu-0.5.4/lib/subdomain-fu.rb:145:in `current_domain'

subdomain-fu should gracefully degrade in some way.

map.with_options fails when using :has_many => [ :associated_models ]

Hi there.

Firstly, I have this case:

map.with_options :conditions => { :subdomain => "admin" } do |admin|
admin.resources :characters, :controller => "admin/characters", :only => [ :index, :edit, :update, :destroy ]
end

Note that there is no associated has_many relation to the characters. Secondly I have this in my routes also.

map.with_options :conditions => {:subdomain => 'ingame'} do |ingame|
ingame.resources :characters, :only => [ :show, :edit, :update ], :controller => "ingame/characters", :has_many => [ :character_aliases ]
end

Now, we agree that going to ingame.something.com/characters/1/character_aliases should list the aliases associated with character 1. And that going to admin.something.com/characters/1/character_aliases should return an error, seeing as there is no has_many relation for the admin subdomain?

This, however, is not the case. Going to admin.something.com/characters/1/character_aliases will show the aliases that should require the ingame subdomain.

Is this an error, or is this intentional? If it's intentional, whats the logic behind?

Best regards
Emil

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.