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

v0.9.0 #108

Open
wants to merge 36 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
ac6d3ea
Add make command for postgres backup
giobber Sep 16, 2023
1657fe3
Make Place and WordFrequency accessible readonly
giobber Sep 16, 2023
7c3b1c2
Fix how add_demo_shares script generate locations
giobber Sep 16, 2023
3cbed60
Create app Map
giobber Sep 16, 2023
bf1f14d
Add words as tags in shares (Closes #75)
giobber Sep 16, 2023
31843b5
Add place as field for Share (set inside signal)
giobber Sep 16, 2023
5a70c38
Enable Share.timestamp to be set/modified
giobber Sep 16, 2023
9fc6185
Change Share.place.related_name and merge migrations
giobber Sep 16, 2023
9288b33
Reorganize sqlite commands
giobber Sep 16, 2023
f136906
Move website templates inside app folder
giobber Sep 16, 2023
ed44cf6
Remove map app as not used at the moment
giobber Sep 16, 2023
32653d2
Add a datetime converter
giobber Sep 16, 2023
4f00430
Add view and url
giobber Sep 16, 2023
f238e17
Improve view and template
giobber Sep 17, 2023
d5622f9
Merge pull request #107 from archiviofontiorali/features/history
giobber Sep 17, 2023
4a6b57d
Add make command to load postgres backup
giobber Sep 17, 2023
a3e581a
Add command for recreating postgres db
giobber Sep 17, 2023
5a2cb69
Improve performance and aesthetic for history template
giobber Sep 17, 2023
4386244
Set timestamp to last valid one if timezone.now() is out of bounds
giobber Sep 17, 2023
4287e36
Move to django-static-precompiler
giobber Sep 21, 2023
2c1cb23
Install less and remove sass
giobber Sep 21, 2023
4b56afc
Add package.json and install via npm sass
giobber Sep 21, 2023
1f6cb8e
Reinstall django compressor
giobber Sep 21, 2023
479e444
Improve SCSS code
giobber Sep 21, 2023
929e7e7
Reinstall django-sass-processor
giobber Sep 21, 2023
3700f9f
Remove sass from package.json
giobber Sep 21, 2023
aff2a54
Remove '@use "sass:map"' from _palette.scss
giobber Sep 21, 2023
1fca837
Fix usage of sass tags
giobber Sep 21, 2023
38264bd
Move alert colors to palette
giobber Sep 21, 2023
33debf8
Rename palette- in color-
giobber Sep 21, 2023
0c32f38
Fix imports and variables for palettes
giobber Sep 21, 2023
3c9821a
Add palette based on grey tones
giobber Sep 22, 2023
67423f0
USe css to handle style for menus
giobber Sep 22, 2023
2e593fe
Add script to update pre v0.9.0
giobber Sep 26, 2023
bb96f1a
Merge demo and db-demo commands and improve command descriptions
giobber Sep 30, 2023
8b98281
Make command more specific
giobber Aug 13, 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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,9 @@ dmypy.json
# Pyre type checker
.pyre/

# JS ignored folders
node_modules

# Custom
.backup
.data
Expand Down
8 changes: 4 additions & 4 deletions apps/api/views.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from django.contrib.auth.models import Group, User
from rest_framework import permissions, viewsets
from rest_framework.permissions import IsAuthenticated, IsAuthenticatedOrReadOnly

from ..website.models import Place, Share, WordFrequency
from .serializers import PlaceSerializer, ShareSerializer, WordFrequencySerializer
Expand All @@ -10,20 +10,20 @@ class PlaceViewSet(viewsets.ModelViewSet):

queryset = Place.objects.order_by("slug").all()
serializer_class = PlaceSerializer
permission_classes = [permissions.IsAuthenticated]
permission_classes = [IsAuthenticatedOrReadOnly]


class ShareViewSet(viewsets.ModelViewSet):
"""API endpoint for shares."""

queryset = Share.objects.order_by("timestamp").all()
serializer_class = ShareSerializer
permission_classes = [permissions.IsAuthenticated]
permission_classes = [IsAuthenticated]


class WordFrequencyViewSet(viewsets.ModelViewSet):
"""API endpoint for word frequencies."""

queryset = WordFrequency.objects.order_by("place", "word").all()
serializer_class = WordFrequencySerializer
permission_classes = [permissions.IsAuthenticated]
permission_classes = [IsAuthenticatedOrReadOnly]
6 changes: 3 additions & 3 deletions apps/showcase/templates/showcase/showcase.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{% extends "map.html" %}
{% extends "website/map.html" %}

{% load sass_tags %}
{% load static %}
{% load sass_tags %}

{% block custom_meta %}
{% if reload and reload > 0 %}
Expand All @@ -11,7 +11,7 @@

{% block stylesheet %}
{{ block.super }}
<link rel="stylesheet" href="{% sass_src 'showcase/css/scaling.scss' %}">
<link type="text/css" rel="stylesheet" href="{% sass_src 'showcase/css/scaling.scss' %}">
{% endblock %}


Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Generated by Django 4.2.5 on 2023-09-16 19:06

from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone


class Migration(migrations.Migration):
dependencies = [
("website", "0012_landscape_enabled_alter_landscape_domain"),
]

operations = [
migrations.AddField(
model_name="share",
name="place",
field=models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="shares",
to="website.place",
),
),
migrations.AddField(
model_name="share",
name="words",
field=models.ManyToManyField(
blank=True, related_name="shares", to="website.word"
),
),
migrations.AlterField(
model_name="share",
name="timestamp",
field=models.DateTimeField(default=django.utils.timezone.now),
),
]
30 changes: 20 additions & 10 deletions apps/website/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from django.contrib.gis.geos import Point
from django.db.models import F, Max, Q, Sum
from django.shortcuts import get_object_or_404
from django.utils import timezone
from django.utils.translation import gettext as _

