Maemo.org team/Creating an election

(use <source> for awk script)
(Use <source> for SQL)
Line 8: Line 8:
: The schema is:
: The schema is:
-
    DROP TABLE IF EXISTS `electorate`;
+
<source lang="sql">
-
    /*!40101 SET @saved_cs_client = @@character_set_client */;
+
DROP TABLE IF EXISTS `electorate`;
-
    /*!40101 SET character_set_client = utf8 */;
+
/*!40101 SET @saved_cs_client = @@character_set_client */;
-
    CREATE TABLE `electorate` (
+
/*!40101 SET character_set_client = utf8 */;
-
    `id` int(11) NOT NULL AUTO_INCREMENT,
+
CREATE TABLE `electorate` (
-
    `username` varchar(20) DEFAULT NULL,
+
`id` int(11) NOT NULL AUTO_INCREMENT,
-
    `firstname` varchar(50) NOT NULL DEFAULT '',
+
`username` varchar(20) DEFAULT NULL,
-
    `lastname` varchar(50) NOT NULL DEFAULT '',
+
`firstname` varchar(50) NOT NULL DEFAULT '',
-
    `email` varchar(50) NOT NULL DEFAULT '',
+
`lastname` varchar(50) NOT NULL DEFAULT '',
-
    `karma` int(11) NOT NULL DEFAULT '0',
+
`email` varchar(50) NOT NULL DEFAULT '',
-
    `creation_date` datetime DEFAULT NULL,
+
`karma` int(11) NOT NULL DEFAULT '0',
-
    `talk_id` varchar(70) DEFAULT NULL,
+
`creation_date` datetime DEFAULT NULL,
-
    PRIMARY KEY (`id`)
+
`talk_id` varchar(70) DEFAULT NULL,
-
    ) ENGINE=MyISAM AUTO_INCREMENT=32822 DEFAULT CHARSET=latin1;
+
PRIMARY KEY (`id`)
-
    /*!40101 SET character_set_client = @saved_cs_client */;
+
) ENGINE=MyISAM AUTO_INCREMENT=32822 DEFAULT CHARSET=latin1;
-
    /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
+
/*!40101 SET character_set_client = @saved_cs_client */;
 +
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
 +
</source>
; Create election in the database
; Create election in the database
Line 30: Line 32:
  insert into elections values(10, 'elections', 'Maemo Community Council elections, Q3 2010', '2010-09-16 00:00:00', '2010-09-22 23:59:59', 5, 'In order of preference, which of the following candidates do you want to represent you on the Maemo Community Council?');
  insert into elections values(10, 'elections', 'Maemo Community Council elections, Q3 2010', '2010-09-16 00:00:00', '2010-09-22 23:59:59', 5, 'In order of preference, which of the following candidates do you want to represent you on the Maemo Community Council?');
   
   
-
/* Fields are id, election id, name - id is auto-increment */
+
<source lang="sql">
-
insert into election_choices values
+
/* Fields are id, election id, name - id is auto-increment */
 +
insert into election_choices values
   (0, 10, 'Andrea Grandi (andy80)'),
   (0, 10, 'Andrea Grandi (andy80)'),
   (0, 10, 'Tim Samoff (timsamoff)'),
   (0, 10, 'Tim Samoff (timsamoff)'),
Line 42: Line 45:
   (0, 10, 'Kathy Smith (revdkathy)'),
   (0, 10, 'Kathy Smith (revdkathy)'),
   (0, 10, 'Attila Csipa (achipa)')
   (0, 10, 'Attila Csipa (achipa)')
-
;
+
;
 +
</source>
; Insert electorate into database
; Insert electorate into database
: Insert the rows into your database using the following (note, we ignore the talk profile URL now, but there is still a column for it in the database):
: Insert the rows into your database using the following (note, we ignore the talk profile URL now, but there is still a column for it in the database):
-
/* Truncate old electorate table and old temp tokens */
+
 
-
truncate electorate;
+
<source lang="sql">
-
truncate election_tmp_tokens;
+
/* Truncate old electorate table and old temp tokens */
 +
truncate electorate;
 +
truncate election_tmp_tokens;
   
   
-
/* Load data file using LOAD DATA INFILE (or mysqlimport) */
+
/* Load data file using LOAD DATA INFILE (or mysqlimport) */
-
load data local infile '/path/to/data/users.csv' into table electorate
+
load data local infile '/path/to/data/users.csv' into table electorate
   fields terminated by ',' optionally enclosed by '"'
   fields terminated by ',' optionally enclosed by '"'
   (username,@dummy,firstname,lastname,@email,creation_date,karma,@talk)
   (username,@dummy,firstname,lastname,@email,creation_date,karma,@talk)
   set email=substring_index(@email,';',1),  
   set email=substring_index(@email,';',1),  
       talk_id=substring_index(@talk,'=',-1)
       talk_id=substring_index(@talk,'=',-1)
