Skip to content

Commit

Permalink
Merge branch 'main' into james/search_notes
Browse files Browse the repository at this point in the history
  • Loading branch information
james-otten authored Apr 21, 2024
2 parents c78a0c1 + 0cc3b9d commit d7c7ade
Show file tree
Hide file tree
Showing 6 changed files with 181 additions and 65 deletions.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ dependencies = [
"djangorestframework@git+https://github.com/encode/django-rest-framework.git@4bbfa8d4556b5847e91ba95f457cc862b7a0f027",
"drf-hooks==0.1.3",
"psycopg2-binary==2.9.*",
"gunicorn==21.2.*",
"gunicorn==22.0.*",
"python-dotenv==1.0.*",
"stringcase==1.2.*",
"python-dotenv==1.0.*",
Expand Down
78 changes: 72 additions & 6 deletions src/meshapi/management/commands/scramble_members.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
from random import randrange
from datetime import datetime, timedelta
from random import randint, randrange

from django.core.management.base import BaseCommand
from django.db import transaction
from faker import Faker

from meshapi.models import Install, Member
from meshapi.models import Install, Member, install
from meshapi.models.building import Building
from meshapi.models.devices.device import Device
from meshapi.models.link import Link
from meshapi.models.node import Node


# Uses faker to get fake names, emails, and phone numbers
Expand All @@ -24,11 +30,12 @@ def add_arguments(self, parser):
help="Skip scrambling installs",
)

@transaction.atomic
def handle(self, *args, **options):
print("Scrambling members...")
members = Member.objects.all()
print("Scrambling database with fake information")
fake = Faker()
if not options["skip_members"]:
members = Member.objects.all()
print("Scrambling members...")
for member in members:
member.name = fake.name()
Expand All @@ -39,14 +46,73 @@ def handle(self, *args, **options):
member.slack_handle = ""
member.notes = fake.text()
member.save()
print(f"{member.id} - {member.name}")

if not options["skip_installs"]:
print("Scrambling installs...")
installs = Install.objects.all()
for install in installs:
install.unit = randrange(100)
install.notes = fake.text()
install.request_date, install.install_date, install.abandon_date = self.fuzz_dates(
install.request_date, install.install_date, install.abandon_date
)
install.save()
print(install.install_number)

print("Scrambling all other notes and dates")

print("Scrambling buildings...")
buildings = Building.objects.all()
for building in buildings:
building.notes = fake.text()
# Fuzz the street address, if possible
if building.street_address:
address = building.street_address.split(" ")
if len(address) > 0:
try:
fuzzed_street_number = str(int(address[0]) + randint(1, 20))
street_name = " ".join(address[1:])
building.street_address = f"{fuzzed_street_number} {street_name}"
except ValueError:
pass

building.save()

print("Scrambling devices...")
devices = Device.objects.all()
for device in devices:
device.notes = fake.text()
_, device.install_date, device.abandon_date = self.fuzz_dates(
None, device.install_date, device.abandon_date
)
device.save()

print("Scrambling links...")
links = Link.objects.all()
for link in links:
link.notes = fake.text()
_, link.install_date, link.abandon_date = self.fuzz_dates(None, link.install_date, link.abandon_date)
link.save()

print("Scrambling nodes...")
nodes = Node.objects.all()
for node in nodes:
node.notes = fake.text()
_, node.install_date, node.abandon_date = self.fuzz_dates(None, node.install_date, node.abandon_date)
node.save()

print("Done")

@staticmethod
def fuzz_dates(request_date, install_date, abandon_date):
if request_date:
# Make it happen sooner so that there's no way the request date is
# now beyond the install/abandon date.
request_date -= timedelta(days=randint(14, 100))

if install_date:
install_date += timedelta(days=randint(14, 100))

if abandon_date:
abandon_date += timedelta(days=randint(100, 200))

return request_date, install_date, abandon_date
29 changes: 29 additions & 0 deletions src/meshapi/views/query_api.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from django.db.models import Q
from django_filters import rest_framework as filters
from drf_spectacular.utils import extend_schema, extend_schema_view

from meshapi.docs import query_form_password_param
from meshapi.models import Install
from meshapi.permissions import LegacyMeshQueryPassword
from meshapi.serializers.query_api import QueryFormSerializer
Expand Down Expand Up @@ -32,6 +34,15 @@ class Meta:
fields = []


