forkmeGo home

meat-a

Introduction

meat-a is a WSGI based REST service allowing users to comment, rate and tag any kind of object. The service could be an attractive option for you if you want to add "social network" features to an existing object database like an image gallery.

Setup

If you want to test the service please install the Rocket module and start the test server:

$ python rocket_server.py

This will start a small HTTP server on port 8000.

You're welcome to use any HTTP server with WSGI support you like, of course. Therefore configure your preferred server and setup the index() function as handler.

Start the mailer to enable email sending:

$ python mailer.py

Data is stored in a PostgreSQL database. Please ensure that the server is running and accessible.

The database schema can be found in the sql subfolder. You can build additional scripts with GNU Make. You need m4 for this step.

All configuration options are located in the config.py file. You should change at least the following settings:

Setting(s)Description
WEBSITE_URLmeat-a generates various URLs. Define the base URL of the web application here.
PG_HOST, PG_PORT, PG_DB, PG_USER, PG_PWDPostgreSQL connection details.
TMP_DIRDirectory for temporary files. An absolute filename is highly recommended.
AVATAR_DIRDirectory for storing avatars. An absolute filename is highly recommended.
SMTP_HOST, SMTP_PORT, SMTP_SSL, SMTP_ADDRESS, SMTP_USERNAME, SMTP_PASSWORDSMTP user credentials and details.
MAILER_HOST, MAILER_PORT, MAILER_ALLOWED_CLIENTSHostname and port of the mailer. You have also to specify the IP addresses of all allowed clients.

Mails and websites are generated using the Cheetah template framework. The template files are located in the tpl directory.

You need the following additional packages to run meat-a. All modules can be installed with pip.

Architecture - a brief overview for developers (only)

Objects are stored in the object database. They are referenced by their guid and have a source (e.g. a link or filename).

Users can tag, rate and comment these objects. The service also offers the option to organize a list of favorites.

Users automatically become friends once they follow each other. Friends are allowed to recommend objects to one another. If a user profile is not protected everyone can recommend objects to him or her. Users are organized in a separate user store.

Several activities generate notifications. When a user profile is not protected these activities are public to all users of the service. By protecting a profile only friends will receive notifications.

Mails are saved in a queue. A separate service sends them out. The queue is processed in a user-defined interval or may be triggered by an UDP message.

The different data stores should only be accessed through the Application class which provides the business logic.

The WSGI module tries to map a requested path to a corresponding Controller. Each controller returns a View used to generate the response.

To test the available modules execute the test.py file.

The REST service

Many functions of the meat-a web interface require an authenticated request. At the moment only HTTP basic authentication is supported.

meat-a provides the following resources:

1. User Accounts

1.1. Request a new user account

OptionValue(s)
Url/rest/registration
MethodPOST
Parametersusername, email
Responseapplication/json
Status code201

Username and email have to be unique. If both parameters are valid a request id and related activation code is generated.

An activation link is sent by email and looks similar to the one found below:

http://example.org/html/registration/cRJ0miyRgZKPnVz4tlZgnla7JKmJ26Ks?code=dETH8fPueOAaP9Q5p1z08WmJArC2spH7

Example response headers

Location: http://example.org/html/registration/cRJ0miyRgZKPnVz4tlZgnla7JKmJ26Ks
ETag: 274542b393fb3dfd63844f231bc4727dd288559df6ed66eaaa10fc050b786b2f

Example response body

{"Location": "http://example.org/html/registration/cRJ0miyRgZKPnVz4tlZgnla7JKmJ26Ks"}

1.2. Activation form

OptionValue(s)
Url/html/registration/$request-id
MethodGET
Parameterscode (optional)
Responsetext/html
Status code200

Response body

An HTML page providing a form to activate the requested user account. It has a field to enter the related request code.

If the code parameter is specified in the URL the related input field is filled.

1.3. Activate a user account

OptionValue(s)
Url/html/registration/$request-id
MethodPOST
Parameterscode
Responsetext/html
Status code200

If the request id and activation code are valid the account is activated. An auto-generated password is sent by email.

Response body

An HTML page displaying a success message.

1.4. View user details

OptionValue(s)
Url/rest/user/$username
MethodGET
HeadersAuthorization
Responseapplication/json
Status code200

Only friends can see the "email", "following" and "avatar" fields if the account is protected.

Example response body

{"avatar": null, "blocked": false, "created_on": {"$date": 1455608163842},
 "email": "john@example.org", "firstname": "John", "following": ["mark smith"],
 "gender": "male", "id": 158724, "language": null, "lastname": null,
 "protected": true, "username": "john.doe"}

1.5. Update user details

