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 `
` spam is more likely, and the API is complicated enough as it is. But requiring a SSL cert pretty much rules out typical Windows trojan botnets.) - And there's no need for custom SSL certs. A single publically-known private cert is used. It's available under [fossil:doc/trunk/doc/submit.pem](http://fossil.include-once.org/freshcode/doc/trunk/doc/submit.pem) (f18b1aba613ac804). - If you want to use a custom cert, just mail in the serial number (`openssl x509 -noout -text -in s.pem`) for registration. ## Response JSON When operations succeeded, the response will usually come with HTTP code 200 or 201, and include a JSON body of `{"success": true}`. Whereas errors can result in HTTP codes 503, 500, 401 with a message body of `{"error": "details..."}`. ## Xfer.JSON If you just want to browse trough projects, then the plain freshcode feed is simpler to deal with. It's available as `http://freshcode.club/feed/xfer` or per-project with `http://freshcode.club/feed/`. Z bacb1307ebbe087963c67da403ea8e36