-
;
+
;
-
/* This is a complicated line, worth explaining.
+
/* This is a complicated line, worth explaining.
-
  * LOAD DATA INFILE basically does a series of inserts, one for each  
+
* LOAD DATA INFILE basically does a series of inserts, one for each  
-
  * line of data in the input file.
+
* line of data in the input file.
-
  * The part in brackets matches fields or variables to entries in the  
+
* The part in brackets matches fields or variables to entries in the  
-
  * data line, with separator, quote and line ending bevahiour as specified.
+
* data line, with separator, quote and line ending bevahiour as specified.
-
  * We drop the "Real name" field. The email field contains semi-colon
+
* We drop the "Real name" field. The email field contains semi-colon
-
  * separated list of all the email addresses associated with the account,
+
* separated list of all the email addresses associated with the account,
-
  * so we search the field for a semicolon, and just take the first one.
+
* so we search the field for a semicolon, and just take the first one.
-
  * The talk field contains a URL with a talk_id after "=", which is what we
+
* The talk field contains a URL with a talk_id after "=", which is what we
-
  *  want, so we look for = and take everything after the first occurrence.
+
*  want, so we look for = and take everything after the first occurrence.
-
  */
+
*/
   
   
-
/* Delete from electorate anyone with insufficient karma */
+
/* Delete from electorate anyone with insufficient karma */
-
delete from electorate where karma < 10;
+
delete from electorate where karma < 10;
-
/* Delete accounts created too recently (3 months before end of election) */
+
/* Delete accounts created too recently (3 months before end of election) */
-
delete from electorate where creation_date > '2010-06-23';
+
delete from electorate where creation_date > '2010-06-23';
 +
</source>
It is also possible to filter on older talk_ids, even if the maemo account was created recently. Ask Reggie for the cut-off Talk user id for the electorate date, and include the cut-off in the "delete from" for recently created accounts.
It is also possible to filter on older talk_ids, even if the maemo account was created recently. Ask Reggie for the cut-off Talk user id for the electorate date, and include the cut-off in the "delete from" for recently created accounts.

Revision as of 10:26, 7 March 2011

These are the steps required to create a new election for the Community Council - essentially the same process applies for a referendum.

Get list of maemo.org accounts
Request a dump of maemo.org accounts including karma and account creation date from Henri or Neithan at the karma cut-off date. The format for each row is:
username,"Real name",firstname,surname,emails(; separated),"join date",karma,talk profile URL
Create database if necessary
The schema is:
DROP TABLE IF EXISTS `electorate`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `electorate` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(20) DEFAULT NULL,
`firstname` varchar(50) NOT NULL DEFAULT '',
`lastname` varchar(50) NOT NULL DEFAULT '',
`email` varchar(50) NOT NULL DEFAULT '',
`karma` int(11) NOT NULL DEFAULT '0',
`creation_date` datetime DEFAULT NULL,
`talk_id` varchar(70) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=32822 DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
Create election in the database
For the Q3 2010 election, that means running the following on the maemoelections database on test.maemo.org:
/* Fields are ID, type ('elections' or 'referendum'), name, start date, end date, # of seats, question */
insert into elections values(10, 'elections', 'Maemo Community Council elections, Q3 2010', '2010-09-16 00:00:00', '2010-09-22 23:59:59', 5, 'In order of preference, which of the following candidates do you want to represent you on the Maemo Community Council?');

/* Fields are id, election id, name - id is auto-increment */
INSERT INTO election_choices VALUES
  (0, 10, 'Andrea Grandi (andy80)'),
  (0, 10, 'Tim Samoff (timsamoff)'),
  (0, 10, 'R&amp;uuml;diger Schiller (chemist)'),
  (0, 10, 'Cosimo Kroll (zehjotkah)'),
  (0, 10, 'Andrew Flegg (Jaffa)'),
  (0, 10, 'Stephen Gadsby (sjgadsby)'),
  (0, 10, 'Felipe Crochik (fcrochik)'),
  (0, 10, 'Robin Burchell (w00t)'),
  (0, 10, 'Kathy Smith (revdkathy)'),
  (0, 10, 'Attila Csipa (achipa)')
;
Insert electorate into database
Insert the rows into your database using the following (note, we ignore the talk profile URL now, but there is still a column for it in the database):
/* Truncate old electorate table and old temp tokens */
TRUNCATE electorate;
TRUNCATE election_tmp_tokens;
 
