configure.in | 1 vote/2013-board/Makefile.am | 14 + vote/2013-board/candidates.wml | 78 +++++++++ vote/2013-board/index.wml | 59 +++++++ vote/2013-board/mkical.py | 253 ++++++++++++++++++++++++++++++++ vote/2013-board/rules.wml | 114 ++++++++++++++ vote/2013-board/timeline.ics | 72 +++++++++ vote/2013-board/voting-instructions.txt | 40 +++++ vote/Makefile.am | 2 vote/index.wml | 1 10 files changed, 633 insertions(+), 1 deletion(-)
New commits: commit 2517f21a67a1ad0967d5040b11a0a3d9ae347961 Author: Thorsten Behrens <t...@documentfoundation.org> Date: Thu Dec 5 16:46:51 2013 +0100 Create 2013 board election pages. diff --git a/configure.in b/configure.in index e285942..5567fea 100644 --- a/configure.in +++ b/configure.in @@ -19,4 +19,5 @@ vote/2011/Makefile vote/2012-confpoll/Makefile vote/2012-mc/Makefile vote/2013-confpoll/Makefile +vote/2013-board/Makefile ]) diff --git a/vote/2013-board/Makefile.am b/vote/2013-board/Makefile.am new file mode 100644 index 0000000..ebb124a --- /dev/null +++ b/vote/2013-board/Makefile.am @@ -0,0 +1,14 @@ +SUBDIRS = + +urlpath = /vote/2013-board + +page_SCRIPTS = \ + index.html \ + candidates.html\ + rules.html + +page_DATA = \ + timeline.ics + mkical.py + +include $(top_srcdir)/rules.common diff --git a/vote/2013-board/candidates.wml b/vote/2013-board/candidates.wml new file mode 100644 index 0000000..f8650f0 --- /dev/null +++ b/vote/2013-board/candidates.wml @@ -0,0 +1,78 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html> + + <head> + <title>The Document Foundation 2013 Board of Directors Election Candidates</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> + </head> + + <body> + <h1>Candidates for The Document Foundation 2013 Board of Directors Election</h1> + + <p> + Below you will find a list of candidates who are running for the + The Document Foundation Board of Directors. A short summary statement from + each candidate and a link to their full candidacy announcement is + provided to help you learn more about them. We encourage all voters + to read the full candidacy statements and related discussions on + <a href="http://listarchives.documentfoundation.org/www/discuss/">discuss@documentfoundation.org</a>. + </p> + + <p> When deciding who you should vote for, please carefully + consider the various tasks the Board of Directors must + perform. This <a href="../overview.html">overview</a> may be + helpful. Keep in mind that the board will make a number of + important decisions and will also have to perform many tasks which + might require a significant amount of time and effort and the + ability to work and communicate with other people, companies, and + the media. It is a good idea to strive for a well-balanced board + consisting of people with various backgrounds, skills, and + perspectives. </p> + + <p> + Additional elections details can be found in the + <a href="http://wiki.documentfoundation.org/CommunityBylaws">Document Foundation Bylaws</a>. + </p> + + <p> + If you have any questions, please send them to either + <a href="http://listarchives.documentfoundation.org/www/discuss/">discuss@documentfoundation.org</a> + or to us at <a + href="mailto:elections@documentfoundation.org">elections@documentfoundation.org</a>. + </p> + + <h2>Candidates for The Document Foundation Board of Directors</h2> + + <ol> + <li><strong>Joe Random Candidate</strong><br /> + Affiliation: <em>ACME</em><br /> + Full statement at <a href="http://www.mail-archive.com/discuss@documentfoundation.org/">http://www.mail-archive.com/discuss@documentfoundation.org/</a> + <blockquote> + Some 75 words of wisdom. + </blockquote> + <!-- Verified Member --> + </li> + </ol> + + <h2>Additional Elections-related Information</h2> + + <p> + Note, that according to the <a + href="http://wiki.documentfoundation.org/CommunityBylaws#Provisions_Concerning_Possible_Conflicts_of_Interest">Bylaws</a>, + there is a 3-person maximum on the number of people affiliated + with any one company that can be on the board and the deputies: + if more than 3 persons from one company get elected, only the + top 3 vote getters will get on. You will be able to vote for up + to 10 candidates of your choice, with no restrictions, except + that you cannot vote more than once for the same candidate. + </p> + + <p> + If you have any futher question, please consult the + <a href="rules.html">Rules for this election</a> or write to + <a href="mailto:electi...@documentfoundation.org">electi...@documentfoundation.org</a>. + </p> + + </body> +</html> diff --git a/vote/2013-board/index.wml b/vote/2013-board/index.wml new file mode 100644 index 0000000..a74469b --- /dev/null +++ b/vote/2013-board/index.wml @@ -0,0 +1,59 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html> + + <head> + <title>The Document Foundation 2013 Board of Directors Election</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta name="author" content="Thorsten Behrens" /> + </head> + + <body> + + <h1>The Document Foundation 2013 Board of Directors Election</h1> + + <p> + The Document Foundation Membership currently elects the Board of + Directors every other year for February, 18th. Any member can + nominate themself to run in the elections. The overall elections + process is overseen by the Membership Committee, + which can be reached + at <a href="mailto:elections@documentfoundation.org">elections@documentfoundation.org</a>. + </p> + + <p> + The elections results from the 2013 Board of Directors elections + will be archived here for public access. + </p> + + <h2>2013 Elections Materials:</h2> + <ul> + <li> + <a href="../results.php?election_id=5">Detailed election results</a> + </li> + <li> + <a href="../votes.php?election_id=5">List of all votes</a> + </li> + <li> + <a href="../vote.php?election_id=5">Interface to vote</a> + </li> + <li> + <a href="candidates.html">List of candidates for Board of Directors</a> + </li> + + <li> + <a href="http://www.documentfoundation.org/foundation/members/">List of registered voters</a> + </li> + + <li> + <a href="rules.html">Elections Rules and Timeline</a> (webcal <a + href="webcal://elections.documentfoundation.org/voting/vote/2013-board/timeline.ics">timeline</a>) + </li> + + <li> + <a href="../overview.html">Overview of the Board of Directors role</a> + </li> + </ul> + + </body> +</html> diff --git a/vote/2013-board/mkical.py b/vote/2013-board/mkical.py new file mode 100755 index 0000000..6347b4b --- /dev/null +++ b/vote/2013-board/mkical.py @@ -0,0 +1,253 @@ +#!/usr/bin/env python +''' +This Python script creates a simple iCal file based on hardcoded events +in this file. +''' + +import calendar +import datetime +import logging +import math +import os +import vobject + + +#### Configure these variables +YEAR = 2013 +CANDIDATES_OPENED_DATE = (YEAR, 10, 23) +CANDIDATES_CLOSED_DATE = (YEAR, 12, 2) +CANDIDATES_ANNOUNCED_DATE = (YEAR, 12, 6) +VOTING_OPENED_DATE = (YEAR, 12, 10) +VOTING_CLOSED_DATE = (YEAR, 12, 17) +PRELIMINARY_RESULTS_DATE = (YEAR, 12, 18) +CHALLENGE_CLOSED_DATE = (YEAR, 12, 23) + + + +### I'm sorry that these functions clutter your calendar-creating experience +### Please scroll down a bit to edit the description texts + +#### Application Data +def c(multilinestring): + ''' + A helper functions which cleans up a multiline string, so that + it doesn't contain any newlines or multiple whitespaces + ''' + stripped = [l.strip() for l in multilinestring.splitlines()] + ret = " ".join (stripped) + return ret + +def d(year, month, day): + ''' + Just a tiny wrapper around datetime.datetime to create a datetime object + ''' + return datetime.date(year, month, day) + + + +CANDIDATES_OPENED = ( + d(*CANDIDATES_OPENED_DATE), + 'Announcements and list of candidates opens', + c("""If you are a member of The Document Foundation and are interested + in running for election, you may nominate yourself by sending an + e-mail to electi...@documentfoundation.org with your name, e-mail + address, corporate affiliation (if any), and a description of why + you'd like to serve, before + %s (23:59 UTC).""" % d(*CANDIDATES_CLOSED_DATE)) + ''' + ''' + c(""" + You should also send a summary of your candidacy announcement + (75 words or less) to disc...@documentfoundation.org. """) + ''' + ''' +) + +CANDIDATES_CLOSED = ( + d(*CANDIDATES_CLOSED_DATE), + 'List of candidates closed', + CANDIDATES_OPENED[2] # Get the same text again +) + +CANDIDATES_ANNOUNCED = ( + d(*CANDIDATES_ANNOUNCED_DATE), + 'List of candidates announced', + 'You may now start to send your questions to the candidates' +) + +VOTING_OPENED = ( + d(*VOTING_OPENED_DATE), + 'Instructions to vote are sent', + 'Please read your email and follow these instructions and submit your vote by %s' % d(*VOTING_CLOSED_DATE) +) +VOTING_CLOSED = ( + d(*VOTING_CLOSED_DATE), + 'Votes must be returned', + 'Preliminary results are announced on %s' % d(*PRELIMINARY_RESULTS_DATE) +) + + +PRELIMINARY_RESULTS = ( + d(*PRELIMINARY_RESULTS_DATE), + 'Preliminary results are announced', + 'The preliminary results can be challenged until %s' % d(*CHALLENGE_CLOSED_DATE) +) + +CHALLENGE_CLOSED = ( + d(*CHALLENGE_CLOSED_DATE), + 'Challenges to the results closed', + "If there weren't any challenges, preliminary results are valid" +) + + + + +def create_ical(eventlist): + '''Generates an ical stream based on the list given as eventlist. + The list shall contain elements with a tuple with a + (date, string, string) object, serving as date when the event takes place, + summary and description respectively. + ''' + log = logging.getLogger('create_ical') + + cal = vobject.iCalendar() + cal.add('method').value = 'PUBLISH' + cal.add('calscale').value = 'GREGORIAN' + cal.add('x-wr-timezone').value = 'UTC' + + for (timestamp, summary, description) in eventlist: + log.debug('creating %s, %s', timestamp, description) + vevent = cal.add('vevent') + vevent.add('dtstart').value = timestamp + vevent.add('dtend').value = timestamp + datetime.timedelta(1) + vevent.add('summary').value = summary + vevent.add('description').value = description + + stream = cal.serialize() + return stream + + +def wraptext(s, width): + '''Wraps a string @s at @width characters. + + >>> wraptext('fooo', 2) + ['fo','oo'] + ''' + l = len(s) + nr_frames = int(math.ceil(float(l)/width)) + print nr_frames + frames = [] + for i in xrange(nr_frames): + start, end = i*width, (i+1) * width + frames.append(s[start:end]) + # One could (and prolly should) yield that + return frames + +def ordinal(n): + n = int(n) + if 10 <= n % 100 < 20: + return str(n) + 'th' + else: + return str(n) + {1 : 'st', 2 : 'nd', 3 : 'rd'}.get(n % 10, "th") + + +def cal_for_month(month, events, width=80, year=datetime.datetime.now().year): + '''Generates a textual calendar for the @month in @year. + It will return a string with the calendar on the left hand side and the + events on the right hand side. + @events shall be a list with tuples: timestamp, summary, description. + + Returns a string with the calendar + ''' + log = logging.getLogger('cal_for_month') + + cal = calendar.TextCalendar() + calstrings = cal.formatmonth(year, month, 3).splitlines() + + for (timestamp, summary, description) in events: + log.debug('creating %s, %s', timestamp, summary) + year, month, day = timestamp.year, timestamp.month, timestamp.day + maxwidth = max([len(cs) for cs in calstrings]) + rightwidth = 80 - maxwidth + for i, line in enumerate(calstrings): + needles = (" %d " % day, + " %d\n" % day) + replacement = "(%d)" % day + # Find the day so that we can highlight it and add a comment + day_in_week = False + for needle in needles: + if needle in line+"\n": + # k, this looks a bit weird but we have that corner + # case with the day being at the end of the line + # which in turn will have been split off + day_in_week = True + break # Set the needle to the found one + if day_in_week == False: # Nothing found, try next week + log.debug('Day (%d) not found in %s', day, line) + continue + else: + log.debug('Day (%d) found in %s', day, line) + new_line = (line+"\n").replace(needle, replacement).rstrip() + new_line += " %s (%s)" % (summary, ordinal(day)) + # Replace in-place for two events in the same week + # FIXME: This has bugs :-( + calstrings[i] = new_line + + return os.linesep.join(calstrings) + +def create_textcal(eventlist): + '''Generates a multiline string containing a calendar with the + events written on the side + The list shall contain elements with a tuple with a + (date, string, string) object, serving as date when the event takes place, + summary and description respectively. + ''' + log = logging.getLogger('textcal') + log.debug('Generating from %s', eventlist) + months = set(map(lambda x: x[0].month, eventlist)) + year = set(map(lambda x: x[0].year, eventlist)).pop() + + final_cal = [] + for month in months: + events = filter(lambda x: x[0].month == month, eventlist) + log.debug('Events for %d: %s', month, events) + month_cal = cal_for_month(month, events, year=year) + final_cal.append(month_cal) + + return os.linesep.join(final_cal) + +if __name__ == "__main__": + from optparse import OptionParser + parser = OptionParser("usage: %prog [options]") + parser.add_option("-l", "--loglevel", dest="loglevel", help="Sets the loglevel to one of debug, info, warn, error, critical", + default=None) + parser.add_option("-i", "--ical", + action="store_true", dest="ical", default=False, + help="print iCal file to stdout") + parser.add_option("-t", "--textcal", + action="store_true", dest="tcal", default=False, + help="print textual calendar to stdout") + (options, args) = parser.parse_args() + + loglevel = {'debug': logging.DEBUG, 'info': logging.INFO, + 'warning': logging.WARNING, 'error': logging.ERROR, + 'critical': logging.CRITICAL}.get(options.loglevel, logging.WARNING) + print loglevel + logging.basicConfig( level=loglevel ) + log = logging.getLogger() + + eventlist = [ + CANDIDATES_OPENED, + CANDIDATES_CLOSED, + CANDIDATES_ANNOUNCED, + VOTING_OPENED, + VOTING_CLOSED, + PRELIMINARY_RESULTS, + CHALLENGE_CLOSED, + ] + + if not any([options.ical, options.tcal]): + parser.error("You want to select either ical or textcal output. See --help for details") + if options.ical: + ical = create_ical( eventlist ) + print ical + if options.tcal: + tcal = create_textcal( eventlist ) + print tcal diff --git a/vote/2013-board/rules.wml b/vote/2013-board/rules.wml new file mode 100644 index 0000000..5c7e35c --- /dev/null +++ b/vote/2013-board/rules.wml @@ -0,0 +1,114 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html> + + <head> + <title>The Document Foundation 2013 Board of Directors Election Rules</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + </head> + + <body> + + <h1>Rules & Timeline for The Document Foundation 2013 Board of Directors Election</h1> + + <h2>Elections Rules</h2> + + <ol> + <li> + See the <a href="http://www.documentfoundation.org/statutes.pdf">The Document + Foundation Statutes</a> §12, II for general rules. + </li> + <li> + There are 7 board slots and 3 deputy roles that are to be filled during these elections. + </li> + + <li> +As per § 7 II of our statues, the Board's term lasts two years. The +Document Foundation has been formally incorporated on February 17, 2012, +at which day the current Board of Directors officially was set in place. +Therefore, the old board remains in charge until the end of February 17, +2014, so the new board will be in charge the day after that, which is +February 18, 2014. + </li> + + <li> +As per § 6 III, only members of the Board of Trustees of The Document +Foundation, as well as current members of any of its bodies, are +eligible to be elected into the Board of Directors, and the election is +overseen by the Membership Comittee (§ 7 II). + </li> + + <li> +The active electoral right is reserved to those who have been members of +the Board of Trustees before this announcement (§ 7 II). + </li> + + <li> +§ 6 III also states that members of the Board of Directors or their +deputies may not be members of the Membership Committee and vice versa. +This means that current members of the Membership Committee are eligible +to the elected, but would have to step down from the Membership +Committee the minute before accepting to become a member of the Board of +Directors. + </li> + + <li> +There is one more notable limitation: Per § 8 IV of the statutes, a +maximum of 1/3 members of the Board of Directors is allowed to work on +an employment basis for the same company, organization, entities, +affiliates or subdivisions. + </li> + + <li> +Nomination of candidates fulfilling the above requirements, as well as +self nomination is welcome. In total, at least seven Board of Directors +members are required, and given there are enough candidates, up to three +deputies can be elected (§ 7 II). + </li> + + <li> +Re-election of current members of the Board of Directors is explicitly +permitted (§ 7 II). + </li> + + <li> + Votes will be held confidential during the elections, but an + anonymized archive of all submitted votes will be made publicly + accessible at its conclusion. + </li> + <li> + The Document Foundation Membership Committee is + responsible for counting the votes. + </li> + </ol> + + <h2>Timeline</h2> + <ul> + <li> +2013-10-23: announcement of the elections; and start of the nomination phase + </li> + <li> +2013-12-02, 24:00 CET/UTC+1: end of the nomination phase (one week before the election starts, as per § 7 II) + </li> + <li> +2013-12-10, 00:00 CET/UTC+1: official start of the elections (at least 45 days after announcement, as per § 7 II) + </li> + <li> +2013-12-17, 24:00 CET/UTC+1: end of the elections + </li> + <li> +2013-12-18: announcement of the preliminary results + </li> + <li> +2013-12-19, 00:00 CET/UTC+1: start of the challenging phase + </li> + <li> +2013-12-23, 24:00 CET/UTC+1: end of the challenging phase + </li> + <li> +afterwards: official announcement of the final results + </li> + </ul> + + </body> +</html> diff --git a/vote/2013-board/timeline.ics b/vote/2013-board/timeline.ics new file mode 100644 index 0000000..d8f6057 --- /dev/null +++ b/vote/2013-board/timeline.ics @@ -0,0 +1,72 @@ +30 +BEGIN:VCALENDAR +VERSION:2.0 +CALSCALE:GREGORIAN +METHOD:PUBLISH +PRODID:-//PYVOBJECT//NONSGML Version 1//EN +BEGIN:VEVENT +UID:20131205t152434z-54...@thinkpad.bad.example +DTSTART;VALUE=DATE:20131023 +DTEND;VALUE=DATE:20131024 +DESCRIPTION:If you are a member of The Document Foundation and are interes + ted in running for election\, you may nominate yourself by sending an e-ma + il to electi...@documentfoundation.org with your name\, e-mail address\, c + orporate affiliation (if any)\, and a description of why you'd like to ser + ve\, before 2013-12-02 (23:59 UTC).\n You should also send a summary o + f your candidacy announcement (75 words or less) to discuss@documentfounda + tion.org.\n +SUMMARY:Announcements and list of candidates opens +END:VEVENT +BEGIN:VEVENT +UID:20131205t152434z-35...@thinkpad.bad.example +DTSTART;VALUE=DATE:20131202 +DTEND;VALUE=DATE:20131203 +DESCRIPTION:If you are a member of The Document Foundation and are interes + ted in running for election\, you may nominate yourself by sending an e-ma + il to electi...@documentfoundation.org with your name\, e-mail address\, c + orporate affiliation (if any)\, and a description of why you'd like to ser + ve\, before 2013-12-02 (23:59 UTC).\n You should also send a summary o + f your candidacy announcement (75 words or less) to discuss@documentfounda + tion.org.\n +SUMMARY:List of candidates closed +END:VEVENT +BEGIN:VEVENT +UID:20131205t152434z-26...@thinkpad.bad.example +DTSTART;VALUE=DATE:20131206 +DTEND;VALUE=DATE:20131207 +DESCRIPTION:You may now start to send your questions to the candidates +SUMMARY:List of candidates announced +END:VEVENT +BEGIN:VEVENT +UID:20131205t152434z-26...@thinkpad.bad.example +DTSTART;VALUE=DATE:20131210 +DTEND;VALUE=DATE:20131211 +DESCRIPTION:Please read your email and follow these instructions and submi + t your vote by 2013-12-17 +SUMMARY:Instructions to vote are sent +END:VEVENT +BEGIN:VEVENT +UID:20131205t152434z-27...@thinkpad.bad.example +DTSTART;VALUE=DATE:20131217 +DTEND;VALUE=DATE:20131218 +DESCRIPTION:Preliminary results are announced on 2013-12-18 +SUMMARY:Votes must be returned +END:VEVENT +BEGIN:VEVENT +UID:20131205t152434z-81...@thinkpad.bad.example +DTSTART;VALUE=DATE:20131218 +DTEND;VALUE=DATE:20131219 +DESCRIPTION:The preliminary results can be challenged until 2013-12-23 +SUMMARY:Preliminary results are announced +END:VEVENT +BEGIN:VEVENT +UID:20131205t152434z...@thinkpad.bad.example +DTSTART;VALUE=DATE:20131223 +DTEND;VALUE=DATE:20131224 +DESCRIPTION:If there weren't any challenges\, preliminary results are vali + d +SUMMARY:Challenges to the results closed +END:VEVENT +X-WR-TIMEZONE:UTC +END:VCALENDAR + diff --git a/vote/2013-board/voting-instructions.txt b/vote/2013-board/voting-instructions.txt new file mode 100644 index 0000000..d49d0d6 --- /dev/null +++ b/vote/2013-board/voting-instructions.txt @@ -0,0 +1,40 @@ +nore...@documentfoundation.org +cor.no...@documentfoundation.org +Your Document Foundation 2013 Board of Directors Voting Token + +Dear $member, + +The election of The Document Foundation Board of Directors will soon +be open. + +Voting will run from 2013-12-10, 00:00 CET/UTC+1 (Tuesday) until +2013-12-17, 24:00 CET/UTC+1. + +To vote, please go to +https://elections.documentfoundation.org/vote.php?election_id=5 +and follow the instructions there. + +A list of candidates and their reasons for running is available at +https://elections.documentfoundation.org/2013-board/candidates.html + +When instructed to do so, enter the following details: + + E-mail: $email + Vote token: $token + +The election has 4 steps - first, you must identify yourself using the +voting token above. Then select your preferred candidates in order of +preference. A third step will show you your choice, and ask you to +confirm or return to the previous step. Finally, after confirming your +choice, a unique identifier will be given to you which will allow you to +verify after the election that your vote was counted correctly. To ensure +anonymity, no link will be kept between this token and your identifiers, +so please keep this token safe. Once you have voted, you will not be able +to vote again. + +Thank you for your vote! + +Regards, + Simon Phipps + election secretary, on behalf of The Document Foundation Membership + and Elections Commitee diff --git a/vote/Makefile.am b/vote/Makefile.am index efc96ce..bc06dba 100644 --- a/vote/Makefile.am +++ b/vote/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = include 2011 2012-confpoll 2012-mc 2013-confpoll +SUBDIRS = include 2011 2012-confpoll 2012-mc 2013-confpoll 2013-board urlpath = /vote diff --git a/vote/index.wml b/vote/index.wml index f898463..59e15bd 100644 --- a/vote/index.wml +++ b/vote/index.wml @@ -39,6 +39,7 @@ <li><a href="2012-confpoll/">Material from the 2012 conference location poll</a></li> <li><a href="2012-mc/">Material from the 2012 Membership Committee Elections</a></li> <li><a href="2013-confpoll/">Material from the 2013 conference location poll</a></li> + <li><a href="2013-board/">Material from the 2013 board of directors elections</a></li> </ul> <!-- Do not close the body or html tag because we still add stuff to the footer -->
_______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits