From 54a02922f785f3f41a40b09959e66bf1f034bb2a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20P=C3=A9ters?= <fpeters@entrouvert.com>
Date: Mon, 11 Nov 2019 20:41:50 +0100
Subject: [PATCH] general: remove "vote" extension and its support code
 (#37573)

---
 extra/pyvotecore/vote_field.py | 277 --------------------------------
 extra/vote/anonymity.py        | 109 -------------
 extra/vote/ranked_items.py     | 281 ---------------------------------
 wcs/formdef.py                 |  12 +-
 wcs/forms/common.py            |   9 --
 5 files changed, 1 insertion(+), 687 deletions(-)
 delete mode 100644 extra/pyvotecore/vote_field.py
 delete mode 100644 extra/vote/anonymity.py
 delete mode 100644 extra/vote/ranked_items.py

diff --git a/extra/pyvotecore/vote_field.py b/extra/pyvotecore/vote_field.py
deleted file mode 100644
index bd3f9e7af..000000000
--- a/extra/pyvotecore/vote_field.py
+++ /dev/null
@@ -1,277 +0,0 @@
-# w.c.s. - web application for online forms
-# Copyright (C) 2005-2010  Entr'ouvert
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301  USA
-
-import random
-from quixote.html import htmltext, TemplateIO
-from wcs.qommon.form import CompositeWidget, IntWidget, WidgetList, StringWidget, \
-        CheckboxWidget, SingleSelectWidget
-from wcs.fields import WidgetField, register_field_class
-from pyvotecore import schulze_method, irv, ranked_pairs, schulze_pr, \
-        schulze_stv, schulze_npr
-
-class VoteWidget(CompositeWidget):
-    readonly = False
-
-    def __init__(self, name, value = None, elements = None, **kwargs):
-        CompositeWidget.__init__(self, name, value, **kwargs)
-        self.element_names = {}
-
-        if kwargs.has_key('title'):
-            del kwargs['title']
-        if kwargs.has_key('readonly'):
-            if kwargs['readonly']:
-                self.readonly = True
-            del kwargs['readonly']
-        if kwargs.has_key('required'):
-            if kwargs['required']:
-                self.required = True
-            del kwargs['required']
-
-        self.randomize_items = False
-        if kwargs.has_key('randomize_items'):
-            if kwargs['randomize_items']:
-                self.randomize_items = True
-            del kwargs['randomize_items']
-
-        for v in elements:
-            if type(v) is tuple:
-                title = v[1]
-                key = v[0]
-                if type(key) is int:
-                    name = 'element%d' % v[0]
-                elif type(key) in (str, htmltext):
-                    name = str('element%s' % v[0])
-                    key = str(key)
-                else:
-                    raise NotImplementedError()
-            else:
-                title = v
-                key = v
-                name = 'element%d' % len(self.element_names.keys())
-
-            if value:
-                position = value.get(key)
-            else:
-                position = None
-            self.add(IntWidget, name, title = title, value = position, size = 5, **kwargs)
-            self.element_names[name] = key
-
-        if self.randomize_items:
-            random.shuffle(self.widgets)
-
-        if self.readonly:
-            def cmp_w(x, y):
-                if x.value is None and y.value is None:
-                    return 0
-                if x.value is None:
-                    return 1
-                if y.value is None:
-                    return -1
-                return cmp(x.value, y.value)
-            self.widgets.sort(cmp_w)
-
-
-    def _parse(self, request):
-        values = {}
-        for name in self.element_names:
-            value = self.get(name)
-            values[self.element_names[name]] = value
-            if type(value) is not int:
-                self.get_widget(name).set_error(IntWidget.TYPE_ERROR)
-        self.value = values or None
-
-    def parse(self, request=None):
-        value = CompositeWidget.parse(self, request=request)
-        for widget in self.widgets:
-            if widget.has_error():
-                self.set_error(_('Some fields were not filled properly.'))
-                break
-        return value
-
-    def render_content(self):
-        r = TemplateIO(html=True)
-        r += htmltext('<ul>')
-        for widget in self.get_widgets():
-            if widget.has_error():
-                r += htmltext('<li class="error"><label>')
-            else:
-                r += htmltext('<li><label>')
-            if self.readonly:
-                widget.attrs['disabled'] = 'disabled'
-                if widget.value:
-                    r += htmltext('<input type="hidden" name="%s" value="%s" >') % (
-                            widget.name, widget.value)
-                widget.name = widget.name + 'xx'
-            r += widget.render_content()
-            r += htmltext('</label>')
-            r += widget.title
-            r += htmltext('</li>')
-        r += htmltext('</ul>')
-        return r.getvalue()
-
-METHODS = {
-        'condorcet-schulze': N_('Condorcet-Shulze'),
-        'irv': N_('Instant Run-off'),
-        'ranked_pairs': N_('Ranked pairs'),
-        'schulze-pr': N_('Schulze Proportional Ranking'),
-        'schulze-stv': N_('Schulze STV'),
-        'schulze-npr': N_('Schulze NPR'),
-        }
-
-class VoteField(WidgetField):
-    key = 'vote-field'
-    description = N_('Ranked choice vote')
-
-    items = None
-    randomize_items = True
-    widget_class = VoteWidget
-    required_winners = None
-    winner_threshold = None
-    tallying_method = 'condorcet-schulze'
-
-    def perform_more_widget_changes(self, form, kwargs, edit = True):
-        kwargs['elements'] = self.items or []
-        kwargs['randomize_items'] = self.randomize_items
-
-    def fill_admin_form(self, form):
-        WidgetField.fill_admin_form(self, form)
-        form.add(WidgetList, 'items', title = _('Items'), element_type = StringWidget,
-                value = self.items, required = True,
-                element_kwargs = {'render_br': False, 'size': 50},
-                add_element_label = _('Add item'))
-        form.add(CheckboxWidget, 'randomize_items', title = _('Randomize Items'),
-                value = self.randomize_items)
-        form.add(SingleSelectWidget, 'tallying_method', title=_('Tallying method'),
-                value=self.tallying_method,
-                options=METHODS.items())
-        form.add(IntWidget, 'required_winners', title=_('Required winners'),
-                value=self.required_winners),
-        form.add(IntWidget, 'winner_threshold', title=_('Winner threshold'),
-                value=self.winner_threshold),
-
-    def get_admin_attributes(self):
-        return WidgetField.get_admin_attributes(self) + ['items',
-                'randomize_items', 'tallying_method', 'required_winners',
-                'winner_threshold']
-
-    def get_view_value(self, value):
-        r = TemplateIO(html=True)
-        r += htmltext('<ul>')
-        items = value.items()
-        items.sort(lambda x,y: cmp(x[1], y[1]))
-        for it in items:
-            if it[1]:
-                r += htmltext('<li>%s: %s</li>') % (it[1], it[0])
-        r += htmltext('</ul>')
-        return r.getvalue()
-
-    def stats(self, values):
-        '''
-           Compute vote result using the pyvotecore library.
-        '''
-        r = TemplateIO(html = True)
-
-        votes = [x.data.get(self.id) for x in values]
-        # build ballots
-        kwargs = { 'winner_threshold': self.winner_threshold,
-                'required_winners': self.required_winners }
-        if self.tallying_method == 'condorcet-schulze':
-            votes = [{ 'count': 1, 'ballot': x } for x in votes if x]
-            method = schulze_method.SchulzeMethod
-        elif self.tallying_method == 'irv':
-            votes = [ x.items() for x in votes ]
-            votes = [ sorted(x, cmp=lambda x,y: cmp(x[1],y[1])) for x in votes ]
-            votes = [ {'count':1, 'ballot': [ a for a,b in x ] } for x in votes ]
-
-            method = irv.IRV
-        elif self.tallying_method == 'ranked_pairs':
-            votes = [{ 'count': 1, 'ballot': x } for x in votes if x]
-            method = ranked_pairs.RankedPairs
-        elif self.tallying_method == 'schulze-pr':
-            votes = [{ 'count': 1, 'ballot': x } for x in votes if x]
-            method = schulze_pr.SchulzePR
-        elif self.tallying_method == 'schulze-stv':
-            votes = [{ 'count': 1, 'ballot': x } for x in votes if x]
-            method = schulze_stv.SchulzeSTV
-        elif self.tallying_method == 'schulze-npr':
-            votes = [{ 'count': 1, 'ballot': x } for x in votes if x]
-            method = schulze_npr.SchulzeNPR
-        else:
-            raise ValueError, 'unknown method', self.tallying_method
-        # Restrain arguments
-        accepted_args = method.__init__.im_func.func_code.co_varnames
-        for key in kwargs.keys():
-            if key not in accepted_args or kwargs.get(key) is None:
-                del kwargs[key]
-        # Run vote
-        result = method(votes, **kwargs).as_dict()
-
-        r += htmltext('<h4>%s</h4>') % _('Method')
-        r += htmltext('<p>%s</p>') % _(METHODS.get(self.tallying_method))
-        if 'candidates' in result:
-            r += htmltext('<h4>%s</h4>') % _('Candidates')
-            r += htmltext('<p>%s</p>') % (', '.join(result['candidates']))
-        if 'quota' in result:
-            r += htmltext('<h4>%s</h4>') % _('Quota')
-            r += htmltext('<p>%s</p>') % result.get('quota')
-        if 'rounds' in result:
-            for i, _round in enumerate(result['rounds']):
-                r += htmltext('<h4>%s</h4><div class="round">') % (_('Round %s') % (i+1))
-                if 'loser' in _round:
-                    r += htmltext('<h5>%s</h5>') % _('Loser')
-                    r += htmltext('<p>%s</p>') % _round['loser']
-                if 'tallies' in _round:
-                    r += htmltext('<h5>%s</h5><ul>') % _('Tallies')
-                    for a, b in _round['tallies'].iteritems():
-                        r += htmltext('<li>%s: %s</li>') % (a,b)
-                    r += htmltext('</ul>')
-                if 'tied_losers' in _round:
-                    r += htmltext('<h5>%s</h5>') % _('Tied losers')
-                    r += htmltext('<p>%s</p>') % ', '.join(list(_round['tied_losers']))
-                if 'winner' in _round:
-                    r += htmltext('<h5>%s</h5>') % _('Winner')
-                    r += htmltext('<p>%s</p>') % _round['winner']
-                r += htmltext('</div>')
-        if 'pairs' in result:
-            r += htmltext('<h4>%s</h4><dl>') % _('Pairs')
-            for a, b in result['pairs'].iteritems():
-                r += htmltext('<dt>%s</dt>') % ', '.join(a)
-                r += htmltext('<dd>%s</dd>') % b
-            r += htmltext('</dl>')
-        if 'strong_pairs' in result:
-            r += htmltext('<h4>%s</h4><dl>') % _('Strong pairs')
-            for a, b in result['strong_pairs'].iteritems():
-                r += htmltext('<dt>%s</dt>') % ', '.join(a)
-                r += htmltext('<dd>%s</dd>') % b
-            r += htmltext('</dl>')
-
-        if 'winner' in result:
-            r += htmltext('<h4>%s</h4>') % _('Winner')
-            r += htmltext('<p>%s</p>') % result['winner']
-        if 'winners' in result:
-            r += htmltext('<h4>%s</h4>') % _('Winners')
-            r += htmltext('<p>%s</p>') % ', '.join(result['winners'])
-        if 'order' in result:
-            r += htmltext('<h4>%s</h4>') % _('Order')
-            r += htmltext('<p>%s</p>') % ', '.join(result['order'])
-        # FIXME: show actions
-        # import pprint
-        # r += htmltext('<pre>%s</pre>') % pprint.pformat(result)
-        return r.getvalue()
-
-register_field_class(VoteField)
diff --git a/extra/vote/anonymity.py b/extra/vote/anonymity.py
deleted file mode 100644
index 67b6c83d1..000000000
--- a/extra/vote/anonymity.py
+++ /dev/null
@@ -1,109 +0,0 @@
-# w.c.s. - web application for online forms
-# Copyright (C) 2005-2010  Entr'ouvert
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301  USA
-
-from quixote import get_publisher
-
-from wcs.fields import WidgetField, register_field_class
-from wcs.qommon.form import *
-
-class VoteAnonymityWidget(CheckboxWidget):
-    vote_anonymity = 'anonymous'
-
-    def __init__(self, name, value = None, elements = None, **kwargs):
-        if kwargs and kwargs.get('vote_anonymity'):
-            self.vote_anonymity = kwargs.get('vote_anonymity')
-        if kwargs and 'required' in kwargs:
-            del kwargs['required']
-        CheckboxWidget.__init__(self, name, value=value, elements=elements, **kwargs)
-
-    def render(self):
-        if self.vote_anonymity != 'choice':
-            # XXX: include info for user ?
-            return ''
-        return CheckboxWidget.render(self)
-
-    def render_title(self, title):
-        return CheckboxWidget.render_title(self, _('Anonymous Voting'))
-
-    def render_content(self):
-        value = True
-        if self.value:
-            if self.value[0] == 'anonymous':
-                value = True
-            else:
-                value = False
-        return htmltag('input', xml_end=True,
-                       type='checkbox',
-                       name=self.name,
-                       value='yes',
-                       checked=value and 'checked' or None,
-                       **self.attrs)
-
-    def _parse(self, request):
-        if self.vote_anonymity == 'anonymous':
-            self.value = ('anonymous', None)
-        elif self.vote_anonymity == 'public':
-            self.value = ('public', request.user.id)
-        else:
-            if type(request.form.get(self.name)) is tuple:
-                self.value = request.form.get(self.name)
-            else:
-                CheckboxWidget._parse(self, request)
-                if self.value is True:
-                    self.value = ('anonymous', None)
-                else:
-                    self.value = ('public', request.user.id)
-
-
-class VoteAnonymityField(WidgetField):
-    key = 'vote-anonymity'
-    description = N_('Vote Anonymity')
-
-    widget_class = VoteAnonymityWidget
-    vote_anonymity = 'anonymous'
-        # possible values:
-        #  'anonymous': anonymous vote
-        #  'public': public vote
-        #  'choice': anonymous or public, choice of voter
-
-    def fill_admin_form(self, form):
-        form.add(StringWidget, 'label', title = _('Label'), value = self.label,
-                required = True, size = 50)
-        form.add(SingleSelectWidget, 'vote_anonymity', title = _('Vote Anonymity'),
-                value = self.vote_anonymity,
-                options = [('anonymous', _('Anonymous Vote')),
-                    ('public', _('Public Vote')),
-                    ('choice', _('Choice of Voter'))])
-
-    def get_admin_attributes(self):
-        return ['label', 'vote_anonymity']
-
-    def perform_more_widget_changes(self, form, kwargs, edit = True):
-        kwargs['vote_anonymity'] = self.vote_anonymity
-
-    def get_view_value(self, value):
-        public = False
-        if self.vote_anonymity == 'choice':
-            if value and value[0] == 'public':
-                public = True
-        if public:
-            return get_publisher().user_class.get(value[1]).get_display_name()
-        else:
-            return _('Anonymous') # XXX: include token?
-
-register_field_class(VoteAnonymityField)
diff --git a/extra/vote/ranked_items.py b/extra/vote/ranked_items.py
deleted file mode 100644
index b975a5e69..000000000
--- a/extra/vote/ranked_items.py
+++ /dev/null
@@ -1,281 +0,0 @@
-# w.c.s. - web application for online forms
-# Copyright (C) 2005-2010  Entr'ouvert
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301  USA
-
-import random
-from quixote.html import htmltext, TemplateIO
-from wcs.qommon.form import *
-from wcs.fields import WidgetField, register_field_class
-
-class RankedItemsWidget(CompositeWidget):
-    readonly = False
-
-    def __init__(self, name, value = None, elements = None, **kwargs):
-        CompositeWidget.__init__(self, name, value, **kwargs)
-        self.element_names = {}
-
-        if kwargs.has_key('title'):
-            del kwargs['title']
-        if kwargs.has_key('readonly'):
-            if kwargs['readonly']:
-                self.readonly = True
-            del kwargs['readonly']
-        if kwargs.has_key('required'):
-            if kwargs['required']:
-                self.required = True
-            del kwargs['required']
-
-        self.randomize_items = False
-        if kwargs.has_key('randomize_items'):
-            if kwargs['randomize_items']:
-                self.randomize_items = True
-            del kwargs['randomize_items']
-
-        for v in elements:
-            if type(v) is tuple:
-                title = v[1]
-                key = v[0]
-                if type(key) is int:
-                    name = 'element%d' % v[0]
-                elif type(key) in (str, htmltext):
-                    name = str('element%s' % v[0])
-                    key = str(key)
-                else:
-                    raise NotImplementedError()
-            else:
-                title = v
-                key = v
-                name = 'element%d' % len(self.element_names.keys())
-
-            if value:
-                position = value.get(key)
-            else:
-                position = None
-            self.add(IntWidget, name, title = title, value = position, size = 5, **kwargs)
-            self.element_names[name] = key
-
-        if self.randomize_items:
-            random.shuffle(self.widgets)
-
-        if self.readonly:
-            def cmp_w(x, y):
-                if x.value is None and y.value is None:
-                    return 0
-                if x.value is None:
-                    return 1
-                if y.value is None:
-                    return -1
-                return cmp(x.value, y.value)
-            self.widgets.sort(cmp_w)
-
-
-    def _parse(self, request):
-        values = {}
-        for name in self.element_names:
-            value = self.get(name)
-            values[self.element_names[name]] = value
-            if type(value) is not int:
-                self.get_widget(name).set_error(IntWidget.TYPE_ERROR)
-        self.value = values or None
-
-    def parse(self, request=None):
-        value = CompositeWidget.parse(self, request=request)
-        for widget in self.widgets:
-            if widget.has_error():
-                self.set_error(_('Some fields were not filled properly.'))
-                break
-        return value
-
-    def render_content(self):
-        r = TemplateIO(html=True)
-        r += htmltext('<ul>')
-        for widget in self.get_widgets():
-            if widget.has_error():
-                r += htmltext('<li class="error"><label>')
-            else:
-                r += htmltext('<li><label>')
-            if self.readonly:
-                widget.attrs['disabled'] = 'disabled'
-                if widget.value:
-                    r += htmltext('<input type="hidden" name="%s" value="%s" >') % (
-                            widget.name, widget.value)
-                widget.name = widget.name + 'xx'
-            r += widget.render_content()
-            r += htmltext('</label>')
-            r += widget.title
-            r += htmltext('</li>')
-        r += htmltext('</ul>')
-        return r.getvalue()
-
-
-class RankedItemsField(WidgetField):
-    key = 'ranked-items'
-    description = N_('Ranked Items')
-
-    items = None
-    randomize_items = True
-    widget_class = RankedItemsWidget
-
-    def perform_more_widget_changes(self, form, kwargs, edit = True):
-        kwargs['elements'] = self.items or []
-        kwargs['randomize_items'] = self.randomize_items
-
-    def fill_admin_form(self, form):
-        WidgetField.fill_admin_form(self, form)
-        form.add(WidgetList, 'items', title = _('Items'), element_type = StringWidget,
-                value = self.items, required = True,
-                element_kwargs = {'render_br': False, 'size': 50},
-                add_element_label = _('Add item'))
-        form.add(CheckboxWidget, 'randomize_items', title = _('Randomize Items'),
-                value = self.randomize_items)
-
-    def get_admin_attributes(self):
-        return WidgetField.get_admin_attributes(self) + ['items', 'randomize_items']
-
-    def get_view_value(self, value):
-        r = TemplateIO(html=True)
-        r += htmltext('<ul>')
-        items = value.items()
-        items.sort(lambda x,y: cmp(x[1], y[1]))
-        for it in items:
-            if it[1]:
-                r += htmltext('<li>%s: %s</li>') % (it[1], it[0])
-        r += htmltext('</ul>')
-        return r.getvalue()
-
-    def stats(self, values):
-        r = TemplateIO(html = True)
-
-        # hardcoded to condorcet for the moment
-        candidates = self.items
-        # compute matrix
-        matrix = {}
-        for c1 in candidates:
-            matrix[c1] = {}
-            for c2 in candidates:
-                matrix[c1][c2] = 0
-        votes = [x.data.get(self.id) for x in values]
-        votes = [x for x in votes if x]
-        for vote in votes:
-            for c1 in candidates:
-                for c2 in candidates:
-                    if c1 == c2:
-                        continue
-                    vote_a = vote.get(c1)
-                    vote_b = vote.get(c2)
-                    if vote_a is None:
-                        vote_a = 99999 # XXX MAX_INT
-                    if vote_b is None:
-                        vote_b = 99999 # idem
-                    if int(vote_a) == int(vote_b):
-                        matrix[c1][c2] += 0.5
-                    elif int(vote_a) < int(vote_b):
-                        matrix[c1][c2] += 1
-        import pprint
-        pprint.pprint(matrix)
-        # compute ratings
-        ratings = {}
-        for c1 in candidates:
-            ratings[c1] = {'win': [], 'loss': [], 'tie': [], 'worst': 0}
-            for c2 in candidates:
-                if c1 == c2:
-                    continue
-                delta = matrix[c1][c2] - matrix[c2][c1]
-                if delta > 0:
-                    ratings[c1]['win'].append(c2)
-                elif delta < 0:
-                    ratings[c1]['loss'].append(c2)
-                    if delta < ratings[c1]['worst']:
-                        ratings[c1]['worst'] = -delta
-                else:
-                    ratings[c1]['tie'].append(c2)
-
-        pprint.pprint(ratings)
-
-        # compute winner
-        winners = []
-        remaining = candidates[:]
-        for c1 in remaining:
-            rating = ratings[c1]
-            winner = True
-            for loss in rating['loss']:
-                if loss not in winners:
-                    winner = False
-                    break
-            if not winner:
-                continue
-            for tie in rating['tie']:
-                if tie not in winners:
-                    winner = False
-                    break
-            if not winner:
-                continue
-            winners.append(c1)
-            remaining.remove(c1)
-            break
-        else:
-            narrowest = None
-            winners = []
-            for c2 in remaining:
-                rating = ratings[c2]
-                if narrowest is None or rating['worst'] < narrowest:
-                    narrowest = rating['worst']
-                    winners = [c2]
-                elif rating['worst'] == narrowest:
-                    winners.append(c2)
-
-        candidates.sort(lambda x,y: cmp(len(ratings[x]['win']), len(ratings[y]['win'])))
-
-        r += htmltext('<table>'
-                '<thead>'
-                '<tr>'
-                '<td></td>')
-        for c in candidates:
-            r += htmltext('<th>%s</th>' % c)
-        r += htmltext('</tr>'
-                '</thead>'
-                '<tbody>')
-        for c1 in candidates:
-            r += htmltext('<tr>'
-                    '<th>%s</th>' % c1)
-            for c2 in candidates:
-                if c2 == c1:
-                    r += htmltext('<td></td>')
-                else:
-                    if matrix[c1][c2] > matrix[c2][c1]:
-                        color = '#0f0'
-                    elif matrix[c1][c2] == matrix[c2][c1]:
-                        color = '#ff0'
-                    else:
-                        color = '#f00'
-                    r += htmltext('<td style="background: %s">' % color)
-                    r += '%.1f' % matrix[c1][c2]
-                    r += htmltext('</td>')
-            r += htmltext('</tr>')
-        r += htmltext('</tbody>'
-                '</table>'
-                '<p>')
-        r += _('Winner:')
-        r += ' '
-        r += ' '.join(winners)
-        r += htmltext('</p>')
-        return r.getvalue()
-
-register_field_class(RankedItemsField)
-
-
-
diff --git a/wcs/formdef.py b/wcs/formdef.py
index b99904a4f..08267248e 100644
--- a/wcs/formdef.py
+++ b/wcs/formdef.py
@@ -1186,17 +1186,7 @@ class FormDef(StorableObject):
     def get_detailed_email_form(self, formdata, url):
         details = []
 
-        display_username = True
-        # this is custom code so it is possible to mark forms as anonyms, this
-        # is done through the VoteAnonymity field, this is very specific but
-        # isn't generalised yet into an useful extension mechanism, as it's not
-        # clear at the moment what could be useful.
-        for f in self.fields:
-            if f.key == 'vote-anonymity':
-                display_username = False
-                break
-
-        if display_username and formdata.user_id and formdata.user:
+        if formdata.user_id and formdata.user:
             details.append(_('User name:'))
             details.append('  %s' % formdata.user.name)
             details.append('')
diff --git a/wcs/forms/common.py b/wcs/forms/common.py
index b72864cdd..dab9d7d91 100644
--- a/wcs/forms/common.py
+++ b/wcs/forms/common.py
@@ -357,15 +357,6 @@ class FormStatusPage(Directory, FormTemplateMixin):
             except KeyError:
                 user = None
 
-        # this is custom code so it is possible to mark forms as anonyms, this
-        # is done through the VoteAnonymity field, this is very specific but
-        # isn't generalised yet into an useful extension mechanism, as it's not
-        # clear at the moment what could be useful.
-        for f in self.formdef.fields:
-            if f.key == 'vote-anonymity':
-                user = None
-                break
-
         r = TemplateIO(html=True)
         klasses = 'foldable'
         if self.should_fold_summary(mine, request_user):
-- 
2.24.0

