Compare commits
2 Commits
85a34b20f9
...
0185c13a95
Author | SHA1 | Date | |
---|---|---|---|
0185c13a95 | |||
9632040ade |
20
Readme.md
20
Readme.md
@ -2,14 +2,14 @@
|
||||
|
||||
lostplaces-backend is a django (3.x) based webproject. It once wants to become a software which allows a group of urban explorers to manage, document and share the locations of lost places while not exposing too much / any information to the public.
|
||||
|
||||
The software is currently in early development status, neither scope, datalmodel(s) nor features are finalized yet. Therefore we would not recommend to download or install this piece of software anywhere - except your local django dev server.
|
||||
The software is currently in early development status, neither scope, datamodel(s) nor features are finalized yet. Therefore we would not recommend to download or install this piece of software anywhere - except your local django dev server.
|
||||
|
||||
We value privacy as a whole, all ressources the frontend requires will be shipped with lostplace's distribution. We also try to minimze the use of JavaScript as far as we can and try to offer JS-less alternatives where we can.
|
||||
We value privacy as a whole, all resources the frontend requires will be shipped with lostplace's distribution. We also try to minimize the use of JavaScript as far as we can and try to offer JS-less alternatives where we can.
|
||||
|
||||
## Features
|
||||
- Manage lost places with lots of usefull information.
|
||||
- Manage lost places with lots of useful information.
|
||||
- OSM-Maps
|
||||
- Sensitive information is not accesiable for anonymous (not logged in) users.
|
||||
- Sensitive information is not accessible for anonymous (not logged in) users.
|
||||
- User self registration using a voucher system, only people you invite can join your instance.
|
||||
- Collaboration, every user can add informations like tags, photos and external links to your place.
|
||||
|
||||
@ -63,9 +63,9 @@ Currently there are two ways to deploy the lostplaces project:
|
||||
|
||||
## Cloning the repository
|
||||
|
||||
Essentially, this is the same as installing a development instance, but without the development server (manage.py runserver) and something powerfull (Apache, NGINX) instead. You have to configure the webserve to work with the *SGI Api respectivly, reference [django's guide for deployment](https://docs.djangoproject.com/en/3.1/howto/deployment/) for further information.
|
||||
Essentially, this is the same as installing a development instance, but without the development server (manage.py runserver) and something powerful (Apache, NGINX) instead. You have to configure the webserver to work with the *SGI Api respectively, reference [django's guide for deployment](https://docs.djangoproject.com/en/3.1/howto/deployment/) for further information.
|
||||
|
||||
You also should setup a dedicated database server, the built-in SQLite file is not recommened for production use. Reference [django's guide for databases](https://docs.djangoproject.com/en/3.1/ref/databases/) for further information.
|
||||
You also should setup a dedicated database server, the built-in SQLite file is not recommended for production use. Reference [django's guide for databases](https://docs.djangoproject.com/en/3.1/ref/databases/) for further information.
|
||||
|
||||
Before making the django instance public, you should tweak the config `settings.py`:
|
||||
1. Change the secret key, the one found in the config is already public. Choose something secure (i.e. [this](https://duckduckgo.com/?q=password+generator+64)).
|
||||
@ -81,7 +81,7 @@ Run `django_lostplaces/managy.py collectstatic` and you should be ready to go.
|
||||
|
||||
If you haven't already setup a django instance, see [django's documentation](https://docs.djangoproject.com/en/3.1/topics/install/).
|
||||
|
||||
After that, download the desired release (probably the latest one) [from the realeases page](https://git.mowoe.com/reverend/lostplaces-backend/releases) and install it using `pip install --user name-of-the-file.tar.gz`
|
||||
After that, download the desired release (probably the latest one) [from the releases page](https://git.mowoe.com/reverend/lostplaces-backend/releases) and install it using `pip install --user name-of-the-file.tar.gz`
|
||||
|
||||
*Note: You can run pip install without the --user flag, which will require root privileges and introduces potential security issues.*
|
||||
|
||||
@ -119,7 +119,7 @@ LOGOUT_REDIRECT_URL = reverse_lazy('django_lostplaces_home')
|
||||
```
|
||||
|
||||
### Configuring the URL's
|
||||
In the `urls.py` configure the `urlpatter` like this:
|
||||
In the `urls.py` configure the `urlpatterns` like this:
|
||||
```python
|
||||
urlpatterns = [
|
||||
path('admin/', admin.site.urls),
|
||||
@ -133,5 +133,7 @@ Before making the django instance public, you should tweak the config `settings.
|
||||
1. Change the secret key, the one found in the config is already public. Choose something secure (i.e. [this](https://duckduckgo.com/?q=password+generator+64)).
|
||||
2. Turn off debug mode by setting `DEBUG = False`.
|
||||
3. Tune the localization settings, see [django's documentation](https://docs.djangoproject.com/en/3.1/topics/i18n/).
|
||||
4. Set a new (random) SECRET_KEY in settings.py, e. g.: `base64 /dev/urandom | head -c50`
|
||||
|
||||
Run `django_lostplaces/managy.py collectstatic` you should be ready to go.
|
||||
|
||||
Run `django_lostplaces/manage.py collectstatic` you should be ready to go.
|
||||
|
@ -13,13 +13,13 @@ The class `lostplaces.models.Explorer` is our custom user profile. It has an For
|
||||
|
||||
You can access the explorer profile by accessing the 'explorer' attribute of any user instance
|
||||
```python
|
||||
user.explorere
|
||||
user.explorer
|
||||
```
|
||||
|
||||
Currently the explorer profile is used by the abstract model 'Submittable' and thus referenced by 'Place' and 'PlaceImage'. The explorer profile therefore has two attributes
|
||||
```python
|
||||
user.explorer.places
|
||||
user.explorere.placeimages
|
||||
user.explorer.placeimages
|
||||
```
|
||||
`places`
|
||||
A list containing all (lost) places the user has submitted
|
||||
@ -36,12 +36,12 @@ TaggableManager, allows the sub class to be tagged, blank=True allows the admin
|
||||
### Mapable
|
||||
The abstract model Mapable represents an model that can be displayed on a map. It consists of tree members
|
||||
`name`
|
||||
Name of the object, displayed on the map, max length 50 characeter
|
||||
Name of the object, displayed on the map, max length 50 characters
|
||||
`latitude`
|
||||
Latitude of the referenced location, -90 <= value <= 90
|
||||
`longitude`
|
||||
Longitude of the referenced location -180 <= value <= 180
|
||||
A mapable model has to provide its own get_aboslute_url, in order to provide a link when clicked.
|
||||
A mapable model has to provide its own get_absolute_url, in order to provide a link when clicked.
|
||||
|
||||
|
||||
### Submittable
|
||||
@ -49,15 +49,15 @@ The abstract model Submittable represents an model that can be submitted by an u
|
||||
`submitted_by`
|
||||
Referencing the explorer profile, see [Explorer](##explorer-user-profile). If the explorer profile is deleted, this instance is kept (on_delete=models.SET_NULL). The related_name is set to the class name, lower case appending an s (%(class)s)
|
||||
`submitted_when`
|
||||
When the object was submitted, automaticly set by django (auto_now_add=True)
|
||||
When the object was submitted, automatically set by django (auto_now_add=True)
|
||||
|
||||
|
||||
### Voucher
|
||||
A voucher code is needed to sign up using lostplaces sign up form. The model contains
|
||||
`code`
|
||||
The voucher code, max length 30 character
|
||||
The voucher code, max length 30 characters
|
||||
`created_when`
|
||||
When the voucher was created automaticly set by django (auto_now_add=True)
|
||||
When the voucher was created automatically set by django (auto_now_add=True)
|
||||
`expires_when`
|
||||
Till what date the voucher remains valid
|
||||
|
||||
@ -65,7 +65,7 @@ Till what date the voucher remains valid
|
||||
### Place
|
||||
The place model is the heart of this project. It stores all information about a place needed.
|
||||
`location`
|
||||
Human readable location description (town, village, street), max length 50 character
|
||||
Human readable location description (town, village, street), max length 50 characters
|
||||
`description`
|
||||
Describing the place in detail
|
||||
The place model uses these abstract super classes
|
||||
|
@ -19,9 +19,9 @@ class ExplorerCreationForm(UserCreationForm):
|
||||
|
||||
def is_valid(self):
|
||||
super().is_valid()
|
||||
sumitted_voucher = self.cleaned_data.get('voucher')
|
||||
submitted_voucher = self.cleaned_data.get('voucher')
|
||||
try:
|
||||
fetched_voucher = Voucher.objects.get(code=sumitted_voucher)
|
||||
fetched_voucher = Voucher.objects.get(code=submitted_voucher)
|
||||
except Voucher.DoesNotExist:
|
||||
self.add_error('voucher', 'Invalid voucher')
|
||||
return False
|
||||
|
@ -48,7 +48,7 @@ def save_user_profile(sender, instance, **kwargs):
|
||||
|
||||
class Taggable(models.Model):
|
||||
'''
|
||||
This abstract model represtens an object that is taggalble
|
||||
This abstract model represtens an object that is taggable
|
||||
using django-taggit
|
||||
'''
|
||||
class Meta:
|
||||
@ -150,7 +150,7 @@ class Place(Submittable, Taggable, Mapable):
|
||||
def generate_image_upload_path(instance, filename):
|
||||
"""
|
||||
Callback for generating path for uploaded images.
|
||||
Returns filename as: placepk-placename{-rndstring}.jpg
|
||||
Returns filename as: place_pk-placename{-rnd_string}.jpg
|
||||
"""
|
||||
|
||||
return 'places/' + str(instance.place.pk) + '-' + str(instance.place.name) + '.' + filename.split('.')[-1]
|
||||
@ -178,7 +178,7 @@ class PlaceImage (Submittable):
|
||||
def __str__(self):
|
||||
"""
|
||||
Returning the name of the corresponding place + id
|
||||
of this image as textual represntation of this instance
|
||||
of this image as textual representation of this instance
|
||||
"""
|
||||
|
||||
return 'Image ' + str(self.pk)
|
||||
|
@ -0,0 +1,3 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
@ -1,3 +1,6 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from django import template
|
||||
|
||||
register = template.Library()
|
||||
|
@ -1,3 +1,6 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import json, os
|
||||
from importlib import import_module
|
||||
|
||||
|
@ -45,7 +45,7 @@ class PlaceTestCase(ModelTestCase):
|
||||
max_length=100
|
||||
)
|
||||
|
||||
def test_decsription(self):
|
||||
def test_description(self):
|
||||
self.assertField('description', models.TextField)
|
||||
|
||||
def test_average_latlon(self):
|
||||
@ -112,7 +112,7 @@ class PlaceTestCase(ModelTestCase):
|
||||
)
|
||||
)
|
||||
self.assertEqual(avg_latlon['longitude'], 0,
|
||||
msg='%s: a(no places) verage longitude missmatch' % (
|
||||
msg='%s: (no places) average longitude missmatch' % (
|
||||
self.model.__name__
|
||||
)
|
||||
)
|
||||
|
@ -10,7 +10,7 @@ from lostplaces.models import Voucher
|
||||
from lostplaces.tests.models import ModelTestCase
|
||||
|
||||
|
||||
class VoucheTestCase(ModelTestCase):
|
||||
class VoucherTestCase(ModelTestCase):
|
||||
model = Voucher
|
||||
|
||||
@classmethod
|
||||
|
@ -9,7 +9,7 @@ from taggit.models import Tag
|
||||
|
||||
class ViewTestCase(TestCase):
|
||||
'''
|
||||
This is a mixni for testing views. It provides functionality to
|
||||
This is a Mixin for testing views. It provides functionality to
|
||||
test the context, forms and HTTP Response of responses.
|
||||
All methods take responses, so this base class can be used
|
||||
with django's RequestFactory and Test-Client
|
||||
@ -71,7 +71,7 @@ class ViewTestCase(TestCase):
|
||||
def assertHttpRedirect(self, response, redirect_to=None):
|
||||
'''
|
||||
Checks weather the response redirected, and if passed,
|
||||
if it redirected to the expected loaction
|
||||
if it redirected to the expected location
|
||||
'''
|
||||
|
||||
self.assertTrue(
|
||||
@ -87,7 +87,7 @@ class ViewTestCase(TestCase):
|
||||
self.assertEqual(
|
||||
response['location'],
|
||||
redirect_to,
|
||||
msg='Expecing the response to redirect to %s, where redirected to %s instea' % (
|
||||
msg='Expecting the response to redirect to %s, where redirected to %s instea' % (
|
||||
str(redirect_to),
|
||||
str(response['location'])
|
||||
)
|
||||
|
@ -16,7 +16,7 @@ from lostplaces.models import Place
|
||||
|
||||
class IsAuthenticatedMixin(LoginRequiredMixin, View):
|
||||
'''
|
||||
A view mixin that checks wether a user is loged in or not.
|
||||
A view mixin that checks wether a user is logged in or not.
|
||||
If the user is not logged in, he gets redirected to
|
||||
the login page.
|
||||
'''
|
||||
@ -29,9 +29,9 @@ class IsAuthenticatedMixin(LoginRequiredMixin, View):
|
||||
|
||||
class IsPlaceSubmitterMixin(UserPassesTestMixin, View):
|
||||
'''
|
||||
A view mixin that checks wethe a user is the submitter
|
||||
of a place Throws 403 if the user is not. The subclass
|
||||
has to provide a get_place method, wich returns the
|
||||
A view mixin that checks wether a user is the submitter
|
||||
of a place, throws 403 if the user is not. The subclass
|
||||
has to provide a get_place method, which returns the
|
||||
place to check.
|
||||
'''
|
||||
place_submitter_error_message = None
|
||||
|
3992
django_lostplaces/testdata/testdata.json
vendored
3992
django_lostplaces/testdata/testdata.json
vendored
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user