{"action":"created","comment":{"url":"https://api.github.com/repos/CartoDB/cartodb/pulls/comments/27476463","id":27476463,"diff_hunk":"@@ -1,313 +1,220 @@\n module CartoDB\n \n-  # Param enforced by app/controllers/application_controller -> ensure_user_domain_param (before_filter)\n-  def self.extract_subdomain(request)\n-    if request.params[:user_domain].nil?\n-      request.host.to_s.gsub(self.session_domain, '')\n-    else\n-      request.params[:user_domain]\n-    end\n+  begin\n+    CARTODB_REV = File.read(\"#{Rails.root}/REVISION\").strip\n+  rescue\n+    CARTODB_REV = nil\n   end\n \n-  def self.extract_host_subdomain(request)\n-    if request.params[:user_domain].nil?\n-      nil\n+  DEFAULT_DB_SCHEMA = 'public'\n+  PUBLIC_DB_USER  = 'publicuser'\n+  PUBLIC_DB_USER_PASSWORD  = 'publicuser'\n+  TILE_DB_USER    = 'tileuser'\n+  SRID            = 4326\n+\n+  # @see services/importer/lib/importer/column.rb -> RESERVED_WORDS\n+  # @see app/models/table.rb -> RESERVED_COLUMN_NAMES\n+  POSTGRESQL_RESERVED_WORDS = %W{ ALL ANALYSE ANALYZE AND ANY ARRAY AS ASC ASYMMETRIC AUTHORIZATION BETWEEN BINARY BOTH CASE CAST\n+                                  CHECK COLLATE COLUMN CONSTRAINT CREATE CROSS CURRENT_DATE CURRENT_ROLE CURRENT_TIME CURRENT_TIMESTAMP\n+                                  CURRENT_USER DEFAULT DEFERRABLE DESC DISTINCT DO ELSE END EXCEPT FALSE FOR FOREIGN FREEZE FROM FULL\n+                                  GRANT GROUP HAVING ILIKE IN INITIALLY INNER INTERSECT INTO IS ISNULL JOIN LEADING LEFT LIKE LIMIT LOCALTIME\n+                                  LOCALTIMESTAMP NATURAL NEW NOT NOTNULL NULL OFF OFFSET OLD ON ONLY OR ORDER OUTER OVERLAPS PLACING PRIMARY\n+                                  REFERENCES RIGHT SELECT SESSION_USER SIMILAR SOME SYMMETRIC TABLE THEN TO TRAILING TRUE UNION UNIQUE USER\n+                                  USING VERBOSE WHEN WHERE XMIN XMAX }\n+\n+  RESERVED_COLUMN_NAMES = %W{ FORMAT CONTROLLER ACTION oid tableoid xmin cmin xmax cmax ctid ogc_fid }\n+\n+  LAST_BLOG_POSTS_FILE_PATH = \"#{Rails.root}/public/system/last_blog_posts.html\"\n+\n+  # Helper method to encapsulate Rails full URL generation compatible with our subdomainless mode\n+  # @param context ActionController::Base or a View or something that holds a request\n+  # @param path String Rails route name\n+  # @param params Hash Parameters to send to the url (Optional)\n+  # @param user User (Optional) If not sent will use subdomain or /user/xxx from controller request\n+  def self.url(context, path, params={}, user = nil)\n+    if user.nil?\n+      subdomain = self.extract_subdomain(context.request)\n+      org_username = nil\n     else\n-      request.host.to_s.gsub(self.session_domain, '')\n+      subdomain = user.subdomain\n+      org_username = user.organization_username\n     end\n+    # Must clean user_domain or else polymorphic_path will use it and generate again /u/xxx/user/xxx\n+    CartoDB.base_url(subdomain, org_username) + context.polymorphic_path(path, params.merge({user_domain:nil}))\n+  end\n+\n+  # Helper method to encapsulate Rails URL path generation compatible with our subdomainless mode\n+  # @param controller ActionController::Base\n+  # @param path String Rails route name\n+  # @param params Hash Parameters to send to the url (Optional)\n+  def self.path(controller, path, params={})\n+    controller.polymorphic_path(path, params)\n   end\n \n-  # Actually the two previous methods return the requested username, not the real subdomain\n-  def self.extract_real_subdomain(request)\n+  # \"Smart\" subdomain extraction from the request, depending on configuration and /u/xxx url fragment\n+  def self.extract_subdomain(request)\n+    user_domain = self.username_from_request(request)\n+    user_domain.nil? ? self.subdomain_from_request(request) : user_domain\n+  end\n+\n+  # Raw subdomain extraction from request\n+  def self.subdomain_from_request(request)\n     request.host.to_s.gsub(self.session_domain, '')\n   end\n \n-  def self.user_url(username, organization = nil)\n-    organization.nil? ? self.base_url(username) : self.base_url(organization, username)\n+  # Flexible subdomain extraction: If /u/xxx or /user/xxxx present uses it, else uses request host (xxx.cartodb.com)\n+  def self.extract_host_subdomain(request)\n+    self.username_from_request(request).nil? ? nil : self.subdomain_from_request(request)\n   end\n \n-  def self.base_url(subdomain, org_username=nil)\n-    if Rails.env.production? || Rails.env.staging?\n-      base_url =\"https://#{subdomain}#{self.session_domain}\"\n-    elsif Rails.env.development?\n-      base_url =\"http://#{subdomain}#{self.session_domain}:3000\"\n+  # Warning, if subdomains are allowed includes the username as the subdomain,\n+  #  but else returns a base url WITHOUT '/u/username'\n+  def self.base_url(subdomain, org_username=nil, protocol_override=nil)\n+    if self.subdomainless_urls?\n+      base_url = self.domainless_base_url(subdomain, protocol_override)\n     else\n-      base_url = \"http://#{subdomain}#{self.session_domain}:53716\"\n-    end\n-    unless org_username.nil?\n-      base_url << \"/u/#{org_username}\"\n+      base_url = self.subdomain_based_base_url(subdomain, org_username, protocol_override)\n     end\n+\n     base_url\n   end\n \n-  def self.session_domain\n-    Cartodb.config[:session_domain]\n+  # NOTE: Not intended for usage outside testing (where is needed to clean state between tests)\n+  def self.clear_internal_cache\n+    remove_class_variable(:@@request_host) if defined?(@@request_host)\n+    remove_class_variable(:@@hostname) if defined?(@@hostname)\n+    remove_class_variable(:@@http_port) if defined?(@@http_port)\n+    remove_class_variable(:@@https_port) if defined?(@@http_ports)\n+    remove_class_variable(:@@session_domain) if defined?(@@session_domain)\n+    remove_class_variable(:@@domain) if defined?(@@domain)\n+    remove_class_variable(:@@subdomainless_urls) if defined?(@@subdomainless_urls)\n+    remove_class_variable(:@@account_host) if defined?(@@account_host)\n+    remove_class_variable(:@@account_path) if defined?(@@account_path)\n   end\n \n-  def self.secret_token\n-    Cartodb.config[:secret_token]\n+  # Note: use ||= only for fields who always have a non-nil, non-false value\n+  #       else, rely on defined? and pure assignment to allow nils and values caching the value\n+\n+  # Stores the non-user part of the domain (e.g. '.cartodb.com')\n+  def self.session_domain\n+    @@session_domain ||= self.get_session_domain\n   end\n \n   def self.domain\n-    @@domain ||= if Rails.env.production? || Rails.env.staging?\n-      `hostname -f`.strip\n-    elsif Rails.env.development?\n-      \"vizzuality#{session_domain}\"\n-    else\n-      \"test#{session_domain}\"\n-    end\n+    return @@domain if defined?(@@domain)\n+    @@domain = self.get_domain\n   end\n \n-  def self.hostname\n-    @@hostname ||= if Rails.env.production? || Rails.env.staging?\n-      \"https://#{domain}\"\n-    elsif Rails.env.development?\n-      \"http://#{domain}:3000\"\n-    else\n-      \"http://#{domain}:53716\"\n-    end\n+  def self.subdomainless_urls?\n+    return @@subdomainless_urls if defined?(@@subdomainless_urls)\n+    @@subdomainless_urls = self.get_subdomainless_urls\n   end\n \n   def self.account_host\n-    Cartodb.config[:account_host]\n+    @@account_host ||= self.get_account_host\n   end\n \n   def self.account_path\n-    Cartodb.config[:account_path]\n+    @@account_path ||= self.get_account_path\n   end\n \n-  # TODO move to separated file and activate in order\n-  # to enable CartoDB plugins\n-  # module Plugin\n-  #   class << self\n-  #     def register(plugin)\n-  #       @registered_plugins ||= []\n-  #       @registered_plugins << plugin\n-  #     end\n-      \n-  #     def registered\n-  #       @registered_plugins\n-  #     end\n-  #   end\n-  # end\n-\n-  module API\n-    VERSION_1 = \"v1\"\n+  def self.request_host=(value)\n+    @@request_host=value\n   end\n \n-  begin\n-    CARTODB_REV = File.read(\"#{Rails.root}/REVISION\").strip\n-  rescue\n-    CARTODB_REV = nil\n+  # \"private\" methods, not intended for direct usage\n+  # ------------------------------------------------\n+\n+  def self.request_host\n+    return @@request_host if defined?(@@request_host)\n+    @@request_host = ''\n   end\n \n-  DEFAULT_DB_SCHEMA = 'public'\n-  PUBLIC_DB_USER  = 'publicuser'\n-  PUBLIC_DB_USER_PASSWORD  = 'publicuser'\n-  TILE_DB_USER    = 'tileuser'\n-  GOOGLE_SRID     = 3857\n-  SRID            = 4326\n-  USER_REQUESTS_PER_DAY = 10000\n-\n-  TYPES = {\n-    \"number\"  => [\"smallint\", /numeric\\(\\d+,\\d+\\)/, \"integer\", \"bigint\", \"decimal\", \"numeric\", \"double precision\", \"serial\", \"big serial\", \"real\"],\n-    \"string\"  => [\"varchar\", \"character varying\", \"text\", /character\\svarying\\(\\d+\\)/, /char\\s*\\(\\d+\\)/, /character\\s*\\(\\d+\\)/],\n-    \"boolean\" => [\"boolean\"],\n-    \"date\"    => [\n-      \"timestamptz\",\n-      \"timestamp with time zone\",\n-      \"timestamp without time zone\"\n-    ]\n-  }\n-\n-  NEXT_TYPE = {\n-    \"number\" => \"double precision\",\n-    \"string\" => \"text\"\n-  }\n-\n-  VALID_GEOMETRY_TYPES = %W{ geometry multipolygon point multilinestring }\n+  def self.hostname\n+    @@hostname ||= self.get_hostname\n+  end\n \n-  # @see services/importer/lib/importer/column.rb -> RESERVED_WORDS\n-  # @see app/models/table.rb -> RESERVED_COLUMN_NAMES\n-  POSTGRESQL_RESERVED_WORDS = %W{ ALL ANALYSE ANALYZE AND ANY ARRAY AS ASC ASYMMETRIC AUTHORIZATION BETWEEN BINARY BOTH CASE CAST\n-                                  CHECK COLLATE COLUMN CONSTRAINT CREATE CROSS CURRENT_DATE CURRENT_ROLE CURRENT_TIME CURRENT_TIMESTAMP\n-                                  CURRENT_USER DEFAULT DEFERRABLE DESC DISTINCT DO ELSE END EXCEPT FALSE FOR FOREIGN FREEZE FROM FULL\n-                                  GRANT GROUP HAVING ILIKE IN INITIALLY INNER INTERSECT INTO IS ISNULL JOIN LEADING LEFT LIKE LIMIT LOCALTIME\n-                                  LOCALTIMESTAMP NATURAL NEW NOT NOTNULL NULL OFF OFFSET OLD ON ONLY OR ORDER OUTER OVERLAPS PLACING PRIMARY\n-                                  REFERENCES RIGHT SELECT SESSION_USER SIMILAR SOME SYMMETRIC TABLE THEN TO TRAILING TRUE UNION UNIQUE USER\n-                                  USING VERBOSE WHEN WHERE XMIN XMAX }\n+  def self.http_port\n+    return @@http_port if defined?(@@http_port)\n+    @@http_port = self.get_http_port\n+  end\n \n-  RESERVED_COLUMN_NAMES = %W{ FORMAT CONTROLLER ACTION }\n+  def self.https_port\n+    return @@https_port if defined?(@@https_port)\n+    @@https_port = self.get_https_port\n+  end\n \n-  LAST_BLOG_POSTS_FILE_PATH = \"#{Rails.root}/public/system/last_blog_posts.html\"\n+  def self.protocol(protocol_override=nil)\n+    default_protocol = self.use_https? ? 'https' : 'http'\n+    protocol_override.nil? ? default_protocol : protocol_override\n+  end\n+\n+  def self.subdomain_based_base_url(subdomain, org_username=nil, protocol_override=nil)\n+    protocol = self.protocol(protocol_override)\n+    base_url =\"#{protocol}://#{subdomain}#{self.session_domain}#{protocol == 'http' ? self.http_port : self.https_port}\"\n+    unless org_username.nil?\n+      base_url << \"/u/#{org_username}\"\n+    end\n+    base_url\n+  end\n+\n+  def self.domainless_base_url(subdomain, protocol_override=nil)\n+    protocol = self.protocol(protocol_override)\n+    port = protocol == 'http' ? self.http_port : self.https_port\n+    request_subdomain = self.request_host.sub(self.session_domain, '')\n+    request_subdomain += '.' if (request_subdomain.length > 0 && !request_subdomain.end_with?('.'))\n+\n+    \"#{protocol}://#{request_subdomain}#{self.session_domain}#{port}/user/#{subdomain}\"","path":"config/initializers/carto_db.rb","position":269,"original_position":269,"commit_id":"df69b334623c8a2ec3b914f6f431e96218401ebf","original_commit_id":"df69b334623c8a2ec3b914f6f431e96218401ebf","user":{"login":"rafatower","id":1914276,"avatar_url":"https://avatars.githubusercontent.com/u/1914276?v=3","gravatar_id":"","url":"https://api.github.com/users/rafatower","html_url":"https://github.com/rafatower","followers_url":"https://api.github.com/users/rafatower/followers","following_url":"https://api.github.com/users/rafatower/following{/other_user}","gists_url":"https://api.github.com/users/rafatower/gists{/gist_id}","starred_url":"https://api.github.com/users/rafatower/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rafatower/subscriptions","organizations_url":"https://api.github.com/users/rafatower/orgs","repos_url":"https://api.github.com/users/rafatower/repos","events_url":"https://api.github.com/users/rafatower/events{/privacy}","received_events_url":"https://api.github.com/users/rafatower/received_events","type":"User","site_admin":false},"body":"I think there's a missing colon (`:`) there:\r\n```\r\n\"#{protocol}://#{request_subdomain}#{self.session_domain}:#{port}/user/#{subdomain}\"\r\n#--------------------------------------------------------^\r\n```","created_at":"2015-03-31T13:07:14Z","updated_at":"2015-03-31T13:07:14Z","html_url":"https://github.com/CartoDB/cartodb/pull/1933#discussion_r27476463","pull_request_url":"https://api.github.com/repos/CartoDB/cartodb/pulls/1933","_links":{"self":{"href":"https://api.github.com/repos/CartoDB/cartodb/pulls/comments/27476463"},"html":{"href":"https://github.com/CartoDB/cartodb/pull/1933#discussion_r27476463"},"pull_request":{"href":"https://api.github.com/repos/CartoDB/cartodb/pulls/1933"}}},"pull_request":{"url":"https://api.github.com/repos/CartoDB/cartodb/pulls/1933","id":27917413,"html_url":"https://github.com/CartoDB/cartodb/pull/1933","diff_url":"https://github.com/CartoDB/cartodb/pull/1933.diff","patch_url":"https://github.com/CartoDB/cartodb/pull/1933.patch","issue_url":"https://api.github.com/repos/CartoDB/cartodb/issues/1933","number":1933,"state":"open","locked":false,"title":"Url rewrites - Rails Backend part [Don't Merge]","user":{"login":"Kartones","id":2085449,"avatar_url":"https://avatars.githubusercontent.com/u/2085449?v=3","gravatar_id":"","url":"https://api.github.com/users/Kartones","html_url":"https://github.com/Kartones","followers_url":"https://api.github.com/users/Kartones/followers","following_url":"https://api.github.com/users/Kartones/following{/other_user}","gists_url":"https://api.github.com/users/Kartones/gists{/gist_id}","starred_url":"https://api.github.com/users/Kartones/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Kartones/subscriptions","organizations_url":"https://api.github.com/users/Kartones/orgs","repos_url":"https://api.github.com/users/Kartones/repos","events_url":"https://api.github.com/users/Kartones/events{/privacy}","received_events_url":"https://api.github.com/users/Kartones/received_events","type":"User","site_admin":false},"body":"Fixes #1693 \r\n\r\nTasks still pending:\r\n- [x] 1) check all user_domain: (pending specs only)\r\n- [x] 2) check all _path\r\n- [x] 3) check all _url\r\n- [x] share options not working for MU users (embed url, share url, vizjson is ok)\r\n- [x] (url_for usage (e.g. cartodb/app/views/admin/pages/shared/_pagination.html.erb)\r\n- [ ] new config param `subdomainless_urls`\r\n- [ ] torque not working at least for MU users (@javisantana)\r\n- [ ] Document how subdomains or lack of work at cartodb in the wiki, like this:\r\nhttps://github.com/CartoDB/cartodb/wiki/creating-tables-though-the-SQL-API\r\nhttps://github.com/CartoDB/cartodb/wiki/How-to-configure-basemaps-in-CartoDB\r\n\r\n[Requisites wiki page](https://github.com/CartoDB/cartodb-management/wiki/Worklog-Kartones)\r\n\r\n","created_at":"2015-01-23T11:28:07Z","updated_at":"2015-03-31T13:07:14Z","closed_at":null,"merged_at":null,"merge_commit_sha":"5612a119dbadad0ac571046f50e9652f91855acf","assignee":{"login":"Kartones","id":2085449,"avatar_url":"https://avatars.githubusercontent.com/u/2085449?v=3","gravatar_id":"","url":"https://api.github.com/users/Kartones","html_url":"https://github.com/Kartones","followers_url":"https://api.github.com/users/Kartones/followers","following_url":"https://api.github.com/users/Kartones/following{/other_user}","gists_url":"https://api.github.com/users/Kartones/gists{/gist_id}","starred_url":"https://api.github.com/users/Kartones/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Kartones/subscriptions","organizations_url":"https://api.github.com/users/Kartones/orgs","repos_url":"https://api.github.com/users/Kartones/repos","events_url":"https://api.github.com/users/Kartones/events{/privacy}","received_events_url":"https://api.github.com/users/Kartones/received_events","type":"User","site_admin":false},"milestone":null,"commits_url":"https://api.github.com/repos/CartoDB/cartodb/pulls/1933/commits","review_comments_url":"https://api.github.com/repos/CartoDB/cartodb/pulls/1933/comments","review_comment_url":"https://api.github.com/repos/CartoDB/cartodb/pulls/comments{/number}","comments_url":"https://api.github.com/repos/CartoDB/cartodb/issues/1933/comments","statuses_url":"https://api.github.com/repos/CartoDB/cartodb/statuses/df69b334623c8a2ec3b914f6f431e96218401ebf","head":{"label":"CartoDB:issue-1693","ref":"issue-1693","sha":"df69b334623c8a2ec3b914f6f431e96218401ebf","user":{"login":"CartoDB","id":1799254,"avatar_url":"https://avatars.githubusercontent.com/u/1799254?v=3","gravatar_id":"","url":"https://api.github.com/users/CartoDB","html_url":"https://github.com/CartoDB","followers_url":"https://api.github.com/users/CartoDB/followers","following_url":"https://api.github.com/users/CartoDB/following{/other_user}","gists_url":"https://api.github.com/users/CartoDB/gists{/gist_id}","starred_url":"https://api.github.com/users/CartoDB/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/CartoDB/subscriptions","organizations_url":"https://api.github.com/users/CartoDB/orgs","repos_url":"https://api.github.com/users/CartoDB/repos","events_url":"https://api.github.com/users/CartoDB/events{/privacy}","received_events_url":"https://api.github.com/users/CartoDB/received_events","type":"Organization","site_admin":false},"repo":{"id":4909355,"name":"cartodb","full_name":"CartoDB/cartodb","owner":{"login":"CartoDB","id":1799254,"avatar_url":"https://avatars.githubusercontent.com/u/1799254?v=3","gravatar_id":"","url":"https://api.github.com/users/CartoDB","html_url":"https://github.com/CartoDB","followers_url":"https://api.github.com/users/CartoDB/followers","following_url":"https://api.github.com/users/CartoDB/following{/other_user}","gists_url":"https://api.github.com/users/CartoDB/gists{/gist_id}","starred_url":"https://api.github.com/users/CartoDB/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/CartoDB/subscriptions","organizations_url":"https://api.github.com/users/CartoDB/orgs","repos_url":"https://api.github.com/users/CartoDB/repos","events_url":"https://api.github.com/users/CartoDB/events{/privacy}","received_events_url":"https://api.github.com/users/CartoDB/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/CartoDB/cartodb","description":"Geospatial database for the cloud","fork":false,"url":"https://api.github.com/repos/CartoDB/cartodb","forks_url":"https://api.github.com/repos/CartoDB/cartodb/forks","keys_url":"https://api.github.com/repos/CartoDB/cartodb/keys{/key_id}","collaborators_url":"https://api.github.com/repos/CartoDB/cartodb/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/CartoDB/cartodb/teams","hooks_url":"https://api.github.com/repos/CartoDB/cartodb/hooks","issue_events_url":"https://api.github.com/repos/CartoDB/cartodb/issues/events{/number}","events_url":"https://api.github.com/repos/CartoDB/cartodb/events","assignees_url":"https://api.github.com/repos/CartoDB/cartodb/assignees{/user}","branches_url":"https://api.github.com/repos/CartoDB/cartodb/branches{/branch}","tags_url":"https://api.github.com/repos/CartoDB/cartodb/tags","blobs_url":"https://api.github.com/repos/CartoDB/cartodb/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/CartoDB/cartodb/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/CartoDB/cartodb/git/refs{/sha}","trees_url":"https://api.github.com/repos/CartoDB/cartodb/git/trees{/sha}","statuses_url":"https://api.github.com/repos/CartoDB/cartodb/statuses/{sha}","languages_url":"https://api.github.com/repos/CartoDB/cartodb/languages","stargazers_url":"https://api.github.com/repos/CartoDB/cartodb/stargazers","contributors_url":"https://api.github.com/repos/CartoDB/cartodb/contributors","subscribers_url":"https://api.github.com/repos/CartoDB/cartodb/subscribers","subscription_url":"https://api.github.com/repos/CartoDB/cartodb/subscription","commits_url":"https://api.github.com/repos/CartoDB/cartodb/commits{/sha}","git_commits_url":"https://api.github.com/repos/CartoDB/cartodb/git/commits{/sha}","comments_url":"https://api.github.com/repos/CartoDB/cartodb/comments{/number}","issue_comment_url":"https://api.github.com/repos/CartoDB/cartodb/issues/comments{/number}","contents_url":"https://api.github.com/repos/CartoDB/cartodb/contents/{+path}","compare_url":"https://api.github.com/repos/CartoDB/cartodb/compare/{base}...{head}","merges_url":"https://api.github.com/repos/CartoDB/cartodb/merges","archive_url":"https://api.github.com/repos/CartoDB/cartodb/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/CartoDB/cartodb/downloads","issues_url":"https://api.github.com/repos/CartoDB/cartodb/issues{/number}","pulls_url":"https://api.github.com/repos/CartoDB/cartodb/pulls{/number}","milestones_url":"https://api.github.com/repos/CartoDB/cartodb/milestones{/number}","notifications_url":"https://api.github.com/repos/CartoDB/cartodb/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/CartoDB/cartodb/labels{/name}","releases_url":"https://api.github.com/repos/CartoDB/cartodb/releases{/id}","created_at":"2012-07-05T15:23:45Z","updated_at":"2015-03-31T11:56:18Z","pushed_at":"2015-03-31T12:57:50Z","git_url":"git://github.com/CartoDB/cartodb.git","ssh_url":"git@github.com:CartoDB/cartodb.git","clone_url":"https://github.com/CartoDB/cartodb.git","svn_url":"https://github.com/CartoDB/cartodb","homepage":"www.cartodb.com","size":421437,"stargazers_count":757,"watchers_count":757,"language":"JavaScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":170,"mirror_url":null,"open_issues_count":473,"forks":170,"open_issues":473,"watchers":757,"default_branch":"master"}},"base":{"label":"CartoDB:master","ref":"master","sha":"dac869472e3f296db4117ccba101b55e28b29163","user":{"login":"CartoDB","id":1799254,"avatar_url":"https://avatars.githubusercontent.com/u/1799254?v=3","gravatar_id":"","url":"https://api.github.com/users/CartoDB","html_url":"https://github.com/CartoDB","followers_url":"https://api.github.com/users/CartoDB/followers","following_url":"https://api.github.com/users/CartoDB/following{/other_user}","gists_url":"https://api.github.com/users/CartoDB/gists{/gist_id}","starred_url":"https://api.github.com/users/CartoDB/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/CartoDB/subscriptions","organizations_url":"https://api.github.com/users/CartoDB/orgs","repos_url":"https://api.github.com/users/CartoDB/repos","events_url":"https://api.github.com/users/CartoDB/events{/privacy}","received_events_url":"https://api.github.com/users/CartoDB/received_events","type":"Organization","site_admin":false},"repo":{"id":4909355,"name":"cartodb","full_name":"CartoDB/cartodb","owner":{"login":"CartoDB","id":1799254,"avatar_url":"https://avatars.githubusercontent.com/u/1799254?v=3","gravatar_id":"","url":"https://api.github.com/users/CartoDB","html_url":"https://github.com/CartoDB","followers_url":"https://api.github.com/users/CartoDB/followers","following_url":"https://api.github.com/users/CartoDB/following{/other_user}","gists_url":"https://api.github.com/users/CartoDB/gists{/gist_id}","starred_url":"https://api.github.com/users/CartoDB/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/CartoDB/subscriptions","organizations_url":"https://api.github.com/users/CartoDB/orgs","repos_url":"https://api.github.com/users/CartoDB/repos","events_url":"https://api.github.com/users/CartoDB/events{/privacy}","received_events_url":"https://api.github.com/users/CartoDB/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/CartoDB/cartodb","description":"Geospatial database for the cloud","fork":false,"url":"https://api.github.com/repos/CartoDB/cartodb","forks_url":"https://api.github.com/repos/CartoDB/cartodb/forks","keys_url":"https://api.github.com/repos/CartoDB/cartodb/keys{/key_id}","collaborators_url":"https://api.github.com/repos/CartoDB/cartodb/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/CartoDB/cartodb/teams","hooks_url":"https://api.github.com/repos/CartoDB/cartodb/hooks","issue_events_url":"https://api.github.com/repos/CartoDB/cartodb/issues/events{/number}","events_url":"https://api.github.com/repos/CartoDB/cartodb/events","assignees_url":"https://api.github.com/repos/CartoDB/cartodb/assignees{/user}","branches_url":"https://api.github.com/repos/CartoDB/cartodb/branches{/branch}","tags_url":"https://api.github.com/repos/CartoDB/cartodb/tags","blobs_url":"https://api.github.com/repos/CartoDB/cartodb/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/CartoDB/cartodb/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/CartoDB/cartodb/git/refs{/sha}","trees_url":"https://api.github.com/repos/CartoDB/cartodb/git/trees{/sha}","statuses_url":"https://api.github.com/repos/CartoDB/cartodb/statuses/{sha}","languages_url":"https://api.github.com/repos/CartoDB/cartodb/languages","stargazers_url":"https://api.github.com/repos/CartoDB/cartodb/stargazers","contributors_url":"https://api.github.com/repos/CartoDB/cartodb/contributors","subscribers_url":"https://api.github.com/repos/CartoDB/cartodb/subscribers","subscription_url":"https://api.github.com/repos/CartoDB/cartodb/subscription","commits_url":"https://api.github.com/repos/CartoDB/cartodb/commits{/sha}","git_commits_url":"https://api.github.com/repos/CartoDB/cartodb/git/commits{/sha}","comments_url":"https://api.github.com/repos/CartoDB/cartodb/comments{/number}","issue_comment_url":"https://api.github.com/repos/CartoDB/cartodb/issues/comments{/number}","contents_url":"https://api.github.com/repos/CartoDB/cartodb/contents/{+path}","compare_url":"https://api.github.com/repos/CartoDB/cartodb/compare/{base}...{head}","merges_url":"https://api.github.com/repos/CartoDB/cartodb/merges","archive_url":"https://api.github.com/repos/CartoDB/cartodb/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/CartoDB/cartodb/downloads","issues_url":"https://api.github.com/repos/CartoDB/cartodb/issues{/number}","pulls_url":"https://api.github.com/repos/CartoDB/cartodb/pulls{/number}","milestones_url":"https://api.github.com/repos/CartoDB/cartodb/milestones{/number}","notifications_url":"https://api.github.com/repos/CartoDB/cartodb/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/CartoDB/cartodb/labels{/name}","releases_url":"https://api.github.com/repos/CartoDB/cartodb/releases{/id}","created_at":"2012-07-05T15:23:45Z","updated_at":"2015-03-31T11:56:18Z","pushed_at":"2015-03-31T12:57:50Z","git_url":"git://github.com/CartoDB/cartodb.git","ssh_url":"git@github.com:CartoDB/cartodb.git","clone_url":"https://github.com/CartoDB/cartodb.git","svn_url":"https://github.com/CartoDB/cartodb","homepage":"www.cartodb.com","size":421437,"stargazers_count":757,"watchers_count":757,"language":"JavaScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":170,"mirror_url":null,"open_issues_count":473,"forks":170,"open_issues":473,"watchers":757,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/CartoDB/cartodb/pulls/1933"},"html":{"href":"https://github.com/CartoDB/cartodb/pull/1933"},"issue":{"href":"https://api.github.com/repos/CartoDB/cartodb/issues/1933"},"comments":{"href":"https://api.github.com/repos/CartoDB/cartodb/issues/1933/comments"},"review_comments":{"href":"https://api.github.com/repos/CartoDB/cartodb/pulls/1933/comments"},"review_comment":{"href":"https://api.github.com/repos/CartoDB/cartodb/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/CartoDB/cartodb/pulls/1933/commits"},"statuses":{"href":"https://api.github.com/repos/CartoDB/cartodb/statuses/df69b334623c8a2ec3b914f6f431e96218401ebf"}}}}