@extend_schema_view(
get=extend_schema(
tags=["Legacy Query Form"],
parameters=[query_form_password_param],
summary="Query & filter based on Member attributes. "
"Results are returned as flattened spreadsheet row style output",
auth=[],
),
)
class QueryMember(FilterRequiredListAPIView):
queryset = (
Install.objects.all()
Expand All @@ -53,6 +64,15 @@ class Meta:
fields = ["install_number", "member", "building", "status"]


@extend_schema_view(
get=extend_schema(
tags=["Legacy Query Form"],
parameters=[query_form_password_param],
summary="Query & filter based on Install attributes. "
"Results are returned as flattened spreadsheet row style output",
auth=[],
),
)
class QueryInstall(FilterRequiredListAPIView):
queryset = (
Install.objects.all()
Expand All @@ -78,6 +98,15 @@ class Meta:
fields = ["bin", "zip_code"]


@extend_schema_view(
get=extend_schema(
tags=["Legacy Query Form"],
parameters=[query_form_password_param],
summary="Query & filter based on Building attributes. "
"Results are returned as flattened spreadsheet row style output",
auth=[],
),
)
class QueryBuilding(FilterRequiredListAPIView):
queryset = (
Install.objects.all()
Expand Down
49 changes: 49 additions & 0 deletions src/meshweb/static/meshweb/styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
.max-width-container {
max-width: 1200px !important;
padding: 0em 3em;
/* margin: 0 auto; */
/* padding: 10em; */
}

a {
color: inherit !important;
}

body {
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: stretch;
}

footer,
nav {
--bs-bg-opacity: 1;
background-color: #f4f4f4 !important;
}

footer {
width: 100%;
left: 0;
bottom: 0;
flex-grow: 1;
}

footer a {
text-decoration: none;
}

.links {
display: flex;
justify-content: center !important;
column-gap: 3rem;
row-gap: 2rem;
flex-wrap: wrap;
align-content: flex-start;
}

.toolList {
display: flex;
flex-direction: column;
line-height: 3em;
}
68 changes: 11 additions & 57 deletions src/meshweb/templates/meshweb/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,51 +10,7 @@
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous">
<link rel="shortcut icon" href="{% static 'meshweb/favicon.png' %}" />
<style>
.max-width-container {
max-width: 1200px !important;
padding: 0em 3em;
/* margin: 0 auto; */
/* padding: 10em; */
}

a {
color: inherit !important;
}

body {
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: stretch;
}

footer,
nav {
--bs-bg-opacity: 1;
background-color: #f4f4f4 !important;
}

footer {
width: 100%;
left: 0;
bottom: 0;
flex-grow: 1;
}

footer a {
text-decoration: none;
}

.links {
display: flex;
justify-content: center !important;
column-gap: 3rem;
row-gap: 2rem;
flex-wrap: wrap;
align-content: flex-start;
}
</style>
<link rel="stylesheet" href="{% static 'meshweb/styles.css' %}" />
</head>

<body>
Expand Down Expand Up @@ -105,19 +61,17 @@ <h1>Welcome to MeshDB!</h1>
It can be used to track Installs, Members, and Buildings in the mesh.
</p>
<p>Reach out on Slack if you need access.</p>
<b>Here are some links to various services provided by this server:</b>
<div style=" display:flex; flex-direction: row; justify-content: space-between; margin-top: 20px" class="links">
<a href="https://forms.grandsvc.mesh.nycmesh.net/join/">Join Our Community Network!</a>
<a href="/admin">Admin Panel</a>
<a href="https://forms.grandsvc.mesh.nycmesh.net/">Other Forms</a>
<a href="/api/v1/">MeshDB Data API</a>
<a href="/api-docs/swagger/">API Documentation (Swagger)</a>
<a href="/api-docs/redoc/">API Documentation (Redoc)</a>
<a href="https://los.grandsvc.mesh.nycmesh.net/">Line of Sight Tool</a>
<a href="https://map.grandsvc.mesh.nycmesh.net">Map</a>
<a href="https://github.com/nycmeshnet/meshdb">Source Code</a>
<hr>
<div style="display:flex; flex-direction: row; justify-content: space-between; margin-top: 20px" class="links">
{% for category, tools in links.items %}
<div class="toolList">
<h3>{{ category }}</h3>
{% for link, description in tools %}
<a href={{ link }}>{{ description }}</a>
{% endfor %}
</div>
{% endfor %}
</div>

</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"
Expand Down
20 changes: 19 additions & 1 deletion src/meshweb/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,23 @@
@permission_classes([permissions.AllowAny])
def index(request):
template = loader.get_template("meshweb/index.html")
context = {}
links = {
"Member Tools": [
("https://forms.grandsvc.mesh.nycmesh.net/join/", "Join Form"),
("https://los.grandsvc.mesh.nycmesh.net/", "Line of Sight Tool"),
("https://map.grandsvc.mesh.nycmesh.net", "Map"),
],
"Volunteer Tools": [
("/admin", "Admin Panel"),
("/api/v1/geography/whole-mesh.kml", "KML Download"),
("https://forms.grandsvc.mesh.nycmesh.net/", "Other Forms"),
],
"Developer Tools": [
("https://github.com/nycmeshnet/meshdb", "Source Code"),
("/api/v1/", "MeshDB Data API"),
("/api-docs/swagger/", "API Documentation (Swagger)"),
("/api-docs/redoc/", "API Documentation (Redoc)"),
],
}
context = {"links": links}
return HttpResponse(template.render(context, request))

0 comments on commit d7c7ade

Please sign in to comment.