Skip to content

20centaurifux/meat-a

Repository files navigation

##########################################################################
# meat-a - README
##########################################################################

Table of contents

1. Description
2. Architecture - Brief Overview (only for developers)
3. Setup
4. The Web Interface


################################################################
# 1. Description
################################################################

meat-a is a WSGI based webservice for the organization of objects and related
meta information.

Objects have a guid and a source (e.g. a filename or an URL). meat-a lets
users share meta information like tags or comments. The data is stored in a
PostgreSQL database.


################################################################
# 2. Architecture - Brief Overview (for developers)
################################################################

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

Users can tag and rate objects. They can also add objects to their
personal favorite list and recommend them to other users. It's possible to
write comments too.

If two users follow each other they are friends.  Friends can recommend
objects to each other. If a user profile is not protected everyone can
recommend objects to him/her.

Users are organized in a separate user store (database.UserDb).

Several activities generate notifications. If a user writes a comment friends
receive a notification, for instance. If the user profile is not protected
a notification is stored in a global stream. Notifications are stored in a
separated data store named database.StreamDb.

Sometimes a user might receive an email. If you're going to create a new user
profile an activation link is sent, for example. Emails are stored in the
database.MailDb data store.

A service (mailer.Mailer) sends emails in a user-defined interval. This process
can be triggered via an UDP request.

The different data stores can be accessed through the app.Application class.

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

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

To configure the service please have a look at the config module.

You need the following additional packages to run the web interface. All modules
can be installed with PIP.

  * PIL (image library)
  * Cheetah
  * psycopg2
  * bson (shipped with pymongo)
  * Rocket (optional)


################################################################
# 3. Setup
################################################################

If you want to test the web application please install the Rocket module and
start the rocket server:

# python rocket_server.py

This will start a small HTTP test 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() method located in
the wsgi.py file as handler.

Without starting the mailer meat-a will not be able to send emails:

# python mailer.py

As mentioned before data is stored in a PostgreSQL database. Please ensure that
the server is running.

The database schema can be found in the sql subfolder. You can build additional
scripts with GNU Make.

Configuration settings can be found in the config.py file. It's recommended to
change a few settings:

* WEBSITE_URL
  meat-a generates various URLs (e.g. for changing passwords). Define the
  base URL of the web application here.

* PG_HOST, PG_PORT, PG_DB, PG_USER, PG_PWD
  Please specify the connection details and database name of your PostgreSQL
  server.

* TMP_DIR
  Directory for temporary files. An absolute filename is highly recommended.

* AVATAR_DIR
  Directory for storing avatars. An absolute filename is highly recommended.

* SMTP_HOST, SMTP_PORT, SMTP_SSL, SMTP_ADDRESS, SMTP_USERNAME, SMTP_PASSWORD
  SMTP user credentials and details.

* MAILER_HOST, MAILER_PORT, MAILER_ALLOWED_CLIENTS
  Hostname and port of the mailer. You have also to specify the IP addresses of all
  allowed clients.

Emails and websites are generated using the Cheetah template framework and can
be found in the "tpl" directory.

Kindly note that meat-a uses the default Python logging functions which can also
be customized in the config.py file.

HTTP requests can be limited IP or user based.


################################################################
# 4. The Web Interface
################################################################

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 functionality:


#################################################
# I. User Accounts
#################################################

---------------------------------------
- 1.1. Request a new user account
---------------------------------------
URL        : /rest/registration
METHOD     : POST
PARAMETERS : username, email
RESPONSE   : application/json
STATUS CODE: 201

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:

# Example activation link:
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
---------------------------------------
URL        : /html/registration/$request-id
METHOD     : GET
PARAMETERS : code (optional)
RESPONSE   : text/html
STATUS CODE: 200

