Skip to content

Commit

Permalink
Merge branch 'main' into production
Browse files Browse the repository at this point in the history
  • Loading branch information
mouse-reeve committed Apr 4, 2023
2 parents 0c427ea + d35b1d9 commit ffb7f66
Show file tree
Hide file tree
Showing 66 changed files with 10,386 additions and 2,432 deletions.
1 change: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ __pycache__
.git
.github
.pytest*
.env
6 changes: 6 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,12 @@ AWS_SECRET_ACCESS_KEY=
# AWS_S3_REGION_NAME=None # "fr-par"
# AWS_S3_ENDPOINT_URL=None # "https://s3.fr-par.scw.cloud"

# Commented are example values if you use Azure Blob Storage
# USE_AZURE=true
# AZURE_ACCOUNT_NAME= # "example-account-name"
# AZURE_ACCOUNT_KEY= # "base64-encoded-access-key"
# AZURE_CONTAINER= # "example-blob-container-name"
# AZURE_CUSTOM_DOMAIN= # "example-account-name.blob.core.windows.net"

# Preview image generation can be computing and storage intensive
ENABLE_PREVIEW_IMAGES=False
Expand Down
11 changes: 10 additions & 1 deletion bookwyrm/activitystreams.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,15 @@
from django.db import transaction
from django.db.models import signals, Q
from django.utils import timezone
from opentelemetry import trace

from bookwyrm import models
from bookwyrm.redis_store import RedisStore, r
from bookwyrm.tasks import app, LOW, MEDIUM, HIGH
from bookwyrm.telemetry import open_telemetry


tracer = open_telemetry.tracer()


class ActivityStream(RedisStore):
Expand Down Expand Up @@ -136,8 +141,10 @@ def _get_audience(self, status): # pylint: disable=no-self-use
)
return audience.distinct()

def get_audience(self, status): # pylint: disable=no-self-use
@tracer.start_as_current_span("ActivityStream.get_audience")
def get_audience(self, status):
"""given a status, what users should see it"""
trace.get_current_span().set_attribute("stream_id", self.key)
return [user.id for user in self._get_audience(status)]

def get_stores_for_object(self, obj):
Expand All @@ -160,7 +167,9 @@ class HomeStream(ActivityStream):

key = "home"

@tracer.start_as_current_span("HomeStream.get_audience")
def get_audience(self, status):
trace.get_current_span().set_attribute("stream_id", self.key)
audience = super()._get_audience(status)
if not audience:
return []
Expand Down
2 changes: 1 addition & 1 deletion bookwyrm/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class BookwyrmConfig(AppConfig):
# pylint: disable=no-self-use
def ready(self):
"""set up OTLP and preview image files, if desired"""
if settings.OTEL_EXPORTER_OTLP_ENDPOINT:
if settings.OTEL_EXPORTER_OTLP_ENDPOINT or settings.OTEL_EXPORTER_CONSOLE:
# pylint: disable=import-outside-toplevel
from bookwyrm.telemetry import open_telemetry

Expand Down
61 changes: 61 additions & 0 deletions bookwyrm/migrations/0178_auto_20230328_2132.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Generated by Django 3.2.18 on 2023-03-28 21:32

import bookwyrm.models.fields
from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
("auth", "0012_alter_user_first_name_max_length"),
("bookwyrm", "0177_merge_0174_auto_20230222_1742_0176_hashtag_support"),
]

operations = [
migrations.AlterField(
model_name="hashtag",
name="name",
field=bookwyrm.models.fields.CICharField(max_length=256),
),
migrations.AlterField(
model_name="sitesettings",
name="default_user_auth_group",
field=models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.RESTRICT,
to="auth.group",
),
),
migrations.AlterField(
model_name="user",
name="preferred_language",
field=models.CharField(
blank=True,
choices=[
("en-us", "English"),
("ca-es", "Català (Catalan)"),
("de-de", "Deutsch (German)"),
("eo-uy", "Esperanto (Esperanto)"),
("es-es", "Español (Spanish)"),
("eu-es", "Euskara (Basque)"),
("gl-es", "Galego (Galician)"),
("it-it", "Italiano (Italian)"),
("fi-fi", "Suomi (Finnish)"),
("fr-fr", "Français (French)"),
("lt-lt", "Lietuvių (Lithuanian)"),
("no-no", "Norsk (Norwegian)"),
("pl-pl", "Polski (Polish)"),
("pt-br", "Português do Brasil (Brazilian Portuguese)"),
("pt-pt", "Português Europeu (European Portuguese)"),
("ro-ro", "Română (Romanian)"),
("sv-se", "Svenska (Swedish)"),
("zh-hans", "简体中文 (Simplified Chinese)"),
("zh-hant", "繁體中文 (Traditional Chinese)"),
],
max_length=255,
null=True,
),
),
]
51 changes: 39 additions & 12 deletions bookwyrm/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import requests
from django.utils.translation import gettext_lazy as _
from django.core.exceptions import ImproperlyConfigured


