Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ Provider and query may be given as positionals after `s` / `-s`, or with `-P` /
| `negativespace` | [NegativeSpace](https://negativespace.co) | Free high-resolution CC0 stock photography | Direct master full-resolution photo downloads. |
| `skitterphoto` | [Skitterphoto](https://skitterphoto.com) | 100% free CC0 public domain photography | Direct high-resolution photo downloads. |
| `libreshot` | [LibreShot](https://libreshot.com) | Free CC0 stock photos by Martin Vorel | Direct master full-resolution photo downloads. |
| `moveast` | [Moveast](https://moveast.me) | Free CC0 travel and documentary photography by João Pacheco | Direct high-resolution photo downloads. |

List providers at runtime via `ast help` (printed under **PROVIDERS**).

Expand Down Expand Up @@ -304,6 +305,7 @@ src/
negativespace.zig
skitterphoto.zig
libreshot.zig
moveast.zig
assets/ README banner and static assets
docs/ Provider implementation notes
install.sh curl | bash installer (Linux release binaries)
Expand Down
13 changes: 13 additions & 0 deletions docs/providers.md
Original file line number Diff line number Diff line change
Expand Up @@ -208,3 +208,16 @@ This document summarizes the network endpoints, transport models, and image down
* Master full-resolution URL extracted by stripping geometry suffixes (`-508x339`, `-508x300`) from `wp-content/uploads/` image URLs.
* **Download**: Direct GET on original full-resolution master photo JPEG/PNG (up to 10+ MB).
* **License**: CC0 / Free Public Domain Stock Photos.

---

## 18. Moveast (`moveast.me`)

* **Search**: `GET https://moveast.me/api/read/json?tagged={tag}&num={limit}` (with fallback to main feed).
* **Format**: Tumblr JSON feed by Portuguese designer/traveler João Pacheco.
* **Extraction**:
* Clean HTML stripped from photo captions.
* Tag buffer and slug fallback for descriptive search prompts.
* 1280px / 500px CDN image endpoints.
* **Download**: Direct GET on high-resolution Tumblr CDN JPEG assets.
* **License**: CC0 / 100% Free Public Domain.
2 changes: 1 addition & 1 deletion docs/stock_photo_sites.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ This document tracks all 24 stock photo websites listed in the [GrayGrids 21+ Be

- **Total Sites Listed**: 24
- **Implemented & Working**: 13 (`unsplash`, `isorepublic`, `picjumbo`, `foodiesfeed`, `picography`, `gratisography`, `startupstockphotos`, `burst`, `jaymantri`, `publicdomainarchive`, `magdeleine`, `splitshire`, `deviantart`)
- *(Additional Providers Implemented in `ast`)*: `aura` ([Aura.build](https://www.aura.build)), `negativespace` ([NegativeSpace.co](https://negativespace.co)), `skitterphoto` ([Skitterphoto.com](https://skitterphoto.com)), `libreshot` ([LibreShot.com](https://libreshot.com))
- *(Additional Providers Implemented in `ast`)*: `aura` ([Aura.build](https://www.aura.build)), `negativespace` ([NegativeSpace.co](https://negativespace.co)), `skitterphoto` ([Skitterphoto.com](https://skitterphoto.com)), `libreshot` ([LibreShot.com](https://libreshot.com)), `moveast` ([Moveast.me](https://moveast.me))
- **Unimplemented / Blocked / Pending**: 11

---
Expand Down
9 changes: 9 additions & 0 deletions src/commands/search.zig
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const deviantart = @import("../providers/deviantart.zig");
const negativespace = @import("../providers/negativespace.zig");
const skitterphoto = @import("../providers/skitterphoto.zig");
const libreshot = @import("../providers/libreshot.zig");
const moveast = @import("../providers/moveast.zig");
const stdio = @import("../stdio.zig");
const Allocator = std.mem.Allocator;
const Io = std.Io;
Expand Down Expand Up @@ -92,6 +93,9 @@ fn doSearch(
if (std.ascii.eqlIgnoreCase(provider_id, "libreshot")) {
return libreshot.search(client, allocator, query, limit);
}
if (std.ascii.eqlIgnoreCase(provider_id, "moveast")) {
return moveast.search(client, allocator, query, limit);
}
return error.UnknownProvider;
}

Expand Down Expand Up @@ -154,6 +158,9 @@ fn doDownload(
if (std.ascii.eqlIgnoreCase(provider_id, "libreshot")) {
return libreshot.download(client, allocator, io, a, output_dir);
}
if (std.ascii.eqlIgnoreCase(provider_id, "moveast")) {
return moveast.download(client, allocator, io, a, output_dir);
}
return error.UnknownProvider;
}

Expand All @@ -175,6 +182,7 @@ fn doPrompt(provider_id: []const u8, a: Asset) ?[]const u8 {
if (std.ascii.eqlIgnoreCase(provider_id, "negativespace")) return negativespace.getPrompt(a);
if (std.ascii.eqlIgnoreCase(provider_id, "skitterphoto")) return skitterphoto.getPrompt(a);
if (std.ascii.eqlIgnoreCase(provider_id, "libreshot")) return libreshot.getPrompt(a);
if (std.ascii.eqlIgnoreCase(provider_id, "moveast")) return moveast.getPrompt(a);
return a.prompt orelse a.description;
}

Expand All @@ -196,6 +204,7 @@ fn doUrl(provider_id: []const u8, a: Asset) ?[]const u8 {
if (std.ascii.eqlIgnoreCase(provider_id, "negativespace")) return negativespace.getUrl(a);
if (std.ascii.eqlIgnoreCase(provider_id, "skitterphoto")) return skitterphoto.getUrl(a);
if (std.ascii.eqlIgnoreCase(provider_id, "libreshot")) return libreshot.getUrl(a);
if (std.ascii.eqlIgnoreCase(provider_id, "moveast")) return moveast.getUrl(a);
return a.image_url;
}

Expand Down
9 changes: 9 additions & 0 deletions src/interactive.zig
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const deviantart = @import("providers/deviantart.zig");
const negativespace = @import("providers/negativespace.zig");
const skitterphoto = @import("providers/skitterphoto.zig");
const libreshot = @import("providers/libreshot.zig");
const moveast = @import("providers/moveast.zig");
const registry = @import("providers/registry.zig");
const stdio = @import("stdio.zig");
const Allocator = std.mem.Allocator;
Expand Down Expand Up @@ -89,6 +90,9 @@ fn searchProvider(
if (std.ascii.eqlIgnoreCase(provider_id, "libreshot")) {
return libreshot.search(client, allocator, query, config.default_limit);
}
if (std.ascii.eqlIgnoreCase(provider_id, "moveast")) {
return moveast.search(client, allocator, query, config.default_limit);
}
return error.UnknownProvider;
}

Expand Down Expand Up @@ -150,6 +154,9 @@ fn downloadAsset(
if (std.ascii.eqlIgnoreCase(provider_id, "libreshot")) {
return libreshot.download(client, allocator, io, a, config.default_output_dir);
}
if (std.ascii.eqlIgnoreCase(provider_id, "moveast")) {
return moveast.download(client, allocator, io, a, config.default_output_dir);
}
return error.UnknownProvider;
}

Expand All @@ -171,6 +178,7 @@ fn promptOf(provider_id: []const u8, a: Asset) ?[]const u8 {
if (std.ascii.eqlIgnoreCase(provider_id, "negativespace")) return negativespace.getPrompt(a);
if (std.ascii.eqlIgnoreCase(provider_id, "skitterphoto")) return skitterphoto.getPrompt(a);
if (std.ascii.eqlIgnoreCase(provider_id, "libreshot")) return libreshot.getPrompt(a);
if (std.ascii.eqlIgnoreCase(provider_id, "moveast")) return moveast.getPrompt(a);
return a.prompt;
}

Expand All @@ -192,6 +200,7 @@ fn urlOf(provider_id: []const u8, a: Asset) ?[]const u8 {
if (std.ascii.eqlIgnoreCase(provider_id, "negativespace")) return negativespace.getUrl(a);
if (std.ascii.eqlIgnoreCase(provider_id, "skitterphoto")) return skitterphoto.getUrl(a);
if (std.ascii.eqlIgnoreCase(provider_id, "libreshot")) return libreshot.getUrl(a);
if (std.ascii.eqlIgnoreCase(provider_id, "moveast")) return moveast.getUrl(a);
return a.image_url;
}

Expand Down
Loading
Loading