Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fair-vote module #2555

Open
wants to merge 64 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
1c09332
fairvote module
oriyalperin Nov 2, 2023
3260e87
Modify the "fairvote" module
Nov 7, 2023
b59d4a3
database example
oriyalperin Nov 3, 2023
56d7a2f
update scss
erelsgl Nov 7, 2023
09337f2
test commit
erelsgl Nov 8, 2023
fad66fa
fair vote
oriyalperin Nov 22, 2023
2e10b87
fair vote: idea choins
oriyalperin Nov 22, 2023
3b5fd5d
fair vote: add choins to templates
oriyalperin Nov 22, 2023
d7b5da8
fair vote: new phase model
oriyalperin Nov 22, 2023
74b5b45
fair vote module
oriyalperin Dec 5, 2023
49115a2
fix typo
oriyalperin Dec 5, 2023
eada19b
db example
oriyalperin Dec 5, 2023
765a545
fair vote fetch api
oriyalperin Dec 5, 2023
e774a94
fairvote
oriyalperin Feb 11, 2024
e6deb19
Create FAIRVOTE.md
oriyalperin Feb 12, 2024
4950423
Update FAIRVOTE.md
oriyalperin Feb 12, 2024
5889ee7
Update FAIRVOTE.md
oriyalperin Feb 12, 2024
c015ddf
Update FAIRVOTE.md
oriyalperin Feb 13, 2024
07a0eec
Update FAIRVOTE.md
oriyalperin Feb 13, 2024
21fdfbb
Update FAIRVOTE.md
erelsgl Feb 13, 2024
1bed735
Update FAIRVOTE.md
erelsgl Feb 13, 2024
b98797f
settings
oriyalperin Mar 5, 2024
854a334
module tabs
oriyalperin Mar 5, 2024
ad2bacd
choin event admin
oriyalperin Mar 5, 2024
ed03169
'welcome' choin event
oriyalperin Mar 7, 2024
6e85174
fix typo and remove prints
oriyalperin Mar 7, 2024
d4532ed
style
oriyalperin Mar 7, 2024
ab538bb
fairvote
oriyalperin Mar 27, 2024
fc1a8a4
simulations
oriyalperin Mar 31, 2024
8d913a8
fix supporting other modules
oriyalperin Apr 1, 2024
9408a69
update simulations
oriyalperin Apr 9, 2024
82f806c
Move methods to 'algroithms' file
oriyalperin Apr 9, 2024
0fa6adc
Add comments
oriyalperin Apr 9, 2024
2396551
Add rating modification implementation
oriyalperin Apr 9, 2024
8176b85
Remove comment
oriyalperin Apr 9, 2024
11fd9e0
Merge branch 'fairvote' into fairvote-tests
oriyalperin Apr 9, 2024
5c5da20
fair acceptance idea
oriyalperin May 8, 2024
d3640c4
fairvote algorithms and info
oriyalperin May 8, 2024
c8ea25c
remove file
oriyalperin May 8, 2024
f5acf8a
floatformat
oriyalperin May 8, 2024
2c90878
ideas contribution
oriyalperin May 8, 2024
9a192bd
Merge branch 'liqd:main' into fairvote
oriyalperin May 8, 2024
f7e785a
fix chions update
oriyalperin May 12, 2024
641e2c0
update readme
oriyalperin May 12, 2024
f0901ff
Update README.md
oriyalperin May 15, 2024
4a19987
fix idea choins update
oriyalperin May 16, 2024
82b9a63
Comments on urls
erelsgl Aug 8, 2024
f44156b
fairvote
oriyalperin Aug 8, 2024
18f8652
Merge branch 'fairvote' of https://github.com/ariel-research/adhocrac…
oriyalperin Aug 8, 2024
65d390c
remove identation from eslint, and settings from gitignore
oriyalperin Aug 8, 2024
7f8eb26
Merge branch 'fairvote' of github.com:ariel-research/adhocracy-plus i…
erelsgl Aug 8, 2024
0b8a406
fairvote additions
oriyalperin Aug 21, 2024
342adbd
fairvote tests
oriyalperin Aug 21, 2024
531c7a1
fix error 500
erelsgl Aug 21, 2024
9a7bf64
fairvote
oriyalperin Aug 27, 2024
dff85a3
delete .env
oriyalperin Aug 27, 2024
0a64e32
fix urls.py error
oriyalperin Aug 27, 2024
e96c0a8
Update installation_ariel-res.md
erelsgl Aug 27, 2024
2edd4d2
Update installation_ariel-res.md
erelsgl Aug 27, 2024
acc6137
Update installation_ariel-res.md
erelsgl Aug 27, 2024
26fce78
Update changes_and_adjustments.md
erelsgl Aug 27, 2024
96c61de
Update changes_and_adjustments.md
erelsgl Aug 27, 2024
86f3e8e
Update changes_and_adjustments.md
erelsgl Aug 27, 2024
e959b6f
gitignore aplus-media
oriyalperin Aug 27, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ __pycache__/
*.py[cod]
*$py.class