# pylint: disable=line-too-long
Expand All @@ -18,15 +19,15 @@
"https://api.github.com/repos/bookwyrm-social/bookwyrm/releases/latest",
)

PAGE_LENGTH = env("PAGE_LENGTH", 15)
PAGE_LENGTH = env.int("PAGE_LENGTH", 15)
DEFAULT_LANGUAGE = env("DEFAULT_LANGUAGE", "English")

JS_CACHE = "a7d4e720"

# email
EMAIL_BACKEND = env("EMAIL_BACKEND", "django.core.mail.backends.smtp.EmailBackend")
EMAIL_HOST = env("EMAIL_HOST")
EMAIL_PORT = env("EMAIL_PORT", 587)
EMAIL_PORT = env.int("EMAIL_PORT", 587)
EMAIL_HOST_USER = env("EMAIL_HOST_USER")
EMAIL_HOST_PASSWORD = env("EMAIL_HOST_PASSWORD")
EMAIL_USE_TLS = env.bool("EMAIL_USE_TLS", True)
Expand Down Expand Up @@ -68,13 +69,15 @@
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = env("SECRET_KEY")

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = env.bool("DEBUG", True)
USE_HTTPS = env.bool("USE_HTTPS", not DEBUG)

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = env("SECRET_KEY")
if not DEBUG and SECRET_KEY == "7(2w1sedok=aznpq)ta1mc4i%4h=xx@hxwx*o57ctsuml0x%fr":
raise ImproperlyConfigured("You must change the SECRET_KEY env variable")

ALLOWED_HOSTS = env.list("ALLOWED_HOSTS", ["*"])

# Application definition
Expand Down Expand Up @@ -205,14 +208,14 @@

# redis/activity streams settings
REDIS_ACTIVITY_HOST = env("REDIS_ACTIVITY_HOST", "localhost")
REDIS_ACTIVITY_PORT = env("REDIS_ACTIVITY_PORT", 6379)
REDIS_ACTIVITY_PORT = env.int("REDIS_ACTIVITY_PORT", 6379)
REDIS_ACTIVITY_PASSWORD = requests.utils.quote(env("REDIS_ACTIVITY_PASSWORD", ""))
REDIS_ACTIVITY_DB_INDEX = env("REDIS_ACTIVITY_DB_INDEX", 0)
REDIS_ACTIVITY_DB_INDEX = env.int("REDIS_ACTIVITY_DB_INDEX", 0)
REDIS_ACTIVITY_URL = env(
"REDIS_ACTIVITY_URL",
f"redis://:{REDIS_ACTIVITY_PASSWORD}@{REDIS_ACTIVITY_HOST}:{REDIS_ACTIVITY_PORT}/{REDIS_ACTIVITY_DB_INDEX}",
)
MAX_STREAM_LENGTH = int(env("MAX_STREAM_LENGTH", 200))
MAX_STREAM_LENGTH = env.int("MAX_STREAM_LENGTH", 200)

