{"id":43558450,"url":"https://github.com/jaryncolbert/recurse-world-map","last_synced_at":"2026-02-03T20:47:48.776Z","repository":{"id":39152949,"uuid":"190075261","full_name":"jaryncolbert/recurse-world-map","owner":"jaryncolbert","description":"Geocodes and maps the current locations for Recurse Center community members","archived":false,"fork":false,"pushed_at":"2023-07-25T21:14:20.000Z","size":7226,"stargazers_count":6,"open_issues_count":17,"forks_count":4,"subscribers_count":4,"default_branch":"main","last_synced_at":"2024-04-14T11:08:35.195Z","etag":null,"topics":["flask","flask-api","geocoder-library","geonames","leaflet","leaflet-markercluster","openstreetmap","react","react-leaflet","react-leaflet-markercluster","recurse-center","recurse-center-api"],"latest_commit_sha":null,"homepage":"https://world.recurse.com/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jaryncolbert.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-06-03T20:12:36.000Z","updated_at":"2023-10-21T09:20:18.000Z","dependencies_parsed_at":"2022-07-12T20:00:33.852Z","dependency_job_id":null,"html_url":"https://github.com/jaryncolbert/recurse-world-map","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/jaryncolbert/recurse-world-map","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaryncolbert%2Frecurse-world-map","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaryncolbert%2Frecurse-world-map/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaryncolbert%2Frecurse-world-map/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaryncolbert%2Frecurse-world-map/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jaryncolbert","download_url":"https://codeload.github.com/jaryncolbert/recurse-world-map/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaryncolbert%2Frecurse-world-map/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29056907,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-03T20:13:53.544Z","status":"ssl_error","status_checked_at":"2026-02-03T20:13:40.507Z","response_time":96,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["flask","flask-api","geocoder-library","geonames","leaflet","leaflet-markercluster","openstreetmap","react","react-leaflet","react-leaflet-markercluster","recurse-center","recurse-center-api"],"created_at":"2026-02-03T20:47:47.931Z","updated_at":"2026-02-03T20:47:48.753Z","avatar_url":"https://github.com/jaryncolbert.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# World of Recurse\n\nVisualize the locations of members\nof the [Recurse Center](https://recurse.com) community\non an interactive map.\n\n## Using the Map\n\nThe app starts by displaying a map of the world\nwith markers for each city or country\nwhere a Recurser is located.\n\n\u003cimg src=\"./screenshots/world_map.png?raw=true\" alt=\"RC World Map\" width=\"500\"/\u003e\n\nGreen markers are generally single cities,\nand the number inside the marker indicates\nthe number of Recursers in that location.\nClicking on a green marker will produce a popup\nthat displays the location name\nand names of all Recursers at that location.\nEach name is a link to that person's entry\nin the [RC Directory](https://www.recurse.com/directory).\n\nGrey markers are clusters of locations\nthat are spaced closely together,\nand zooming into the map will automatically expand\nthe grey clusters into green markers.\n\nThe search bar at the top allows searching\nfor locations by name\nwith autosuggest provided by the RC API's locations endpoint.\n\n\u003cimg src=\"./screenshots/london_autosuggest.png?raw=true\" alt=\"RC World Map\" width=\"500\"/\u003e\n\nOnce a location is selected\nfrom the search bar,\nthe map will pan and zoom to that location\nand display the popup with information\nabout Recursers in that location.\n\n\u003cimg src=\"./screenshots/london_results.png?raw=true\" alt=\"RC World Map\" width=\"500\"/\u003e\n\n## Stack\n\nInitially, this code was ported over\nfrom Jason Owens' [Recurse Faces app](https://github.com/jasonaowen/recurse-faces)!\nLike Faces, its main stack is also mainly Postgresql, Flask, and React.\n\nThis app reads Recursers' locations\nfrom their profiles in the\n[Recurse Center API](https://github.com/recursecenter/wiki/wiki/Recurse-Center-API)\n(_login required_),\nand then uses the [Geocoder](http://geocoder.readthedocs.io) Python library\nwith the [GeoNames](https://geonames.org) geocoder\nto find the latitude and longitude\nfor each location name.\nOnce those locations are retrieved,\nthe points are displayed on a [Leaflet](https://leafletjs.com/) map\nusing [OpenStreetMap](https://www.openstreetmap.org/#map=19/40.65010/-73.94958) tiles.\n\n## Local Set Up\n\nThe app is comprised of a Flask back-end and a React front-end.\nThe instructions below detail\nhow to set up and start both parts of the app.\n\n### Start the Back End with the RC API\n\nThe Python server is a Flask app\nthat serves the index page and the JavaScript,\ngeocodes and stores the locations,\nproxies the requests for location names\nin the autocomplete search bar,\nand looks up locations and associated users\nin the database.\n\nRunning the API locally requires populating the database\nand setting up the Python environment.\n\n#### Python Virtual Environment\n\nYou'll first need to install the Python dependencies.\nFirst, set up a [virtual environment](https://docs.python.org/3/tutorial/venv.html):\n\n```sh\n$ python3 -m venv venv\n```\n\nor\n\n```sh\n$ python3 -m virtualenv --python=python3 venv\n```\n\nThen, activate the virtual environment\nand install the app's dependencies into it:\n\n```sh\n$ . venv/bin/activate\n(venv)$ pip install -r requirements.txt\n```\n\nTo populate the database or start the Flask app,\nthe scripts must be run in this virtual environment (venv).\nThe virtual environment can be reactivated at any time with the command:\n\n```sh\n$ . venv/bin/activate\n```\n\n#### Create a .env File\n\nThe Flask app needs some configuration,\nwhich it takes through environment variables.\nFor convenience, this project uses a `.env` file\nto store these variables.\n\nFirst, copy the `env.template` file to a new file named `.env`:\n\n```sh\n$ cp env.template .env\n```\n\nThe next few sections will describe\nhow to set and add to this initial set of variables.\n\n**Note**: The `.env` file should not be placed under version control\nand is included in the `.gitignore` file.\n\n#### Populate the Database\n\nWe use [PostgreSQL](https://www.postgresql.org/) as our database.\nFollow the [installation instructions](https://www.postgresql.org/download/)\nfor your platform to set up the database server.\n\nFirst, choose or [create](https://www.postgresql.org/docs/current/tutorial-createdb.html)\na database:\n\n```sh\n$ createdb --owner=$(whoami) worldmap\n```\n\nDepending on your platform,\nyou may need to run that command\nas the operating system user which owns the database server:\n\n```sh\n$ sudo -u postgres createdb --owner=$(whoami) worldmap\n```\n\nThen, create the schema:\n\n```sh\n$ psql worldmap \u003c schema.sql\n```\n\nAdd your database connection URL to the `.env` file:\n`DATABASE_URL=postgres:///worldmap/`\n\n**Note**: the `DATABASE_URL` can be any\n[libpq connection string](https://www.postgresql.org/docs/current/static/libpq-connect.html#LIBPQ-CONNSTRING).\nAn alternate database URL you might try is\n`postgres://localhost/worldmap`\nto connect over TCP/IP to the database named `worldmap`.\n\nThe `update_data.py` script pulls RC profile data\nfrom the Recurse Center API,\nwhich also powers the [RC Directory](https://www.recurse.com/directory),\nand stores it in the database.\nTo connect to the RC API,\nthe script needs a personal access token,\nwhich you can create in the\n[Apps page in your RC Settings](https://www.recurse.com/settings/apps).\nThe personal access token will only be shown once,\nso copy it to a safe place\nand add it to the `.env` file:\n`RC_API_ACCESS_TOKEN=\u003cpersonal_access_token\u003e`\n\nThe script also geocodes the locations retrieved\nfrom the RC API\nusing the [GeoNames database](https://www.geonames.org/).\nTo connect to GeoNames,\nthe script needs a registered GeoNames username,\nwhich you can create\non the [GeoNames login page](http://www.geonames.org/login).\nAdd your username\nto the `.env` file:\n`GEONAMES_USERNAME=\u003cusername\u003e`\n\nRun the script to populate the database\nin your [Python Virtual Environment](#python-virtual-environment):\n\n```sh\n(venv)$ ./update_data.py\n```\n\nIt should print out\nhow many people, locations, batches, and stints\nwere added.\n\n**Note**: GeoNames rate limits the number\nof requests per second\nthat can be delivered to a single app,\nso this script can take a long time to complete,\nespecially on an empty database.\nThe script will display informational messages\nwhen it retrieves lat/lng results\nfor each location\nand when the script is complete.\n\n#### Build Front-End Assets\n\nFirst, install dependencies by running the [npm](https://www.npmjs.com/get-npm) command:\n\n```sh\n$ npm install\n```\n\nNext, build the static resources for the Flask app to serve:\n\n```sh\n$ npm run build\n```\n\n#### Start the Flask App\n\nNext, start the Flask API\nin your [Python Virtual Environment](#python-virtual-environment):\n\n```sh\n(venv)$ flask run\n```\n\nNow, your local instance of Recurse Faces\nwith live data from the RC API\nwill be available at http://127.0.0.1:5001/:\n\nHowever, because this instance is running\nwith statically generated resources from `npm build`,\nlocal changes to the React front end\nwill not be reflected at this URL.\n\nThe React dev server is configured to proxy the Flask API,\nso to run your local front end code\nwith live data from the RC API,\nleave the Flask app running\nand start the React front end in another terminal tab or window:\n\n```sh\n$ npm run start\n```\n\nNow, the React front end reflecting any local code changes\nwill be running at http://localhost:3000/\nwith data from the Flask back end API\nrunning at http://127.0.0.1:5001/.\n\n## Troubleshooting\n\nIf you receive either of the following messages:\n\n```sh\nFile \"./update_data.py\", line 24\nheaders = {'Authorization': f'Bearer {token}'}\n                                                ^\nSyntaxError: invalid syntax\n```\n\nor\n\n```sh\n/usr/bin/python: No module named flask\n```\n\nreactivate your [Python virtual environment](#python-virtual-environment),\nand then try to run the previous command again.\n\nIf you receive the following message:\n\n```sh\npsycopg2.OperationalError: could not connect to server: No such file or directory\n\tIs the server running locally and accepting\n\tconnections on Unix domain socket \"/tmp/.s.PGSQL.5432\"?\n```\n\nmake sure Postgres is running locally and the database connection URL is specified in the .env file.\n\n\u003ca href='http://www.recurse.com' title='Made with love at the Recurse Center'\u003e\u003cimg src='https://cloud.githubusercontent.com/assets/2883345/11325206/336ea5f4-9150-11e5-9e90-d86ad31993d8.png' height='20px'/\u003e\u003c/a\u003e\n![Licensed under the AGPL, version 3](https://img.shields.io/badge/license-AGPL3-blue.svg)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjaryncolbert%2Frecurse-world-map","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjaryncolbert%2Frecurse-world-map","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjaryncolbert%2Frecurse-world-map/lists"}