# 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
---------------------------------------
URL        : /html/registration/$request-id
METHOD     : POST
PARAMETERS : code
RESPONSE   : text/html
STATUS CODE: 200

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
---------------------------------------
URL        : /rest/user/$username
METHOD     : GET
HEADERS    : Authorization
RESPONSE   : application/json
STATUS CODE: 200

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:
---------------------------------------
URL        : /rest/user/$username
METHOD     : POST
PARAMETERS : firstname, lastname, email, gender, language, protected
HEADERS    : Authorization
RESPONSE   : application/json
STATUS CODE: 200

# Response body:
A dictionary providing user details (see 1.4).


---------------------------------------
- 1.6. Delete user account:
---------------------------------------
URL        : /rest/user/$username
METHOD     : DELETE
HEADERS    : Authorization
RESPONSE   : text/plain
STATUS CODE: 204

Users can only delete themselves.


---------------------------------------
- 1.6. Get avatar
---------------------------------------
URL        : /rest/user/$username/avatar
METHOD     : GET
HEADERS    : Authorization
RESPONSE   : Application/Octet-Stream
STATUS CODE: 200

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


---------------------------------------
- 1.7. Update avatar
---------------------------------------
URL        : /rest/user/$username/avatar
METHOD     : POST (multipart)
PARAMETERS : filename, file
HEADERS    : Authorization
RESPONSE   : application/json
STATUS CODE: 200

This resource expects a multipart form.

# Example response body:
{"filename": "42b393fb27453dfd63831bc4727dd288544f259df6ed66efc050aaa10b786b2f"}


---------------------------------------
- 1.8. Update password
---------------------------------------
URL        : /rest/user/$username/password
METHOD     : POST
PARAMETERS : old_password, new_password1, new_password2
HEADERS    : Authorization
RESPONSE   : application/json
STATUS CODE: 200

# Example response:
{"password": "my secret"}


---------------------------------------
- 1.9. Request new password
---------------------------------------
URL        : /rest/user/$username/password/change
METHOD     : POST
PARAMETERS : email
RESPONSE   : application/json
STATUS CODE: 201

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 email:
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.10. Password change form
---------------------------------------
URL        : /html/user/$username/password/reset/$request-id
METHOD     : GET
PARAMETERS : code (optional)
RESPONSE   : text/html
STATUS CODE: 200

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

* code: request code related to the request id
* password1, password2: password to set

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


---------------------------------------
- 1.11. Set new password
---------------------------------------
URL        : /html/user/$username/password/reset/$request-id
METHOD     : POST
PARAMETERS : code, new_password1, new_password2
RESPONSE   : text/html
STATUS CODE: 200

# Example response:
A page displaying the success status or a failure message.


---------------------------------------
- 1.12. Search users
---------------------------------------
URL        : /rest/user/search/$query
METHOD     : GET
HEADERS    : Authorization
RESPONSE   : application/json
STATUS CODE: 200

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 vector with dictionaries providing user details (see 1.4).


---------------------------------------
- 1.13. Add/remove/get friendship
---------------------------------------
URL        : /rest/user/$username/friendship
METHOD     : PUT, DELETE, GET
HEADERS    : Authorization
RESPONSE   : application/json
STATUS CODE: 200

# Example response body:
{"followed": false, "following": true}


---------------------------------------
- 1.14. Get favorites
---------------------------------------
URL        : /rest/favorites
METHOD     : PUT, DELETE, GET
PARAMETERS : guid (only PUT & GET)
HEADERS    : Authorization
RESPONSE   : application/json
STATUS CODE: 200

# 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.15. Get messages
---------------------------------------
URL        : /rest/messages
METHOD     : GET
HEADERS    : Authorization
PARAMETERS : limit (optional, maximum number of messages), after (optional)
RESPONSE   : application/json
STATUS CODE: 200

A message can have one of the following types:

* "following"
* "unfollowing"
* "recommendation"
* "wrote-comment"
* "voted-object"

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.16. Get public messages
---------------------------------------
URL        : /rest/public
METHOD     : GET
HEADERS    : Authorization
PARAMETERS : limit (optional, maximum number of messages), after (optional)
RESPONSE   : application/json
STATUS CODE: 200

