lfapi

changeset 33:25aba6a34c44

Added missing related objects, fixed smaller bugs,
author bsw
date Sat May 19 13:58:50 2012 +0200 (2012-05-19)
parents be8ca05d0315
children a5a5de8dbac2
files config.js lfapi/fields.js lfapi/main.js
line diff
     1.1 --- a/config.js	Sat Feb 25 21:56:55 2012 +0100
     1.2 +++ b/config.js	Sat May 19 13:58:50 2012 +0200
     1.3 @@ -16,15 +16,15 @@
     1.4  exports.public_access_level = 'full';
     1.5  
     1.6  // connection string to access the LiquidFeedback Core database
     1.7 -exports.connectionString = 'pg://localhost/liquid_feedback';
     1.8 +exports.connectionString = 'pg://localhost/liquid_feedback2';
     1.9  
    1.10  // public base url (including trailing slash)
    1.11 -exports.public_url_path = 'http://lf.example.org/api/';
    1.12 +exports.public_url_path = 'http://apitest.liquidfeedback.org:25520/';
    1.13  
    1.14  // mail server, email sender and subject settings
    1.15  exports.mail = {
    1.16 -  from:                'Sender name <senderaddress@example.org>',
    1.17 -  subject_prefix:      '[email subject prefix] '
    1.18 +  from:                'LiquidFeedback Maintainers <lqfb-maintainers@public-software-group.org>',
    1.19 +  subject_prefix:      '[lfapi alpha] '
    1.20  };
    1.21  
    1.22  exports.settings = {
     2.1 --- a/lfapi/fields.js	Sat Feb 25 21:56:55 2012 +0100
     2.2 +++ b/lfapi/fields.js	Sat May 19 13:58:50 2012 +0200
     2.3 @@ -2,7 +2,7 @@
     2.4  // fields of main data structures
     2.5  // --------------------------------------------------------------------------
     2.6  
     2.7 -exports.member =  ['id', 'name', 'identification', 'organizational_unit', 'internal_posts', 'realname', 'birthday', 'address', 'email', 'xmpp_address', 'website', 'phone', 'mobile_phone', 'profession', 'external_memberships', 'external_posts', 'statement', 'active', 'locked', 'created', 'last_activity'];
     2.8 +exports.member =  ['id', 'name', 'organizational_unit', 'internal_posts', 'realname', 'birthday', 'address', 'email', 'xmpp_address', 'website', 'phone', 'mobile_phone', 'profession', 'external_memberships', 'external_posts', 'statement', 'active', 'locked', 'created', 'last_activity'];
     2.9  exports.member_pseudonym = ['id', 'name'];
    2.10  exports.policy = ['id', 'index', 'active', 'name', 'description', 'admission_time', 'discussion_time', 'verification_time', 'voting_time', 'issue_quorum_num', 'issue_quorum_den', 'initiative_quorum_num', 'initiative_quorum_den', 'direct_majority_num', 'direct_majority_den', 'direct_majority_strict', 'direct_majority_positive', 'direct_majority_non_negative', 'indirect_majority_num', 'indirect_majority_den', 'indirect_majority_strict', 'indirect_majority_positive', 'indirect_majority_non_negative', 'no_reverse_beat_path', 'no_multistage_majority'];
    2.11  exports.unit = ['id', 'parent_id', 'active', 'name', 'description', 'member_count'];
     3.1 --- a/lfapi/main.js	Sat Feb 25 21:56:55 2012 +0100
     3.2 +++ b/lfapi/main.js	Sat May 19 13:58:50 2012 +0200
     3.3 @@ -99,6 +99,7 @@
     3.4            http_status, 
     3.5            {
     3.6              'Content-Type': content_type,
     3.7 +            'Access-Control-Allow-Origin': '*'
     3.8              //'Content-Length': body.length // TODO doesn't work in chrome with JSONP
     3.9            }
    3.10          );
    3.11 @@ -331,13 +332,15 @@
    3.12      var html = [];
    3.13      html.push('<h2>welcome to lfapi public developer alpha test</h2>');
    3.14      html.push('<p>This service is provided for testing purposes and is <i><b>dedicated to developers interested in creating applications</b></i> based on LiquidFeedback.</p>');
    3.15 +    html.push('<h2>developer registration</h2>');
    3.16 +    html.push('<p>To register as developer and receive an account, please send an email to beta20120312@public-software-group.org and you\'ll receive an invitation to the testing system. Read access is available without registering an account.</p>');
    3.17      html.push('<h2>how to use</h2>');
    3.18      html.push('<p>The programming interface is described in the <a href="http://dev.liquidfeedback.org/trac/lf/wiki/API">LiquidFeedback API specification</a>.</p>')
    3.19      html.push('<p>The current implementation status of lfapi is published at the <a href="http://dev.liquidfeedback.org/trac/lf/wiki/lfapi">LiquidFeedback API server</a> page in our Wiki.</p>');
    3.20      html.push('<p><b><i>Neither the API specification nor the implementation of lfapi is finished yet.</i></b> This public test should enable developers to join the specification process of the programming interface and makes it possible to start creating applications.</p>');
    3.21      html.push('<h2>questions and suggestions</h2>');
    3.22      html.push('<p>Please use our <a href="http://dev.liquidfeedback.org/cgi-bin/mailman/listinfo/main">public mailing list</a> if you have any questions or suggestions.</p>');
    3.23 -    html.push('<h2>developer registration</h2>');
    3.24 +/*
    3.25      html.push('<p>To register as developer and receive an account, please submit the following form. You\'ll receive an email with instructions to complete the registration process by verifying your email address.<br />');
    3.26      html.push('<form action="register_test" method="POST">');
    3.27      html.push('<label for="name">Your name:</label> <input type="text" id="name" name="name" /> &nbsp; &nbsp; ');
    3.28 @@ -353,6 +356,7 @@
    3.29      html.push('</div>');
    3.30      html.push('<br />');
    3.31      html.push('<input type="submit" value="Register account" />');
    3.32 +*/
    3.33      respond('html', null, req, res, 'ok', html.join(''));
    3.34    },
    3.35    
    3.36 @@ -483,7 +487,7 @@
    3.37        db.query(conn, req, res, query, function (member_history_result, conn) {
    3.38          var result = { result: member_history_result.rows }
    3.39          includes = [];
    3.40 -        if (params.include_members) includes.push({ class: 'member', objects: 'result'});
    3.41 +        if (params.include_members) includes.push({ clazz: 'member', objects: 'result'});
    3.42          addRelatedData(conn, req, res, result, includes);
    3.43        });
    3.44      });
    3.45 @@ -493,8 +497,17 @@
    3.46      requireAccessLevel(conn, req, res, 'full', function() {
    3.47        var query = new selector.Selector();
    3.48        query.from('"member_image" JOIN "member" ON "member"."id" = "member_image"."member_id"');
    3.49 -      query.addField('"member_image".*');
    3.50 +      query.addField('"member_image"."member_id"');
    3.51 +      query.addField('"member_image"."image_type"');
    3.52 +      query.addField('"member_image"."scaled"');
    3.53 +      query.addField('"member_image"."content_type"');
    3.54 +      query.addField('encode("member_image"."data", \'base64\')', 'data');
    3.55        query.addWhere('member_image.scaled');
    3.56 +      if (params.type == "avatar") {
    3.57 +        query.addWhere('member_image.image_type = \'avatar\'');
    3.58 +      } else if (params.type == "photo") {
    3.59 +        query.addWhere('member_image.image_type = \'photo\'');
    3.60 +      }
    3.61        general_params.addMemberOptions(req, query, params);
    3.62        query.addOrderBy = ['member_image.member_id, member_image.image_type'];
    3.63        db.query(conn, req, res, query, function (result, conn) {
    3.64 @@ -536,8 +549,8 @@
    3.65        db.query(conn, req, res, query, function (privilege_result, conn) {
    3.66          var result = { result: privilege_result.rows }
    3.67          includes = [];
    3.68 -        if (params.include_units) includes.push({ class: 'unit', objects: 'result'});
    3.69 -        if (params.include_members) includes.push({ class: 'member', objects: 'result'});
    3.70 +        if (params.include_units) includes.push({ clazz: 'unit', objects: 'result'});
    3.71 +        if (params.include_members) includes.push({ clazz: 'member', objects: 'result'});
    3.72          addRelatedData(conn, req, res, result, includes);
    3.73        });
    3.74      });
    3.75 @@ -582,7 +595,7 @@
    3.76        db.query(conn, req, res, query, function (area_result, conn) {
    3.77          var result = { result: area_result.rows }
    3.78          includes = [];
    3.79 -        if (params.include_units) includes.push({ class: 'unit', objects: 'result'});
    3.80 +        if (params.include_units) includes.push({ clazz: 'unit', objects: 'result'});
    3.81          addRelatedData(conn, req, res, result, includes);
    3.82        });
    3.83      });
    3.84 @@ -601,9 +614,9 @@
    3.85      db.query(conn, req, res, query, function (allowed_policy_result, conn) {
    3.86        var result = { result: allowed_policy_result.rows }
    3.87        includes = [];
    3.88 -      if (params.include_policies) includes.push({ class: 'policy', objects: 'result'});
    3.89 -      if (params.include_areas) includes.push({ class: 'area', objects: 'result'});
    3.90 -      if (params.include_units) includes.push({ class: 'unit', objects: 'areas'});
    3.91 +      if (params.include_policies) includes.push({ clazz: 'policy', objects: 'result'});
    3.92 +      if (params.include_areas) includes.push({ clazz: 'area', objects: 'result'});
    3.93 +      if (params.include_units) includes.push({ clazz: 'unit', objects: 'areas'});
    3.94        addRelatedData(conn, req, res, result, includes);
    3.95      });
    3.96    }); },
    3.97 @@ -620,9 +633,9 @@
    3.98        db.query(conn, req, res, query, function (membership_result, conn) {
    3.99          var result = { result: membership_result.rows }
   3.100          includes = [];
   3.101 -        if (params.include_members) includes.push({ class: 'member', objects: 'result'});
   3.102 -        if (params.include_areas) includes.push({ class: 'area', objects: 'result'});
   3.103 -        if (params.include_units) includes.push({ class: 'unit', objects: 'areas'});
   3.104 +        if (params.include_members) includes.push({ clazz: 'member', objects: 'result'});
   3.105 +        if (params.include_areas) includes.push({ clazz: 'area', objects: 'result'});
   3.106 +        if (params.include_units) includes.push({ clazz: 'unit', objects: 'areas'});
   3.107          addRelatedData(conn, req, res, result, includes);
   3.108        });
   3.109      });
   3.110 @@ -639,9 +652,9 @@
   3.111        db.query(conn, req, res, query, function (issue_result, conn) {
   3.112          var result = { result: issue_result.rows }
   3.113          includes = [];
   3.114 -        if (params.include_areas) includes.push({ class: 'area', objects: 'result'});
   3.115 -        if (params.include_units) includes.push({ class: 'unit', objects: 'areas'});
   3.116 -        if (params.include_policies) includes.push({ class: 'policy', objects: 'result' });
   3.117 +        if (params.include_areas) includes.push({ clazz: 'area', objects: 'result'});
   3.118 +        if (params.include_units) includes.push({ clazz: 'unit', objects: 'areas'});
   3.119 +        if (params.include_policies) includes.push({ clazz: 'policy', objects: 'result' });
   3.120          addRelatedData(conn, req, res, result, includes);
   3.121        });
   3.122      });
   3.123 @@ -690,11 +703,11 @@
   3.124        db.query(conn, req, res, query, function (population_result, conn) {
   3.125          var result = { result: population_result.rows }
   3.126          includes = [];
   3.127 -        if (params.include_members) includes.push({ class: 'member', objects: 'result'});
   3.128 -        if (params.include_issues) includes.push({ class: 'issue', objects: 'result'});
   3.129 -        if (params.include_areas) includes.push({ class: 'area', objects: 'areas'});
   3.130 -        if (params.include_units) includes.push({ class: 'unit', objects: 'areas'});
   3.131 -        if (params.include_policies) includes.push({ class: 'policy', objects: 'issues' });
   3.132 +        if (params.include_members) includes.push({ clazz: 'member', objects: 'result'});
   3.133 +        if (params.include_issues) includes.push({ clazz: 'issue', objects: 'result'});
   3.134 +        if (params.include_areas) includes.push({ clazz: 'area', objects: 'areas'});
   3.135 +        if (params.include_units) includes.push({ clazz: 'unit', objects: 'areas'});
   3.136 +        if (params.include_policies) includes.push({ clazz: 'policy', objects: 'issues' });
   3.137          addRelatedData(conn, req, res, result, includes);
   3.138        });
   3.139      });
   3.140 @@ -752,11 +765,11 @@
   3.141        db.query(conn, req, res, query, function (interest_result, conn) {
   3.142          var result = { result: interest_result.rows }
   3.143          includes = [];
   3.144 -        if (params.include_members) includes.push({ class: 'member', objects: 'result'});
   3.145 -        if (params.include_issues) includes.push({ class: 'issue', objects: 'result'});
   3.146 -        if (params.include_areas) includes.push({ class: 'area', objects: 'issues'});
   3.147 -        if (params.include_units) includes.push({ class: 'unit', objects: 'areas'});
   3.148 -        if (params.include_policies) includes.push({ class: 'policy', objects: 'issues' });
   3.149 +        if (params.include_members) includes.push({ clazz: 'member', objects: 'result'});
   3.150 +        if (params.include_issues) includes.push({ clazz: 'issue', objects: 'result'});
   3.151 +        if (params.include_areas) includes.push({ clazz: 'area', objects: 'issues'});
   3.152 +        if (params.include_units) includes.push({ clazz: 'unit', objects: 'areas'});
   3.153 +        if (params.include_policies) includes.push({ clazz: 'policy', objects: 'issues' });
   3.154          addRelatedData(conn, req, res, result, includes);
   3.155        });
   3.156      });
   3.157 @@ -774,11 +787,11 @@
   3.158        db.query(conn, req, res, query, function (issue_comment_result, conn) {
   3.159          var result = { result: issue_comment_result.rows }
   3.160          includes = [];
   3.161 -        if (params.include_members) includes.push({ class: 'member', objects: 'result'});
   3.162 -        if (params.include_issues) includes.push({ class: 'issue', objects: 'result'});
   3.163 -        if (params.include_areas) includes.push({ class: 'area', objects: 'issues'});
   3.164 -        if (params.include_units) includes.push({ class: 'unit', objects: 'areas'});
   3.165 -        if (params.include_policies) includes.push({ class: 'policy', objects: 'issues' });
   3.166 +        if (params.include_members) includes.push({ clazz: 'member', objects: 'result'});
   3.167 +        if (params.include_issues) includes.push({ clazz: 'issue', objects: 'result'});
   3.168 +        if (params.include_areas) includes.push({ clazz: 'area', objects: 'issues'});
   3.169 +        if (params.include_units) includes.push({ clazz: 'unit', objects: 'areas'});
   3.170 +        if (params.include_policies) includes.push({ clazz: 'policy', objects: 'issues' });
   3.171          addRelatedData(conn, req, res, result, includes);
   3.172        });
   3.173      });
   3.174 @@ -795,10 +808,10 @@
   3.175        db.query(conn, req, res, query, function (initiative_result, conn) {
   3.176          var result = { result: initiative_result.rows }
   3.177          includes = [];
   3.178 -        if (params.include_issues) includes.push({ class: 'issue', objects: 'result'});
   3.179 -        if (params.include_areas) includes.push({ class: 'area', objects: 'issues'});
   3.180 -        if (params.include_units) includes.push({ class: 'unit', objects: 'areas'});
   3.181 -        if (params.include_policies) includes.push({ class: 'policy', objects: 'issues' });
   3.182 +        if (params.include_issues) includes.push({ clazz: 'issue', objects: 'result'});
   3.183 +        if (params.include_areas) includes.push({ clazz: 'area', objects: 'issues'});
   3.184 +        if (params.include_units) includes.push({ clazz: 'unit', objects: 'areas'});
   3.185 +        if (params.include_policies) includes.push({ clazz: 'policy', objects: 'issues' });
   3.186          addRelatedData(conn, req, res, result, includes);
   3.187        });
   3.188      });
   3.189 @@ -820,12 +833,12 @@
   3.190        db.query(conn, req, res, query, function (initiator, conn) {
   3.191          var result = { result: initiator.rows }
   3.192          includes = [];
   3.193 -        if (params.include_members) includes.push({ class: 'member', objects: 'result'});
   3.194 -        if (params.include_initiatives) includes.push({ class: 'initiative', objects: 'result'});
   3.195 -        if (params.include_issues) includes.push({ class: 'issue', objects: 'initiatives'});
   3.196 -        if (params.include_areas) includes.push({ class: 'area', objects: 'issues'});
   3.197 -        if (params.include_units) includes.push({ class: 'unit', objects: 'areas'});
   3.198 -        if (params.include_policies) includes.push({ class: 'policy', objects: 'issues' });
   3.199 +        if (params.include_members) includes.push({ clazz: 'member', objects: 'result'});
   3.200 +        if (params.include_initiatives) includes.push({ clazz: 'initiative', objects: 'result'});
   3.201 +        if (params.include_issues) includes.push({ clazz: 'issue', objects: 'initiatives'});
   3.202 +        if (params.include_areas) includes.push({ clazz: 'area', objects: 'issues'});
   3.203 +        if (params.include_units) includes.push({ clazz: 'unit', objects: 'areas'});
   3.204 +        if (params.include_policies) includes.push({ clazz: 'policy', objects: 'issues' });
   3.205          addRelatedData(conn, req, res, result, includes);
   3.206        });
   3.207      });
   3.208 @@ -892,12 +905,12 @@
   3.209        db.query(conn, req, res, query, function (supporter, conn) {
   3.210          var result = { result: supporter.rows }
   3.211          includes = [];
   3.212 -        if (params.include_members) includes.push({ class: 'member', objects: 'result'});
   3.213 -        if (params.include_initiatives) includes.push({ class: 'initiative', objects: 'result'});
   3.214 -        if (params.include_issues) includes.push({ class: 'issue', objects: 'initiatives'});
   3.215 -        if (params.include_areas) includes.push({ class: 'area', objects: 'issues'});
   3.216 -        if (params.include_units) includes.push({ class: 'unit', objects: 'areas'});
   3.217 -        if (params.include_policies) includes.push({ class: 'policy', objects: 'issues' });
   3.218 +        if (params.include_members) includes.push({ clazz: 'member', objects: 'result'});
   3.219 +        if (params.include_initiatives) includes.push({ clazz: 'initiative', objects: 'result'});
   3.220 +        if (params.include_issues) includes.push({ clazz: 'issue', objects: 'initiatives'});
   3.221 +        if (params.include_areas) includes.push({ clazz: 'area', objects: 'issues'});
   3.222 +        if (params.include_units) includes.push({ clazz: 'unit', objects: 'areas'});
   3.223 +        if (params.include_policies) includes.push({ clazz: 'policy', objects: 'issues' });
   3.224          addRelatedData(conn, req, res, result, includes);
   3.225        });
   3.226      });
   3.227 @@ -914,11 +927,11 @@
   3.228        db.query(conn, req, res, query, function (result, conn) {
   3.229          var result = { result: result.rows }
   3.230          includes = [];
   3.231 -        if (params.include_initiatives) includes.push({ class: 'initiative', objects: 'result'});
   3.232 -        if (params.include_issues) includes.push({ class: 'issue', objects: 'initiatives'});
   3.233 -        if (params.include_areas) includes.push({ class: 'area', objects: 'issues'});
   3.234 -        if (params.include_units) includes.push({ class: 'unit', objects: 'areas'});
   3.235 -        if (params.include_policies) includes.push({ class: 'policy', objects: 'issues' });
   3.236 +        if (params.include_initiatives) includes.push({ clazz: 'initiative', objects: 'result'});
   3.237 +        if (params.include_issues) includes.push({ clazz: 'issue', objects: 'initiatives'});
   3.238 +        if (params.include_areas) includes.push({ clazz: 'area', objects: 'issues'});
   3.239 +        if (params.include_units) includes.push({ clazz: 'unit', objects: 'areas'});
   3.240 +        if (params.include_policies) includes.push({ clazz: 'policy', objects: 'issues' });
   3.241          addRelatedData(conn, req, res, result, includes);
   3.242        });
   3.243      });
   3.244 @@ -926,14 +939,14 @@
   3.245    
   3.246    '/draft': function (conn, req, res, params) {
   3.247      requireAccessLevel(conn, req, res, 'anonymous', function() {
   3.248 -      var fields = ['draft.initiative_id', 'draft.id', 'draft.formatting_engine', 'draft.content', 'draft.author_id'];
   3.249 +      var fields = ['draft.initiative_id', 'draft.id', 'draft.formatting_engine', 'draft.created'];
   3.250        var query = new selector.Selector();
   3.251        query.from('draft JOIN initiative ON initiative.id = draft.initiative_id JOIN issue ON issue.id = initiative.issue_id JOIN policy ON policy.id = issue.policy_id JOIN area ON area.id = issue.area_id JOIN unit ON area.unit_id = unit.id');
   3.252        fields.forEach( function(field) {
   3.253          query.addField(field, null, ['grouped']);
   3.254        });
   3.255        if (req.current_access_level != 'anonymous' || req.current_member_id) {
   3.256 -        query.addField('draft.author_id');
   3.257 +        query.addField('draft.author_id', null, ['grouped']);
   3.258        }
   3.259        if (params.draft_id) {
   3.260          query.addWhere('draft.id = ?', params.draft_id);
   3.261 @@ -941,17 +954,23 @@
   3.262        if (params.current_draft) {
   3.263          query.join('current_draft', null, 'current_draft.initiative_id = initiative.id AND current_draft.id = draft.id')
   3.264        }
   3.265 +      if (params.render_content == "html") {
   3.266 +        query.join('rendered_draft', null, 'rendered_draft.draft_id = draft.id AND rendered_draft.format = \'html\'');
   3.267 +        query.addField('rendered_draft.content', null, ['grouped']);
   3.268 +      } else {
   3.269 +        query.addField('draft.content', null, ['grouped']);
   3.270 +      }
   3.271        general_params.addInitiativeOptions(req, query, params);
   3.272        query.addOrderBy('draft.initiative_id, draft.id');
   3.273        general_params.addLimitAndOffset(query, params);
   3.274        db.query(conn, req, res, query, function (result, conn) {
   3.275          var result = { result: result.rows }
   3.276          includes = [];
   3.277 -        if (params.include_initiatives) includes.push({ class: 'initiative', objects: 'result'});
   3.278 -        if (params.include_issues) includes.push({ class: 'issue', objects: 'initiatives'});
   3.279 -        if (params.include_areas) includes.push({ class: 'area', objects: 'issues'});
   3.280 -        if (params.include_units) includes.push({ class: 'unit', objects: 'areas'});
   3.281 -        if (params.include_policies) includes.push({ class: 'policy', objects: 'issues' });
   3.282 +        if (params.include_initiatives) includes.push({ clazz: 'initiative', objects: 'result'});
   3.283 +        if (params.include_issues) includes.push({ clazz: 'issue', objects: 'initiatives'});
   3.284 +        if (params.include_areas) includes.push({ clazz: 'area', objects: 'issues'});
   3.285 +        if (params.include_units) includes.push({ clazz: 'unit', objects: 'areas'});
   3.286 +        if (params.include_policies) includes.push({ clazz: 'policy', objects: 'issues' });
   3.287          addRelatedData(conn, req, res, result, includes);
   3.288        });
   3.289      });
   3.290 @@ -972,11 +991,11 @@
   3.291        db.query(conn, req, res, query, function (result, conn) {
   3.292          var result = { result: result.rows }
   3.293          includes = [];
   3.294 -        if (params.include_initiatives) includes.push({ class: 'initiative', objects: 'result'});
   3.295 -        if (params.include_issues) includes.push({ class: 'issue', objects: 'initiatives'});
   3.296 -        if (params.include_areas) includes.push({ class: 'area', objects: 'issues'});
   3.297 -        if (params.include_units) includes.push({ class: 'unit', objects: 'areas'});
   3.298 -        if (params.include_policies) includes.push({ class: 'policy', objects: 'issues' });
   3.299 +        if (params.include_initiatives) includes.push({ clazz: 'initiative', objects: 'result'});
   3.300 +        if (params.include_issues) includes.push({ clazz: 'issue', objects: 'initiatives'});
   3.301 +        if (params.include_areas) includes.push({ clazz: 'area', objects: 'issues'});
   3.302 +        if (params.include_units) includes.push({ clazz: 'unit', objects: 'areas'});
   3.303 +        if (params.include_policies) includes.push({ clazz: 'policy', objects: 'issues' });
   3.304          addRelatedData(conn, req, res, result, includes);
   3.305        });
   3.306      });
   3.307 @@ -997,12 +1016,12 @@
   3.308        db.query(conn, req, res, query, function (result, conn) {
   3.309          var result = { result: result.rows }
   3.310          includes = [];
   3.311 -        if (params.include_suggestions) includes.push({ class: 'suggestion', objects: 'result'});
   3.312 -        if (params.include_initiatives) includes.push({ class: 'initiative', objects: 'suggestions'});
   3.313 -        if (params.include_issues) includes.push({ class: 'issue', objects: 'initiatives'});
   3.314 -        if (params.include_areas) includes.push({ class: 'area', objects: 'issues'});
   3.315 -        if (params.include_units) includes.push({ class: 'unit', objects: 'areas'});
   3.316 -        if (params.include_policies) includes.push({ class: 'policy', objects: 'issues' });
   3.317 +        if (params.include_suggestions) includes.push({ clazz: 'suggestion', objects: 'result'});
   3.318 +        if (params.include_initiatives) includes.push({ clazz: 'initiative', objects: 'suggestions'});
   3.319 +        if (params.include_issues) includes.push({ clazz: 'issue', objects: 'initiatives'});
   3.320 +        if (params.include_areas) includes.push({ clazz: 'area', objects: 'issues'});
   3.321 +        if (params.include_units) includes.push({ clazz: 'unit', objects: 'areas'});
   3.322 +        if (params.include_policies) includes.push({ clazz: 'policy', objects: 'issues' });
   3.323          addRelatedData(conn, req, res, result, includes);
   3.324        });
   3.325      });
   3.326 @@ -1043,12 +1062,42 @@
   3.327      });
   3.328    },
   3.329  
   3.330 +  '/voter': function (conn, req, res, params) {
   3.331 +    requireAccessLevel(conn, req, res, 'pseudonym', function() {
   3.332 +      var query = new selector.Selector();
   3.333 +      query.from('direct_voter JOIN member ON member.id = direct_voter.member_id JOIN issue ON issue.id = direct_voter.issue_id JOIN policy ON policy.id = issue.policy_id JOIN area ON area.id = issue.area_id JOIN unit ON area.unit_id = unit.id');
   3.334 +      query.addField('direct_voter.*');
   3.335 +      query.addWhere('issue.closed NOTNULL');
   3.336 +      general_params.addMemberOptions(req, query, params);
   3.337 +      general_params.addIssueOptions(req, query, params);
   3.338 +      general_params.addLimitAndOffset(query, params);
   3.339 +      db.query(conn, req, res, query, function (result, conn) {
   3.340 +        respond('json', conn, req, res, 'ok', { result: result.rows });
   3.341 +      });
   3.342 +    });
   3.343 +  },
   3.344 +
   3.345 +  '/delegating_voter': function (conn, req, res, params) {
   3.346 +    requireAccessLevel(conn, req, res, 'pseudonym', function() {
   3.347 +      var query = new selector.Selector();
   3.348 +      query.from('delegating_voter JOIN member ON member.id = delegating_voter.member_id JOIN issue ON issue.id = delegating_voter.issue_id JOIN policy ON policy.id = issue.policy_id JOIN area ON area.id = issue.area_id JOIN unit ON area.unit_id = unit.id');
   3.349 +      query.addField('delegating_voter.*');
   3.350 +      query.addWhere('issue.closed NOTNULL');
   3.351 +      general_params.addMemberOptions(req, query, params);
   3.352 +      general_params.addIssueOptions(req, query, params);
   3.353 +      general_params.addLimitAndOffset(query, params);
   3.354 +      db.query(conn, req, res, query, function (result, conn) {
   3.355 +        respond('json', conn, req, res, 'ok', { result: result.rows });
   3.356 +      });
   3.357 +    });
   3.358 +  },
   3.359 +
   3.360    '/vote': function (conn, req, res, params) {
   3.361      requireAccessLevel(conn, req, res, 'pseudonym', function() {
   3.362        var query = new selector.Selector();
   3.363        query.from('vote JOIN member ON member.id = vote.member_id JOIN initiative ON initiative.id = vote.initiative_id JOIN issue ON issue.id = initiative.issue_id JOIN policy ON policy.id = issue.policy_id JOIN area ON area.id = issue.area_id JOIN unit ON area.unit_id = unit.id');
   3.364        query.addField('vote.*');
   3.365 -      query.addWhere('issue.closed_at NOTNULL');
   3.366 +      query.addWhere('issue.closed NOTNULL');
   3.367        general_params.addMemberOptions(req, query, params);
   3.368        general_params.addInitiativeOptions(req, query, params);
   3.369        general_params.addLimitAndOffset(query, params);
   3.370 @@ -1068,16 +1117,16 @@
   3.371        });
   3.372        general_params.addMemberOptions(req, query, params);
   3.373        general_params.addInitiativeOptions(req, query, params);
   3.374 -      query.addOrderBy('event.id');
   3.375 +      query.addOrderBy('event.id DESC');
   3.376        general_params.addLimitAndOffset(query, params);
   3.377        db.query(conn, req, res, query, function (events, conn) {
   3.378          var result = { result: events.rows }
   3.379          includes = [];
   3.380 -        if (params.include_initiatives) includes.push({ class: 'initiative', objects: 'result'});
   3.381 -        if (params.include_issues) includes.push({ class: 'issue', objects: 'result'});
   3.382 -        if (params.include_areas) includes.push({ class: 'area', objects: 'issues'});
   3.383 -        if (params.include_units) includes.push({ class: 'unit', objects: 'areas'});
   3.384 -        if (params.include_policies) includes.push({ class: 'policy', objects: 'issues' });
   3.385 +        if (params.include_initiatives) includes.push({ clazz: 'initiative', objects: 'result'});
   3.386 +        if (params.include_issues) includes.push({ clazz: 'issue', objects: 'result'});
   3.387 +        if (params.include_areas) includes.push({ clazz: 'area', objects: 'issues'});
   3.388 +        if (params.include_units) includes.push({ clazz: 'unit', objects: 'areas'});
   3.389 +        if (params.include_policies) includes.push({ clazz: 'policy', objects: 'issues' });
   3.390          addRelatedData(conn, req, res, result, includes);
   3.391        });
   3.392      });
   3.393 @@ -1198,7 +1247,6 @@
   3.394  \n\
   3.395  Account ID:               " + member_id + "\n\
   3.396  Login:                    " + member_login + "\n\
   3.397 -Password:                 " + member_password + "\n\
   3.398  \n\
   3.399  \n\
   3.400  To make you able to actually access the API interface, we added the following\n\

Impressum / About Us