{"id":48278332,"url":"https://github.com/guanana/image_slideshow","last_synced_at":"2026-04-04T22:41:12.666Z","repository":{"id":334630316,"uuid":"1139206700","full_name":"guanana/image_slideshow","owner":"guanana","description":"Simple Image Slideshow (created with Antigravity)","archived":false,"fork":false,"pushed_at":"2026-01-26T10:17:19.000Z","size":165,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-01-26T16:05:37.607Z","etag":null,"topics":["antigravity","dashboard-control","image-slideshow","images","inky","inkyimpression","raspberry-pi","slideshow"],"latest_commit_sha":null,"homepage":"","language":"Python","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/guanana.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,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-01-21T16:57:14.000Z","updated_at":"2026-01-26T10:17:24.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/guanana/image_slideshow","commit_stats":null,"previous_names":["guanana/image_slideshow"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/guanana/image_slideshow","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/guanana%2Fimage_slideshow","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/guanana%2Fimage_slideshow/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/guanana%2Fimage_slideshow/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/guanana%2Fimage_slideshow/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/guanana","download_url":"https://codeload.github.com/guanana/image_slideshow/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/guanana%2Fimage_slideshow/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31417648,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-04T20:09:54.854Z","status":"ssl_error","status_checked_at":"2026-04-04T20:09:44.350Z","response_time":60,"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":["antigravity","dashboard-control","image-slideshow","images","inky","inkyimpression","raspberry-pi","slideshow"],"created_at":"2026-04-04T22:41:12.207Z","updated_at":"2026-04-04T22:41:12.648Z","avatar_url":"https://github.com/guanana.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Image Slideshow\n\nA simple, robust Python image slideshow that covers the whole screen while maintaining aspect ratio (never crops).\n\n## 🚀 Quick Start\n\n1. **Run the Setup Script**:\n   ```bash\n   bash setup.sh\n   ```\n   *Options:*\n   - `-b, --boot`: Automatically enable startup on boot (no prompt).\n   - `-t, --skip-test`: Skip the post-installation GUI verification test.\n   - `-u, --uninstall`: Revert boot startup and uninstall the service.\n   - `-h, --help`: Show help and exit.\n\n2. **Run manually**:\n   ```bash\n   slideshow-app\n   ```\n\n## ⌨️ Controls\n- **F**: Toggle Fullscreen\n- **Esc**: Exit Fullscreen\n- **Q**: Quit\n- **Right Arrow**: Next image (if enabled in config)\n- **Left Arrow**: Previous image (if enabled in config)\n\n## ⚙️ Configuration\nEdit `config.ini` to change defaults:\n- `default_folder`: Folder to scan for images (defaults to `~/Pictures`).\n- `default_interval`: Seconds between images.\n- `background_color`: Background color for images.\n- `enable_manual_controls`: Enable arrow key navigation.\n\nSee [CONFIGURATION.md](CONFIGURATION.md) for detailed configuration options.\n\n## 📥 Image Sources (Providers)\n\nThe slideshow supports **external image source providers** — a modular plugin system that allows you to automatically download images from remote services directly to your slideshow folder.\n\n### Built-in Providers\n\n| Provider | Description |\n|----------|-------------|\n| **Immich** | Download images from your [Immich](https://immich.app/) photo server |\n\n### Using Providers via Dashboard\n\n1. Open the web dashboard at `http://\u003cdevice-ip\u003e:8080`\n2. Scroll to the **Image Sources** section\n3. Click **Configure** on a provider to enter credentials\n4. Click **Test** to verify the connection\n5. Click **Refresh Images** to download photos to your slideshow folder\n\nProvider settings (including credentials) are stored in the local SQLite database.\n\n\u003e ⚠️ **Immich API Key Permissions**\n\u003e\n\u003e If your Immich server uses granular permissions for API keys, ensure your key has the following enabled:\n\u003e - `album.read`: To fetch the list of available albums.\n\u003e - `asset.read`: To retrieve photo metadata.\n\u003e - `asset.download`: To download the high-resolution photos.\n\u003e\n\u003e Alternatively, you can use a key with the `all` permission(better not!).\n\n### Adding Custom Providers\n\nTo add support for another image source (e.g., Google Photos, Dropbox), create a new provider class:\n\n```python\n# providers/my_provider.py\nfrom .base import BaseImageProvider, ConfigField, RefreshResult, RefreshStatus\nfrom . import register_provider\n\n@register_provider\nclass MyProvider(BaseImageProvider):\n    name = \"my_provider\"           # Unique identifier\n    display_name = \"My Provider\"   # Shown in dashboard\n    description = \"Download images from My Service\"\n    \n    def get_config_fields(self):\n        return [\n            ConfigField(key=\"api_key\", label=\"API Key\", field_type=\"password\", required=True),\n            # Add more fields as needed\n        ]\n    \n    def configure(self, settings):\n        self._config = settings\n    \n    def validate_config(self):\n        if not self._config.get(\"api_key\"):\n            return False, \"API Key is required\"\n        return True, None\n    \n    def test_connection(self):\n        # Test connection to your service\n        return True, \"Connected successfully\"\n    \n    def refresh(self, target_folder):\n        # Download images to target_folder\n        # Return RefreshResult with statistics\n        return RefreshResult(\n            status=RefreshStatus.SUCCESS,\n            message=\"Downloaded 10 images\",\n            downloaded=10, total=10\n        )\n```\n\nThe provider will automatically appear in the dashboard once registered.\n\n## 🌐 Web Dashboard \u0026 API\n\nThe application exposes a REST API on port **8080**:\n\n| Endpoint | Method | Description |\n|----------|--------|-------------|\n| `/` | GET | Web dashboard |\n| `/config` | GET/POST | View or update slideshow settings |\n| `/providers` | GET | List all image source providers |\n| `/providers/{name}/config` | GET/POST | View or update provider settings |\n| `/providers/{name}/test` | POST | Test provider connection |\n| `/providers/{name}/refresh` | POST | Trigger image download |\n| `/current-image` | GET | Get currently displayed image |\n| `/restart` | POST | Restart the application |\n\n## 🍓 Raspberry Pi Deployment\nInstallation is the same as above. The `setup.sh` script will ask if you want to enable a **systemd service** to start the slideshow automatically when the Pi boots.\n\n## 🧪 Testing\nRun `./run_tests.sh` to access the test menu.\n\n## 📁 Project Structure\n\n```\nimage_slideshow/\n├── main.py              # Application entry point\n├── slideshow.py         # Tkinter slideshow GUI\n├── api.py               # FastAPI REST endpoints\n├── database.py          # SQLite configuration storage\n├── dashboard.html       # Web dashboard UI\n├── providers/           # Image source provider plugins\n│   ├── __init__.py      # Provider registry\n│   ├── base.py          # Abstract base class\n│   └── immich.py        # Immich provider implementation\n└── tests/               # Unit and integration tests\n```\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fguanana%2Fimage_slideshow","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fguanana%2Fimage_slideshow","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fguanana%2Fimage_slideshow/lists"}