Collaborative keywords mixing project

Overview
The aim of this project is to generate new ingenies by presenting users a combination of different keywords like this (but with only 3 or 4 mixing keywords this time of this list):

Components and structure of the project: +-+    +-+     +--+     +-+  | IRC Bot |     | SocialN |     | Software |     |   ... |    user interfaces +++    +++     +-++     +++       |               |                |               |  ++---++---++  |                   Keyword Mixing Core                    |     computations ++-+                              |  ++-+  |                        Database                          |     data storage +--+

Users interfaces: TODO: For using the Core module from user software we need a secure communication channel between client and server. For now, only interfaces running as server processes are secure!
 * IRC bot
 * Social Networks: Diaspora/twitter/fb/salut à toi/movim/..
 * software on windows/GNU/Linux/FreeBSD/android/iphone/etc..

Active developers (programming language):
 * Core: No active develompent (Haskell? PHP? Python?). If you are interested in working on that tool, please contact us on IRC!
 * IRC bot: pavonia (Haskell)
 * Database: pavonia (MySQL)

Core
Core is a web server process that handles requests from several user interfaces, computes combinations and manages storing the data in a database.

Keywords
Keywords are choosen from two list; This two lists of keywords used to describe ingenies in libreidea. This list is always updated as long as there is new ingenies.
 * wis: list of Wis
 * wisf: list of Wisf

Advantanges:
 * Limit the number of possible combinations
 * Stay in the familiar environment of active users, i.e. if they are no doctors and no artists today on LI, there won't be words about those specialities in the list that active creators are not aware of

Data types

 * Filter to select combinations from the database. (TODO)
 * Filter to select combinations from the database. (TODO)


 * ID of a keyword combination.
 * ID of a keyword combination.


 * ID of a game.
 * ID of a game.


 * Filter to select keywords from the database. (TODO)
 * Filter to select keywords from the database. (TODO)


 * The rating a user can give to a combination is an integer number in the range from 1 to 10. Other values may be used for special cases, e.g. 0 for “bad” combinations.
 * The rating a user can give to a combination is an integer number in the range from 1 to 10. Other values may be used for special cases, e.g. 0 for “bad” combinations.


 * ID of a user.
 * TODO: Use Wiki IDs or create new mapping?
 * TODO: Use Wiki IDs or create new mapping?

Combination functions

 * This function creates a new combination of  different keywords. The keywords are choosen by applying   to all available keywords in the database. Only keywords that match   are used for the new combination. The function has to assert that only unique keyword combinations are generated to avoid duplicate checks later.
 * Parameters
 * The number of keywords the combination consists of (default is )
 * The filter to be used for selecting keywords from the database (default is the filter that matches all keywords)
 * Returns
 * Exceptions
 * General database error
 * Not enough matching keywords to create a new combination
 * General database error
 * Not enough matching keywords to create a new combination


 * Chooses a random combination matching  from the database.
 * Parameters
 * The filter to be used for selecting combinations from the database (default is the filter that matches all combinations)
 * Returns
 * Exceptions
 * General database error
 * No combination matches
 * General database error
 * No combination matches


 * Returns all combinations that match  from the database.
 * Parameters
 * The filter to be used for selecting combinations from the database
 * Returns
 * Exceptions
 * General database error
 * Exceptions
 * General database error

Game functions

 * Starts a new game and returns a fresh game ID.
 * Parameters
 * None
 * Returns
 * Exceptions
 * General database error
 * Exceptions
 * General database error


 * Ends an active game with ID . If there are still active combinations or players in the game they have to be marked as inactive.
 * Parameters
 * Returns
 * Nothing
 * Exceptions
 * General database error
 * doesn't exist
 * General database error
 * doesn't exist


 * Adds the user with ID  to the game with ID   or marks it active if they have played that game before.
 * Parameters
 * Returns
 * Nothing
 * Exceptions
 * General database error
 * doesn't exist
 * doesn't exist
 * General database error
 * doesn't exist
 * doesn't exist


 * Updates the combinations for Game with ID . This function has to make sure all combinations that were active before the update are kept. If there are users in the game that aren't able to rate at least   combinations, new combinations have to be added to the game until this property is satisfied. Only combinations matching   are added. The number of new combinations should be kept to a minimum.
 * Parameters
 * Minimum number of unrated combinations for each user in the game (default is )
 * The filter to be used for selecting combinations from the database (default is the filter that matches all combinations)
 * Returns
 * The (possibly empty) list of combination IDs that were added to the game
 * Exceptions
 * General database error
 * doesn't exist
 * New combinations would have to be added but not enough combinations match the filter
 * doesn't exist
 * New combinations would have to be added but not enough combinations match the filter


 * Marks the user with ID  as inactive for the game with ID.
 * Parameters
 * Returns
 * Nothing
 * Exceptions
 * General database error
 * doesn't exist
 * doesn't exist
 * User  isn't playing game
 * doesn't exist
 * doesn't exist
 * User  isn't playing game


 * Adds a rating with an optional comment from user  for a combination.
 * Parameters
 * Returns
 * Nothing
 * Exceptions
 * General database error
 * doesn't exist
 * doesn't exist
 * User  has already rated combination
 * Exceptions
 * General database error
 * doesn't exist
 * doesn't exist
 * User  has already rated combination

Global constants
This is a list of global constants used in various functions. These constants should be configurable from the database eventually.


 * The number of keywords for new combinations.
 * The number of unrated combinations in a game that must be rateable for each user.
 * The maximum number of ratings for a combination per game. If the number of ratings for a combination reaches this limit, it's out of the game.
 * The average value of ratings for a combination that marks this combination as bad.