STREAMS = [
{"key": "home", "name": _("Home Timeline"), "shortname": _("Home")},
Expand All @@ -221,12 +224,12 @@

# Search configuration
# total time in seconds that the instance will spend searching connectors
SEARCH_TIMEOUT = int(env("SEARCH_TIMEOUT", 8))
SEARCH_TIMEOUT = env.int("SEARCH_TIMEOUT", 8)
# timeout for a query to an individual connector
QUERY_TIMEOUT = int(env("QUERY_TIMEOUT", 5))
QUERY_TIMEOUT = env.int("QUERY_TIMEOUT", 5)

# Redis cache backend
if env("USE_DUMMY_CACHE", False):
if env.bool("USE_DUMMY_CACHE", False):
CACHES = {
"default": {
"BACKEND": "django.core.cache.backends.dummy.DummyCache",
Expand Down Expand Up @@ -256,7 +259,7 @@
"USER": env("POSTGRES_USER", "bookwyrm"),
"PASSWORD": env("POSTGRES_PASSWORD", "bookwyrm"),
"HOST": env("POSTGRES_HOST", ""),
"PORT": env("PGPORT", 5432),
"PORT": env.int("PGPORT", 5432),
},
}

Expand Down Expand Up @@ -291,6 +294,7 @@
("en-us", _("English")),
("ca-es", _("Català (Catalan)")),
("de-de", _("Deutsch (German)")),
("eo-uy", _("Esperanto (Esperanto)")),
("es-es", _("Español (Spanish)")),
("eu-es", _("Euskara (Basque)")),
("gl-es", _("Galego (Galician)")),
Expand Down Expand Up @@ -341,6 +345,7 @@
CSRF_COOKIE_SECURE = True

USE_S3 = env.bool("USE_S3", False)
USE_AZURE = env.bool("USE_AZURE", False)

if USE_S3:
# AWS settings
Expand All @@ -364,6 +369,27 @@
DEFAULT_FILE_STORAGE = "bookwyrm.storage_backends.ImagesStorage"
CSP_DEFAULT_SRC = ["'self'", AWS_S3_CUSTOM_DOMAIN] + CSP_ADDITIONAL_HOSTS
CSP_SCRIPT_SRC = ["'self'", AWS_S3_CUSTOM_DOMAIN] + CSP_ADDITIONAL_HOSTS
elif USE_AZURE:
AZURE_ACCOUNT_NAME = env("AZURE_ACCOUNT_NAME")
AZURE_ACCOUNT_KEY = env("AZURE_ACCOUNT_KEY")
AZURE_CONTAINER = env("AZURE_CONTAINER")
AZURE_CUSTOM_DOMAIN = env("AZURE_CUSTOM_DOMAIN")
# Azure Static settings
STATIC_LOCATION = "static"
STATIC_URL = (
f"{PROTOCOL}://{AZURE_CUSTOM_DOMAIN}/{AZURE_CONTAINER}/{STATIC_LOCATION}/"
)
STATICFILES_STORAGE = "bookwyrm.storage_backends.AzureStaticStorage"
# Azure Media settings
MEDIA_LOCATION = "images"
MEDIA_URL = (
f"{PROTOCOL}://{AZURE_CUSTOM_DOMAIN}/{AZURE_CONTAINER}/{MEDIA_LOCATION}/"
)
MEDIA_FULL_URL = MEDIA_URL
STATIC_FULL_URL = STATIC_URL
DEFAULT_FILE_STORAGE = "bookwyrm.storage_backends.AzureImagesStorage"
CSP_DEFAULT_SRC = ["'self'", AZURE_CUSTOM_DOMAIN] + CSP_ADDITIONAL_HOSTS
CSP_SCRIPT_SRC = ["'self'", AZURE_CUSTOM_DOMAIN] + CSP_ADDITIONAL_HOSTS
else:
STATIC_URL = "/static/"
MEDIA_URL = "/images/"
Expand All @@ -377,6 +403,7 @@
OTEL_EXPORTER_OTLP_ENDPOINT = env("OTEL_EXPORTER_OTLP_ENDPOINT", None)
OTEL_EXPORTER_OTLP_HEADERS = env("OTEL_EXPORTER_OTLP_HEADERS", None)
OTEL_SERVICE_NAME = env("OTEL_SERVICE_NAME", None)
OTEL_EXPORTER_CONSOLE = env.bool("OTEL_EXPORTER_CONSOLE", False)

TWO_FACTOR_LOGIN_MAX_SECONDS = env.int("TWO_FACTOR_LOGIN_MAX_SECONDS", 60)
TWO_FACTOR_LOGIN_VALIDITY_WINDOW = env.int("TWO_FACTOR_LOGIN_VALIDITY_WINDOW", 2)
Expand Down
4 changes: 2 additions & 2 deletions bookwyrm/static/css/bookwyrm/components/_tabs.scss
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,12 @@

.bw-tabs a:hover {
border-bottom-color: transparent;
color: $text;
color: $text
}

.bw-tabs a.is-active {
border-bottom-color: transparent;
color: $link;
color: $link
}

.bw-tabs.is-left {
Expand Down
16 changes: 16 additions & 0 deletions bookwyrm/static/css/themes/bookwyrm-dark.scss
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,22 @@ $family-secondary: $family-sans-serif;
}


.tabs li:not(.is-active) a {
color: #2e7eb9 !important;
}
.tabs li:not(.is-active) a:hover {
border-bottom-color: #2e7eb9 !important;
}

.tabs li:not(.is-active) a {
color: #2e7eb9 !important;
}
.tabs li.is-active a {
color: #e6e6e6 !important;
border-bottom-color: #e6e6e6 !important ;
}


#qrcode svg {
background-color: #a6a6a6;
}
Expand Down
16 changes: 16 additions & 0 deletions bookwyrm/static/css/themes/bookwyrm-light.scss
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,22 @@ $family-secondary: $family-sans-serif;
color: $grey !important;
}

