Skip to content

Commit

Permalink
updated to work with new frontend
Browse files Browse the repository at this point in the history
  • Loading branch information
saylorsd committed Feb 16, 2025
1 parent ffb43a8 commit ea3f902
Show file tree
Hide file tree
Showing 10 changed files with 152 additions and 22 deletions.
3 changes: 3 additions & 0 deletions api/accounts/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,9 +137,12 @@ def activate(request, uidb64, token):
@api_view(['GET'])
@permission_classes([permissions.IsAuthenticated])
def check_login(request: Request):
print('😼', request.user)
try:
profile = UserProfile.objects.get(user=request.user)

except UserProfile.DoesNotExist:
print("missing")
return Response({'details': 'not logged in'}, status=status.HTTP_403_FORBIDDEN)
if profile.approved:
return Response(UserProfileSerializer(profile).data)
Expand Down
5 changes: 4 additions & 1 deletion api/housecat/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = os.environ.get('DEBUG', 'False').lower() in ['true', '1']

ALLOWED_HOSTS = json.loads(os.environ.get('ALLOWED_HOSTS', '["www.housecatpgh.org", "localhost"]'))
ALLOWED_HOSTS = ['127.0.0.1', 'localhost'] # sjson.loads(os.environ.get('ALLOWED_HOSTS', '["www.housecatpgh.org", "localhost", "127.0.0.1"]'))

# Application definition
INSTALLED_APPS = [
Expand All @@ -38,6 +38,7 @@
'django.contrib.staticfiles',
'rest_framework',
'rest_framework_gis',
'rest_framework.authtoken',

'housing_data',
'accounts'
Expand Down Expand Up @@ -155,7 +156,9 @@

REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.TokenAuthentication',
'rest_framework.authentication.SessionAuthentication',

],

'DEFAULT_RENDERER_CLASSES': (
Expand Down
8 changes: 6 additions & 2 deletions api/housecat/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,17 @@
from django.contrib import admin
from django.urls import path, include
from django.conf import settings

from rest_framework.authtoken.views import obtain_auth_token
urlpatterns = [
path('admin/', admin.site.urls),

path("auth/", include("django.contrib.auth.urls")),

path('data/', include('housing_data.urls')),
path('accounts/', include('accounts.urls'))

path('accounts/', include('accounts.urls')),

path('api-token-auth/', obtain_auth_token)
]

if settings.BASE_URL_PREFIX:
Expand Down
4 changes: 3 additions & 1 deletion api/housing_data/management/commands/connect_datastore.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,9 @@ def handle(self, *args, **options):
"fcb7cd5d-71f6-4f38-bb78-a3002be47ed6",
"a6b93b7b-e04e-42c9-96f9-ee788e4f0978",
"afba564f-cc68-42f0-b37b-fc8d70e8ef47",
"ecdbf89a-bbe7-4e82-b902-d6b774758d3a"
"ecdbf89a-bbe7-4e82-b902-d6b774758d3a",
"0b6a109e-b1f1-4064-8f42-eeb5355dc9df",
"e82411f8-623d-4336-b714-ecdded80703d"
)
FROM SERVER datastore INTO datastore;
Expand Down
37 changes: 37 additions & 0 deletions api/housing_data/migrations/0003_groupindex_parcelindex.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Generated by Django 5.1.4 on 2025-01-13 13:41

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('housing_data', '0002_fhlbfundingid_fhlbrentalprojects_and_more'),
]

operations = [
migrations.CreateModel(
name='GroupIndex',
fields=[
('id', models.IntegerField(db_column='_id', primary_key=True, serialize=False)),
('house_cat_id', models.CharField(max_length=100)),
('group_id', models.CharField(max_length=100)),
],
options={
'db_table': '0b6a109e-b1f1-4064-8f42-eeb5355dc9df',
'managed': False,
},
),
migrations.CreateModel(
name='ParcelIndex',
fields=[
('id', models.IntegerField(db_column='_id', primary_key=True, serialize=False)),
('parcel_id', models.CharField(max_length=100)),
('group_id', models.CharField(max_length=100)),
],
options={
'db_table': 'e82411f8-623d-4336-b714-ecdded80703d',
'managed': False,
},
),
]
80 changes: 77 additions & 3 deletions api/housing_data/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
from django.contrib.auth.models import User
from django.contrib.gis.db import models
from django.contrib.gis.geos import Point
from django.contrib.postgres.fields import ArrayField
from django.db import connections
from django.db.models import QuerySet, Q
from django.db.models.fields import CharField

from housecat.abstract_models import DatastoreDataset, Described
from housing_data.housing_datasets import (
Expand Down Expand Up @@ -76,6 +77,24 @@ def get_fkeys(model: Type['LookupTable'], origin_id: int):
TODAY = datetime.now().date()


class GroupIndex(DatastoreDataset):
house_cat_id = CharField(max_length=100)
group_id = CharField(max_length=100)

class Meta:
managed = False
db_table = '0b6a109e-b1f1-4064-8f42-eeb5355dc9df'


class ParcelIndex(DatastoreDataset):
parcel_id = CharField(max_length=100)
group_id = CharField(max_length=100)

class Meta:
managed = False
db_table = "e82411f8-623d-4336-b714-ecdded80703d"


class ProjectIndex(DatastoreDataset):
"""
Index of projects.
Expand Down Expand Up @@ -112,6 +131,14 @@ class Meta:
managed = False
db_table = '1885161c-65f3-4cb2-98aa-4402487ae888'

@property
def groups(self) -> list[str]:
return [g.group_id for g in GroupIndex.objects.filter(house_cat_id=self.house_cat_id)]

@property
def parcels(self) -> list[str]:
return [p.parcel_id for p in ParcelIndex.objects.filter(group_id__in=self.groups)]

@property
def subsidy_expiration_date(self):
""" Returns the earliest expiration date found to be associated with project """
Expand Down Expand Up @@ -153,6 +180,55 @@ def reac_scores(self):

return None

def has_parcel(self, parcel_ids: list[str]) -> bool:
"""Checks if this project has a parcel in the set of parcels in `parcel_ids` """
project_parcels = set(self.parcels)
search_parcels = set(parcel_ids)
result = project_parcels.intersection(search_parcels)
return bool(len(result))

@staticmethod
def filter_by_recent_sale(queryset: QuerySet['ProjectIndex'], months=6):
""" Finds projects that have had a parcel sell within the past `months` months """
conn = connections['datastore']
with conn.cursor() as cursor:
cursor.execute(
f"""SELECT "PARID" FROM "5bbe6c55-bce6-4edb-9d04-68edeb6bf7b1" WHERE "SALEDATE" > ('now'::timestamp - '{months} month'::interval)""")
parcels = [row[0] for row in cursor.fetchall()]

groups = [p.group_id for p in ParcelIndex.objects.filter(parcel_id__in=parcels)]
housecat_ids = [g.house_cat_id for g in GroupIndex.objects.filter(group_id__in=groups)]

return queryset.filter(house_cat_id__in=housecat_ids)

@staticmethod
def filter_by_recent_foreclosure(queryset: QuerySet['ProjectIndex'], months=6):
""" Finds projects that have had a foreclosure within the past `months` months """
conn = connections['datastore']
with conn.cursor() as cursor:
cursor.execute(
f"""SELECT "pin" FROM "859bccfd-0e12-4161-a348-313d734f25fd" WHERE "filing_date" > ('now'::timestamp - '{months} month'::interval)""")
parcels = [row[0] for row in cursor.fetchall()]

groups = [p.group_id for p in ParcelIndex.objects.filter(parcel_id__in=parcels)]
housecat_ids = [g.house_cat_id for g in GroupIndex.objects.filter(group_id__in=groups)]

return queryset.filter(house_cat_id__in=housecat_ids)

@staticmethod
def filter_by_recent_code_violation(queryset: QuerySet['ProjectIndex'], months=6):
""" Finds projects that have had a PLI violation within the past `months` months """
conn = connections['datastore']
with conn.cursor() as cursor:
cursor.execute(
f"""SELECT "parcel_id" FROM "70c06278-92c5-4040-ab28-17671866f81c" WHERE "investigation_date" > ('now'::timestamp - '{months} month'::interval)""")
parcels = [row[0] for row in cursor.fetchall()]

groups = [p.group_id for p in ParcelIndex.objects.filter(parcel_id__in=parcels)]
housecat_ids = [g.house_cat_id for g in GroupIndex.objects.filter(group_id__in=groups)]

return queryset.filter(house_cat_id__in=housecat_ids)

@staticmethod
def filter_by_risk_level(
queryset: QuerySet['ProjectIndex'],
Expand Down Expand Up @@ -487,5 +563,3 @@ def fhlb_projects(self):

def __str__(self):
return f'{self.id}: {self.hud_property_name}'


10 changes: 7 additions & 3 deletions api/housing_data/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -502,7 +502,6 @@ class Meta:
)



class FHLBRentalProjectsSerializer(serializers.ModelSerializer):
class Meta:
model = FHLBRentalProjects
Expand Down Expand Up @@ -554,7 +553,6 @@ class ProjectIndexSerializer(serializers.ModelSerializer):
fhlb_properties = FHLBRentalPropertiesSerializer(many=True)
fhlb_projects = FHLBRentalProjectsSerializer(many=True)


class Meta:
model = ProjectIndex
fields = (
Expand Down Expand Up @@ -601,7 +599,13 @@ class Meta:
'subsidy_info',

'fhlb_properties',
'fhlb_projects'
'fhlb_projects',

'groups',
'parcels',

"longitude",
"latitude",
)


Expand Down
17 changes: 13 additions & 4 deletions api/housing_data/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,27 @@ def get_filtered_project_indices(request: Request) -> QuerySet[ProjectIndex]:
.all()

# Match filter form items from app's map page
watchlist = request.query_params.get('watchlist')
recent_sale = request.query_params.get('recent-sale')
recent_foreclosure = request.query_params.get('recent-foreclosure')
recent_code_violation = request.query_params.get('recent-code-violation')

risk_level = request.query_params.get('risk-level')
lihtc_compliance = request.query_params.get('lihtc-compliance')
reac_score = request.query_params.get('reac-score')
last_inspection = request.query_params.get('last-inspection')
funding_category = request.query_params.get('funding-category')
status = request.query_params.get('status')

print(recent_sale)

# run all the filters
if watchlist:
wl = Watchlist.objects.get(slug=watchlist)
queryset = ProjectIndex.objects.filter(property_id__in=wl.items)
if recent_sale:
queryset = ProjectIndex.filter_by_recent_sale(queryset, months=int(recent_sale))
if recent_foreclosure:
queryset = ProjectIndex.filter_by_recent_foreclosure(queryset, months=int(recent_foreclosure))
if recent_code_violation:
queryset = ProjectIndex.filter_by_recent_code_violation(queryset, months=int(recent_code_violation))

if risk_level:
queryset = ProjectIndex.filter_by_risk_level(queryset, lvl=risk_level)
if lihtc_compliance:
Expand Down
8 changes: 0 additions & 8 deletions explorer/pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,6 @@ function HousecatHome() {
</div>
</button>
</Link>
{/*<Link href="/watchlist">*/}
{/* <button className={styles.bigButton}>*/}
{/* <div className={styles.buttonTitle}>✔️ Watchlist</div>*/}
{/* <div className={styles.buttonText}>*/}
{/* Limit to selected projects*/}
{/* </div>*/}
{/* </button>*/}
{/*</Link>*/}
<Link href="/search">
<button className={styles.bigButton}>
<div className={styles.buttonTitle}>🔍 Search</div>
Expand Down
2 changes: 2 additions & 0 deletions explorer/parts/MapInterface/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ export function MapInterface({

const { source, layers } = mapData || { extras: {} };

console.log(source);

return (
<div className={styles.wrapper}>
<div className={styles.menuSection}>
Expand Down

0 comments on commit ea3f902

Please sign in to comment.