Generate your Proof of Personhood
@modal-dismissed="hideModal()">
-
-
-
.
-
-"""
-
-"""
-*********
-CONTROLLER LOGIC 4 Quadratic Lands Initial Distribution--)>
-*********
-"""
-
-import binascii
-import hashlib
-import hmac
-import json
-import logging
-import random
-
-from django.conf import settings
-from django.contrib.auth.decorators import login_required
-from django.http import Http404, HttpResponse, JsonResponse
-from django.views.decorators.http import require_http_methods
-
-import requests
-from dashboard.models import Profile
-from eth_utils import is_address, is_checksum_address, to_checksum_address
-from quadraticlands.models import (
- GTCSteward, InitialTokenDistribution, MissionStatus, QLVote, QuadLandsFAQ, SchwagCoupon,
-)
-from ratelimit.decorators import ratelimit
-
-logger = logging.getLogger(__name__)
-
-def get_FAQ(request):
- '''Get FAQ objects from the db and bundle them up to be added to faq context'''
- faq_dict = {}
- full_faq = {}
- item = {}
-
- try:
- faq = QuadLandsFAQ.objects.all()
- except Exception as e:
- logger.info(f'QuadLands - There was an issue getting FAQ DB object - {e}')
- faq = False
-
- for faq_item in faq:
- item = {
- 'question' : faq_item.question,
- 'answer' : faq_item.answer
- }
- faq_dict[str(faq_item.position)] = item
-
- full_faq['FAQ'] = faq_dict
-
- return full_faq
-
-def get_profile_from_username(request):
- '''Return profile object for a given request'''
- try:
- profile = request.user.profile
- except Exception as e:
- logger.info(f'QuadLands - There was an issue getting user profile object - {e}')
- profile = False
- return profile
-
-@require_http_methods(["GET"])
-def get_mission_status(request):
- '''Retrieve mission status/state from the DB'''
- if request.user.is_authenticated:
- profile = get_profile_from_username(request)
- try:
- mission_status = MissionStatus.objects.get(profile=profile)
-
- completed_missions = 0
- if mission_status.proof_of_use:
- completed_missions += 1
- if mission_status.proof_of_knowledge:
- completed_missions += 1
- if mission_status.proof_of_receive:
- completed_missions += 1
-
- game_state = {
- "id" : mission_status.id,
- "proof_of_use" : mission_status.proof_of_use,
- "proof_of_knowledge" : mission_status.proof_of_knowledge,
- "proof_of_receive" : mission_status.proof_of_receive,
- "completed_missions": completed_missions
- }
- return game_state
- except MissionStatus.DoesNotExist:
- pass
-
- # if state doesn't exist yet or user is not logged in
- no_game_state = {
- "id" : False,
- "proof_of_use" : False,
- "proof_of_knowledge" : False,
- "proof_of_receive" : False,
- "completed_missions": 0
- }
- return no_game_state
-
-
-def get_initial_dist(request):
- '''Accpets request, returns initial dist info from the DB in units WEI & GTC'''
- no_claim = {"total_claimable_gtc": 0, "total_claimable_wei": 0}
- if not request.user.is_authenticated:
- return no_claim
-
- profile = get_profile_from_username(request)
- try:
- initial_dist_wei = InitialTokenDistribution.objects.get(profile=profile).claim_total
- initial_dist_gtc = initial_dist_wei / 10**18
- context = {
- 'total_claimable_gtc': initial_dist_gtc,
- 'total_claimable_wei': initial_dist_wei
- }
- except InitialTokenDistribution.DoesNotExist: # if user doesn't have a token claim record in DB
- context = {
- 'total_claimable_gtc': 0,
- 'total_claimable_wei': 0
- }
- return context
-
-def get_initial_dist_breakdown(request):
- '''Accpets request, returns initial dist breakdown info from the DB'''
- profile = get_profile_from_username(request)
-
- try:
- initial_dist = InitialTokenDistribution.objects.get(profile=profile).distribution
- # logger.info(f'initial dist: {initial_dist}')
- context = {
- 'active_user': int(initial_dist["active_user"]) / 10**18,
- 'kernel': int(initial_dist["kernel"]) / 10**18,
- 'GMV': int(initial_dist["GMV"]) / 10**18
- }
- except Exception as e: # if user doesn't have a token claim record in DB
- # logger.error(f'QuadLands: Error getting initial dist: {e}')
- context = {
- 'active_user': 0,
- 'kernel': 0,
- 'GMV': 0
- }
-
- return context
-
-@login_required
-@require_http_methods(["POST"])
-@ratelimit(key='ip', rate='10/m', method=ratelimit.UNSAFE, block=True)
-def vote(request):
- '''
- Receives AJAX post from vote.html with sig,r,s,v,full_vote_msg
- Saves to DB and return 200, no data expected on return
- '''
- profile = get_profile_from_username(request)
- logger.info(f'vote save profile id: {profile.id}')
- # extract POST data
- try:
- r = request.POST.get('r')
- s = request.POST.get('s')
- v = request.POST.get('v')
- sig = request.POST.get('sig')
- string_vote_msg = request.POST.get('full_vote_msg')
- full_vote_msg = json.loads(string_vote_msg)
-
- except Exception as e:
- logger.info(f'QuadLands: There was an error getting vote post data from user: {e}')
- resp = {'vote_save': 'error 1'}
- return JsonResponse(resp, status=400)
-
- # write to DB
- try:
- voted = QLVote.objects.create(profile=profile, signature=sig, vote=full_vote_msg['message'], full_msg=full_vote_msg)
- except Exception as e:
- logger.error(f'QuadLands: Error saving vote to DB - {e}')
- resp = {'vote_save': 'error 2'}
- return JsonResponse(resp, status=400)
-
- # all good, send 200
- resp = {'vote_save': 'success'}
- return JsonResponse(resp, status=200)
-
-
-def get_stewards():
- '''Return stewards for a given request'''
- steward_dict = {}
- full_stewards = {}
- steward = {}
- try:
- # grab the stewards
- raw_stewards = GTCSteward.objects.all()
- # loop through querySet
- for s in raw_stewards:
- steward = {
- 'profile' : s.profile,
- 'real_name' : s.real_name,
- 'bio': s.bio,
- 'gtc_address' : s.gtc_address,
- 'profile_link' : s.profile_link,
- 'custom_steward_img': s.custom_steward_img
- }
- # add to dict
- steward_dict[str(s.profile)] = steward
-
- # randomize order of stewards
- steward_list = list(steward_dict.items())
- random.shuffle(steward_list)
- steward_dict = dict(steward_list)
-
- # one more dict for easy interation on UI
- full_stewards['stewards'] = steward_dict
- return full_stewards
-
- except Exception as e:
- stewards = {'stewards' : False}
- logger.info(f'QuadLands - There was an issue getting stewards from the DB - {e}')
- return stewards
-
-
-
-def get_coupon_code(request):
- '''Return coupon code if user has completed missions and has claimable GTC'''
-
- coupon_code = None
- initial_dist, game_status = get_initial_dist(request), get_mission_status(request)
- print(initial_dist)
- total_claimable_gtc = initial_dist['total_claimable_gtc']
- profile = get_profile_from_username(request)
-
- # check to ensure user has completeg missions and has gtc to claim
- if game_status['completed_missions'] < 3 or total_claimable_gtc == 0:
- return coupon_code
-
- # return coupon code is user already has been assigned
- coupon = SchwagCoupon.objects.filter(profile=profile).first()
- if coupon:
- return coupon.coupon_code
-
- total_claimable_gtc = total_claimable_gtc / (10 ** 18)
-
- # fetch empty coupons
- coupons = SchwagCoupon.objects.filter(profile__isnull=True)
- # assign coupon code based on claimable GTC tokens
- if total_claimable_gtc < 50:
- # 20% coupon
- coupon = coupons.filter(discount_type='20_off').first()
-
- elif total_claimable_gtc < 1000:
- # 40% coupon
- coupon = coupons.filter(discount_type='40_off').first()
-
- else:
- # 60% coupon
- coupon = coupons.filter(discount_type='60_off').first()
-
- if coupon:
- coupon.profile = profile
- coupon.save()
-
- return coupon.coupon_code
diff --git a/app/quadraticlands/migrations/0010_auto_20220209_1850.py b/app/quadraticlands/migrations/0010_auto_20220209_1850.py
new file mode 100644
index 00000000000..9ce83ac191f
--- /dev/null
+++ b/app/quadraticlands/migrations/0010_auto_20220209_1850.py
@@ -0,0 +1,76 @@
+# Generated by Django 2.2.24 on 2022-02-09 18:50
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('quadraticlands', '0009_game_gamefeed_gameplayer'),
+ ]
+
+ operations = [
+ migrations.RemoveField(
+ model_name='gamefeed',
+ name='game',
+ ),
+ migrations.RemoveField(
+ model_name='gamefeed',
+ name='player',
+ ),
+ migrations.RemoveField(
+ model_name='gameplayer',
+ name='game',
+ ),
+ migrations.RemoveField(
+ model_name='gameplayer',
+ name='profile',
+ ),
+ migrations.RemoveField(
+ model_name='gtcsteward',
+ name='profile',
+ ),
+ migrations.RemoveField(
+ model_name='initialtokendistribution',
+ name='profile',
+ ),
+ migrations.RemoveField(
+ model_name='missionstatus',
+ name='profile',
+ ),
+ migrations.RemoveField(
+ model_name='qlvote',
+ name='profile',
+ ),
+ migrations.DeleteModel(
+ name='QuadLandsFAQ',
+ ),
+ migrations.RemoveField(
+ model_name='schwagcoupon',
+ name='profile',
+ ),
+ migrations.DeleteModel(
+ name='Game',
+ ),
+ migrations.DeleteModel(
+ name='GameFeed',
+ ),
+ migrations.DeleteModel(
+ name='GamePlayer',
+ ),
+ migrations.DeleteModel(
+ name='GTCSteward',
+ ),
+ migrations.DeleteModel(
+ name='InitialTokenDistribution',
+ ),
+ migrations.DeleteModel(
+ name='MissionStatus',
+ ),
+ migrations.DeleteModel(
+ name='QLVote',
+ ),
+ migrations.DeleteModel(
+ name='SchwagCoupon',
+ ),
+ ]
diff --git a/app/quadraticlands/models.py b/app/quadraticlands/models.py
index 23744c91437..e4c20400093 100644
--- a/app/quadraticlands/models.py
+++ b/app/quadraticlands/models.py
@@ -31,462 +31,3 @@
from django_extensions.db.fields import AutoSlugField
from economy.models import SuperModel
-
-class Uint256Field(models.DecimalField):
- description = _("Ethereum uint256 number")
- '''
- Field to store ethereum uint256 values. Uses Decimal db type without decimals to store
- in the database, but retrieve as `int` instead of `Decimal` (https://docs.python.org/3/library/decimal.html)
- https://github.com/gnosis/gnosis-py/blob/master/gnosis/eth/django/models.py
- '''
- def __init__(self, *args, **kwargs):
- kwargs['max_digits'] = 79 # 2 ** 256 is 78 digits
- kwargs['decimal_places'] = 0
- super().__init__(*args, **kwargs)
-
- def deconstruct(self):
- name, path, args, kwargs = super().deconstruct()
- del kwargs['max_digits']
- del kwargs['decimal_places']
- return name, path, args, kwargs
-
- def from_db_value(self, value, expression, connection):
- if value is None:
- return value
- return int(value)
-
-class QuadLandsFAQ(models.Model):
- '''Table for storing quadlands FAQ items'''
- position = models.IntegerField(
- blank=False,
- unique=True
- )
- created_on = models.DateTimeField(
- auto_now=True
- )
- question = models.TextField(
- default='',
- blank=True
- )
- answer = models.TextField(
- default='',
- blank=True
- )
- def __str__(self):
- """String for representing the Model object."""
- return f'{self.question}'
-
-class InitialTokenDistribution(models.Model):
- '''Table for storing the initial gitcoin retroactive token distribution details'''
- profile = models.ForeignKey(
- 'dashboard.Profile',
- related_name='initial_distribution',
- on_delete=models.CASCADE
- )
- created_on = models.DateTimeField(
- auto_now=True
- )
- claim_total = Uint256Field(
- default=0
- )
- distribution = JSONField(
- default=dict
- )
-
- def __str__(self):
- """String for representing the Model object."""
- return f'{self.profile.handle}, {self.claim_total}, {self.created_on}, {self.distribution}'
-
-class QLVote(models.Model):
- '''Store signed messages and vote data for QL initial dist vote'''
- profile = models.ForeignKey(
- 'dashboard.Profile',
- related_name='vote_status',
- on_delete=models.CASCADE
- )
- signature = models.CharField(
- default='',
- max_length=255,
- )
- vote = JSONField(
- default=dict
- )
- full_msg = JSONField(
- default=dict
- )
- created_on = models.DateTimeField(
- auto_now=True
- )
- def __str__(self):
- """String for representing the Model object."""
- return f'{self.profile.handle}, {self.signature}, {self.vote}, {self.created_on}'
-
-
-class MissionStatus(models.Model):
- ''' Track which missions a given user has completed'''
- profile = models.ForeignKey(
- 'dashboard.Profile',
- related_name='mission_status',
- on_delete=models.CASCADE
- )
- proof_of_use = models.BooleanField(
- default=False
- )
- proof_of_receive = models.BooleanField(
- default=False
- )
- proof_of_knowledge = models.BooleanField(
- default=False
- )
- def __str__(self):
- """String for representing the Model object."""
- return f'{self.profile.handle}, {self.proof_of_use}, {self.proof_of_receive}, {self.proof_of_knowledge}'
-
-class GTCSteward(models.Model):
- '''Store data for Gitcoin Stewards'''
- profile = models.ForeignKey(
- 'dashboard.Profile',
- related_name='GTCSteward',
- on_delete=models.CASCADE
- )
- real_name = models.CharField(
- default=False,
- max_length=50
- )
- bio = models.CharField(
- default=False,
- max_length=64
- )
- gtc_address = models.CharField(
- default='0x0',
- max_length=255,
- )
- profile_link = models.URLField(
- default=False,
- max_length=255
- )
- custom_steward_img = models.ImageField(
- upload_to=get_upload_filename,
- null=True,
- blank=True,
- help_text=_('override steward image as opposed to profile avatar'),
- )
-
- def __str__(self):
- """String for representing the Model object."""
- return f'{self.profile.handle}, {self.real_name}, {self.bio}, {self.gtc_address}, {self.profile_link}'
-
-
-class SchwagCoupon(models.Model):
- '''Coupon Code for users who have completed missions'''
- DISCOUNT_TYPE = [
- ('20_off', '20 OFF'),
- ('40_off', '40 OFF'),
- ('60_off', '60 OFF'),
- ]
- profile = models.ForeignKey(
- 'dashboard.Profile',
- on_delete=models.CASCADE,
- null=True,
- blank=True,
- help_text=_('profile which has claimed the coupon'),
- )
- coupon_code = models.CharField(
- default=False,
- max_length=20,
- help_text=_('actual coupon code'),
- )
- discount_type = models.CharField(
- max_length=10,
- choices=DISCOUNT_TYPE,
- help_text="discount"
- )
-
- def __str__(self):
- """String for representing the Model object."""
- return f'{self.discount_type}, {self.coupon_code}, {self.profile}'
-
-def create_game_helper(handle, title):
- game = Game.objects.create(
- _type = 'diplomacy',
- title = title,
- )
- player = GamePlayer.objects.create(
- game = game,
- profile = Profile.objects.get(handle=handle),
- active = True,
- admin = True
- )
- game.players.add(player)
-
- GameFeed.objects.create(
- game=game,
- player=player,
- data={
- 'action': 'created the game',
- },
- )
- game.add_player(player.profile.handle)
- return game
-
-class Game(SuperModel):
-
- title = models.CharField(max_length=500, blank=True)
- _type = models.CharField(
- default='',
- db_index=True,
- max_length=255,
- )
- uuid=models.UUIDField(default=uuid.uuid4, unique=True)
- slug = AutoSlugField(populate_from='title')
-
- def players_text(self):
- return ", ".join([player.profile.handle for player in self.players.all()])
-
- def get_absolute_url(self):
- return f'/quadraticlands/mission/diplomacy/{self.uuid}/{self.slug}'
-
- @property
- def url(self):
- return self.get_absolute_url()
-
- @property
- def relative_url(self):
- return self.get_absolute_url()[1:]
-
- @property
- def gtc_used(self):
- return self.current_votes_total
-
- @property
- def reverse_feed(self):
- return self.feed.all().order_by('-created_on')
-
- @property
- def sybil_created(self):
- amount = self.current_votes_total * 0.007 # estimate of the GTC to trust bonus ratio
- return amount
-
- def is_active_player(self, handle):
- return self.active_players.filter(profile__handle=handle).exists()
-
- def add_player(self, handle):
- profile = Profile.objects.get(handle=handle)
- if not self.is_active_player(handle):
- GamePlayer.objects.create(profile=profile, active=True, game=self)
-
- return GameFeed.objects.create(
- game=self,
- player=self.players.get(profile__handle=handle),
- data={
- 'action': 'joined',
- },
- )
-
- def remove_player(self, handle):
- player = self.players.filter(profile__handle=handle).first()
- player.active = False
- player.save()
-
- return GameFeed.objects.create(
- game=self,
- player=self.players.get(profile__handle=handle),
- data={
- 'action': 'left the game',
- },
- )
-
- if player.admin:
- player.admin = False
- player.save()
-
- # promote someone new to admin
- self.promote_admin()
-
- def promote_admin(self):
- if not self.active_players.exists():
- return False
-
- player = self.active_players.first()
- return GameFeed.objects.create(
- game=self,
- player=player,
- data={
- 'action': 'was promoted to admin',
- },
- )
-
- def make_move(self, handle, package):
-
- gf = GameFeed.objects.create(
- game=self,
- player=self.players.get(profile__handle=handle),
- data={
- 'action': 'vouched',
- 'package': package,
- },
- )
- for player in self.active_players.all():
- player.save()
- return gf
-
- def chat(self, handle, chat):
-
- return GameFeed.objects.create(
- game=self,
- player=self.players.get(profile__handle=handle),
- data={
- 'action': 'chatted',
- 'chat': chat,
- },
- )
-
- def leave_game(self, handle):
-
- return GameFeed.objects.create(
- game=self,
- player=self.players.get(profile__handle=handle),
- data={
- 'action': 'left the game',
- },
- )
-
- def __str__(self):
- return self.title
-
-
- @property
- def admin(self):
- return self.players.filter(admin=True).first()
-
- @property
- def current_votes_total(self):
- return sum(player.tokens_in for player in self.active_players.all())
-
- @property
- def active_players(self):
- return self.players.filter(active=True)
-
- @property
- def active_players_by_rank(self):
- return self.active_players.order_by('-cached_data__tokens_in')
-
-
-@receiver(pre_save, sender=Game, dispatch_uid="psave_game")
-def psave_game(sender, instance, **kwargs):
- pass
-
-class GameFeed(SuperModel):
-
- game = models.ForeignKey(
- 'quadraticlands.Game',
- related_name='feed',
- null=True,
- on_delete=models.CASCADE,
- help_text=_('Link to Game')
- )
- player = models.ForeignKey(
- 'quadraticlands.GamePlayer',
- related_name='game_feed',
- on_delete=models.CASCADE,
- help_text=_('The game feed update creators\'s profile.'),
- null=True,
- )
- action = models.CharField(
- default='',
- max_length=255,
- blank=True,
- db_index=True,
- )
- data = JSONField(default=dict)
-
-
- def __str__(self):
- return f"{self.game}, {self.player.profile.handle}: {self.data}"
-
- def votes(self):
- if self.data['action'] != 'vouched':
- return []
- return self.data.get('package',{}).get('moves',{}).get('votes',[])
-
-@receiver(pre_save, sender=GameFeed, dispatch_uid="psave_gf")
-def psave_gf(sender, instance, **kwargs):
- instance.action = instance.data['action']
-
-class GamePlayer(SuperModel):
-
- game = models.ForeignKey(
- 'quadraticlands.Game',
- related_name='players',
- on_delete=models.CASCADE,
- help_text=_('The Game')
- )
- profile = models.ForeignKey(
- 'dashboard.Profile',
- related_name='players',
- on_delete=models.CASCADE,
- help_text=_('The player of the game.'),
- )
- admin = models.BooleanField(
- default=False
- )
- active = models.BooleanField(
- default=False
- )
- cached_data = JSONField(default=dict, blank=True)
-
- def __str__(self):
- return f"{self.game} / {self.profile.handle} / Admin: {self.admin} / Active: {self.active}"
-
- @property
- def last_action(self):
- return self.game.feed.filter(player=self).order_by('-created_on').first()
-
- @property
- def last_move(self):
- return self.game.feed.filter(player=self, action='vouched').order_by('-created_on').first()
-
- def votes(self):
- if self.data['action'] != 'vouched':
- return []
- return self.data.get('package',{}).get('moves',{}).get('votes',[])
-
-
- @property
- def votes_in(self):
- return self.cached_data['votes_in']
-
- @property
- def tokens_in(self):
- return self.cached_data['tokens_in']
-
- @property
- def tokens_out(self):
- return self.cached_data['tokens_out']
-
- def compute_votes_in(self):
- return_dict = {
-
- }
- for player in self.game.active_players:
- return_dict[player.profile.handle] = 0
- last_move = player.last_move
- if last_move:
- for vote in last_move.votes():
- if vote['username'] == self.profile.handle:
- return_dict[player.profile.handle] += float(vote['value'])
- return return_dict
-
- def compute_tokens_in(self):
- return sum(ele for key, ele in self.votes_in.items())
-
- def compute_tokens_out(self):
- if not self.last_move:
- return 0
- return sum(float(ele['value']) for ele in self.last_move.votes())
-
-@receiver(pre_save, sender=GamePlayer, dispatch_uid="psave_gp")
-def psave_gp(sender, instance, **kwargs):
- instance.cached_data['votes_in'] = instance.compute_votes_in()
- instance.cached_data['tokens_out'] = instance.compute_tokens_out()
- instance.cached_data['tokens_in'] = instance.compute_tokens_in()
diff --git a/app/quadraticlands/router.py b/app/quadraticlands/router.py
deleted file mode 100644
index c8bf7264a8d..00000000000
--- a/app/quadraticlands/router.py
+++ /dev/null
@@ -1,39 +0,0 @@
-# -*- coding: utf-8 -*-
-"""Define dashboard specific DRF API routes.
-
-Copyright (C) 2021 Gitcoin Core
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU Affero General Public License as published
-by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
-
-You should have received a copy of the GNU Affero General Public License
-along with this program. If not, see .
-
-"""
-from quadraticlands.serializer import GTCStewardSerializer
-from rest_framework import routers, viewsets
-from rest_framework.pagination import PageNumberPagination
-
-from .models import GTCSteward
-
-
-class GTCStewardPagination(PageNumberPagination):
- page_size = 30
- page_size_query_param = 'page_size'
-
-
-class GTCStewardViewSet(viewsets.ModelViewSet):
- queryset = GTCSteward.objects.all()
- serializer_class = GTCStewardSerializer
- pagination_class = GTCStewardPagination
-
-
-router = routers.DefaultRouter()
-router.register(r'stewards', GTCStewardViewSet)
diff --git a/app/quadraticlands/scripts/ingest_coupons.py b/app/quadraticlands/scripts/ingest_coupons.py
deleted file mode 100644
index 30628aeb82a..00000000000
--- a/app/quadraticlands/scripts/ingest_coupons.py
+++ /dev/null
@@ -1,36 +0,0 @@
-###
-# Script is used to populate the coupon into SchwagCoupon
-# run form same directory as the csv file with something like:
-# docker-compose exec web python3 app/manage.py runscript ingest_coupons.py
-#
-####
-
-import csv
-import os
-from decimal import Decimal
-
-from quadraticlands.models import SchwagCoupon # imports the model
-
-path = './app/quadraticlands'
-os.chdir(path)
-
-# SchwagCoupon.objects.all().delete() # clear the table
-
-def ingest(path, discount_type):
- with open(path) as csvfile:
- reader = csv.DictReader(csvfile)
- for row in reader:
- try:
- coupon = SchwagCoupon(coupon_code=row['Code'], discount_type=discount_type)
- coupon.save()
- except Exception as error:
- print(f"Unable to ingest coupon: {row['Code']}. Error: {error}")
-
-
-ingest('scripts/20_off_coupons.csv', '20_off')
-ingest('scripts/40_off_coupons.csv', '40_off')
-ingest('scripts/60_off_coupons.csv', '60_off')
-
-print('Coupons Ingested')
-
-exit()
diff --git a/app/quadraticlands/scripts/ingest_faq.py b/app/quadraticlands/scripts/ingest_faq.py
deleted file mode 100644
index 18807192774..00000000000
--- a/app/quadraticlands/scripts/ingest_faq.py
+++ /dev/null
@@ -1,101 +0,0 @@
-###
-# Script is used to populate QuadLandsFAQ
-# docker-compose exec web python3 app/manage.py runscript ingest_coupons.py
-#
-####
-
-from quadraticlands.models import QuadLandsFAQ # imports the model
-
-QuadLandsFAQ.objects.all().delete() # clear the table
-
-faqs = [
- {
- 'position': '1',
- 'question': 'Why is Gitcoin launching a token?',
- 'answer': '''
The short answer is we know we need to decentralize, and GTC is the best way to do that. Increasingly, more people and projects are using Gitcoin to build and fund digital public goods, and as Gitcoin becomes more popular we are faced with governance questions.
-
-
We do not want to be a centralized arbiter, making decisions best left to the community. So we launched GTC to allow the community to actively participate in governing Gitcoin.
'''
- },
- {
- 'position': '2',
- 'question': 'What is the GTC Issuance?',
- 'answer': '''
100mm tokens:
-
-
50% allocated to the Community Treasury (future builders).
-
50% allocated to active community members, team members, and investors (past builders).
.'''
- },
- {
- 'position': '3',
- 'question': 'How do I claim my tokens?',
- 'answer': "Follow the instructions here."
- },
- {
- 'position': '4',
- 'question': 'Why don’t I have tokens?',
- 'answer': "Tokens were airdropped to people who have been active on Gitcoin.co through bounties, hackathons, and grants. If this describes you but you didn’t receive tokens and you think that’s in error, please reach out to the Gitcoin Team in Discord."
- },
- {
- 'position': '5',
- 'question': 'What types of things can the community govern with GTC?',
- 'answer': 'At first, the community will be able to decide things that have to do with Gitcoin Grants Rounds, like round size and ratification. Gradually the community will govern all aspects of Gitcoin including product features and how the treasury will be allocated.'
- },
- {
- 'position': '6',
- 'question': 'What is the Gitcoin Stewards Delegation Program?',
- 'answer': '''
So far one of the biggest challenges of DAO governance is maintaining an active community, which is crucial for legitimacy. To that end, Gitcoin is launching a liquid democracy through a Stewardship Delegation program. How it works:
-
-
GTC holders have voting rights proportional to the amount of tokens they hold. They may assign their voting rights to community Stewards to vote on their behalf, without giving up their tokens
-
Stewards are active community members who participate in governance. Their influence is directly determined by the community. The more voting rights assigned to them, the more trust the community has in their stewardship.
-
Some of Ethereum’s most trusted members have volunteered to be the first Gitcoin Stewards, but anyone may become a Steward simply by accepting voting rights.
'''
- },
- {
- 'position': '7',
- 'question': 'Tell me more about Stewardship.',
- 'answer': '''
The Gitcoin Governance ecosystem is a delegated voting system (liquid democracy) which allows token holders to delegate their voting power to someone else. Community members who have had tokens delegated to them are Stewards, and may vote in on/off chain governance proposals.
-
-
Token holders may delegate their voting power to themselves if they wish to participate as Stewards. Stewards who alone or with a group meet quorum (1mm token supply) may submit governance proposals that call for a vote.
'''
- },
- {
- 'position': '9',
- 'question': 'How do I get involved in governance?',
- 'answer': '''Join Discord to engage with the community. If you have tokens, delegate them to a community Steward or to yourself if you wish to participate as a Steward. Discuss governance proposals on gov.gitcoin.co, or vote on Snapshot Snapshot, or Tally.'''
- },
- {
- 'position': '10',
- 'question': 'What are governance workstreams?',
- 'answer': '''These are working groups created around objectives. At the start there will be four workstreams: Public Goods Funding, Ant-Fraud Detection, Progressive Decentralization, and Special Projects. Workstreams will be created/archived as community Stewards see fit. For a larger discussion around Stewards and workstreams, please visit gov.gitcoin.co.'''
- },
- {
- 'position': '11',
- 'question': 'What is GitcoinDAO?',
- 'answer': 'GitcoinDAO is the community governed org that will be responsible for the future of Gitcoin. We hope it’s the vessel that will take us to Quadratic Lands, the ideal future state where public goods are democratically allocated and appropriately funded.'
- },
- {
- 'position': '12',
- 'question': 'Will you eventually dissolve Gitcoin as a company?',
- 'answer': 'Maybe. Or maybe Gitcoin Holdings will continue on, curating grants or collections. Who knows? But governance over the Gitcoin treasury will eventually be handed over to the community.'
- }
-]
-
-
-for faq in faqs:
- _faq = QuadLandsFAQ(
- position = faq['position'],
- question = faq['question'],
- answer = faq['answer'],
- )
- _faq.save()
-
-
-print('FAQs Ingested')
-
-exit()
diff --git a/app/quadraticlands/scripts/ingest_stewards.py b/app/quadraticlands/scripts/ingest_stewards.py
deleted file mode 100644
index a9a27c048d6..00000000000
--- a/app/quadraticlands/scripts/ingest_stewards.py
+++ /dev/null
@@ -1,55 +0,0 @@
-###
-# Script is used to populate the stewards into GTCSteward
-# run form same directory as the csv file with something like:
-# docker-compose exec web python3 app/manage.py runscript ingest_steward.py
-#
-####
-
-import csv
-import os
-from decimal import Decimal
-from urllib.request import urlopen
-
-from django.core.files import File
-from django.core.files.temp import NamedTemporaryFile
-
-from dashboard.models import Profile
-from quadraticlands.models import GTCSteward # imports the model
-
-path = './app/quadraticlands'
-os.chdir(path)
-
-GTCSteward.objects.all().delete() # clear the table
-
-def ingest(path):
- with open(path) as csvfile:
- reader = csv.DictReader(csvfile)
- for row in reader:
- try:
- image_url = row['image']
- img_temp = NamedTemporaryFile(delete = True)
- img_temp.write(urlopen(image_url).read())
- img_temp.flush()
-
-
- handle=row['handle']
- profile = Profile.objects.get(handle=handle)
- steward = GTCSteward(
- profile=profile,
- real_name=row['real_name'],
- bio=row['bio'],
- gtc_address=row['gtc_address'],
- profile_link=row['profile_link'],
- custom_steward_img = File(img_temp)
- )
- steward.save()
- except Exception as error:
- print(f"Unable to ingest steward: {row['handle']}. Error: {error}")
-
-
-ingest('scripts/stewards.csv')
-
-
-print('Stewards Ingested')
-
-exit()
diff --git a/app/quadraticlands/scripts/intial_dist.py b/app/quadraticlands/scripts/intial_dist.py
deleted file mode 100644
index 8142eda757a..00000000000
--- a/app/quadraticlands/scripts/intial_dist.py
+++ /dev/null
@@ -1,41 +0,0 @@
-###
-# Script is used to populate the initial token distribution in the DB
-# run form same directory as the initial_dist.csv file with something like:
-# docker-compose exec web python3 app/manage.py runscript initial_dist.py
-#
-####
-# from quadraticlands.models import InitialTokenDistribution
-# from dashboard.models import Profile
-import csv
-import os
-from decimal import Decimal
-
-from dashboard.models import Profile # import profile model
-from quadraticlands.models import InitialTokenDistribution # imports the model
-
-path = './app/quadraticlands'
-os.chdir(path)
-
-InitialTokenDistribution.objects.all().delete() # clear the table
-
-with open('scripts/initial_dist.csv') as csvfile:
- reader = csv.DictReader(csvfile)
- for row in reader:
- try:
- # grab the user_id and amount
- user_id = int(row['user_id'])
- amount_in_wei = Decimal(row['total'])
- dist = {
- "active_user": row['active_user'],
- "kernel": row['kernel'],
- "GMV": row['GMV']
- }
- # get the profile for this user_id
- p = Profile.objects.get(id=user_id)
- # create the record
- c = InitialTokenDistribution(profile=p, claim_total=amount_in_wei, distribution=dist) # create initial dist record
- # save record
- c.save()
- except Exception as error:
- print(f"User: {row['handle']} - {row['user_id']} was not added. Error: {error}")
-exit()
diff --git a/app/quadraticlands/scripts/stewards.csv b/app/quadraticlands/scripts/stewards.csv
deleted file mode 100644
index 3d04adfb711..00000000000
--- a/app/quadraticlands/scripts/stewards.csv
+++ /dev/null
@@ -1,40 +0,0 @@
-handle,real_name,bio,gtc_address,profile_link,image
-yalormewn,Yalor Arnold,https://gov.gitcoin.co/t/introducing-stewards-governance/41/2,0x66b1De0f14a0ce971F7f248415063D44CAF19398,https://gitcoin.co/yalormewn,https://sjc2.discourse-cdn.com/standard11/user_avatar/gov.gitcoin.co/yalor/120/39_2.png
-anettrolikova,Anett Rolikova,https://gov.gitcoin.co/t/introducing-stewards-governance/41/3,0x16D2AD8Cc04888b537bB7B631715335a901B57cA,https://gitcoin.co/anettrolikova,https://sjc2.discourse-cdn.com/standard11/user_avatar/gov.gitcoin.co/anett/120/22_2.png
-lefterisjp,Lefteris Karapetsas,https://gov.gitcoin.co/t/introducing-stewards-governance/41/4,0x2b888954421b424c5d3d9ce9bb67c9bd47537d12,https://gitcoin.co/lefterisjp,https://sjc2.discourse-cdn.com/standard11/user_avatar/gov.gitcoin.co/lefterisjp/120/24_2.png
-simona-pop,Simona Pop,https://gov.gitcoin.co/t/introducing-stewards-governance/41/5,0x54becc7560a7be76d72ed76a1f5fee6c5a2a7ab6,https://gitcoin.co/simona-pop,https://sjc2.discourse-cdn.com/standard11/user_avatar/gov.gitcoin.co/pop/120/23_2.png
-linda-xie,Linda Xie,https://gov.gitcoin.co/t/introducing-stewards-governance/41/6,0x5e349eca2dc61aBCd9dD99Ce94d04136151a09Ee,https://gitcoin.co/linda-xie,https://sjc2.discourse-cdn.com/standard11/user_avatar/gov.gitcoin.co/linda/120/26_2.png
-amsos,Aaron,https://gov.gitcoin.co/t/introducing-stewards-governance/41/7,0x58f123BD4261EA25955B362Be57D89F4B6E7110a,https://gitcoin.co/amsos,https://sjc2.discourse-cdn.com/standard11/user_avatar/gov.gitcoin.co/amsos/120/25_2.png
-muskaankalra24,Muskan Kalra,https://gov.gitcoin.co/t/introducing-stewards-governance/41/8,0x4Bc519F0b7b348FaE780Afb2DD4aa76841bA8e9e,https://gitcoin.co/muskaankalra24,https://avatars.discourse-cdn.com/v4/letter/m/7ea924/120.png
-fireeyesxyz,Cooper Turley,https://gov.gitcoin.co/t/introducing-stewards-governance/41/9,0xD23aff9aD562C445BCaB03321CBfE63bf4b0BcF2,https://gitcoin.co/fireeyesxyz,https://sjc2.discourse-cdn.com/standard11/user_avatar/gov.gitcoin.co/coopahtroopa/120/28_2.png
-mrbrucespringsteen,Matt Stephenson,https://gov.gitcoin.co/t/introducing-stewards-governance/41/10,0x5BA02f4Ff6Af1d9d2Af8774D10fD32Eb57d4E2E6,https://gitcoin.co/mrbrucespringsteen,https://sjc2.discourse-cdn.com/standard11/user_avatar/gov.gitcoin.co/planckmatt/120/29_2.png
-pet3r-pan,Peter,https://gov.gitcoin.co/t/introducing-stewards-governance/41/11,0x71553dF14eFe2708BF16734AAB821af239A24d3B,https://gitcoin.co/pet3r-pan,https://sjc2.discourse-cdn.com/standard11/user_avatar/gov.gitcoin.co/pet3rpan/120/30_2.png
-tvanepps,Trenton Van Epps,https://gov.gitcoin.co/t/introducing-stewards-governance/41/12,0x4C0a466DF0628FE8699051b3Ac6506653191cc21,https://gitcoin.co/tvanepps,https://sjc2.discourse-cdn.com/standard11/user_avatar/gov.gitcoin.co/trent/120/32_2.png
-anneconnelly,Anne Connelly,https://gov.gitcoin.co/t/introducing-stewards-governance/41/13,0xA30Ab83e693Ad49F3F651085DaD11d049c818923,https://gitcoin.co/anneconnelly,https://sjc2.discourse-cdn.com/standard11/user_avatar/gov.gitcoin.co/anneconnelly/120/34_2.png
-nkennethk,Kenneth Ng,https://gov.gitcoin.co/t/introducing-stewards-governance/41/14,0xa2bf1b0a7e079767b4701b5a1d9d5700eb42d1d1,https://gitcoin.co/nkennethk,https://sjc2.discourse-cdn.com/standard11/user_avatar/gov.gitcoin.co/ken/120/36_2.png
-ubipromoter,Philip Silva,https://gov.gitcoin.co/t/introducing-stewards-governance/41/15,0xd9ffaF2e880dF0cc7B7104e9E789d281a81824cf,https://gitcoin.co/ubipromoter,https://sjc2.discourse-cdn.com/standard11/user_avatar/gov.gitcoin.co/ubipromoter/120/38_2.png
-tjayrush,Thomas Jay Rush,https://gov.gitcoin.co/t/introducing-stewards-governance/41/16,0xf503017d7baf7fbc0fff7492b751025c6a78179b,https://gitcoin.co/tjayrush,https://sjc2.discourse-cdn.com/standard11/user_avatar/gov.gitcoin.co/tjayrush/120/41_2.png
-makoto,Makoto Inoue,https://gov.gitcoin.co/t/introducing-stewards-governance/41/17,0x5a384227b65fa093dec03ec34e111db80a040615,https://gitcoin.co/makoto,https://sjc2.discourse-cdn.com/standard11/user_avatar/gov.gitcoin.co/makoto/120/42_2.png
-andytudhope,Andy Tudhope,https://gov.gitcoin.co/t/introducing-stewards-governance/41/18,0x31482858561725b74b5ec2a739e447bc74cdf7b9,https://gitcoin.co/andytudhope,https://sjc2.discourse-cdn.com/standard11/user_avatar/gov.gitcoin.co/cryptowanderer/120/44_2.png
-adamstallard,Adam Stallard,https://gov.gitcoin.co/t/introducing-stewards-governance/41/19,0xdC0046B52e2E38AEe2271B6171ebb65cCD337518,https://gitcoin.co/adamstallard,https://sjc2.discourse-cdn.com/standard11/user_avatar/gov.gitcoin.co/castall/120/45_2.png
-jordanlyall,Jordan Lyall,https://gov.gitcoin.co/t/introducing-stewards-governance/41/20,0xcf88fa6ee6d111b04be9b06ef6fad6bd6691b88c,https://gitcoin.co/jordanlyall,https://sjc2.discourse-cdn.com/standard11/user_avatar/gov.gitcoin.co/jordanlyall/120/58_2.png
-hello-shreyas,Shreyas Hariharan,https://gov.gitcoin.co/t/introducing-stewards-governance/41/21,0x10D6d2e343281D388291A3e02f3293AaEdA67178,https://gitcoin.co/hello-shreyas,https://sjc2.discourse-cdn.com/standard11/user_avatar/gov.gitcoin.co/helloshreyas/120/50_2.png
-auryn-macmillan,Auryn Macmillan,https://gov.gitcoin.co/t/introducing-stewards-governance/41/22,0x8B405dBf2F30844B608b08DaD20447A6955A6C6E,https://gitcoin.co/auryn-macmillan,https://sjc2.discourse-cdn.com/standard11/user_avatar/gov.gitcoin.co/auryn/120/66_2.png
-anish-agnihotri,Anish Agnihotri,https://gov.gitcoin.co/t/introducing-stewards-governance/41/23,0x016c8780e5ccb32e5caa342a926794ce64d9c364,https://gitcoin.co/anish-agnihotri,https://sjc2.discourse-cdn.com/standard11/user_avatar/gov.gitcoin.co/anishagnihotri/120/65_2.png
-peth-yursick,,https://gov.gitcoin.co/t/introducing-stewards-governance/41/25,0xb53b0255895c4f9e3a185e484e5b674bccfbc076,https://gitcoin.co/peth-yursick,https://sjc2.discourse-cdn.com/standard11/user_avatar/gov.gitcoin.co/peth/120/74_2.png
-androolloyd,Andrew Lloyd,https://gov.gitcoin.co/t/introducing-stewards-governance/41/26,0x86d3ee9ff0983bc33b93cc8983371a500f873446,https://gitcoin.co/androolloyd,https://sjc2.discourse-cdn.com/standard11/user_avatar/gov.gitcoin.co/androolloyd/120/75_2.png
-opolist,John Paller,https://gov.gitcoin.co/t/introducing-stewards-governance/41/27,0x7221b104fba7701084759fd25faca19ac6300855,https://gitcoin.co/Opolist,https://avatars.discourse-cdn.com/v4/letter/b/838e76/120.png
-griffgreen,Griff Green,https://gov.gitcoin.co/t/introducing-stewards-governance/41/28,0x839395e20bbB182fa440d08F850E6c7A8f6F0780,https://gitcoin.co/GriffGreen,https://sjc2.discourse-cdn.com/standard11/user_avatar/gov.gitcoin.co/griff/120/82_2.png
-waffi1998,,https://gov.gitcoin.co/t/introducing-stewards-governance/41/29,0x35EFa46f22e0fb34Cd8cb3DDF87149140D444b7c,https://gitcoin.co/waffi1998,https://avatars.discourse-cdn.com/v4/letter/s/bb73d2/120.png
-niran,Niran Babalola,https://gov.gitcoin.co/t/introducing-stewards-governance/41/30,0x02Eb89D2ff910989024e19673f8302a695bBD979,https://gitcoin.co/niran,https://sjc2.discourse-cdn.com/standard11/user_avatar/gov.gitcoin.co/niran/120/85_2.png
-austintgriffith,Austin Griffith,https://gov.gitcoin.co/t/introducing-stewards-governance/41/31,0x34aa3f359a9d614239015126635ce7732c18fdf3,https://gitcoin.co/austintgriffith,https://sjc2.discourse-cdn.com/standard11/user_avatar/gov.gitcoin.co/austingriffith/120/37_2.png
-amy-jung,Amy Jung,https://gov.gitcoin.co/t/introducing-stewards-governance/41/32,0x73186b2a81952c2340c4eb2e74e89869e1183df0,https://gitcoin.co/amy-jung,https://avatars.discourse-cdn.com/v4/letter/a/4da419/120.png
-cpstl,Charles St.Louis,https://gov.gitcoin.co/t/introducing-stewards-governance/41/33,0x88cCA876eEBB2A541ED87584F189319c3441Aca6,https://gitcoin.co/cpstl,https://sjc2.discourse-cdn.com/standard11/user_avatar/gov.gitcoin.co/cpstl/120/40_2.png
-johncpalmer,John Palmer,https://gov.gitcoin.co/t/introducing-stewards-governance/41/35,0xb0623c91c65621df716ab8afe5f66656b21a9108,https://gitcoin.co/johncpalmer,https://avatars.discourse-cdn.com/v4/letter/j/b19c9b/120.png
-mangorocoro,Daniel Hwang,https://gov.gitcoin.co/t/introducing-stewards-governance/41/36,0xc3fAb4228Ce462653DbF0BB3e4f3FDd81697FEc4,https://gitcoin.co/mangorocoro,https://sjc2.discourse-cdn.com/standard11/user_avatar/gov.gitcoin.co/dan/120/109_2.png
-martz,Chris Martz,https://gov.gitcoin.co/t/introducing-stewards-governance/41/37,0x224e69025A2f705C8f31EFB6694398f8Fd09ac5C,https://gitcoin.co/martz,https://avatars.discourse-cdn.com/v4/letter/m/2bfe46/120.png
-zakcole,Zak Cole,https://gov.gitcoin.co/t/introducing-stewards-governance/41/38,0x554c5af96e9e3c05aec01ce18221d0dd25975ab4,https://gitcoin.co/zakcole,https://avatars.discourse-cdn.com/v4/letter/z/8edcca/120.png
-tobyshorin,Toby Shorin,https://gov.gitcoin.co/t/introducing-stewards-governance/41/39,0xc7e6bbf6dbe78b40640385e73dc1958f4428fb3e,https://gitcoin.co/tobyshorin,https://sjc2.discourse-cdn.com/standard11/user_avatar/gov.gitcoin.co/toby/120/110_2.png
-octopus,,https://gov.gitcoin.co/t/introducing-stewards-governance/41/40,0x77d40c87D423eFb7ec576e80998A48377Adf86dF,https://gitcoin.co/octopus,https://avatars.discourse-cdn.com/v4/letter/o/ebca7d/120.png
-phutchins,Philip Hutchins,https://gov.gitcoin.co/t/introducing-stewards-governance/41/41,0x6BF1EBa9740441D0A8822EDa4E116a74f850d81B,https://gitcoin.co/phutchins,https://sjc2.discourse-cdn.com/standard11/user_avatar/gov.gitcoin.co/phutchins/120/95_2.png
-ntnsndr,Nathan Schneider,https://gov.gitcoin.co/t/introducing-stewards-governance/41/42,0x6375885ce997543cc7e057fe9af3e255d52fb4f4,https://gitcoin.co/ntnsndr,https://sjc2.discourse-cdn.com/standard11/user_avatar/gov.gitcoin.co/ntnsndr/120/118_2.png
\ No newline at end of file
diff --git a/app/quadraticlands/serializer.py b/app/quadraticlands/serializer.py
deleted file mode 100644
index 36fb161f844..00000000000
--- a/app/quadraticlands/serializer.py
+++ /dev/null
@@ -1,15 +0,0 @@
-from dashboard.models import ProfileSerializer
-from rest_flex_fields import FlexFieldsModelSerializer
-
-from .models import GTCSteward
-
-
-class GTCStewardSerializer(FlexFieldsModelSerializer):
- """Handle serializing of GTCSteward"""
- class Meta:
- """Define the GrantCLR serializer metadata."""
- model = GTCSteward
- fields = ('profile', 'real_name', 'bio', 'gtc_address', 'profile_link', 'custom_steward_img')
- expandable_fields = {
- 'profile': ProfileSerializer
- }
diff --git a/app/quadraticlands/templates/quadraticlands/_inlinesvg/arrow.svg b/app/quadraticlands/templates/quadraticlands/_inlinesvg/arrow.svg
deleted file mode 100644
index 1284b9751f5..00000000000
--- a/app/quadraticlands/templates/quadraticlands/_inlinesvg/arrow.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
diff --git a/app/quadraticlands/templates/quadraticlands/_inlinesvg/arrow_down.svg b/app/quadraticlands/templates/quadraticlands/_inlinesvg/arrow_down.svg
deleted file mode 100644
index a7ae2ec0738..00000000000
--- a/app/quadraticlands/templates/quadraticlands/_inlinesvg/arrow_down.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/app/quadraticlands/templates/quadraticlands/_inlinesvg/arrow_up.svg b/app/quadraticlands/templates/quadraticlands/_inlinesvg/arrow_up.svg
deleted file mode 100644
index a354a7adc90..00000000000
--- a/app/quadraticlands/templates/quadraticlands/_inlinesvg/arrow_up.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/app/quadraticlands/templates/quadraticlands/_inlinesvg/burger.svg b/app/quadraticlands/templates/quadraticlands/_inlinesvg/burger.svg
deleted file mode 100644
index 6abb37d0e03..00000000000
--- a/app/quadraticlands/templates/quadraticlands/_inlinesvg/burger.svg
+++ /dev/null
@@ -1,2 +0,0 @@
-
\ No newline at end of file
diff --git a/app/quadraticlands/templates/quadraticlands/_inlinesvg/close.svg b/app/quadraticlands/templates/quadraticlands/_inlinesvg/close.svg
deleted file mode 100644
index 9828ea452d5..00000000000
--- a/app/quadraticlands/templates/quadraticlands/_inlinesvg/close.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/app/quadraticlands/templates/quadraticlands/_inlinesvg/disconnect.svg b/app/quadraticlands/templates/quadraticlands/_inlinesvg/disconnect.svg
deleted file mode 100644
index 903d13241c0..00000000000
--- a/app/quadraticlands/templates/quadraticlands/_inlinesvg/disconnect.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/app/quadraticlands/templates/quadraticlands/_inlinesvg/done.svg b/app/quadraticlands/templates/quadraticlands/_inlinesvg/done.svg
deleted file mode 100644
index b5433bda351..00000000000
--- a/app/quadraticlands/templates/quadraticlands/_inlinesvg/done.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
diff --git a/app/quadraticlands/templates/quadraticlands/_inlinesvg/footersocial/discord.svg b/app/quadraticlands/templates/quadraticlands/_inlinesvg/footersocial/discord.svg
deleted file mode 100644
index f92f507f3f0..00000000000
--- a/app/quadraticlands/templates/quadraticlands/_inlinesvg/footersocial/discord.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/app/quadraticlands/templates/quadraticlands/_inlinesvg/footersocial/email.svg b/app/quadraticlands/templates/quadraticlands/_inlinesvg/footersocial/email.svg
deleted file mode 100644
index ca937955487..00000000000
--- a/app/quadraticlands/templates/quadraticlands/_inlinesvg/footersocial/email.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/app/quadraticlands/templates/quadraticlands/_inlinesvg/footersocial/facebook.svg b/app/quadraticlands/templates/quadraticlands/_inlinesvg/footersocial/facebook.svg
deleted file mode 100644
index a7f2803dc66..00000000000
--- a/app/quadraticlands/templates/quadraticlands/_inlinesvg/footersocial/facebook.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/app/quadraticlands/templates/quadraticlands/_inlinesvg/footersocial/github.svg b/app/quadraticlands/templates/quadraticlands/_inlinesvg/footersocial/github.svg
deleted file mode 100644
index 169e43c178f..00000000000
--- a/app/quadraticlands/templates/quadraticlands/_inlinesvg/footersocial/github.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/app/quadraticlands/templates/quadraticlands/_inlinesvg/footersocial/twitter.svg b/app/quadraticlands/templates/quadraticlands/_inlinesvg/footersocial/twitter.svg
deleted file mode 100644
index 053e09a0bcf..00000000000
--- a/app/quadraticlands/templates/quadraticlands/_inlinesvg/footersocial/twitter.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/app/quadraticlands/templates/quadraticlands/_inlinesvg/footersocial/youtube.svg b/app/quadraticlands/templates/quadraticlands/_inlinesvg/footersocial/youtube.svg
deleted file mode 100644
index 065415b960b..00000000000
--- a/app/quadraticlands/templates/quadraticlands/_inlinesvg/footersocial/youtube.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/app/quadraticlands/templates/quadraticlands/_inlinesvg/gtctoken.svg b/app/quadraticlands/templates/quadraticlands/_inlinesvg/gtctoken.svg
deleted file mode 100644
index 725acd9c9a3..00000000000
--- a/app/quadraticlands/templates/quadraticlands/_inlinesvg/gtctoken.svg
+++ /dev/null
@@ -1,4 +0,0 @@
-
diff --git a/app/quadraticlands/templates/quadraticlands/_inlinesvg/hero-about.svg b/app/quadraticlands/templates/quadraticlands/_inlinesvg/hero-about.svg
deleted file mode 100644
index 5494eedb68b..00000000000
--- a/app/quadraticlands/templates/quadraticlands/_inlinesvg/hero-about.svg
+++ /dev/null
@@ -1,205 +0,0 @@
-
\ No newline at end of file
diff --git a/app/quadraticlands/templates/quadraticlands/_inlinesvg/hero-diplomacy.svg b/app/quadraticlands/templates/quadraticlands/_inlinesvg/hero-diplomacy.svg
deleted file mode 100644
index b966ecbd0ca..00000000000
--- a/app/quadraticlands/templates/quadraticlands/_inlinesvg/hero-diplomacy.svg
+++ /dev/null
@@ -1,86 +0,0 @@
-
\ No newline at end of file
diff --git a/app/quadraticlands/templates/quadraticlands/_inlinesvg/hero-workstream.svg b/app/quadraticlands/templates/quadraticlands/_inlinesvg/hero-workstream.svg
deleted file mode 100644
index e33a7492ac4..00000000000
--- a/app/quadraticlands/templates/quadraticlands/_inlinesvg/hero-workstream.svg
+++ /dev/null
@@ -1,94 +0,0 @@
-
diff --git a/app/quadraticlands/templates/quadraticlands/_inlinesvg/hero_town.svg b/app/quadraticlands/templates/quadraticlands/_inlinesvg/hero_town.svg
deleted file mode 100644
index 9cdc7e14ce5..00000000000
--- a/app/quadraticlands/templates/quadraticlands/_inlinesvg/hero_town.svg
+++ /dev/null
@@ -1,1171 +0,0 @@
-
-
diff --git a/app/quadraticlands/templates/quadraticlands/_inlinesvg/logo_arrow.svg b/app/quadraticlands/templates/quadraticlands/_inlinesvg/logo_arrow.svg
deleted file mode 100644
index 1dcc5e71c78..00000000000
--- a/app/quadraticlands/templates/quadraticlands/_inlinesvg/logo_arrow.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
diff --git a/app/quadraticlands/templates/quadraticlands/_inlinesvg/logo_gitcoin.svg b/app/quadraticlands/templates/quadraticlands/_inlinesvg/logo_gitcoin.svg
deleted file mode 100644
index 23a35dcdca6..00000000000
--- a/app/quadraticlands/templates/quadraticlands/_inlinesvg/logo_gitcoin.svg
+++ /dev/null
@@ -1,4 +0,0 @@
-
diff --git a/app/quadraticlands/templates/quadraticlands/_inlinesvg/ql.svg b/app/quadraticlands/templates/quadraticlands/_inlinesvg/ql.svg
deleted file mode 100644
index 4b99e204e04..00000000000
--- a/app/quadraticlands/templates/quadraticlands/_inlinesvg/ql.svg
+++ /dev/null
@@ -1,50 +0,0 @@
-
\ No newline at end of file
diff --git a/app/quadraticlands/templates/quadraticlands/_inlinesvg/rhombus.svg b/app/quadraticlands/templates/quadraticlands/_inlinesvg/rhombus.svg
deleted file mode 100644
index 1dac4d2dad2..00000000000
--- a/app/quadraticlands/templates/quadraticlands/_inlinesvg/rhombus.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
diff --git a/app/quadraticlands/templates/quadraticlands/_inlinesvg/spinner.svg b/app/quadraticlands/templates/quadraticlands/_inlinesvg/spinner.svg
deleted file mode 100644
index e7e57c90bac..00000000000
--- a/app/quadraticlands/templates/quadraticlands/_inlinesvg/spinner.svg
+++ /dev/null
@@ -1,8 +0,0 @@
-
\ No newline at end of file
diff --git a/app/quadraticlands/templates/quadraticlands/_inlinesvg/town.svg b/app/quadraticlands/templates/quadraticlands/_inlinesvg/town.svg
deleted file mode 100644
index 21b850e0b9f..00000000000
--- a/app/quadraticlands/templates/quadraticlands/_inlinesvg/town.svg
+++ /dev/null
@@ -1,927 +0,0 @@
-
-
-
diff --git a/app/quadraticlands/templates/quadraticlands/_inlinesvg/wallet.svg b/app/quadraticlands/templates/quadraticlands/_inlinesvg/wallet.svg
deleted file mode 100644
index 9e878ebaff0..00000000000
--- a/app/quadraticlands/templates/quadraticlands/_inlinesvg/wallet.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/app/quadraticlands/templates/quadraticlands/about.html b/app/quadraticlands/templates/quadraticlands/about.html
deleted file mode 100644
index 6c2e11835d6..00000000000
--- a/app/quadraticlands/templates/quadraticlands/about.html
+++ /dev/null
@@ -1,209 +0,0 @@
-{% extends 'quadraticlands/components/base.html' %}
-{% load humanize static i18n %}
-
-
-{% block 'twittercard' %}
-
-
-
-
-
-{% endblock %}
-
-
-{% block 'content' %}
-
-
-
-
-
-
-
-
- {% include "quadraticlands/_inlinesvg/hero-about.svg" %}
-
-
-
-
Govern Gitcoin with GTC
-
-
-
-
-
-
-
-
-
-
-
About GTC
-
GTC is the governance token we’re using to decentralize Gitcoin into a DAO (GitcoinDAO) ecosystem, collectively working to fund the next generation of public goods.
-
-
GitcoinDAO aims to be the best place to collectively build and fund our digital infrastructure. With our ecosystem partners, we want to help create the biggest and boldest experiments in open source, and double down on what works. We are:
-
-
-
-
building a community that cares about public goods
-
designing & launching experiments
-
supporting & scaling them
-
collectively governing them
-
-
-
-
In order to facilitate this, we are working with the community to build GitcoinDAO—the decentralized organization building the vessel to the Quadratic Lands: a better world for public goods and digital democracy.
-
-
Holders of the token will help guide Gitcoin’s direction as we move from a partially centralized Web2.5 platform to a completely decentralized protocol. Our first step is turning over governance of Gitcoin Grants to community stewards, but over time increasingly more decisions will be left entirely in the community’s hands.
-
-
Want to get involved in governance? Join a workstream here!
-
-
-
-
-
-
-
-
-
-
-
-
-
-
How it Works
-
-
-
-
The Gitcoin governance ecosystem is built around GTC, which leverages a COMP/UNI style governance that makes on-chain voting, snapshot voting and community led governance possible. At its base layer, GTC is a standard ERC20-style token with a 100mm supply. 50% of the token supply has been allocated to those who have provided value to the ecosystem in the past (community members, investors and the existing team), and 50% will be unlocked for the community to manage in the future.
-
At launch, GitcoinDAO has an even split between past Gitcoin builders and participants, and future ones. The tokens reserved for future builders will be held in treasury, governed by community stewards and then ultimately the DAO.
We have had the support of some of the best in the space to bring this roadmap to life.
-
-
-
-
-
-
-
-
Epoch 1
-
-
-
#Launch
-
GTC is launched
-
-
-
Epoch 2
-
-
-
#Short Term
-
GitcoinDAO workstreams take shape
-
-
-
Epoch 3
-
-
-
#Medium Term
-
Implementation of ideas from workstreams
-
Community led proposals to solve Sybil
-
Community led decentralization of Gitcoin Grants
-
-
-
Epoch 4
-
-
-
#Medium-Long Term
-
Continue growing an amazing community for experiments in open source funding
-
-
-
-
Epoch 5
-
-
-
#Long Term
-
Become the best place to collectively build and fund our digital infrastructure
-
Meme the Quadratic Lands into existence
-
-
-
-
-
-
-
-
-
-
-
-{% endblock %}
-
-
-
-{% block 'scripts' %}
-
-
-
-
-
-
-
-{% endblock %}
diff --git a/app/quadraticlands/templates/quadraticlands/components/base.html b/app/quadraticlands/templates/quadraticlands/components/base.html
deleted file mode 100644
index c1fc61f967a..00000000000
--- a/app/quadraticlands/templates/quadraticlands/components/base.html
+++ /dev/null
@@ -1,77 +0,0 @@
-{% comment %}
- Copyright (C) 2020 Gitcoin Core
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see .
-{% endcomment %}
-
-{% load i18n static %}
-
-
-
-
-
- {% include 'quadraticlands/components/head.html' %}
- {% block 'twittercard' %}{% endblock %}
-
- {% include 'shared/tag_manager_1.html' %}
-
-
-
-
-
- {% include 'quadraticlands/components/flashmessage.html' %}
-
-
- {% include 'quadraticlands/components/nav.html' %}
-
-
- {% if user.is_authenticated %}
- {% include 'quadraticlands/components/wallet-provider.html' %}
- {% endif %}
-
-
- {% block 'content' %}
- {% endblock %}
-
-
- {% include 'quadraticlands/components/footersocial.html' %}
-
-
- {% include 'quadraticlands/components/footer.html' %}
-
-
- {% include 'quadraticlands/components/footer_scripts.html' %}
-
-
- {% include 'quadraticlands/components/cookielaw.html' %}
-
-
- {% include 'shared/tag_manager_2.html' %}
-
-
-
-{% block 'scripts' %}
-{% endblock %}
-
-
\ No newline at end of file
diff --git a/app/quadraticlands/templates/quadraticlands/components/cookielaw.html b/app/quadraticlands/templates/quadraticlands/components/cookielaw.html
deleted file mode 100644
index 96b4a25319b..00000000000
--- a/app/quadraticlands/templates/quadraticlands/components/cookielaw.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{% load i18n %}
-
GTC is a governance token with no economic value.
-
-
- GTC governs Gitcoin, where we work to decentralize grants, manage disputes, and govern the treasury. With your help, we’re accelerating progress towards the mission of building & funding digital public goods and decentralizing from web2 to web3. Let’s see what this thing can do.
-
We believe that Gitcoin’s future is a community-centric, self-governing DAO that generates funding for public goods. GTC is the first step on our path towards progressive decentralization of Gitcoin. Each voice in the community has the power to shape our future.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#Quadratic Voting
-
Where you’ll always have a voice
-
Quadratic Funding (QF) is the mathematically optimal way to fund public goods in a democratic community because it prohibits whales and central power brokers from controlling the ecosystem. This distributes power back to each community member.
-
-
- Similarly, Quadratic Voting (QV) is an optimal mechanism for democratic governance. Implementing QV for governance is a proposed milestone on Gitcoin’s decentralization timeline.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#Information Age
-
Powering Public Goods in the Information Age
-
Open Source Software is a public good. Its funding is one of the information age’s most critical, yet unsolved coordination problems. It is in Gitcoin's DNA to build & fund the open web, and we are committed to solving this problem. We aspire to demonstrate a sustainable & decentralized model for building public goods.
-
-
-
-
-
-
-
-
-
-
-
-
#Earn your first Tokens
-
Welcome to the Quadratic Lands
-
Complete your first mission, “Proof of Knowledge,” to git your distribution of GTC.
- {% for player in invite.active_players %}
-
- {% endfor %}
-
-
- {% endif %}
-
- {% if not games %}
- You have no game, and also no active games.
-
-
- Create a game below, or ask your mates for an invite to theirs.
-
- {% endif %}
-
- {% for game in games %}
-
-
-
{{game.title}}{{game.active_players.count}}
-
Created by @{{game.admin.profile.handle}}.
-
-
- {% for player in game.active_players %}
-
- {% endfor %}
-
This room was created {{game.created_on | naturaltime}} by @{{game.admin.profile.handle}} and has {{game.active_players.count}} members. It represents {{game.gtc_used}} of GTC and has created {{game.sybil_created}} PersonHoodScore of Sybil Resistence on Gitcoin.
-
-
-
-
-
-
Members
-
-
-
-
-
-
- {% for player in game.active_players_by_rank.all %}
-
-
-
-
@{{player.profile.handle}}
-
{{player.tokens_in}}
-
{{player.tokens_out}}
-
-
-
-
- {% for username, value in player.votes_in.items %}
-
@{{username}}{{value}}
- {% endfor %}
-
-
- {% if player.last_move %}
- {% for vote in player.last_move.votes %}
-
- One of the founding myths of Ethereum is about creating coordination games with transparent rules that can't change on you.
-
- Gitcoin is a vessel for this founding myth, a means for the community to get to the Quadratic Lands.
-
- As a way of evangelizing this great promise of Ethereum, we'd like to invite you to join us celebrating the great promise of Ethereum through these memes, media, & mechanisms.
-
-
-
-
-
-
1. Ethereum 4 Public Goods Comic Book
-
-
- As a way of evangelizing this great promise of Ethereum, the Gitcoin core team commissioned a comic book. The storyline of this comic is the Etherum community can coming together to fight Moloch - the God of coordination failures.
-
-
-
- We asked Ethereum community member @songadaymann to write a song about the founding myth of Ethereum, and how we might solve the problem of coordination.
-
-
GTC is a governance token, and the vehicle we’ll use to fully decentralize Gitcoin — eventually
- into a community governed GitcoinDAO
-
-
While the GitcoinDAO is an end in itself, it is also a means to another end: To chart a course to the Quadratic
- Lands- a place where communities are empowered to build for the common good.
-
-
-
-
We envision the Quadratic Lands as this place
-
There are numerous opportunities to create financial sovereignty while working side-by-side with people who
- share similar values.
-
Individuals have sovereignty to make their own choices, but incentives are aligned for cooperation that
- generates both individual and community benefit.
-
The economic infrastructure is a set of economic games with transparent rules that cannot be changed on us.
-
Because of composability of blockchain-based systems, the surface area of opportunity is growing exponentially
- as the tools compound upon each other.
-
-
How to use this postcard tool:
-
- Step 1: Write your text
-
-
- Step 2: Hit submit to update the text
-
-
- Step 3: Screen shot both the front and back
-
-
- Step 4: tweet out both sides - you can even do it in a thread. One image per tweet!
-
- Thank you for being a part of the Gitcoin Community.
-
-
- Now that you've claimed your GTC tokens, we would like to gift a discount coupon code
- which you can use to at the Gitcoin Schwag Store.
-
Digital public goods like the ones we’re building in web3 will one day be ubiquitous, and Gitcoin’s mission is to build and fund them. But right now, Gitcoin’s products are crypto-aware but not fully decentralized. We call this Web 2.5
-
-
But Gitcoin should not be a centralized pillar of a decentralized ecosystem, and mature experiments for public goods funding should ultimately be run on credibly neutral technology. From 2021-2025, we will be actively working to decentralize Gitcoin. This means building fully decentralized new web experiences, and eventually turning over every Gitcoin Company managed property to a community-run DAO. Join this working group to help decentralize Gitcoin!
-
-
-
-
-
Example Quests:
-
Help define the architecture for the next iteration of Gitcoin Grants and beyond
-
Work with anti-sybil and other workstreams to ensure any solutions we come up with meet a strong definition of “sufficient decentralization”
-
Build out L2 interfaces for Gitcoin Grants, eventually replacing the Web2.5 grants experience entirely.
-
Create a core set of APIs that the community can use to build on top of Gitcoin
-
- {% include "quadraticlands/_inlinesvg/hero-workstream.svg" %}
-
-
-
-
Workstreams
-
-
-
-
-
-
-
-
-
-
-
Git Involved in building GitcoinDAO
-
GitcoinDAO aims to be the best place to collectively build and fund our digital infrastructure.
-
-
-
- With our ecosystem partners, we want to help create the biggest and boldest experiments in open source, and double down on what works. We are:
-
-
-
-
-
building a community that cares about public goods
-
designing & launching experiments
-
supporting & scaling them
-
collectively governing them
-
-
-
-
-
In order to facilitate this, we are working with the community to find stewards who have the mastery, autonomy, and purpose to create GitcoinDAO—the decentralized organization building the vessel to the Quadratic Lands: a better world for public goods and digital democracy.
-
The time commitment for each workstream is 3-5 hours / quarter to stay in the know (join discord, attend monthly call), and variable based on what side-quests you complete.
-
-
-
-
Why git involved?
-
-
Meet some of the best web3 community members & level up your skills.
-
Work on something meaningful.
-
Do something good for web3.
-
-
-
-
-
Here’s how to participate:
-
-
Choose a workstream that best fits your interests (these will expand over time)
-
Git your bearings by showing up to monthly meetings and connecting with community members who share the same goals.
-
Check out some of the existing workstream problems / choose your own.
-
Start working with the DAO and get rewarded for your efforts.
-
-
-
-
-
-
-
-
-
-
-
Available Workstreams
-
-
-
-
-
-
-
#WorkstreamPublic Goods Funding
-
This workgroup focuses on finding ways to govern and grow funding for public goods. Help rally the community around funding our collective infrastructure, define key details of matching rounds, and help us find new categories of public goods we might have missed!
Gitcoin Grants - our first mature product - is built on quadratic funding, which depends on strong sybil/collusion resistance. Some of the top developers and data scientists in the ecosystem are working together to build better tooling around identity (e.g. DIDs), collusion detection, and more. Join them!
We’re committed to building and funding the open web and part of that process is decentralizing Gitcoin itself. Team up with community stewards creating GitcoinDAO, a community-built, decentralized, credibly-neutral, web-scale organization.
Build the change you want to see in the world. Share exciting new prototypes you’ve been working on around funding public goods, and find ways to plug them into the Gitcoin ecosystem.
We now have the internet of money; and we can program our values into our money. And we value public goods, so we are going to build programmable money experiments to create public goods awareness and to fund public goods. If you are a builder or creator who wants to meme for the public good or build for the public good, this workstream is for you.
-
-
-
-
-
Example Quests:
-
Create experiments for funding public goods (eg: NFTs for public goods, Gitcoin.dance)
-
Help build prototypes of ideas that plug into new Gitcoin tools like our Proof of Personhood Passport
Where would we be without open source software? Public Goods (like Open Source Software) create a ton of value for the world. Our digital infrastructure needs better funding models, and we believe that the crypto community can help.
-
-
This workgroup will be focused on finding ways to fund public goods.
-
-
-
-
-
-
-
-
-
Example Quests:
-
Help meme “Public Goods” into mainstream consciousness, convince people that these coordination problems ARE solvable, and spin the Belief => Participation => Momentum flywheel.
-
Manage the Gitcoin Grants funding pool by governing round sizes, themes, and parameters.
-
Create policy regarding what is/is not an acceptable grant, and what actions are considered attacks on QF
-
Design a process for deciding what kinds of public goods we should fund
-
Help us decide on what a fair dispute resolution process for grants might look like
-
Propose grant discoverability solutions using staking and other ideas in mechanism design
Gitcoin Grants is one of the largest community funding mechanisms in the Ethereum ecosystem, delivering millions/quarter to builders of digital public goods. It’s also the first real world implementation of quadratic funding, a democratic mechanism that’s built on the assumption of sybil/collusion/fraud resistance.
-
-
This working group will dive deep to solve these unsolved research issues, with the goal of keeping the Gitcoin Grants fraud tax down while maintaining Gitcoin’s legitimacy.
-
-
-
-
-
Example Quests:
-
Support ecosystem efforts to create sybil resistance, and research the current state of public research
-
Analyze Gitcoin Grants data and design policy proposals to prevent collusion
-
Develop decentralized identity and other ecosystem tools that leverage GTC, raising the cost to attack QF or stopping it entirely without the negative consequences of big-tech
-
-
-
- Get Involved on Discourse
-
-
-
-
-{% endblock %}
-
-
-
-
-{% block 'scripts' %}
-
-
-
-
-{% endblock %}
diff --git a/app/quadraticlands/tests.py b/app/quadraticlands/tests.py
deleted file mode 100644
index 7ce503c2dd9..00000000000
--- a/app/quadraticlands/tests.py
+++ /dev/null
@@ -1,3 +0,0 @@
-from django.test import TestCase
-
-# Create your tests here.
diff --git a/app/quadraticlands/urls.py b/app/quadraticlands/urls.py
deleted file mode 100644
index bb69f964305..00000000000
--- a/app/quadraticlands/urls.py
+++ /dev/null
@@ -1,72 +0,0 @@
-# -*- coding: utf-8 -*-
-"""Handle grant URLs.
-
-Copyright (C) 2020 Gitcoin Core
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU Affero General Public License as published
-by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
-
-You should have received a copy of the GNU Affero General Public License
-along with this program. If not, see .
-
-"""
-from django.conf import settings
-from django.conf.urls import include, url
-from django.urls import path, re_path
-
-from quadraticlands.helpers import vote
-from quadraticlands.router import router
-from quadraticlands.views import (
- base, base_auth, dashboard_index, handler400, handler403, handler404, handler500, index, mission_diplomacy,
- mission_diplomacy_room, mission_index, mission_lore, mission_postcard, mission_postcard_svg, mission_schwag,
- workstream_base, workstream_index,
-)
-
-app_name = 'quadraticlands'
-
-urlpatterns = [
- path('', index, name='quadraticlands'),
- re_path(r'^dashboard/?$', dashboard_index, name='dashboard'),
- re_path(r'^vote/?$', vote, name='vote_json'),
- re_path(r'^(?Pabout|faq)/?$', base, name='quadraticlands_base'),
- re_path(r'^(?P|dashboard|stewards)/?$', base_auth, name='quadraticlands_auth_base'),
-
- # workstreams
- re_path(r'^workstream/(?Ppublicgoods|sybil|decentralization|labs)/?$', workstream_base, name='workstream_base'),
- re_path(r'^workstream/?$', workstream_index, name='workstream'),
-
- # misc
- re_path(r'^mission/?$', mission_index, name='mission'),
- re_path(r'^mission/postcard$', mission_postcard, name='mission_postcard'),
- re_path(r'^mission/postcard/svg$', mission_postcard_svg, name='mission_postcard_svg'),
- re_path(r'^mission/ql-lore$', mission_lore, name='mission_lore'),
- re_path(r'^mission/schwag$', mission_schwag, name='mission_schwag'),
-
- #richard test to build new interface stuff
- path('mission/diplomacy///', mission_diplomacy_room, name='mission_diplomacy_room'),
- path('mission/diplomacy//', mission_diplomacy_room, name='mission_diplomacy_room'),
- re_path(r'^mission/diplomacy/?', mission_diplomacy, name='mission_diplomacy'),
-
- url(r'^api/v1/', include(router.urls)),
-]
-
-
-# if settings.DEBUG:
-urlpatterns += [
- re_path(r'^400/?$', handler400, name='400'),
- re_path(r'^403/?$', handler403, name='403'),
- re_path(r'^404/?$', handler404, name='404'),
- re_path(r'^500/?$', handler500, name='500'),
-]
-
-handler403 = 'quadraticlands.views.handler403'
-handler404 = 'quadraticlands.views.handler404'
-handler500 = 'quadraticlands.views.handler500'
-handler400 = 'quadraticlands.views.handler400'
diff --git a/app/quadraticlands/views.py b/app/quadraticlands/views.py
deleted file mode 100644
index e26752f3c1f..00000000000
--- a/app/quadraticlands/views.py
+++ /dev/null
@@ -1,408 +0,0 @@
-# -*- coding: utf-8 -*-
-"""Define the quadraticlands views.
-
-Copyright (C) 2020 Gitcoin Core
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU Affero General Public License as published
-by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
-
-You should have received a copy of the GNU Affero General Public License
-along with this program. If not, see .
-
-"""
-
-import json
-import logging
-
-from django.contrib import messages
-from django.contrib.admin.views.decorators import staff_member_required
-from django.contrib.auth.decorators import login_required
-from django.http import Http404, HttpResponse, JsonResponse
-from django.shortcuts import redirect
-from django.template.response import TemplateResponse
-from django.urls import reverse
-from django.utils.translation import gettext_lazy as _
-from django.views.decorators.csrf import csrf_protect
-from django.views.decorators.http import require_POST
-
-import bleach
-from dashboard.abi import erc20_abi
-from dashboard.utils import get_web3
-from eth_account.messages import defunct_hash_message
-from quadraticlands.helpers import (
- get_coupon_code, get_FAQ, get_initial_dist, get_initial_dist_breakdown, get_mission_status, get_stewards,
-)
-from ratelimit.decorators import ratelimit
-from web3 import Web3
-
-from .models import Game, GameFeed, GamePlayer, create_game_helper
-
-logger = logging.getLogger(__name__)
-
-
-def index(request):
- '''render template for base index page'''
- context, game_status = get_initial_dist(request), get_mission_status(request)
- context.update(game_status)
- return TemplateResponse(request, 'quadraticlands/index.html', context)
-
-
-def base(request, base):
- '''render templates for /quadraticlands/'''
- context, game_status = get_initial_dist(request), get_mission_status(request)
- context.update(game_status)
- if base == 'faq':
- context.update(get_FAQ(request))
- return TemplateResponse(request, f'quadraticlands/{base}.html', context)
-
-
-@login_required
-def base_auth(request, base):
- '''render templates for /quadraticlands/'''
- context, game_status = get_initial_dist(request), get_mission_status(request)
- context.update(game_status)
- if base == 'stewards':
- context.update(get_stewards())
- return TemplateResponse(request, f'quadraticlands/{base}.html', context)
-
-
-@login_required
-def mission_index(request):
- '''render quadraticlands/mission/index.html'''
- context, game_status = get_initial_dist(request), get_mission_status(request)
- context.update(game_status)
- return TemplateResponse(request, 'quadraticlands/mission/index.html', context)
-
-
-@login_required
-def dashboard_index(request):
- '''render quadraticlands/dashboard/index.html'''
- context, game_status = get_initial_dist(request), get_mission_status(request)
- context.update(game_status)
- return TemplateResponse(request, 'quadraticlands/dashboard/index.html', context)
-
-
-def workstream_index(request):
- '''Use to render quadraticlands/workstream/index.html'''
- return TemplateResponse(request, 'quadraticlands/workstream/index.html')
-
-
-def workstream_base(request, stream_name):
- '''Used to render quadraticlands/workstream/.html'''
- return TemplateResponse(request, f'quadraticlands/workstream/{stream_name}.html')
-
-
-@login_required
-def mission_postcard(request):
- '''Used to handle quadraticlands///'''
- attrs = {
- 'front_frame': ['1', '2', '3', '4', '5', '6'],
- 'front_background': ['a', 'b', 'c', 'd', 'e'],
- 'back_background': ['a', 'b', 'c', 'd', 'e'],
- 'color': ['light', 'dark'],
- }
- context = {
- 'attrs': attrs,
- }
- return TemplateResponse(request, f'quadraticlands/mission/postcard/postcard.html', context)
-
-
-@ratelimit(key='ip', rate='4/s', method=ratelimit.UNSAFE, block=True)
-def mission_postcard_svg(request):
- import xml.etree.ElementTree as ET
-
- from django.http import HttpResponse
-
- width = 100
- height = 100
- ET.register_namespace('', "http://www.w3.org/2000/svg")
- prepend = f'''
-
-'''
-
- package = {
- k: bleach.clean(v) for k, v in
- request.GET.dict().items()
- }
-
- file = 'assets/v2/images/quadraticlands/postcard.svg'
- with open(file) as file:
- elements = []
- tree = ET.parse(file)
- for item in tree.getroot():
- output = ET.tostring(item).decode('utf-8')
-
- _id = item.attrib.get('id')
- include_item = _id == 'include'
- if _id == 'text':
-
- # get text
- replace_text = package.get('text')
-
- # chop up the text by word length to create line breaks.
- line_words_length = int(package.get('line_words_length', 8))
- include_item = True
- end_wrap = ''
- words = replace_text.split(' ')
- new_words = []
- line_offset = 0
- line_counter_for_newline_insert = 0
- for i in range(0, len(words)):
- line_counter_for_newline_insert += 1
- if words[i] == 'NEWLINE':
- line_counter_for_newline_insert = 0
- insert_newline = line_counter_for_newline_insert % line_words_length == 0
- if words[i] == 'NEWLINE':
- insert_newline = True
- if insert_newline:
- line_offset += 1
-
- y = 26 + (line_offset) * 26
- start_wrap = f''
-
- if i == 0:
- new_words.append(start_wrap)
- if insert_newline:
- new_words.append(end_wrap)
- new_words.append(start_wrap)
- if words[i] != 'NEWLINE':
- new_words.append(words[i])
- if i == (len(words) - 1):
- new_words.append(end_wrap)
-
- # actually insert the text
- replace_text = " ".join(new_words)
- output = output.replace('POSTCARD_TEXT_GOES_HERE', replace_text)
- replace_color = '#1a103d' if package.get('color','') == 'light' else '#FFFFFF'
- output = output.replace('POSTCARD_COLOR_GOES_HERE', replace_color)
- if _id:
- val = _id.split(":")[-1]
- key = _id.split(":")[0]
- if val == package.get(key):
- include_item = True
- if include_item:
- elements.append(output)
- output = prepend + "".join(elements) + postpend
-
- response = HttpResponse(output, content_type='image/svg+xml')
- return response
-
-
-@login_required
-@ratelimit(key='ip', rate='4/s', method=ratelimit.UNSAFE, block=True)
-def mission_lore(request):
- from perftools.models import StaticJsonEnv
- data = StaticJsonEnv.objects.get(key='QL_LORE').data
- MOLOCH_COMIC_LINK = data['MOLOCH_COMIC_LINK']
- QL_SONG_LINK = data['QL_SONG_LINK']
- params = {
- 'MOLOCH_COMIC_LINK': MOLOCH_COMIC_LINK,
- 'QL_SONG_LINK': QL_SONG_LINK,
- }
- return TemplateResponse(request, f'quadraticlands/mission/lore/index.html', params)
-
-
-@login_required
-@ratelimit(key='ip', rate='4/s', method=ratelimit.UNSAFE, block=True)
-def mission_schwag(request):
-
- context = {
- 'coupon_code': get_coupon_code(request)
- }
-
- return TemplateResponse(request, f'quadraticlands/mission/schwag/index.html', context)
-
-
-def handler403(request, exception=None):
- return error(request, 403)
-
-
-def handler404(request, exception=None):
- return error(request, 404)
-
-
-def handler500(request, exception=None):
- return error(request, 500)
-
-
-def handler400(request, exception=None):
- return error(request, 400)
-
-
-def error(request, code):
- context = {
- 'code': code,
- 'title': "Error {}".format(code)
- }
- return_as_json = 'api' in request.path
-
- if return_as_json:
- return JsonResponse(context, status=code)
- return TemplateResponse(request, f'quadraticlands/error.html', context, status=code)
-
-@staff_member_required
-def mission_diplomacy(request):
- return mission_diplomacy_helper(request)
-
-max_games = 4
-max_players_per_game = 16
-def mission_diplomacy_helper(request, invited_to_game=None):
- games = []
-
- # check for what games the user is in
- if request.user.is_authenticated:
- players = GamePlayer.objects.filter(active=True, profile=request.user.profile)
- games = Game.objects.filter(pk__in=players.values_list("game"))
-
- # handle the creation of a new game.
- if request.POST:
- if games.count() > max_games:
- messages.info(
- request,
- f'You are already in the maximum number of games'
- )
- else:
- title = request.POST.get('title', '')
- if not title:
- messages.info(
- request,
- f'Please enter a title'
- )
- game = create_game_helper(request.user.profile.handle, title)
- messages.success(
- request,
- f'Your Game has been created successfully'
- )
- messages.success(
- request,
- f'Share this link with ur frens to have them join!'
- )
- return redirect(game.url)
- else:
- if request.POST:
- messages.error(
- request,
- f'You must login to create a game.'
- )
-
-
-
- # return the vite
- params = {
- 'title': 'Quadratic Diplomacy',
- 'games': games,
- 'invite': invited_to_game,
- }
- return TemplateResponse(request, 'quadraticlands/mission/diplomacy/index.html', params)
-
-
-@login_required
-@staff_member_required
-def mission_diplomacy_room(request, uuid, name):
- # get the game
- try:
- game = Game.objects.get(uuid=uuid)
- except:
- raise Http404
- return mission_diplomacy_room_helper(request, game)
-
-def mission_diplomacy_room_helper(request, game):
-
- # handle invites
- users_players = GamePlayer.objects.filter(active=True, profile=request.user.profile)
- users_games = Game.objects.filter(pk__in=users_players.values_list("game"))
- users_player = users_players.first()
- if game not in users_games:
- if request.user.is_authenticated:
-
- # too many user condition
- if game.active_players.count() >= max_players_per_game:
- messages.info(
- request,
- f'There are already {max_players_per_game} in the game. Wait for someone to leave + try again.'
- )
- return mission_diplomacy_helper(request)
-
- # show invite
- if request.GET.get('join'):
- game.add_player(request.user.profile.handle)
- else:
- return mission_diplomacy_helper(request, invited_to_game=game)
- else:
- # logged out condition
- messages.info(
- request,
- f'Please login to join this game.'
- )
-
- # in game experience
- is_member = game.is_active_player(request.user.profile.handle)
- is_admin = game.players.filter(admin=True, profile=request.user.profile).exists()
- if is_admin:
- if request.GET.get('remove'):
- remove_this_fool = request.GET.get('remove')
- for player in game.players.filter(active=True, profile__handle=remove_this_fool):
- game.remove_player(player.profile.handle)
- messages.info(
- request,
- f'{remove_this_fool} has been removed'
- )
-
- # delete game
- if is_member and request.GET.get('delete'):
- game.remove_player(request.user.profile.handle)
- messages.info(
- request,
- f'You have left this game.'
- )
- return redirect('/quadraticlands/mission/diplomacy')
-
- # chat in game
- if is_member and request.POST.get('chat'):
- game.chat(request.user.profile.handle, request.POST.get('chat'))
-
- # make a move
- if is_member and request.POST.get('signature'):
- package = request.POST.get('package')
- moves = json.loads(package)
- signature = request.POST.get('signature')
- recipient_address = Web3.toChecksumAddress(moves['account'])
- web3 = get_web3('mainnet')
- gtc = web3.eth.contract(address=Web3.toChecksumAddress('0xde30da39c46104798bb5aa3fe8b9e0e1f348163f'), abi=erc20_abi)
- balance = int((gtc.functions.balanceOf(recipient_address).call()) / (10 ** 18))
- claimed_balance = int(moves['balance'])
- signer_address = Web3.toChecksumAddress(web3.eth.account.recoverHash(defunct_hash_message(text=package), signature=signature))
- claimed_address = Web3.toChecksumAddress(moves['account'])
-
- if claimed_balance != balance:
- return HttpResponse('not authorized - bad balance', status=401)
-
- if claimed_address != signer_address:
- return HttpResponse('not authorized - bad addr', status=401)
-
- data = {
- 'moves': moves,
- 'signature': signature,
- }
- game.make_move(request.user.profile.handle, data)
- return JsonResponse({'msg':'OK', 'url' : game.url})
-
- # game view
- params = {
- 'title': game.title,
- 'users_player': users_player,
- 'game': game,
- 'is_admin': is_admin,
- 'max_players': max_players_per_game,
- }
- return TemplateResponse(request, 'quadraticlands/mission/diplomacy/room.html', params)