Skip to content

Commit

Permalink
Merge pull request #41 from animorphcoop/development
Browse files Browse the repository at this point in the history
Ongoing deployment
  • Loading branch information
nektdev authored Oct 13, 2024
2 parents 9407bd4 + efce717 commit f1ecd0e
Show file tree
Hide file tree
Showing 12 changed files with 818 additions and 1,821 deletions.
9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Shared Futures Space
# Shared Futures App

A project management platform where your community collaborates and gets stuff
done.
Expand Down Expand Up @@ -69,7 +69,7 @@ npm run dev

This will start a server that’s only serving static files.

Now your development instance (given you have started docker containers) is up and running! To see the app locally go to **http://127.0.0.1:9000**
Now your development instance (given you have started docker containers) is up and running! To see the app locally go to **http://127.0.0.1:9000** or **http://localhost:9000/** (0.0.0.0 is not going to render styles)

#### Building assets for production

Expand Down Expand Up @@ -176,6 +176,11 @@ Or Resources
docker compose -f dev/docker-compose.yaml exec app python3 manage.py load_resources dev/autoupload/resources.json
```

You can remove resources with the following command
```sh
docker compose -f dev/docker-compose.yaml exec app python3 manage.py clear_resources
```


Have a look at `devdata/devdata.json` for some user accounts you can log in as.

Expand Down
19 changes: 19 additions & 0 deletions apps/core/management/commands/clear_resources.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from django.core.management.base import BaseCommand
from resources.models import CaseStudy, HowTo, ResourceTag, CustomTag
from taggit.models import Tag


class Command(BaseCommand):
help = 'Clears all HowTo and CaseStudy entries from the database'

def handle(self, *args, **options):
# clear tags
ResourceTag.objects.all().delete()
CustomTag.objects.all().delete()
Tag.objects.all().delete()

# remove items
HowTo.objects.all().delete()
CaseStudy.objects.all().delete()
ResourceTag.objects.all().delete()
self.stdout.write(self.style.SUCCESS('Successfully cleared HowTo and CaseStudy entries'))
101 changes: 4 additions & 97 deletions apps/core/management/commands/load_devdata.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import json
from io import BytesIO
import os

from allauth.account.admin import EmailAddress
from area.models import Area, PostCode
Expand All @@ -11,83 +12,11 @@
from userauth.models import CustomUser, Organisation, UserAvatar
from wagtail.images.models import Image
from wagtail.rich_text import RichText
from django.contrib.contenttypes.models import ContentType
from taggit.models import Tag

DATA_DIR = "dev/autoupload/"


def add_resources(resource_data):
for new_howto_data in resource_data["How To"]:
try:
new_howto = HowTo.objects.get_or_create(
title=new_howto_data["title"],
summary=new_howto_data["summary"],
link=new_howto_data["link"],
location=new_howto_data.get("location", None),
location_exact=new_howto_data.get("location_exact", True),
)[0]
for tag in new_howto_data["tags"]:
new_howto.tags.add(tag)
new_howto.save()
except Exception as e:
print(
"could not add howto with definition: "
+ str(new_howto_data)
+ "\nerror given: "
+ repr(e)
)
for new_casestudy_data in resource_data["Case Study"]:
if new_casestudy_data["image"] != "":
try:
with open(DATA_DIR + new_casestudy_data["image"], "rb") as f:
pimg = PillowImage.open(DATA_DIR + new_casestudy_data["image"])
img = Image.objects.get_or_create(
file=ImageFile(
BytesIO(f.read()), name=new_casestudy_data["image"]
),
width=pimg.width,
height=pimg.height,
)[0]
new_casestudy = CaseStudy.objects.get_or_create(
title=new_casestudy_data["title"],
summary=new_casestudy_data["summary"],
case_study_image=img,
link=new_casestudy_data["link"],
location=new_casestudy_data.get("location", None),
location_exact=new_casestudy_data.get("location_exact", True),
)[0]
new_casestudy.body.append(
("body_text", {"content": RichText(new_casestudy_data["body"])})
)

for tag in new_casestudy_data["tags"]:
new_casestudy.tags.add(tag)
new_casestudy.save()

except Exception as e:
print(
"could not load case study image: "
+ str(new_casestudy_data["title"])
+ "\nerror given: "
+ repr(e)
)
else:
print(str(new_casestudy_data["title"]) + " has no image")
new_casestudy = CaseStudy.objects.get_or_create(
title=new_casestudy_data["title"],
summary=new_casestudy_data["summary"],
link=new_casestudy_data["link"],
location=new_casestudy_data.get("location", None),
location_exact=new_casestudy_data.get("location_exact", True),
)[0]
new_casestudy.body.append(
("body_text", {"content": RichText(new_casestudy_data["body"])})
)

for tag in new_casestudy_data["tags"]:
new_casestudy.tags.add(tag)
new_casestudy.save()


def add_organisations(data):
for org_data in data:
try:
Expand All @@ -103,22 +32,6 @@ def add_organisations(data):
)


def add_avatars(avatars_data):
for avatar_data in avatars_data:
try:
with open(DATA_DIR + avatar_data["avatar"], "rb") as f:
new_avatar = UserAvatar.objects.create()
new_avatar.avatar = ImageFile(f)
new_avatar.save()
except Exception as e:
print(
"could not add avatar with definition: "
+ str(avatar_data)
+ "\nerror given: "
+ repr(e)
)


def add_users(users_data):
for user_data in users_data:
try:
Expand Down Expand Up @@ -196,12 +109,6 @@ def handle(self, *args, **options):
print("could not read from file: " + options["datafile"])
exit()

add_avatars(data["User Avatars"])
if options["datafile"] == "autoupload/avatars.json":
# if datafile is avatars only, exit with success,
# else continue with the rest
exit(0)
add_areas(data["Areas"])
add_resources(data["Resources"])
add_organisations(data["Organisations"])
add_users(data["Users"])
add_users(data["Users"])
189 changes: 102 additions & 87 deletions apps/core/management/commands/load_resources.py
Original file line number Diff line number Diff line change
@@ -1,110 +1,125 @@
import json
from io import BytesIO

import os
from django.core.files.images import ImageFile
from django.core.management.base import BaseCommand
from django.contrib.gis.geos import Point
from PIL import Image as PillowImage
from resources.models import CaseStudy, HowTo
from taggit.models import Tag
from resources.models import CaseStudy, HowTo, CustomTag
from wagtail.images.models import Image
from wagtail.rich_text import RichText

DATA_DIR = "dev/autoupload/"


def add_resources(resource_data):
for new_howto_data in resource_data["How To"]:
try:
new_howto = HowTo.objects.get_or_create(
title=new_howto_data["title"],
summary=new_howto_data["summary"],
link=new_howto_data["link"],
location=new_howto_data.get("location", None),
location_exact=new_howto_data.get("location_exact", True),
)[0]
for tag_name in new_howto_data["tags"]:
tag, created = Tag.objects.get_or_create(name=tag_name)
new_howto.tags.add(tag)
new_howto.save()
except Exception as e:
print(
"could not add howto with definition: "
+ str(new_howto_data)
+ "\nerror given: "
+ repr(e)
)
for new_casestudy_data in resource_data["Case Study"]:
if new_casestudy_data["image"] != "":
class Command(BaseCommand):
help = 'Adds HowTo and CaseStudy entries from the database'

def add_arguments(self, parser):
parser.add_argument('resource_file', type=str, help='Path to the resources JSON file')

def handle(self, *args, **options):
resource_file = options['resource_file']
with open(resource_file, 'r') as file:
resource_data = json.load(file)
self.add_resources(resource_data)

def add_resources(self, resource_data):
resources = resource_data.get("Resources", {})
how_to_resources = resources.get("How To", [])
case_study_resources = resources.get("Case Study", [])

added_how_tos = 0
added_case_studies = 0

for new_howto_data in how_to_resources:
try:
# Ensure mandatory fields are not None
if any(key not in new_howto_data or new_howto_data[key] is None for key in
["title", "summary", "link"]):
raise ValueError(f"Missing mandatory field for How To: {new_howto_data}")

# Check if HowTo already exists
try:
new_howto = HowTo.objects.get(title=new_howto_data["title"])
is_new = False
except HowTo.DoesNotExist:
is_new = True
new_howto = HowTo(
title=new_howto_data["title"],
summary=new_howto_data["summary"],
link=new_howto_data["link"],
location_exact=new_howto_data.get("location_exact", True),
)

# Handle location
if location_data := new_howto_data.get('location'): # Check if location key exists and is not None
lat = float(location_data["lat"])
lng = float(location_data["lng"])
new_howto.location = Point(lng, lat)

# Handle tags
for tag_name in new_howto_data.get("tags", []): # Ensure 'tags' is an empty list if missing
new_howto.tags.add(tag_name)

new_howto.save()

if is_new:
added_how_tos += 1

except Exception as e:
self.stdout.write(
self.style.ERROR(f"Error loading How To '{new_howto_data.get('title', 'Unknown')}': {e}")
)

for new_casestudy_data in case_study_resources:
try:
with open(DATA_DIR + new_casestudy_data["image"], "rb") as f:
pimg = PillowImage.open(DATA_DIR + new_casestudy_data["image"])
img = Image.objects.get_or_create(
file=ImageFile(
BytesIO(f.read()), name=new_casestudy_data["image"]
),
width=pimg.width,
height=pimg.height,
)[0]
new_casestudy = CaseStudy.objects.get_or_create(
# Ensure mandatory fields are not None
if any(key not in new_casestudy_data or new_casestudy_data[key] is None for key in
["title", "summary", "link", "body"]):
raise ValueError(f"Missing mandatory field for case study: {new_casestudy_data}")

# Check if case study already exists
try:
new_casestudy = CaseStudy.objects.get(title=new_casestudy_data["title"])
is_new = False
except CaseStudy.DoesNotExist:
is_new = True
new_casestudy = CaseStudy(
title=new_casestudy_data["title"],
summary=new_casestudy_data["summary"],
case_study_image=img,
link=new_casestudy_data["link"],
location=new_casestudy_data.get("location", None),
location_exact=new_casestudy_data.get("location_exact", True),
)[0]
new_casestudy.body.append(
("body_text", {"content": RichText(new_casestudy_data["body"])})
)

for tag_name in new_casestudy_data["tags"]:
tag, created = Tag.objects.get_or_create(name=tag_name)
new_casestudy.tags.add(tag)
new_casestudy.save()
# Handle image
if (image_name := new_casestudy_data.get("image")): # Check if image key exists and is not None
image_path = os.path.join(DATA_DIR, image_name)
if os.path.exists(image_path): # Check if the image file exists
with open(image_path, "rb") as f:
img = Image.objects.get_or_create(
file=ImageFile(BytesIO(f.read()), name=image_name)
)[0]
new_casestudy.case_study_image = img
elif is_new:
new_casestudy.case_study_image = None

except Exception as e:
print(
"could not load case study image: "
+ str(new_casestudy_data["title"])
+ "\nerror given: "
+ repr(e)
)
else:
print(str(new_casestudy_data["title"]) + " has no image")
new_casestudy = CaseStudy.objects.get_or_create(
title=new_casestudy_data["title"],
summary=new_casestudy_data["summary"],
link=new_casestudy_data["link"],
location=new_casestudy_data.get("location", None),
location_exact=new_casestudy_data.get("location_exact", True),
)[0]
new_casestudy.body.append(
("body_text", {"content": RichText(new_casestudy_data["body"])})
)

for tag_name in new_casestudy_data["tags"]:
tag, created = Tag.objects.get_or_create(name=tag_name)
new_casestudy.tags.add(tag)
new_casestudy.save()
if new_casestudy_data.get("body"): # Check if body key exists
new_casestudy.body = [("body_text", {"content": RichText(new_casestudy_data["body"])})]

# Handle tags
for tag_name in new_casestudy_data.get("tags", []): # Ensure 'tags' is an empty list if missing
new_casestudy.tags.add(tag_name)

class Command(BaseCommand):
help = "import resource data"
new_casestudy.save()

def add_arguments(self, parser):
parser.add_argument("datafile", nargs="?", type=str)
if is_new:
added_case_studies += 1

def handle(self, *args, **options):
try:
f = open(options["datafile"])
try:
data = json.load(f)
except:
print("could not parse valid json from " + options["datafile"])
exit()
f.close()
except:
print("could not read from file: " + options["datafile"])
exit()

add_resources(data["Resources"])
except Exception as e:
self.stdout.write(
self.style.ERROR(f"Error loading case study '{new_casestudy_data.get('title', 'Unknown')}': {e}")
)

self.stdout.write(
self.style.SUCCESS(f"Added {added_how_tos} HowTo(s) and {added_case_studies} CaseStudy(ies) successfully."))
Loading

0 comments on commit f1ecd0e

Please sign in to comment.