A message can have one of the following types:

* "wrote-comment"
* "voted-object"

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.


#################################################
# II. Objects
#################################################

---------------------------------------
- 2.1. Get a single object
---------------------------------------
URL        : /rest/object/$guid
METHOD     : GET
HEADERS    : Authorization
RESPONSE   : application/json
STATUS CODE: 200

# 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
---------------------------------------
URLS       : /rest/objects
             /rest/objects/page/$page
METHOD     : GET
HEADERS    : Authorization
PARAMETERS : page_size (optional)
RESPONSE   : application/json
STATUS CODE: 200

# Response body:
An array holding objects (see 2.1).


---------------------------------------
- 2.3. Get objects (filtered by tag)
---------------------------------------
URLS       : /rest/objects/tag/$tag
             /rest/objects/tag/$tag/page/$page
METHOD     : GET
HEADERS    : Authorization
PARAMETERS : page_size (optional)
RESPONSE   : application/json
STATUS CODE: 200

# Response body:
An array holding objects (see 2.1).


---------------------------------------
- 2.4. Get tag cloud
---------------------------------------
URL        : /rest/objects/tags
METHOD     : GET
HEADERS    : Authorization
RESPONSE   : application/json
STATUS CODE: 200

# Example response body:
[{"count": 23, "tag": "foo"}, {"count": 42, "tag": "bar"}]


---------------------------------------
- 2.5. Get/assign object tags
---------------------------------------
URL        : /rest/object/$guid/tags
METHOD     : PUT, GET
PARAMETERS : tags (comma-separated list, PUT only)
HEADERS    : Authorization
RESPONSE   : application/json
STATUS CODE: 200

# Example response body:
["foo", "bar", "23"]


---------------------------------------
- 2.4. Get popular objects
---------------------------------------
URLS       : /rest/objects/popular
             /rest/objects/popular/page/$page
METHOD     : GET
HEADERS    : Authorization
PARAMETERS : page_size (optional)
RESPONSE   : application/json
STATUS CODE: 200

# Response body:
An array holding objects (see 2.1).


---------------------------------------
- 2.5. Get random objects
---------------------------------------
URL        : /rest/objects/random
METHOD     : GET
HEADERS    : Authorization
PARAMETERS : page_size (optional)
RESPONSE   : application/json
STATUS CODE: 200

# Response body:
An array holding objects (see 2.1).


---------------------------------------
- 2.6. Rate an object
---------------------------------------
URL        : /rest/object/$guid/vote
METHOD     : POST, GET
PARAMETERS : up (POST only)
HEADERS    : Authorization
RESPONSE   : application/json
STATUS CODE: 200

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)
---------------------------------------
URLS       : /rest/object/$guid/comments
             /rest/object/$guid/comments/page/$page
METHOD     : POST, GET
PARAMETERS : text (POST only), page & page_size (GET only)
HEADERS    : Authorization
RESPONSE   : application/json
STATUS CODE: 200

# 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
---------------------------------------
URL        : /rest/comment/$id
METHOD     : GET
HEADERS    : Authorization
RESPONSE   : application/json
STATUS CODE: 200

# 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
---------------------------------------
URLS       : /rest/recommendations
             /rest/recommendations/page/$page
METHOD     : GET
HEADERS    : Authorization
PARAMETERS : page_size (optional)
RESPONSE   : application/json
STATUS CODE: 200

# Response body:
An array holding objects (see 2.1).


---------------------------------------
- 2.11. Recommend object
---------------------------------------
URL        : /rest/object/$guid/recommend
METHOD     : PUT
HEADERS    : Authorization
PARAMETERS : receivers (comma-separated list of usernames)
RESPONSE   : application/json
STATUS CODE: 200

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


---------------------------------------
- 2.12. Report abuse
---------------------------------------
URL        : /rest/object/$guid/abuse
METHOD     : PUT
HEADERS    : Authorization
RESPONSE   : application/json
STATUS CODE: 200

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

About

REST service for adding social network features to an object database.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published