/* Load data file using LOAD DATA INFILE (or mysqlimport) */
LOAD DATA LOCAL INFILE '/path/to/data/users.csv' INTO TABLE electorate
   FIELDS terminated BY ',' OPTIONALLY ENCLOSED BY '"'
   (username,@dummy,firstname,lastname,@email,creation_date,karma,@talk)
   SET email=substring_index(@email,';',1), 
       talk_id=substring_index(@talk,'=',-1)
;
/* This is a complicated line, worth explaining.
 * LOAD DATA INFILE basically does a series of inserts, one for each 
 * line of data in the input file.
 * The part in brackets matches fields or variables to entries in the 
 * data line, with separator, quote and line ending bevahiour as specified.
 * We drop the "Real name" field. The email field contains semi-colon
 * separated list of all the email addresses associated with the account,
 * so we search the field for a semicolon, and just take the first one.
 * The talk field contains a URL with a talk_id after "=", which is what we
 *  want, so we look for = and take everything after the first occurrence.
 */
 
/* Delete from electorate anyone with insufficient karma */
DELETE FROM electorate WHERE karma < 10;
/* Delete accounts created too recently (3 months before end of election) */
DELETE FROM electorate WHERE creation_date > '2010-06-23';

It is also possible to filter on older talk_ids, even if the maemo account was created recently. Ask Reggie for the cut-off Talk user id for the electorate date, and include the cut-off in the "delete from" for recently created accounts.

Extract eligible candidates

Generating the list:

 mysql -e 'select username, firstname, lastname, karma  from electorate where karma>100 order by lastname'> eligible.txt

Awk script to generate the table:


GeSHi Error: GeSHi could not find the language awk (using path /usr/share/php-geshi/geshi/) (code 2)

You need to specify a language like this: <source lang="html4strict">...</source>

Supported languages for syntax highlighting:

abap, actionscript, actionscript3, ada, apache, applescript, apt_sources, asm, asp, autoit, avisynth, bash, basic4gl, bf, bibtex, blitzbasic, bnf, boo, c, c_mac, caddcl, cadlisp, cfdg, cfm, cil, cmake, cobol, cpp, cpp-qt, csharp, css, d, dcs, delphi, diff, div, dos, dot, eiffel, email, erlang, fo, fortran, freebasic, genero, gettext, glsl, gml, gnuplot, groovy, haskell, hq9plus, html4strict, idl, ini, inno, intercal, io, java, java5, javascript, kixtart, klonec, klonecpp, latex, lisp, locobasic, lolcode, lotusformulas, lotusscript, lscript, lsl2, lua, m68k, make, matlab, mirc, modula3, mpasm, mxml, mysql, nsis, oberon2, objc, ocaml, ocaml-brief, oobas, oracle11, oracle8, pascal, per, perl, php, php-brief, pic16, pixelbender, plsql, povray, powershell, progress, prolog, properties, providex, python, qbasic, rails, rebol, reg, robots, ruby, sas, scala, scheme, scilab, sdlbasic, smalltalk, smarty, sql, tcl, teraterm, text, thinbasic, tsql, typoscript, vb, vbnet, verilog, vhdl, vim, visualfoxpro, visualprolog, whitespace, whois, winbatch, xml, xorg_conf, xpp, z80

Generate election tokens and send out emails
Tokens and emails are created with scripts in the maemo2midgard repository - create-tmp-tokens.pl and mail-instructions.pl Database credentials are in a private local file called config.pl
We need to modify the email instructions (instructions.txt) every election with the candidate list, links to election materials, etc. First we generate the tmp tokens, insert them in the database by running the resulting file through the mysql client, and then using the instructions and the generated maildata.txt file as inputs, we mail the instructions out.
./create-tmp-tokens.pl <election_id> <tokens_file> <maildata_file>
mysql -u<dbuser> -p<dbpasswd> -h<dbhost> < <tokens_file>
./mail-instructions.pl <maildata_file> <instructions>

And we're all done! The election will run until its closing date, at which point you can generate the results

Resending tokens

Sometimes token emails get caught in spam filters, or accidentally deleted, or the first email address associated with their account is dead, or whatever. You can find the anonymous token associated with someone as long as they have not voted yet.

In a Plain Old mysql client, run the following query:

select e.id, e.username, e.firstname, e.lastname, e.email,
       t.election_id, t.tmp_token
from electorate as e, election_tmp_token as t
where e.id=t.member_id and e.username='<username>';

You can also look using "LIKE" on the username, first name or last name if you need to. This will give you the email/tmp_token pairing which the person can then use to vote, and which you can then send on to them, after verifying that they are who they say they are.