Client–Server communication
The client communicates with the server by sending HTTP requests describing the action to be performed; the server answers them by replying with a JSON object that either includes the action's result or information about errors that occured while processing the request.

TODO: Use OAuth for secure communication?

Client requests
Clients send HTTP requests in a RESTful style. Each request represents a single server function call. Requests that only query database entries but do not alter the database are sent as GET requests; all other requests are sent as POST requests. The request's path takes the form  where   is the namespace of the server function, e.g. combination or game, and   the name of the function to be processed. All parameters of the server function are passed as parameters of the corresponding HTTP method with their values properly encoded as.

Examples: GET /combination/new?number=3&filter=all POST /game/start POST /game/removeUser; userID=123&gameID=45

TODO:  requests for global constants?

Server responses
Server responses are sent as a single JSend-compliant JSON object. Each object therefore has two mandatory fields:, giving information about success or client-side/server-side errors, and  , including the requested data or additional information about errors that occurred. In case of a server-side error the  field is replaced by.

Successful requests

Successful requests are answered with a field. If there wasn't any response data the  field is set to , otherwise it's an object with a key/value mapping representing the result parameters with their corresponding values.

Examples: Request: GET /combination/filter?filter=all Response: { "status" : "success", "data" : { "combIDs" : ["i3", "i7", "i24"] } }

Client-side errors

If a request couldn't be parsed correctly, had missing or included unknown parameters, or were erroneous in any other way, the server responds with an object that has its  field set to. The  field is an object with keys for each parameter that was missing, superfluous or badly formed, or in case of an unknown function call a key of the function name. The corresponding value is an error message describing the problem.

Examples: Request: POST game/remove; gameID=100 Response: { "status" : "fail", "data" : { "game/remove" : "Unknown function `Game.remove'" } }

Request: POST game/end; gameID=100 Response: { "status" : "fail", "data" : { "gameID" : "No game with ID 100 found" } }

Server-side error

Requests that couldn't be handled because of an error that occurred while processing a correctly formed request, e.g. due to a database error, are answered with the  field set to. Instead of a  field, error responses include a   field with a descriptive error message.

Examples: Request: game/end; gameID=100 Response: { "status" : "error", "message" : "Table `games' not found in database" }

IRC bot
The bot makes it possible to rate keyword combinations from IRC channels by several user playing rating games.

Functioning
Whenever the bot joins an IRC channel, a new game is started with zero players playing it. All users in a channel can then join the current game. Games in different channels have to be joined separately. There are no private games for now (games played outside of a channel), so users cannot communicate with the bot via private messages. Games cannot be stopped by users, the bot stops them when it leaves a channel or quits.

If a new user joins a game, a call of  is issued and all new combinations are presented. All users playing the game can now rate these new combinations (including all old combinations if there are any). If no new combinations have been added to the game, the user can display a set of combinations rateable by them. Each user can leave the game at any point of the game.

Every user can rate any active combination in a game. If  users rated the same combination, this combination is out of the game and will be marked either as a bad combination (average rating <  ) or as a good combination otherwise. The same user cannot rate the same combination twice. If they tries, a random unrated combination is shown as a hint. After a user has rated a combination,  is issued such that a new combination is available for further rating.

TODO: What to do on network interruptions? TODO: Continue old game when re-joining the same channel at another time? TODO: How to associate IRC nick names with Wiki account names?

Bot commands

 * Syntax
 * Normal text denotes variable names
 * Bold text denotes literal syntax (keywords etc.)
 * Text in square brackets is optional syntax
 * The pipe character denotes alternative syntax. Parentheses can be used to delimit the scope of the pipes, e.g.  is different from.

Adds a user to the active game in the channel.

 :game join  Antoine joined the game.  :game join  You already are in the game.

Removes a user from the game in the channel.

 :game leave  Antoine left the game.  :game leave  You are not in the game.

Adds a rating with an optional comment for a keyword combination by a user.

   :game rate i2 10 Super great ingenie!!1!  ...    :game rate i3 7  ...    :game rate i3 7  Sorry, you've already rated combination [i3].  ...    :game rate i4 3 <IdeaBot> No combination found for ID [i4].

List all combinations rateable by the user.

(temporary command) Associates the current IRC nick name with the user name. The user name will be stored in the database, and all ratings, issued by a nick that is associated with this user name, will be stored for the same user. Ideally, this user name should be the Wiki account name.

<Charly>  :register Charles <IdeaBot> Associated nick Charly with user Charles. <Charly>  :rate i3 8 <IdeaBot> ... Charly changes nick to Karl <Karl>    :register Charles <IdeaBot> Associated nick Karl with user Charles. <Karl>    :rate i3 8 <IdeaBot> Sorry, you've already rated combination [i3].

NOTE: This is only a temporary hack which is used until a more sophisticated user registration scheme has been introduced.

Database
For the storage a MySQL database is used. As some data, e.g. keywords, has to be accessed from the keyword mixing tool and the wiki, the wiki database will be used for the storage.

Table structure
, PK = primary key, FK = foreign key. The given types are (Haskell) synonyms for underlying MySQL types, e.g. types ending with &ldquo;ID&rdquo; are usually synonyms for INT UNSIGNED.


 * combination
 * PK


 * keyword
 * PK
 * Note: This shouldn't be a new table but a reference to the Wiki table for categories
 * Note: This shouldn't be a new table but a reference to the Wiki table for categories


 * combination_keyword
 * PK FK
 * PK FK


 * rating
 * PK FK
 * PK FK


 * game
 * PK


 * game_combination
 * PK FK
 * PK FK
 * Is the combination still in that game?


 * game_user
 * PK FK
 * PK FK
 * Is the user still playing that game?


 * user
 * PK
 * Note: This also shouldn't be a new table but a reference to the Wiki table for registered users