mirror of
https://github.com/bookwyrm-social/bookwyrm.git
synced 2024-12-04 23:36:32 +00:00
Merge branch 'main' into production
This commit is contained in:
commit
d5cc1d2f02
15 changed files with 119 additions and 31 deletions
12
.github/FUNDING.yml
vendored
Normal file
12
.github/FUNDING.yml
vendored
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
# These are supported funding model platforms
|
||||||
|
|
||||||
|
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
||||||
|
patreon: bookwrym
|
||||||
|
open_collective: # Replace with a single Open Collective username
|
||||||
|
ko_fi: # Replace with a single Ko-fi username
|
||||||
|
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||||
|
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||||
|
liberapay: # Replace with a single Liberapay username
|
||||||
|
issuehunt: # Replace with a single IssueHunt username
|
||||||
|
otechie: # Replace with a single Otechie username
|
||||||
|
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
|
|
@ -8,6 +8,7 @@ Social reading and reviewing, decentralized with ActivityPub
|
||||||
- [The role of federation](#the-role-of-federation)
|
- [The role of federation](#the-role-of-federation)
|
||||||
- [Features](#features)
|
- [Features](#features)
|
||||||
- [Setting up the developer environment](#setting-up-the-developer-environment)
|
- [Setting up the developer environment](#setting-up-the-developer-environment)
|
||||||
|
- [Installing in Production](#installing-in-production)
|
||||||
- [Project structure](#project-structure)
|
- [Project structure](#project-structure)
|
||||||
- [Book data](#book-data)
|
- [Book data](#book-data)
|
||||||
- [Contributing](#contributing)
|
- [Contributing](#contributing)
|
||||||
|
@ -114,7 +115,7 @@ This project is still young and isn't, at the momoment, very stable, so please p
|
||||||
`cp .env.example .env`
|
`cp .env.example .env`
|
||||||
- Add your domain, email address, mailgun credentials
|
- Add your domain, email address, mailgun credentials
|
||||||
- Set a secure redis password and secret key
|
- Set a secure redis password and secret key
|
||||||
- Update your nginx configuration in `nginx/defautl.conf`
|
- Update your nginx configuration in `nginx/default.conf`
|
||||||
- Replace `your-domain.com` with your domain name
|
- Replace `your-domain.com` with your domain name
|
||||||
- Run the application (this should also set up a Certbot ssl cert for your domain)
|
- Run the application (this should also set up a Certbot ssl cert for your domain)
|
||||||
`docker-compose up --build`
|
`docker-compose up --build`
|
||||||
|
@ -124,13 +125,13 @@ This project is still young and isn't, at the momoment, very stable, so please p
|
||||||
- Run docker-compose in the background
|
- Run docker-compose in the background
|
||||||
`docker-compose up -d`
|
`docker-compose up -d`
|
||||||
- Initialize the database
|
- Initialize the database
|
||||||
`./fr-dev initdb`
|
`./bw-dev initdb`
|
||||||
- Congrats! You did it, go to your domain and enjoy the fruits of your labors
|
- Congrats! You did it, go to your domain and enjoy the fruits of your labors
|
||||||
### Configure your instance
|
### Configure your instance
|
||||||
- Register a user account in the applcation UI
|
- Register a user account in the applcation UI
|
||||||
- Make your account a superuser (warning: do *not* use django's `createsuperuser` command)
|
- Make your account a superuser (warning: do *not* use django's `createsuperuser` command)
|
||||||
- On your server, open the django shell
|
- On your server, open the django shell
|
||||||
`./fr-dev shell`
|
`./bw-dev shell`
|
||||||
- Load your user and make it a superuser
|
- Load your user and make it a superuser
|
||||||
```python
|
```python
|
||||||
from bookwyrm import models
|
from bookwyrm import models
|
||||||
|
|
8
bookwyrm/context_processors.py
Normal file
8
bookwyrm/context_processors.py
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
''' customize the info available in context for rendering templates '''
|
||||||
|
from bookwyrm import models
|
||||||
|
|
||||||
|
def site_settings(request):
|
||||||
|
''' include the custom info about the site '''
|
||||||
|
return {
|
||||||
|
'site': models.SiteSettings.objects.get()
|
||||||
|
}
|
28
bookwyrm/migrations/0016_auto_20201211_2026.py
Normal file
28
bookwyrm/migrations/0016_auto_20201211_2026.py
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
# Generated by Django 3.0.7 on 2020-12-11 20:26
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('bookwyrm', '0015_auto_20201128_0349'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='sitesettings',
|
||||||
|
name='admin_email',
|
||||||
|
field=models.EmailField(blank=True, max_length=255, null=True),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='sitesettings',
|
||||||
|
name='support_link',
|
||||||
|
field=models.CharField(blank=True, max_length=255, null=True),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='sitesettings',
|
||||||
|
name='support_title',
|
||||||
|
field=models.CharField(blank=True, max_length=100, null=True),
|
||||||
|
),
|
||||||
|
]
|
|
@ -17,6 +17,9 @@ class SiteSettings(models.Model):
|
||||||
code_of_conduct = models.TextField(
|
code_of_conduct = models.TextField(
|
||||||
default="Add a code of conduct here.")
|
default="Add a code of conduct here.")
|
||||||
allow_registration = models.BooleanField(default=True)
|
allow_registration = models.BooleanField(default=True)
|
||||||
|
support_link = models.CharField(max_length=255, null=True, blank=True)
|
||||||
|
support_title = models.CharField(max_length=100, null=True, blank=True)
|
||||||
|
admin_email = models.EmailField(max_length=255, null=True, blank=True)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get(cls):
|
def get(cls):
|
||||||
|
|
|
@ -75,6 +75,7 @@ TEMPLATES = [
|
||||||
'django.template.context_processors.request',
|
'django.template.context_processors.request',
|
||||||
'django.contrib.auth.context_processors.auth',
|
'django.contrib.auth.context_processors.auth',
|
||||||
'django.contrib.messages.context_processors.messages',
|
'django.contrib.messages.context_processors.messages',
|
||||||
|
'bookwyrm.context_processors.site_settings',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -3,13 +3,13 @@
|
||||||
|
|
||||||
<div class="columns">
|
<div class="columns">
|
||||||
<div class="column block">
|
<div class="column block">
|
||||||
{% include 'snippets/about.html' with site_settings=site_settings %}
|
{% include 'snippets/about.html' %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="column block">
|
<div class="column block">
|
||||||
<h2 class="title">Code of Conduct</h2>
|
<h2 class="title">Code of Conduct</h2>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
{{ site_settings.code_of_conduct | safe }}
|
{{ site.code_of_conduct | safe }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="column">
|
<div class="column">
|
||||||
<div class="block">
|
<div class="block">
|
||||||
{% include 'snippets/about.html' with site_settings=site_settings %}
|
{% include 'snippets/about.html' %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<title>{% if title %}{{ title }} | {% endif %}BookWyrm</title>
|
<title>{% if title %}{{ title }} | {% endif %}{{ site.name }}</title>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<link type="text/css" rel="stylesheet" href="/static/css/bulma.min.css">
|
<link type="text/css" rel="stylesheet" href="/static/css/bulma.min.css">
|
||||||
<link type="text/css" rel="stylesheet" href="/static/css/format.css">
|
<link type="text/css" rel="stylesheet" href="/static/css/format.css">
|
||||||
|
@ -11,12 +11,10 @@
|
||||||
<link rel="shortcut icon" type="image/x-icon" href="/static/images/favicon.ico">
|
<link rel="shortcut icon" type="image/x-icon" href="/static/images/favicon.ico">
|
||||||
|
|
||||||
<meta name="twitter:card" content="summary">
|
<meta name="twitter:card" content="summary">
|
||||||
<meta name="twitter:title" content="BookWyrm">
|
<meta name="twitter:title" content="{{ site.name }}">
|
||||||
<meta name="og:title" content="BookWyrm">
|
<meta name="og:title" content="{{ site.name }}">
|
||||||
<meta name="twitter:description" content="Federated Social Reading">
|
<meta name="twitter:description" content="Federated Social Reading">
|
||||||
<meta name="og:description" content="Federated Social Reading">
|
<meta name="og:description" content="Federated Social Reading">
|
||||||
<meta name="twitter:creator" content="@tripofmice">
|
|
||||||
<meta name="twitter:site" content="@tripofmice">
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
|
@ -123,6 +121,30 @@
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="footer">
|
||||||
|
<div class="columns">
|
||||||
|
<div class="column">
|
||||||
|
<p>
|
||||||
|
<a href="/about">About this server</a>
|
||||||
|
</p>
|
||||||
|
{% if site.admin_email %}
|
||||||
|
<p>
|
||||||
|
<a href="mailto:{{ site.admin_email }}">Contact site admin</a>
|
||||||
|
</p>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% if site.support_link %}
|
||||||
|
<div class="column">
|
||||||
|
<span class="icon icon-heart"></span>
|
||||||
|
Support {{ site.name }} on <a href="{{ site.support_link }}" target="_blank">{{ site.support_title }}</a>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
<div class="column">
|
||||||
|
BookWyrm is open source software. You can contribute or report issues on <a href="https://github.com/mouse-reeve/bookwyrm">GitHub</a>.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
var csrf_token = '{{ csrf_token }}';
|
var csrf_token = '{{ csrf_token }}';
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div class="box has-background-primary-light">
|
<div class="box has-background-primary-light">
|
||||||
{% if site_settings.allow_registration %}
|
{% if site.allow_registration %}
|
||||||
<h2 class="title">Create an Account</h2>
|
<h2 class="title">Create an Account</h2>
|
||||||
<form name="register" method="post" action="/user-register">
|
<form name="register" method="post" action="/user-register">
|
||||||
{% include 'snippets/register_form.html' %}
|
{% include 'snippets/register_form.html' %}
|
||||||
|
@ -50,7 +50,7 @@
|
||||||
|
|
||||||
<div class="column">
|
<div class="column">
|
||||||
<div class="block">
|
<div class="block">
|
||||||
{% include 'snippets/about.html' with site_settings=site_settings %}
|
{% include 'snippets/about.html' %}
|
||||||
|
|
||||||
<p class="block">
|
<p class="block">
|
||||||
<a href="/about/">More about this site</a>
|
<a href="/about/">More about this site</a>
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
{% extends 'layout.html' %}
|
{% extends 'layout.html' %}
|
||||||
{% load humanize %}l
|
{% load humanize %}
|
||||||
|
{% load fr_display %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="block">
|
<div class="block">
|
||||||
<h1 class="title">Notifications</h1>
|
<h1 class="title">Notifications</h1>
|
||||||
|
@ -12,9 +13,10 @@
|
||||||
|
|
||||||
<div class="block">
|
<div class="block">
|
||||||
{% for notification in notifications %}
|
{% for notification in notifications %}
|
||||||
<div class="notification level{% if notification.id in unread %} is-primary{% endif %}">
|
<div class="notification {% if notification.id in unread %} is-primary{% endif %}">
|
||||||
<div class="level-left">
|
<div class="block">
|
||||||
<p>
|
<p>
|
||||||
|
{# DESCRIPTION #}
|
||||||
{% if notification.related_user %}
|
{% if notification.related_user %}
|
||||||
{% include 'snippets/avatar.html' with user=notification.related_user %}
|
{% include 'snippets/avatar.html' with user=notification.related_user %}
|
||||||
{% include 'snippets/username.html' with user=notification.related_user %}
|
{% include 'snippets/username.html' with user=notification.related_user %}
|
||||||
|
@ -30,10 +32,8 @@
|
||||||
<a href="{{ notification.related_status.remote_id}}">replied</a>
|
<a href="{{ notification.related_status.remote_id}}">replied</a>
|
||||||
to your
|
to your
|
||||||
<a href="{{ notification.related_status.reply_parent.remote_id}}">status</a>
|
<a href="{{ notification.related_status.reply_parent.remote_id}}">status</a>
|
||||||
|
|
||||||
{% elif notification.notification_type == 'FOLLOW' %}
|
{% elif notification.notification_type == 'FOLLOW' %}
|
||||||
followed you
|
followed you
|
||||||
|
|
||||||
{% elif notification.notification_type == 'FOLLOW_REQUEST' %}
|
{% elif notification.notification_type == 'FOLLOW_REQUEST' %}
|
||||||
sent you a follow request
|
sent you a follow request
|
||||||
<div class="row shrink">
|
<div class="row shrink">
|
||||||
|
@ -45,17 +45,30 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% else %}
|
{% else %}
|
||||||
your <a href="/import-status/{{ notification.related_import.id }}">import</a> completed.
|
your <a href="/import-status/{{ notification.related_import.id }}">import</a> completed.
|
||||||
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
{% if notification.related_status %}
|
||||||
<p class="level-right">{{ notification.created_date | naturaltime }}</p>
|
<div class="block">
|
||||||
|
{# PREVIEW #}
|
||||||
|
<div class="notification py-2 {% if notification.id in unread %}is-primary is-light{% else %}has-background-white{% if notification.notification_type == 'REPLY' or notification.notification_type == 'MENTION' %} has-text-black{% else %}-bis has-text-grey-dark{% endif %}{% endif %}">
|
||||||
|
<div class="columns">
|
||||||
|
<div class="column">
|
||||||
|
<a href="{{ notification.related_status.remote_id }}">{{ notification.related_status.content | truncatewords_html:10 }}</a>
|
||||||
|
</div>
|
||||||
|
<div class="column is-narrow {% if notification.notification_type == 'REPLY' or notification.notification_type == 'MENTION' %}has-text-black{% else %}has-text-grey-dark{% endif %}">
|
||||||
|
{{ notification.related_status.published_date | post_date }}
|
||||||
|
{% include 'snippets/privacy-icons.html' with item=notification.related_status %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
{% if not notifications %}
|
{% if not notifications %}
|
||||||
<p>You're all caught up!</p>
|
<p>You're all caught up!</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
|
|
||||||
<div class="column">
|
<div class="column">
|
||||||
<div class="block">
|
<div class="block">
|
||||||
{% include 'snippets/about.html' with site_settings=site_settings %}
|
{% include 'snippets/about.html' %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<h1 class="title">About {{ site_settings.name }}</h1>
|
<h1 class="title">About {{ site.name }}</h1>
|
||||||
<div class="block">
|
<div class="block">
|
||||||
<img src="/static/images/logo.png" alt="BookWyrm">
|
<img src="/static/images/logo.png" alt="BookWyrm">
|
||||||
</div>
|
</div>
|
||||||
<p class="block">
|
<p class="block">
|
||||||
{{ site_settings.instance_description }}
|
{{ site.instance_description }}
|
||||||
</p>
|
</p>
|
||||||
|
|
|
@ -42,7 +42,6 @@ def user_login(request):
|
||||||
login_form.non_field_errors = 'Username or password are incorrect'
|
login_form.non_field_errors = 'Username or password are incorrect'
|
||||||
register_form = forms.RegisterForm()
|
register_form = forms.RegisterForm()
|
||||||
data = {
|
data = {
|
||||||
'site_settings': models.SiteSettings.get(),
|
|
||||||
'login_form': login_form,
|
'login_form': login_form,
|
||||||
'register_form': register_form
|
'register_form': register_form
|
||||||
}
|
}
|
||||||
|
@ -78,7 +77,6 @@ def register(request):
|
||||||
|
|
||||||
if errors:
|
if errors:
|
||||||
data = {
|
data = {
|
||||||
'site_settings': models.SiteSettings.get(),
|
|
||||||
'login_form': forms.LoginForm(),
|
'login_form': forms.LoginForm(),
|
||||||
'register_form': form
|
'register_form': form
|
||||||
}
|
}
|
||||||
|
|
|
@ -131,7 +131,7 @@ def get_activity_feed(user, filter_level, model=models.Status):
|
||||||
activities = model.objects
|
activities = model.objects
|
||||||
|
|
||||||
activities = activities.filter(
|
activities = activities.filter(
|
||||||
deleted=False
|
deleted=False,
|
||||||
).order_by(
|
).order_by(
|
||||||
'-published_date'
|
'-published_date'
|
||||||
)
|
)
|
||||||
|
@ -160,6 +160,11 @@ def get_activity_feed(user, filter_level, model=models.Status):
|
||||||
Q(user__in=following, privacy='followers') | Q(privacy='public')
|
Q(user__in=following, privacy='followers') | Q(privacy='public')
|
||||||
)
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
activities = activities.filter(~Q(boosters__in=activities))
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
|
||||||
return activities
|
return activities
|
||||||
|
|
||||||
|
|
||||||
|
@ -235,7 +240,6 @@ def login_page(request):
|
||||||
# send user to the login page
|
# send user to the login page
|
||||||
data = {
|
data = {
|
||||||
'title': 'Login',
|
'title': 'Login',
|
||||||
'site_settings': models.SiteSettings.get(),
|
|
||||||
'login_form': forms.LoginForm(),
|
'login_form': forms.LoginForm(),
|
||||||
'register_form': forms.RegisterForm(),
|
'register_form': forms.RegisterForm(),
|
||||||
}
|
}
|
||||||
|
@ -247,7 +251,6 @@ def about_page(request):
|
||||||
''' more information about the instance '''
|
''' more information about the instance '''
|
||||||
data = {
|
data = {
|
||||||
'title': 'About',
|
'title': 'About',
|
||||||
'site_settings': models.SiteSettings.get(),
|
|
||||||
}
|
}
|
||||||
return TemplateResponse(request, 'about.html', data)
|
return TemplateResponse(request, 'about.html', data)
|
||||||
|
|
||||||
|
@ -295,7 +298,6 @@ def invite_page(request, code):
|
||||||
|
|
||||||
data = {
|
data = {
|
||||||
'title': 'Join',
|
'title': 'Join',
|
||||||
'site_settings': models.SiteSettings.get(),
|
|
||||||
'register_form': forms.RegisterForm(),
|
'register_form': forms.RegisterForm(),
|
||||||
'invite': invite,
|
'invite': invite,
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue