D 2015-04-11T21:26:15.752
L Freecode\sJSON\sAPI
N text/x-markdown
P c5535ec34bb40da1fd9524c1cfb7df17ae16a59e
U mario
W 11198
Freshcode reimplements the [Freecode JSON API](http://web.archive.org/web/20130412231142/http://help.freecode.com/kb/api-7/data-api-releases)
to allow for project and release updating per command line ([freecode-submit](finfo/doc/fc-submit)).
# Setup and Usage
To utilize remote updates, you just need an extra password in your project listing. Add at least one OpenID handle and a password hash in the **`Lock`** field. (Trust me, you need both!)
http://your.openid.com/, $1$rua41x5V$mZHrJHKySV0uXfLA4EjEz0
You can generate a password hash using:
* using PHPs [password_hash()](http://php.net/password_hash)
* in Python with `bcrypt.hashpw("pw123", bcrypt.gensalt( 12 ))`
* `openssl passwd -1` for MD5
* `mkpasswd -m sha-256 -S saltsalt`
* Online services like [bcrypt-generator.com/](http://www.bcrypt-generator.com/), [bcrypthashgenerator.apphb.com/](http://bcrypthashgenerator.apphb.com/) or via [htpassword generator](http://aspirine.org/htpasswd_en.html)
For `freshcode-submit` list the plain password in your `~/.netrc` file:
machine freshcode
account pw123
password none
Afterwards submitting release updates is as simple as
freshcode-submit -P name -v 2.0 -c "Changes.."
A complete patch is currently in preparation.
# API scheme
State: implemented, testing
The request URLs and data formats are broadly compatible:
method | URL path | function | 1:1 |
GET | /projects/<name>.json | query | YES |
PUT | /projects/<name>.json | update_core | YES |
CREATE | /projects/<name>.json | new_project | NEW |
POST | /projects/<name>/releases.json | publish | YES |
GET | /projects/<name>/releases/pending.json | pending | YES |
DELETE | /projects/<name>/releases/<int>.json | withdraw | YES |
GET | /projects/<name>/urls.json | urls | NEW |
PUSH | /projects/<name>/urls.json | update_urls | NEW |
See also [http://web.archive.org/web/20130412231142/http://help.freecode.com/kb/api-7/data-api-releases](http://web.archive.org/web/20130412231142/http://help.freecode.com/kb/api-7/data-api-releases) for the original reference.
There are semantic differences in that freshcode.club does not currently require pre-moderation and approvals. Still the API is unchanged apart from the URL updating.
### General
GET requests append an `?auth_code=` which contains the plain auth\_token / password.
POST/PUT instead wrap the `"auth_code"` in the outermost layer of the JSON content body.
## Query GET`/projects/.json`
Retrieves general project information. The original Freecode.com included:
{
"project": {
"id": "424902329",
"permalink": "project_name",
"oneliner": "First sentence of description.",
"license_list": "BSDL",
"approved_urls": [
{ "label": "src", "redirector": "http://example.org" }
]
}
}
Additionally the extended Freshcode.club [feed](http://freshcode.club/feed/xfer) fields are present (tags, homepage, image, urls, etc.).
If the GET request also includes an `?auth_code=`, then the raw database contents are even returned (lock, submitter, submitter\_openid, hidden, flags, social\_links, regex, ...)
## Update_core PUT `/projects/.json`
To edit the general project information, send the basic fields via `PUT` wrapped in a JSON dict contaning:
{
"auth_code": "plain_pw_123",
"project": {
"description": "Project does foo and bar.",
"oneliner": "__will_be_ignored__",
"license_list": "GNU GPL",
"project_tag_list": "desktop,end-user,browser,gtk",
}
}
In addition freshcode honors any included `homepage` and `download` URL, or updating the `state` (alpha, beta, stable, etc.)
## Publish POST `/projects//releases.json`
Submitting a new release is just as straightforward. The `POST` body ought to list:
{
"auth_code": "pw123",
"project": {
"version": "3.0",
"changelog": "User-friendly summary of changes..",
"tag_list": "major,bugfix,security,stable",
"hidden_from_frontpage": false,
}
}
The `tag_list` is split into our `scope` and `state` fields, and the special tag `hidden` sets the hidden\_from\_frontpage flag implicitly. A new `download` URL can also be submitted herein.
## URLs dict GET/PUSH `/projects//urls.json`
The URL retrieval and storage methods have been simplified. Freecode used oddly nested JSON (see the Query example). It required the update process to first `GET` a list, then tediously `PUT`ing in updated entries, `POST`ing new ones, and `DELETE`ing stale ones each. Which is not only a long-winded implementation for API server and client, but would incur around 15 database revisions when updating just 3 URLs. ^^
Instead we'll just pass around an associative urls dictionary/array.
For `GET` requests on `/projects//urls.json` you receive:
{
"urls": {
"src": "http://example.org/pkg-src.txz",
"blog": "http://example.org/proj-blog/"
}
}
Updating all URLs at once takes the same format, but includes an `auth_code` of course. The API is indifferent to `PUT` or `POST` or even **`PUSH`** here.
{
"auth_code": "plain_pw_123",
"urls": {
"txz": "http://example.org/pkg-$version.txz",
}
}
Notice that all URLs may contain a [`$version` placeholder](wiki/$version+placeholder) as usual. Which somewhat alleviates the need to update URLs anyway.
## withdraw_release DELETE
The [doubly versioned database scheme](wiki/database+scheme) is meant to be somewhat immutable. As such there is no actual deleting taking place. Withdrawing a release is still possible. It'll just be marked as hidden, and/or flagged for moderator attention, (or somewhen use the `deleted` flag even).
It takes two steps:
1. **GET** `/projects//releases/pending.json` to uncover the associated `id` for a `version`.
[
{
"release": {
"id": "1403557288",
"version": "3.15.1",
"approved_at": "2014-06-28T22:51:00+0000"
}
},
{
"release": {
"id": "1403995977",
"version": "3.15.2",
"created_at": "2014-06-28T22:52:57+0000"
}
}
]
(There are more fields, absent from this example.)
2. Send a **DELETE** request onto `/projects//releases/.json?auth_code=..` to remove that project revision.
The `id` is always numeric. Also it's basically the t_published timestamp.
Because there is no pending/approval stage on freshcode.club anymore, this even works for previous releases, not just the current one.
## New_project CREATE `/projects/.json`
For submitting an entirely new project, send a CREATE request onto `/projects/.json`.
Basically this request method is just an extension over the `PUT` method (Update_core).
{
"auth_code": "your_new_pw_123",
"project": {
"title": "My project",
"description": "...",
"image": "http://example.org/screenshot.png",
"submitter": "Your Name, username@gravatar",
"scope": "stable",
"version": "2.0.0-current",
"autoupdate_url": "http://example.org/NEWS.txt",
"license_list": "MITL",
"project_tag_list": "desktop,end-user,browser,gtk",
}
}
This method accepts way more fields than other request schemes. (Since this is a diversion from old freecode API, it might as well be more convenient). Please note that most fields are entirely optional still:
- The project **name** is derived from the `/projects/name.json` request URL.
- If the project **title** is omitted, the project basename will be used simply.
- A project **description** text could also be submitted via PUT (update_core) later.
- The **image** can contain an application screenshot URL. If left out, a homepage screenshot will be generated automatically / as usual.
- With **submitter** you could define an author name. Or a gravatar email address, or user@github, user@launchpad, user@sourceforge icon. Both are optional.
- Optionally declare the current **version**.
- Or submit the current **changelog** right along.
- And of course you can submit all the fields that "update_core" already accepts:
- Project **homepage**
- and **download** URL
- the **license**
- and **tags**
- release **state** (alpha, beta, stable)
- and **scope** (minor bugfix, major feature)
- CREATE basically can make a subsequent PUT redundant. (The additional fields should probably be made accessible via PUT/update_core too..)
**Auth_code**: A project can only be created once. Which is because this request populates the project authorization hash. The unencrypted `auth_code` from the CREATE payload is used for that. (It's bcrypt-hashed internally, and stored in our lock database field..)
**SSL Authorization**: *Still undecided*. This CREATE request is also only accepted when a client SSL certificate is sent along.
- This is ***not a security feature***. Just obscures the API access to avert spambot submissions. (Perhaps redundant, because `