{"id":18495053,"url":"https://github.com/johnelliott/image-hub","last_synced_at":"2026-04-19T04:34:21.461Z","repository":{"id":73854291,"uuid":"110906463","full_name":"johnelliott/image-hub","owner":"johnelliott","description":"👁 Rapidly share images from a digital camera","archived":false,"fork":false,"pushed_at":"2018-08-11T00:58:46.000Z","size":1480,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":5,"default_branch":"master","last_synced_at":"2024-12-25T16:42:35.558Z","etag":null,"topics":["camera","image-processing","local","nodejs","photography","raspberry-pi","webapp"],"latest_commit_sha":null,"homepage":"https://hub.primitivemachine.com","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/johnelliott.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2017-11-16T01:20:53.000Z","updated_at":"2018-08-11T01:21:52.000Z","dependencies_parsed_at":"2023-04-18T13:49:34.774Z","dependency_job_id":null,"html_url":"https://github.com/johnelliott/image-hub","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnelliott%2Fimage-hub","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnelliott%2Fimage-hub/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnelliott%2Fimage-hub/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/johnelliott%2Fimage-hub/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/johnelliott","download_url":"https://codeload.github.com/johnelliott/image-hub/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239210675,"owners_count":19600595,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["camera","image-processing","local","nodejs","photography","raspberry-pi","webapp"],"created_at":"2024-11-06T13:23:14.663Z","updated_at":"2026-04-19T04:34:16.411Z","avatar_url":"https://github.com/johnelliott.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Image Hub 👁\nHelper hardware to rapidly share images from a digital camera\n\n\n![Image of Image Hub](https://github.com/johnelliott/image-hub/raw/master/ih.jpg)\n\nImage Hub is a computer that joins your Wifi and accepts your camera memory card. It ingests JPEG images, creates a gallery web-app, and serves the app over the local network. Image Hub provides image browsing and saving for publishing to Instagram stories, facebook or other social media.\n\nThe intended hardware is a Raspberry Pi 3 board, USB card reader, and USB power bank. A little OLED display is optional.\n\nThe display isn't covered here.\n\n## caveats\n- tested with jpegs created by a digital camera, this is easy way to avoid any missing data from jpegs from the web that may have EXIF stripped out\n- two sd card readers are supported on Raspberry Pi, but it's easier to run on mac and drag files into `storage` to add to the ETL/db\n\n## install\n- npm install the node application\n- create the `/media` directory structure the node apps expect\n- create `.env` file\n\n### /media directory structure\nthis is the directory structure on the root of the pi filesystem\n```\nmedia\n├── thumbs\n├── small\n├── storage\n└── stories\n```\n\n### .env example\nplace a file named `.env` in the project directory:\n```ini\nDISABLE_SERVER_RENDER=false\nEXIFTOOL_PATH=/bin/exiftool\nHOST=localhost\nINITIAL_STATIC_SERVER=false\nMEDIA_PATH=/media\nPORT=3000\nSQLITE_USE_WAL_MODE=true\nSQLITE_WAL_CHECK_INTERVAL_SECONDS=10\n```\n\n## run locally\n- npm run etl in one terminal\n- drag/drop a filename.JPG with exif data (an exif preview thumbnail is necessary, camera pictures work well for this) into the `storage` directory\n- use `npm run db:images` orr sqlite3 CLI (`sqlite3 cam.db`) to check the `image` table has data\n- npm run server in another terminal\n- load up `localhost:3000/all` (all ignores image create dates) to see the server loads\n\n### server.js feature flags\n#### SEVER_RENDER_OFF=true\nturn off server rendering for debugging\n#### INITIAL_STATIC_SERVER=true\nturn on a front-controller-style static file server for the media directroy (for emulating nginx sitting in front of the express app)\n\n## remote logging\n- `./live-logs.sh hub1sshhost` for node app access logs in journal\n- `./pull-nginx-journal-report.sh hub1sshhost` get and view nginx server report for hub1sshhost\n- `./pull-express-journal-report.sh hub1sshhost` get and view express server report for hub1sshhost\n- `./pull-nginx-access-report.sh someotherhost` get and view nginx access.log server report for someotherhost\n\n## hardware setup\n- get a raspberry pi 3 with a large enough SD card to keep lots of JPEGS on (32gb+)\n- install Raspbian Stretch lite or Stretch and expand the filesystem, set locales etc.\n- set up the raspi with ssh key access i.e. `$ ssh mypi` lets you run commands via ssh\n- connect some Raspberry Pis with ssh access via their ssh host name on your network\n- get a UGREEN 20250 or Transcend TS-RDF5K card reader to use with the pi\n\n## deploy setup\n- connect prepared Raspberry Pis to the network\n- install [Ansible](https://ansible.com) 2.4+ via [homebrew](https://brew.sh)\n- create create ansible config file for deploys\n- create create ansible inventory file for deploys\n- create wpa_supplicant.conf\n- put `~/.ssh/raspi-deploy` key in place that works to get this repository from github\n- npm run deploy\n\n### ansible.cfg example\nlocated in project directory\n```conf\n[defaults]\ninventory=inventory.ini\n```\n### inventory.ini example\nlocated in project directory\nthis has the channel and psk variables set for specified hosts\n```conf\n[hubs]\nhub1sshhost\nhub2sshhostwithdisplay\n\n[display-hubs]\nhub2sshhostwithdisplay\n\n[ap-hubs]\nhub1sshhost channel=7\nhub2sshhostwithdisplay channel=6\n\n[ap-hubs:vars]\npsk=mywifipassword\ncert_domain=mydomain.com\ncert_path=/etc/letsencrypt/live/mydomain.com\n```\n### wpa_supplicant.conf example\nlocated in `this_project_directory/roles/wifi/files/wpa_supplicant.conf`\n```\nctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev\nupdate_config=1\nnetwork={\n\tssid=\"My iPhone Hotspot\"\n\tkey_mgmt=WPA-PSK\n\tpsk=wpa_passphrase_result0000000000000000000000000000000000000000000\n\tpriority=100\n}\nnetwork={\n\tssid=\"my-home-network\"\n\tpsk=wpa_passphrase_result0000000000000000000000000000000000000000000\n\tkey_mgmt=WPA-PSK\n\tpriority=99\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjohnelliott%2Fimage-hub","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjohnelliott%2Fimage-hub","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjohnelliott%2Fimage-hub/lists"}