OptionValue(s)
Url/rest/user/$username
MethodPOST
Parametersfirstname, lastname, email, gender, language, protected
HeadersAuthorization
Responseapplication/json
Status code200

Response body

A dictionary providing user details (see 1.4).

1.6. Delete user account:

OptionValue(s)
Url/rest/user/$username
MethodDELETE
HeadersAuthorization
Responsetext/plain
Status code204

Users can only delete themselves.

1.7. Get avatar

OptionValue(s)
Url/rest/user/$username/avatar
MethodGET
HeadersAuthorization
ResponseApplication/Octet-Stream
Status code200

Only friends can download the avatar if the account is protected.

1.8. Update avatar

OptionValue(s)
Url/rest/user/$username/avatar
MethodPOST (multipart)
Parametersfilename, file
HeadersAuthorization
Responseapplication/json
Status code200

This resource expects a multipart form.

Example response body

{"filename": "42b393fb27453dfd63831bc4727dd288544f259df6ed66efc050aaa10b786b2f"}

1.9. Update password

OptionValue(s)
Url/rest/user/$username/password
MethodPOST
Parametersold_password, new_password1, new_password2
HeadersAuthorization
Responseapplication/json
Status code200

Example response

{"password": "my secret"}

1.10. Request new password

OptionValue(s)
Url/rest/user/$username/password/change
MethodPOST
Parametersemail
Responseapplication/json
Status code201

To change a password without knowing the current one a change request can be created. A request id and code is sent by mail to the user.

Example password change link sent by mail

http://example.org/html/user/john.doe/password/rest/8IlWH0aFitqAge7kqCskBuHbtbD5FpJu&code=nw8b0Veu1jYUaaLHfmXCCykH1J7xol23

Example response headers

Location: http://example.org/html/user/john.doe/password/rest/8IlWH0aFitqAge7kqCskBuHbtbD5FpJu
ETag: 93426807d9ebdb79d1276be519de4b97c4618c6b4ba39b5e5748243d85115e06

Example response body

{"Location": "http://example.org/html/user/john.doe/password/reset/8IlWH0aFitqAge7kqCskBuHbtbD5FpJu"}

1.11. Password change form

OptionValue(s)
Url/html/user/$username/password/reset/$request-id
MethodGET
Parameterscode (optional)
Responsetext/html
Status code200

Response body

An HTML page providing a form to change the password of a user account. It has three fields:

If the code parameter is specified in the URL the related input field is filled.

1.12. Set new password

OptionValue(s)
Url/html/user/$username/password/reset/$request-id
MethodPOST
Parameterscode, new_password1, new_password2
Responsetext/html
Status code200

Example response

A page displaying the success status or a failure message.

1.13. Search users

OptionValue(s)
Url/rest/user/search/$query
MethodGET
HeadersAuthorization
Responseapplication/json
Status code200

This function searches the user store. Only friends can see the "email", "following" and "avatar" fields when the found account is protected.

Response body

An array with dictionaries providing user details (see 1.4).

1.14. Change friendship

OptionValue(s)
Url/rest/user/$username/friendship
MethodPUT, DELETE, GET
HeadersAuthorization
Responseapplication/json
Status code200

Example response body

{"followed": false, "following": true}

1.15. Get favorites

OptionValue(s)
Url/rest/favorites
MethodPUT, DELETE, GET
Parametersguid (only PUT & GET)
HeadersAuthorization
Responseapplication/json
Status code200

Example response body

[{"comments_n": 0, "created_on": {"$date": 1455720684068},
  "guid": "914423ec-d585-11e5-bedf-50d719563991", "locked": false, "reported": false,
  "score": {"down": 0, "fav": 1, "up": 0}, "source": "foo", "tags": []},
  {"comments_n": 0, "created_on": {"$date": 1455720667357},
  "guid": "8eb02b44-d585-11e5-bdfe-50d719563991", "locked": false, "reported": false,
  "score": {"down": 0, "fav": 1, "up": 0}, "source": "bar", "tags": []}]

1.16. Get messages

OptionValue(s)
Url/rest/messages
MethodGET
HeadersAuthorization
Parameterslimit (optional, maximum number of messages), after (optional)
Responseapplication/json
Status code200

A message can have one of the following types:

Each message has a "type" field, a "source" (the sender) and a "target" (e.g. a voted or recommended object).

The "after" parameter may provide an UNIX timestamp (UTC). Only messages created after this timestamp will be returned.

1.17. Get public messages

OptionValue(s)
Url/rest/public
MethodGET
HeadersAuthorization
Parameterslimit (optional, maximum number of messages), after (optional)
Responseapplication/json
Status code200

A message can have one of the following types:

Each message has a "type" field, a "source" (the sender) and a "target" (e.g. a voted object).

The "after" parameter may provide an UNIX timestamp (UTC). Only messages created after this timestamp will be returned.

2. Objects

2.1. Get a single object

OptionValue(s)
Url/rest/object/$guid
MethodGET
HeadersAuthorization
Responseapplication/json
Status code200

Example response body

{"comments_n": 0, "created_on": {"$date": 1455720684068},
 "guid": "914423ec-d585-11e5-bedf-50d719563991", "locked": false,
 "reported": false, "score": {"down": 0, "fav": 1, "up": 0},
 "source": "foo", "tags": []}

2.2. Get multiple objects

OptionValue(s)
Urls/rest/objects, /rest/objects/page/$page
MethodGET
HeadersAuthorization
Parameterspage_size (optional)
Responseapplication/json
Status code200

Response body

An array holding objects (see 2.1).

2.3. Get objects (filtered by tag)

OptionValue(s)
Urls/rest/objects/tag/$tag, /rest/objects/tag/$tag/page/$page
MethodGET
HeadersAuthorization
Parameterspage_size (optional)
Responseapplication/json
Status code200

Response body

An array holding objects (see 2.1).

2.4. Get tag cloud

OptionValue(s)
Url/rest/objects/tags
MethodGET
HeadersAuthorization
Responseapplication/json
Status code200

Example response body

[{"count": 23, "tag": "foo"}, {"count": 42, "tag": "bar"}]

2.5. Get/assign object tags

OptionValue(s)
Url/rest/object/$guid/tags
MethodPUT, GET
Parameterstags (comma-separated list, PUT only)
HeadersAuthorization
Responseapplication/json
Status code200

Example response body

["foo", "bar", "23"]

2.4. Get popular objects

OptionValue(s)
Urls/rest/objects/popular, /rest/objects/popular/page/$page
MethodGET
HeadersAuthorization
Parameterspage_size (optional)
Responseapplication/json
Status code200

Response body

An array holding objects (see 2.1).

2.5. Get random objects

OptionValue(s)
Url/rest/objects/random
MethodGET
HeadersAuthorization
Parameterspage_size (optional)
Responseapplication/json
Status code200

Response body

An array holding objects (see 2.1).

2.6. Rate an object

OptionValue(s)
Url/rest/object/$guid/vote
MethodPOST, GET
Parametersup (POST only)
HeadersAuthorization
Responseapplication/json
Status code200

Use the "up" parameter to upvote/downvote an object (e.g. "true" to upvote).

Example response body

{"up": true}

2.7. Create/get comment(s)

OptionValue(s)
Urls/rest/object/$guid/comments, /rest/object/$guid/comments/page/$page
MethodPOST, GET
Parameterstext (POST only), page & page_size (GET only)
HeadersAuthorization
Responseapplication/json
Status code200

Example response body

[{"created_on": {"$date": 1455726032630}, "deleted": false, "id": 1324558,
  "text": "foo", "user": {"avatar": null, "blocked": false,
  "created_on": {"$date": 1455719502808}, "email": "john@example.org",
  "firstname": null, "following": ["fnord"], "gender": null,
  "id": 158726, "lastname": null, "protected": true, "username": "john.doe"}}]

2.8. Get comment

OptionValue(s)
Url/rest/comment/$id
MethodGET
HeadersAuthorization
Responseapplication/json
Status code200

Example response body

{"created_on": {"$date": 1455726032630}, "deleted": false, "id": 1324558,
 "text": "foo", "user": {"avatar": null, "blocked": false,
 "created_on": {"$date": 1455719502808}, "email": "john@example.org",
 "firstname": null, "following": ["fnord"], "gender": null,
 "id": 158726, "lastname": null, "protected": true, "username": "john.doe"}}

2.9. Get recommendations

OptionValue(s)
Urls/rest/recommendations, /rest/recommendations/page/$page
MethodGET
HeadersAuthorization
Parameterspage_size (optional)
Responseapplication/json
Status code200

Response body

An array holding objects (see 2.1).

2.11. Recommend object

OptionValue(s)
Url/rest/object/$guid/recommend
MethodPUT
HeadersAuthorization
Parametersreceivers (comma-separated list of usernames)
Responseapplication/json
Status code200

Example response body

{"guid": "914423EC-D585-11E5-BEDF-50D719563991", "receivers": ["john.doe", "mark smith"]}

2.12. Report abuse

OptionValue(s)
Url/rest/object/$guid/abuse
MethodPUT
HeadersAuthorization
Responseapplication/json
Status code200

Example response body

{"guid": "914423EC-D585-11E5-BEDF-50D719563991", "reported": true}