from .fields import UniqueBooleanField
Expand Down Expand Up @@ -50,16 +51,6 @@ class Meta:
abstract = True


class Share(LocationModel):
timestamp = models.DateTimeField(auto_now_add=True)
message = models.TextField(max_length=500)
landscape = models.ForeignKey("Landscape", on_delete=models.CASCADE)

def __str__(self):
message = textwrap.shorten(self.message, width=20, placeholder="...")
return f"{super().__str__()} [{message}]"


class LeafletProvider(TitledModel):
name = models.CharField(
max_length=100,
Expand Down Expand Up @@ -133,6 +124,25 @@ def __str__(self):
return ("🚩 " if not self.visible else "") + self.text


class Share(LocationModel):
timestamp = models.DateTimeField(default=timezone.now)
message = models.TextField(max_length=500)
landscape = models.ForeignKey("Landscape", on_delete=models.CASCADE)

place = models.ForeignKey(
Place,
related_name="shares",
null=True,
blank=True,
on_delete=models.SET_NULL,
)
words = models.ManyToManyField(Word, related_name="shares", blank=True)

def __str__(self):
message = textwrap.shorten(self.message, width=20, placeholder="...")
return f"{super().__str__()} [{message}]"


class WordFrequency(models.Model):
word = models.ForeignKey(
Word,
Expand Down
23 changes: 14 additions & 9 deletions apps/website/scripts/add_demo_shares.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

from django.conf import settings
from django.contrib.gis.geos import Point
from loguru import logger
from django.utils import timezone
from tqdm import tqdm

from .. import models
Expand All @@ -21,12 +21,20 @@
TEXT_ROW_RE = re.compile(r"[A-Za-z]")


def random_timestamp(delta=1440):
minutes = round(random.gauss(0, delta))
return timezone.now() + timezone.timedelta(minutes=minutes)


def save_share(location: Point, message: str, landscape: models.Landscape):
defaults = {"location": location, "message": message, "landscape": landscape}
share = models.Share(**defaults)
share = models.Share(
location=location,
message=message,
landscape=landscape,
timestamp=random_timestamp(),
)
share.full_clean()
share.save()
logger.debug(f"Created Share: {share}")
return share


Expand All @@ -42,16 +50,13 @@ def run():
shares = fp.readlines()

landscape = models.Landscape.visible_objects.get_default()
places = list(landscape.places.all())
places = [p.coordinates for p in landscape.places.all()]

for message in tqdm(shares):
if not TEXT_ROW_RE.match(message):
continue

point = random.choice(places).location

lat = point.x + random.gauss(0, 0.5)
lon = point.y + random.gauss(0, 0.5)
lat, lon = random.choice(places)
location = Point(x=lon, y=lat)

save_share(location, message, landscape)
46 changes: 46 additions & 0 deletions apps/website/scripts/recalculate_shares.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import re

import spacy.symbols
from django.conf import settings
from django.contrib.gis.db.models.functions import Distance
from loguru import logger
from tqdm import tqdm

from .. import models

# For more info see:
# https://stackoverflow.com/questions/9662346/python-code-to-remove-html-tags-from-a-string
HTML_TAG_RE = re.compile("<.*?>|&([a-z0-9]+|#[0-9]{1,6}|#x[0-9a-f]{1,6});")

try:
nlp = spacy.load(settings.SPACY_MODEL_NAME)
except IOError:
logger.info("Spacy model not found downloading it")
spacy.cli.download(settings.SPACY_MODEL_NAME)
nlp = spacy.load(settings.SPACY_MODEL_NAME)


def recalculate_share(instance: models.Share):
place = (
models.Place.objects.filter(landscape=instance.landscape)
.annotate(distance=Distance("location", instance.location))
.order_by("distance")
.first()
)

instance.place = place
instance.save()

for token in nlp(instance.message):
if token.pos not in settings.SPACY_VALID_TOKENS:
continue

text = HTML_TAG_RE.sub("", token.lemma_).strip().lower()

word, created = models.Word.objects.get_or_create(text=text)
instance.words.add(word)


def run():
for share in tqdm(models.Share.objects.all()):
recalculate_share(share)
5 changes: 5 additions & 0 deletions apps/website/signals.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ def on_share_creation_update_frequencies(
.first()
)

instance.place = place
instance.save()

logger.debug(
f"Receive share near [{place}], update WordFrequency "
f"(message: {instance.message})"
Expand All @@ -59,6 +62,8 @@ def on_share_creation_update_frequencies(
word.full_clean()
word.save()

instance.words.add(word)

wf, _ = models.WordFrequency.objects.get_or_create(place=place, word=word)
wf.frequency = F("frequency") + 1
wf.save()
Expand Down
8 changes: 0 additions & 8 deletions apps/website/static/website/css/_palette.scss

This file was deleted.

8 changes: 5 additions & 3 deletions apps/website/static/website/css/map.scss
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
/* Leaflet map related styles */

@import "../../../../../static/css/palette";

.canvas span {
/* Better solution only available in firefox
-webkit-text-stroke: 2px white;
paint-order: stroke fill; */
$size: 2px;
$size: 1px;
$blur: 0;

$color: white;
$color: $color-background;
text-shadow:
$size $size $blur $color,
-$size $size $blur $color,
Expand All @@ -17,7 +19,7 @@


&:hover {
$color: silver;
$color: var(--color-gray, Gray);
text-shadow:
$size $size $blur $color,
-$size $size $blur $color,
Expand Down
9 changes: 4 additions & 5 deletions apps/website/static/website/css/share.scss
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
/* Share page custom style rules */

@import "palette";
@import "../../../../../static/css/palette";


#location-auto-icon svg{
color: gray;
color: $gray;

&[data-state="disabled"] { color: lightgray; }
&[data-state="disabled"] { color: $light-gray; }
&[data-state="processing"] { color: $orange; }
&[data-state="success"] { color: $green; }
&[data-state="error"] { color: $red; }
Expand All @@ -17,7 +17,7 @@ $animation-colors: ("red": $red, "gray": $gray);
@each $name, $color in $animation-colors {
@keyframes color-animation--#{$name} {
from {
color: $white;
color: $color-background;
}
to {
color: $color;
Expand Down Expand Up @@ -55,5 +55,4 @@ a#record-button {
background-color: $gray;
animation-name: color-animation--gray;
}

}
Loading