# Images added using the wagtail interface
aplus-media


# C extensions
*.so

Expand Down Expand Up @@ -41,7 +45,7 @@ npm-debug.log*
# Django databases
*.sqlite3
db.sqlite3*

!examples-db/*
# Local instance specific settings
adhocracy-plus/config/settings/local.py

Expand Down Expand Up @@ -70,3 +74,8 @@ media/

# vim backups
*.swp
supporter_list.py
apps/fairvote/tests.py

.env
.env.save
1 change: 0 additions & 1 deletion .stylelintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@
]
}],

"indentation": 4,
"max-nesting-depth": 2,

"scale-unlimited/declaration-strict-value": ["/color/", {
Expand Down
45 changes: 45 additions & 0 deletions FAIRVOTE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Fairvote Module Overview

The **fairvote** module aims to balance majority decisions with minority rights.

As an example, suppose there are 40 users that generate various ideas related to citizen concerns. Suppose that

- 60% of users (24 individuals) are from the south districts of the city;
- 40% of users (16 individuals) are from the north districts.

Each user supports only ideas related to his or her district. Therefore, initially the south-oriented ideas appear at the top:

![South Ideas Votes](https://github.com/ariel-research/adhocracy-plus/assets/73301483/267ba19e-00ef-4587-a030-182346dd3078)
![North Ideas Votes](https://github.com/ariel-research/adhocracy-plus/assets/73301483/d10bece9-caf5-4c62-a763-d2daa062e9c5)

Suppose the project manager accepts the top idea, which is south-oriented:
![South Issue Accepted](https://github.com/ariel-research/adhocracy-plus/assets/73301483/33fa1136-e6a8-4b6f-9768-1b584d3e84d6)

The **fairvote** module then gives all users the same amount of "choins" (virtual choice-coins),
and then has the supporters of the accepted idea (the southern users) "pay" their choins for the accepted idea.

The "cost" of each idea is (arbitrarily) set to 150; in the future we will allow different costs for different ideas.
Therefore, each user receives 6.25, the southerners pay all their money to fund the idea, and the northerners remain with 6.25.

As a result, the northern users have more choins, so their supported ideas jump to the top:

![North on Top](https://github.com/ariel-research/adhocracy-plus/assets/73301483/0f11620f-4c95-45be-88b8-172450e32248)
![south-reseted](https://github.com/ariel-research/adhocracy-plus/assets/73301483/80ebf547-f9cb-476b-9283-a1baa22348de)

Near each idea, there are two numbers.

* One is the total amount of money that is held by its supporters. This amount is now 100 for the northern ideas (6.25 times 16), and 0 for the southern ideas.
* The second is the amount of money that each supporter should receive, in order to attain the cost of 150. This amount is now ~3.13 for the northern ideas ((150-100)/16), and 6.25 for the southern ideas.

Within the fairvote module, you can sort ideas by 'most fair', which means an increasing order of the amount of remaining choins needed per user (the second number above).
In our example, the northern ideas need fewer choins, so they appear at the top.

Suppose now that the project manager accepts a northern idea:
![North Issue Accepted](https://github.com/ariel-research/adhocracy-plus/assets/73301483/d744d94b-e4d3-4be5-a7fc-b442b1478c84)

The southern ideas are now on top:
![South on Top](https://github.com/ariel-research/adhocracy-plus/assets/73301483/2ae89a89-b884-4f3e-9665-09621ee50fbc)

Observe that the coins for all North ideas have been reset at this point:
![image](https://github.com/ariel-research/adhocracy-plus/assets/73301483/8e82f69a-9faf-42e8-9835-4e2ede679026)

21 changes: 12 additions & 9 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ SED = sed
ifneq (, $(shell command -v gsed;))
SED = gsed
endif

ifneq (,$(wildcard ./.env))
include .env
export
endif
.PHONY: all
all: help

Expand Down Expand Up @@ -72,13 +75,13 @@ fixtures:

.PHONY: server
server:
$(VIRTUAL_ENV)/bin/python manage.py runserver 8004
$(VIRTUAL_ENV)/bin/python manage.py runserver $(PORT)

.PHONY: watch
watch:
trap 'kill %1' KILL; \
npm run watch & \
$(VIRTUAL_ENV)/bin/python manage.py runserver 8004
$(VIRTUAL_ENV)/bin/python manage.py runserver $(HOST):$(PORT)

.PHONY: background
background:
Expand Down Expand Up @@ -179,22 +182,22 @@ release:

.PHONY: postgres-start
postgres-start:
sudo -u postgres PGDATA=pgsql PGPORT=5556 /usr/lib/postgresql/12/bin/pg_ctl start
sudo -u postgres PGDATA=pgsql PGPORT=5556 /usr/lib/postgresql/14/bin/pg_ctl start

.PHONY: postgres-stop
postgres-stop:
sudo -u postgres PGDATA=pgsql PGPORT=5556 /usr/lib/postgresql/12/bin/pg_ctl stop
sudo -u postgres PGDATA=pgsql PGPORT=5556 /usr/lib/postgresql/14/bin/pg_ctl stop

.PHONY: postgres-create
postgres-create:
if [ -d "pgsql" ]; then \
echo "postgresql has already been initialized"; \
else \
sudo install -d -m 774 -o postgres -g $(USER) pgsql; \
sudo -u postgres /usr/lib/postgresql/12/bin/initdb pgsql; \
sudo -u postgres PGDATA=pgsql PGPORT=5556 /usr/lib/postgresql/12/bin/pg_ctl start; \
sudo -u postgres PGDATA=pgsql PGPORT=5556 /usr/lib/postgresql/12/bin/createuser -s django; \
sudo -u postgres PGDATA=pgsql PGPORT=5556 /usr/lib/postgresql/12/bin/createdb -O django django; \
sudo -u postgres /usr/lib/postgresql/14/bin/initdb pgsql; \
sudo -u postgres PGDATA=pgsql PGPORT=5556 /usr/lib/postgresql/14/bin/pg_ctl start; \
sudo -u postgres PGDATA=pgsql PGPORT=5556 /usr/lib/postgresql/14/bin/createuser -s django; \
sudo -u postgres PGDATA=pgsql PGPORT=5556 /usr/lib/postgresql/14/bin/createdb -O django django; \
fi

.PHONY: local-a4
Expand Down
4 changes: 4 additions & 0 deletions adhocracy-plus/assets/images/blueprint_icons/icon-fv.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 12 additions & 0 deletions adhocracy-plus/assets/images/blueprints/fair-vote.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions adhocracy-plus/assets/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ import {
widget as ReactWidget
} from 'adhocracy4'

import { init as renderUserIdeaChoins } from '../../../apps/fairvote/assets/choins/react_user_idea_choins_init.jsx'
import { init as renderInvestedChoins } from '../../../apps/fairvote/assets/choins/react_invested_choins_init.jsx'
import { init as renderRatingChoins } from '../../../apps/fairvote/assets/ratings/react_ratings_init.jsx'

import { renderLanguageChoice } from '../../../apps/organisations/assets/react_language_choice.jsx'

function init () {
Expand All @@ -26,7 +30,11 @@ function init () {
ReactWidget.initialise('a4', 'ratings', ReactRatings.renderRatings)
ReactWidget.initialise('a4', 'reports', ReactReports.renderReports)

ReactWidget.initialise('aplus', 'ratings', renderRatingChoins)

ReactWidget.initialise('euth', 'language-choice', renderLanguageChoice)
ReactWidget.initialise('aplus', 'fv_modules', renderUserIdeaChoins)
ReactWidget.initialise('aplus', 'invested_choins', renderInvestedChoins)

$('.timeline-carousel__item').slick({
initialSlide: parseInt($('#timeline-carousel').attr('data-initial-slide')),
Expand Down
2 changes: 1 addition & 1 deletion adhocracy-plus/assets/scss/_base.scss
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ dd {

dt {
font-weight: bold;
margin-bottom: $spacer / 2;
margin-bottom: calc($spacer / 2);
margin-top: $spacer;
}

Expand Down
2 changes: 1 addition & 1 deletion adhocracy-plus/assets/scss/components/_accordion.scss
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
.accordion__title {
display: block;
position: relative;
padding: ($padding / 2) (3 * $padding) ($padding / 2) $padding;
padding: calc($padding / 2) calc(3 * $padding) calc($padding / 2) $padding;
color: inherit;
border-bottom: solid 1px $border-color;

Expand Down
4 changes: 2 additions & 2 deletions adhocracy-plus/assets/scss/components/_action.scss
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
@mixin multi-line-icon($lines, $line-height: 1.4) {
$font-size: 0.7 * $lines;
$size: $lines * $line-height / $font-size;
$size: calc($lines * $line-height / $font-size);

line-height: $size;
min-width: 1.5em;
Expand All @@ -9,7 +9,7 @@

@mixin multi-line-main($lines, $line-height: 1.4) {
$font-size: 0.7 * $lines;
$size: $lines * $line-height / $font-size;
$size: calc($lines * $line-height / $font-size);

margin-left: $size * 1em;
}
Expand Down
7 changes: 4 additions & 3 deletions adhocracy-plus/assets/scss/components/_project_header.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,17 @@
display: flex;
flex-direction: column;
justify-content: center;
text-align: center;
padding: 1.3 * $spacer 0;
text-align: right;
align-items: flex-end;
padding: $spacer (-$spacer);
margin: $spacer (-$spacer);

position: relative;

min-height: $hero-height-mobile;

@media (min-width: $breakpoint) {
min-height: ($hero-height-mobile + $hero-height-secondary) / 2;
min-height: calc(($hero-height-mobile + $hero-height-secondary) / 2);
margin: $spacer 0;
}

Expand Down
44 changes: 35 additions & 9 deletions adhocracy-plus/config/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,13 @@

from django.conf import locale
from django.utils.translation import gettext_lazy as _
from dotenv import load_dotenv

load_dotenv()

HOST = os.getenv("HOST")
PORT = os.getenv("PORT")
DOMAIN = os.getenv("DOMAIN")
CONFIG_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
PROJECT_DIR = os.path.dirname(CONFIG_DIR)
BASE_DIR = os.path.dirname(PROJECT_DIR)
Expand Down Expand Up @@ -109,6 +115,7 @@
"apps.polls",
"apps.topicprio",
"apps.debate",
"apps.fairvote",
)

MIDDLEWARE = (
Expand Down Expand Up @@ -163,11 +170,12 @@

DATABASES = {
"default": {
"ENGINE": "django.db.backends.sqlite3",
"NAME": os.path.join(BASE_DIR, "db.sqlite3"),
"TEST": {
"NAME": os.path.join(BASE_DIR, "test_db.sqlite3"),
},
"ENGINE": "django.db.backends.mysql",
"NAME": os.getenv("MYSQL_DB"),
"USER": os.getenv("MYSQL_USERNAME"),
"PASSWORD": os.getenv("MYSQL_PASS"),
"HOST": "localhost",
"PORT": "3306",
}
}

Expand All @@ -176,9 +184,9 @@
# https://docs.djangoproject.com/en/1.8/topics/i18n/

LANGUAGE_CODE = "en"
DEFAULT_USER_LANGUAGE_CODE = "de"
DEFAULT_USER_LANGUAGE_CODE = "he"

TIME_ZONE = "Europe/Berlin"
TIME_ZONE = "Asia/Jerusalem"

USE_I18N = True

Expand All @@ -191,6 +199,7 @@
("nl", _("Dutch")),
("ky", _("Kyrgyz")),
("ru", _("Russian")),
("he", _("Hebrew")),
]

# adding language info for ky
Expand All @@ -201,6 +210,12 @@
"name": "Kyrgyz",
"name_local": "Кыргызча",
},
"he": {
"dir": "rtl",
"code": "he",
"name": "Hebrew",
"name_local": "עברית",
},
}
LANG_INFO = dict(locale.LANG_INFO, **EXTRA_LANG_INFO)
locale.LANG_INFO = LANG_INFO
Expand Down Expand Up @@ -258,7 +273,12 @@
}

ALLOWED_UPLOAD_IMAGES = ("png", "jpeg", "gif")

ALLOWED_HOSTS = [HOST, DOMAIN, "localhost"]
CORS_ALLOWED_ORIGINS = [
f"http://{HOST}:{PORT}",
f"http://{HOST}:8005",
f"https://{DOMAIN}",
]

# Authentication

Expand Down Expand Up @@ -295,6 +315,11 @@
LOGIN_REDIRECT_URL = "/"

EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"
EMAIL_HOST = os.getenv("EMAIL_HOST")
EMAIL_PORT = os.getenv("EMAIL_PORT")
EMAIL_HOST_USER = os.getenv("EMAIL_HOST_USER")
EMAIL_HOST_PASSWORD = os.getenv("EMAIL_HOST_PASSWORD")
DEFAULT_FROM_EMAIL = "{} <{}>".format(os.getenv("FROM_EMAIL"), EMAIL_HOST_USER)

# Rest Framework
REST_FRAMEWORK = {
Expand Down Expand Up @@ -512,6 +537,7 @@
("IE", _("interactive event")),
("TP", _("prioritization")),
("DB", _("debate")),
("FV", _("fair-vote")),
]

A4_MAP_BASEURL = "https://{s}.tile.openstreetmap.org/"
Expand Down Expand Up @@ -559,7 +585,7 @@
CKEDITOR_5_USER_LANGUAGE = True
CKEDITOR_5_CONFIGS = {
"default": {
"language": ["de", "en", "nl", "ru"],
"language": ["he", "de", "en", "nl", "ru"],
"toolbar": [
"bold",
"italic",
Expand Down
Loading