.tabs li:not(.is-active) a {
color: #3273dc !important;
}
.tabs li:not(.is-active) a:hover {
border-bottom-color: #3273dc !important;
}

.tabs li:not(.is-active) a {
color: #3273dc !important;
}
.tabs li.is-active a {
color: #4a4a4a !important;
border-bottom-color: #4a4a4a !important ;
}


@import "../bookwyrm.scss";
@import "../vendor/icons.css";
@import "../vendor/shepherd.scss";
14 changes: 14 additions & 0 deletions bookwyrm/storage_backends.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import os
from tempfile import SpooledTemporaryFile
from storages.backends.s3boto3 import S3Boto3Storage
from storages.backends.azure_storage import AzureStorage


class StaticStorage(S3Boto3Storage): # pylint: disable=abstract-method
Expand Down Expand Up @@ -47,3 +48,16 @@ def _save(self, name, content):
# Upload the object which will auto close the
# content_autoclose instance
return super()._save(name, content_autoclose)


class AzureStaticStorage(AzureStorage): # pylint: disable=abstract-method
"""Storage class for Static contents"""

location = "static"


class AzureImagesStorage(AzureStorage): # pylint: disable=abstract-method
"""Storage class for Image files"""

location = "images"
overwrite_files = False
17 changes: 15 additions & 2 deletions bookwyrm/telemetry/open_telemetry.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
from opentelemetry import trace
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.sdk.trace.export import BatchSpanProcessor, ConsoleSpanExporter

from bookwyrm import settings

trace.set_tracer_provider(TracerProvider())
trace.get_tracer_provider().add_span_processor(BatchSpanProcessor(OTLPSpanExporter()))
if settings.OTEL_EXPORTER_CONSOLE:
trace.get_tracer_provider().add_span_processor(
BatchSpanProcessor(ConsoleSpanExporter())
)
elif settings.OTEL_EXPORTER_OTLP_ENDPOINT:
trace.get_tracer_provider().add_span_processor(
BatchSpanProcessor(OTLPSpanExporter())
)


def instrumentDjango():
Expand All @@ -20,3 +29,7 @@ def instrumentCelery():
@worker_process_init.connect(weak=False)
def init_celery_tracing(*args, **kwargs):
CeleryInstrumentor().instrument()


def tracer():
return trace.get_tracer(__name__)
4 changes: 4 additions & 0 deletions bookwyrm/templates/preferences/edit_user.html
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,10 @@ <h2 class="title is-4">{% trans "Privacy" %}</h2>
{{ form.default_post_privacy }}
</div>
</div>
{% url 'user-shelves' request.user.localname as path %}
<p class="notification is-light">
{% blocktrans %}Looking for shelf privacy? You can set a sepearate visibility level for each of your shelves. Go to <a href="{{ path }}">Your Books</a>, pick a shelf from the tab bar, and click "Edit shelf."{% endblocktrans %}
</p>
</div>
</section>
<div class="field"><button class="button is-primary" type="submit">{% trans "Save" %}</button></div>
Expand Down
Loading

0 comments on commit ffb7f66

Please sign in to comment.