New readme
This commit is contained in:
2
LICENSE
2
LICENSE
@@ -15,4 +15,4 @@ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNES
|
|||||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||||
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|||||||
258
README.md
258
README.md
@@ -1,121 +1,193 @@
|
|||||||
# Neocities C CLI
|
# Neocities C API
|
||||||
|
|
||||||
A simple command-line tool written in C that interacts with the [Neocities API](https://neocities.org/api).
|
Minimal, secure C wrapper for the Neocities API using API key authentication.
|
||||||
Currently, only the `--info` command is implemented — it fetches and displays basic information about your Neocities site.
|
|
||||||
|
No login flow.
|
||||||
|
No credential storage.
|
||||||
|
Stateless by design.
|
||||||
|
|
||||||
|
Users must generate their own API key via the Neocities dashboard.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
- Fetch site information using Neocities API
|
|
||||||
- Authenticates via environment variables
|
* Site info retrieval
|
||||||
- JSON parsing with [jansson](https://digip.org/jansson/)
|
* File listing
|
||||||
- Works on Linux, Windows (MSYS2/MinGW), and Android (via Termux)
|
* Upload files
|
||||||
- Compilable with a Makefile for easy builds
|
* Delete files
|
||||||
|
* TLS verification enabled by default
|
||||||
|
|
||||||
|
Authentication is performed exclusively via:
|
||||||
|
|
||||||
|
```
|
||||||
|
Authorization: Bearer <API_KEY>
|
||||||
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
You’ll need:
|
* libcurl
|
||||||
- A C compiler (`gcc` or `clang`)
|
|
||||||
- [libcurl](https://curl.se/libcurl/)
|
|
||||||
- [jansson](https://digip.org/jansson/)
|
|
||||||
- `make`
|
|
||||||
|
|
||||||
### Linux (Debian/Ubuntu-based)
|
Linux (example):
|
||||||
```bash
|
|
||||||
sudo apt update
|
|
||||||
sudo apt install build-essential libcurl4-openssl-dev libjansson-dev make
|
|
||||||
```
|
|
||||||
|
|
||||||
### Windows (MSYS2 / MinGW)
|
|
||||||
```bash
|
|
||||||
pacman -S mingw-w64-x86_64-gcc mingw-w64-x86_64-curl mingw-w64-x86_64-jansson make
|
|
||||||
```
|
|
||||||
|
|
||||||
### Android (Termux)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
pkg install clang curl-dev jansson make
|
|
||||||
```
|
|
||||||
|
|
||||||
## Building
|
|
||||||
|
|
||||||
Run in cloned repository:
|
|
||||||
```bash
|
|
||||||
make
|
|
||||||
```
|
|
||||||
|
|
||||||
This will generate the executable neocities (or neocities.exe on Windows).
|
|
||||||
|
|
||||||
To clean build files:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
make clean
|
|
||||||
```
|
|
||||||
|
|
||||||
### Environment Variables
|
|
||||||
|
|
||||||
Before running, export your Neocities credentials:
|
|
||||||
|
|
||||||
#### Linux / macOS / Termux
|
|
||||||
|
|
||||||
```bash
|
|
||||||
export NEOCITIES_USER="your_username"
|
|
||||||
export NEOCITIES_PASS="your_password"
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Windows (PowerShell)
|
|
||||||
|
|
||||||
```batch
|
|
||||||
setx NEOCITIES_USER "your_username"
|
|
||||||
setx NEOCITIES_PASS "your_password"
|
|
||||||
```
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
```bash
|
|
||||||
./neocities --info
|
|
||||||
```
|
|
||||||
|
|
||||||
Example output:
|
|
||||||
|
|
||||||
```
|
```
|
||||||
Neocities C CLI
|
sudo apt install libcurl4-openssl-dev
|
||||||
|
|
||||||
Sitename: example
|
|
||||||
Hits: 42
|
|
||||||
Created at: 2024-01-10
|
|
||||||
Last updated: 2025-11-01
|
|
||||||
Domain: domain.com
|
|
||||||
Tags: art, blog, personal.
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Optional: Install Globally
|
---
|
||||||
|
|
||||||
You can move the compiled executable to a directory in your PATH to run it from anywhere:
|
## Authentication
|
||||||
|
|
||||||
#### Linux / Termux
|
Generate your API key at:
|
||||||
|
|
||||||
```bash
|
Neocities > Settings > Manage Site Settings > API
|
||||||
sudo mv neocities /usr/local/bin/
|
(or https://neocities.org/settings/YOUR-USERNAME#api_key)
|
||||||
|
|
||||||
|
If you're coding a CLI or application, you must provide the key at runtime (env var, config file, etc).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## API Overview
|
||||||
|
|
||||||
|
Just an overview. For more detailed information, see: [[Function-Guide.md]]
|
||||||
|
|
||||||
|
### Info (public)
|
||||||
|
|
||||||
|
```c
|
||||||
|
int neocities_info(const char *sitename, neocities_info_t *out);
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Windows (PowerShell)
|
Fetch metadata about a site.
|
||||||
Move neocities.exe to a folder in your PATH, e.g., C:\Windows\System32\.
|
|
||||||
|
|
||||||
After that, you can run:
|
---
|
||||||
|
|
||||||
```batch
|
### List files
|
||||||
neocities --info
|
|
||||||
|
```c
|
||||||
|
int neocities_list(const char *api_key,
|
||||||
|
const char *path,
|
||||||
|
neocities_filelist_t *out);
|
||||||
```
|
```
|
||||||
|
|
||||||
from any folder without specifying the path.
|
List files at a path.
|
||||||
|
|
||||||
## Notes
|
---
|
||||||
|
|
||||||
Only the --info command is implemented for now.
|
### Upload
|
||||||
|
|
||||||
If you get curl_easy_perform errors, check your network and SSL setup.
|
```c
|
||||||
|
int neocities_upload(const char *api_key,
|
||||||
|
const char **local_files,
|
||||||
|
const char **remote_names,
|
||||||
|
size_t count,
|
||||||
|
char **response);
|
||||||
|
```
|
||||||
|
|
||||||
|
Uploads multiple files.
|
||||||
|
|
||||||
|
* `local_files[i]` → local path
|
||||||
|
* `remote_names[i]` → remote filename
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Delete
|
||||||
|
|
||||||
|
```c
|
||||||
|
int neocities_delete(const char *api_key,
|
||||||
|
const char **filenames,
|
||||||
|
size_t count,
|
||||||
|
char **response);
|
||||||
|
```
|
||||||
|
|
||||||
|
Deletes files from the site.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### API Key
|
||||||
|
|
||||||
|
For security reasons, you should get the API key via Neocities settings. This function is not avaiable.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Memory Management
|
||||||
|
|
||||||
|
Always free parsed outputs:
|
||||||
|
|
||||||
|
```c
|
||||||
|
void neocities_free_info(neocities_info_t *info);
|
||||||
|
void neocities_free_filelist(neocities_filelist_t *list);
|
||||||
|
```
|
||||||
|
|
||||||
|
`response` returned by upload/delete must also be freed by caller.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Example Usage
|
||||||
|
|
||||||
|
### List files
|
||||||
|
|
||||||
|
```c
|
||||||
|
neocities_filelist_t list;
|
||||||
|
|
||||||
|
if (neocities_list(api_key, "/", &list) == 0) {
|
||||||
|
for (size_t i = 0; i < list.count; i++)
|
||||||
|
printf("%s\n", list.paths[i]);
|
||||||
|
|
||||||
|
neocities_free_filelist(&list);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Upload
|
||||||
|
|
||||||
|
```c
|
||||||
|
const char *local[] = {"index.html"};
|
||||||
|
const char *remote[] = {"index.html"};
|
||||||
|
char *resp;
|
||||||
|
|
||||||
|
neocities_upload(api_key, local, remote, 1, &resp);
|
||||||
|
free(resp);
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Security Notes
|
||||||
|
|
||||||
|
* TLS verification is enforced
|
||||||
|
* Redirects are disabled intentionally
|
||||||
|
* API key is never persisted internally
|
||||||
|
|
||||||
|
Recommended:
|
||||||
|
|
||||||
|
* Store key in env vars
|
||||||
|
* Avoid hardcoding
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Design Philosophy
|
||||||
|
|
||||||
|
* No login/password support
|
||||||
|
* API key only
|
||||||
|
* Explicit memory ownership
|
||||||
|
* Minimal abstraction
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Future Extensions (Optional)
|
||||||
|
|
||||||
|
Possible areas to explore:
|
||||||
|
|
||||||
|
* Structured responses for upload/delete
|
||||||
|
* JSON passthrough mode
|
||||||
|
* Streaming uploads
|
||||||
|
* Error codes standardization
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
[MIT](LICENSE)
|
||||||
|
|
||||||
On Termux, use clang for the best compatibility.
|
|
||||||
@@ -25,10 +25,9 @@ typedef struct {
|
|||||||
// API functions
|
// API functions
|
||||||
// -------------------------
|
// -------------------------
|
||||||
int neocities_info(const char *sitename, neocities_info_t *out);
|
int neocities_info(const char *sitename, neocities_info_t *out);
|
||||||
int neocities_list(const char *user, const char *pass, const char *path, neocities_filelist_t *out);
|
int neocities_list(const char *api_key, const char *path, neocities_filelist_t *out);
|
||||||
int neocities_upload(const char *user, const char *pass, const char **local_files, const char **remote_names, size_t count, char **response);
|
int neocities_delete(const char *api_key, const char **filenames, size_t count, char **response);
|
||||||
int neocities_delete(const char *user, const char *pass, const char **filenames, size_t count, char **response);
|
int neocities_upload(const char *api_key, const char **local_files, const char **remote_names, size_t count, char **response);
|
||||||
int neocities_get_api_key(const char *user, const char *pass, char **api_key);
|
|
||||||
|
|
||||||
// -------------------------
|
// -------------------------
|
||||||
// Free functions
|
// Free functions
|
||||||
@@ -36,4 +35,4 @@ int neocities_get_api_key(const char *user, const char *pass, char **api_key);
|
|||||||
void neocities_free_info(neocities_info_t *info);
|
void neocities_free_info(neocities_info_t *info);
|
||||||
void neocities_free_filelist(neocities_filelist_t *list);
|
void neocities_free_filelist(neocities_filelist_t *list);
|
||||||
|
|
||||||
#endif // NEOCITIES_H
|
#endif // NEOCITIES_H
|
||||||
|
|||||||
Reference in New Issue
Block a user