• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

gcivil-nyu-org / Wednesday-Fall2023-Team-2 / #613359292

15 Nov 2023 08:49PM UTC coverage: 91.601%. First build
#613359292

Pull #94

travis-ci

Pull Request #94: Add spot

24 of 45 new or added lines in 2 files covered. (53.33%)

927 of 1012 relevant lines covered (91.6%)

0.92 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

68.66
/map/views.py
1
from typing import Optional
1✔
2
from django.views import View
1✔
3
from django.conf import settings
1✔
4
from django.db.models import Max
1✔
5
from better_profanity import profanity
1✔
6
from django.http import HttpRequest, HttpResponse, JsonResponse
7
from django.contrib.auth.mixins import LoginRequiredMixin
1✔
8
from django.shortcuts import get_object_or_404, render, redirect
1✔
9

1✔
10

11
from users.models import User, UserVerification, UserWatchedParkingSpace
1✔
12
from .models import OccupancyHistory, ParkingSpace
13
from .forms import CreatePostForm, CreateParkingSpaceForm
1✔
14

15

1✔
16
profanity.load_censor_words()
17
# Custom swear words can be added to this array
18
custom_badwords = ["bullshittery", "bitchy"]
1✔
19

20

21
class MapView(View):
1✔
22
    """main map view"""
23

1✔
24
    template_name = "map/parking.html"
25

26
    def get(self, request: HttpRequest) -> HttpResponse:
27
        """return map view page
28

29
        Args:
30
            request (HttpRequest): http request object
31

32
        Returns:
1✔
33
            HttpResponse: rendered map view response
1✔
34
        """
35
        user_verification = None
36
        if request.user.is_authenticated:
37
            user_verification = UserVerification.objects.filter(
38
                username=request.user
1✔
39
            ).first()
40

41
        context = {
1✔
42
            "GOOGLE_MAP_ID": settings.GOOGLE_MAP_ID,
43
            "GOOGLE_MAPS_API_KEY": settings.GOOGLE_MAPS_API_KEY,
44
            "user_verification": user_verification,
1✔
45
        }
1✔
46
        return render(request, self.template_name, context)
1✔
47

48

1✔
49
class PostView(View, LoginRequiredMixin):
50
    """create post view"""
51

52
    form_class = CreatePostForm
53
    template_name = "map/post.html"
54

55
    def get(self, request: HttpRequest, parking_spot_id: str) -> HttpResponse:
56
        """return post view
57

58
        Args:
59
            request (HttpRequest): http request object
60
            parking_spot_id (str): PK of ParkingSpace object clicked on map
61

1✔
62
        Returns:
1✔
63
            HttpResponse: rendered post view
1✔
64
        """
65
        spot = get_object_or_404(ParkingSpace, parking_spot_id=parking_spot_id)
1✔
66
        context = {
67
            "spot": spot,
68
            "form": self.form_class(None),
69
            "username": request.user.username,
70
        }
71
        return render(request, self.template_name, context)
72

73
    def post(self, request: HttpRequest, parking_spot_id: str) -> HttpResponse:
74
        """handle Post creation post req
75

76
        Args:
77
            request (HttpRequest): http request object
78
            parking_spot_id (str): PK of ParkingSpace object clicked on map
1✔
79
            username (str): username of post author
1✔
80

1✔
81
        Returns:
1✔
82
            HttpResponse: redirect or register view with error hints
1✔
83
        """
1✔
84
        map_template_name = "map/parking.html"
1✔
85
        author = get_object_or_404(User, username=request.user.username)
1✔
86
        spot = get_object_or_404(ParkingSpace, parking_spot_id=parking_spot_id)
1✔
87
        form = self.form_class(request.POST)
1✔
88
        if form.is_valid():
1✔
89
            profanity.add_censor_words(custom_badwords)
1✔
90
            new_post = form.save(commit=False)
1✔
91
            new_post.author = author
92
            new_post.parking_space = spot
93
            new_post.title = profanity.censor(form.cleaned_data["title"])
1✔
94
            new_post.post = profanity.censor(form.cleaned_data["post"])
95
            new_post.save()
96

1✔
97
            user_verification = None
1✔
98
            if request.user.is_authenticated:
1✔
99
                user_verification = UserVerification.objects.filter(
100
                    username=request.user
1✔
101
                ).first()
102

103
            map_context = {
104
                "GOOGLE_MAPS_API_KEY": settings.GOOGLE_MAPS_API_KEY,
105
                "GOOGLE_MAP_ID": settings.GOOGLE_MAP_ID,
106
                "spot": spot,
107
                "recenter_after_post": True,
108
                "user_verification": user_verification,
109
            }
NEW
110

×
111
            return render(request, map_template_name, map_context)
112

113
        return render(request, self.template_name, {"form": form})
114

115

116
class ParkingSpaceView(View, LoginRequiredMixin):
117
    """Parking Space view"""
NEW
118

×
119
    model = ParkingSpace
120
    form_class = CreateParkingSpaceForm
1✔
121
    template_name = "map/add_spot.html"
NEW
122

×
123
    def get(self, request: HttpRequest) -> HttpResponse:
124
        """return create spot view
NEW
125

×
126
        Args:
127
            request (HttpRequest): http request object
NEW
128
            username (str): username of post author
×
NEW
129

×
130
        Returns:
131
            HttpResponse: rendered create spot view
NEW
132
        """
×
NEW
133
        error = None
×
134
        if not (request.GET.get("lat") and request.GET.get("lon")):
135
            error = "Unable to collect longitude and latitude from URL. Please check if the URL is correct."
1✔
136
        return self.__render_page_with_optional_error(request, error)
137

138
    def __render_page_with_optional_error(
139
        self, request: HttpRequest, error: Optional[str] = None
140
    ) -> HttpResponse:
141
        user_verification = UserVerification.objects.filter(
142
            username=request.user
143
        ).first()
144
        context = {
NEW
145
            "error": error,
×
NEW
146
            "form": self.form_class(None),
×
NEW
147
            "username": request.user.username,
×
NEW
148
            "user_verification": user_verification,
×
NEW
149
        }
×
NEW
150
        return render(request, self.template_name, context)
×
NEW
151

×
NEW
152
    def __get_next_parkingspace_id(self):
×
NEW
153
        """helper method to get next spot ID
×
NEW
154

×
NEW
155
        Returns:
×
NEW
156
            _type_: _description_
×
NEW
157
        """
×
158
        max_parkingspace_id = self.model.objects.aggregate(Max("parking_spot_id"))[
159
            "parking_spot_id__max"
160
        ]
161
        if max_parkingspace_id is None:
162
            return "1"
163
        max_parkingspace_id = int(max_parkingspace_id)
164

165
        # Increment the max_parkingspace_id to get the next parkingspace_id
166
        return str(max_parkingspace_id + 1)
167

168
    def post(self, request: HttpRequest) -> HttpResponse:
169
        """handle spot creation post req
170

171
        Args:
172
            request (HttpRequest): http request object
173

174
        Returns:
175
            HttpResponse: redirect or register view with error hints
176
        """
177
        user = get_object_or_404(User, username=request.user.username)
178
        lat = request.GET.get("lat")
179
        lon = request.GET.get("lon")
180

181
        try:
182
            float(lat)
183
            float(lon)
184
        except ValueError or TypeError:
185
            return self.__render_page_with_optional_error(
186
                request,
187
                "We failed to obtain the longitude and latitude of the new spot you want to create. Please double check your URL to include valid longitude and latitude",
188
            )
189

190
        form = self.form_class(request.POST)
191
        map_template_name = "map/parking.html"
192
        if form.is_valid():
193
            new_spot = form.save(commit=False)
194
            new_spot.parking_spot_id = self.__get_next_parkingspace_id()
195
            new_spot.longitude = lon
196
            new_spot.latitude = lat
197
            new_spot.user = user
198
            new_spot.save()
199

200
            user_verification = None
201
            if request.user.is_authenticated:
202
                user_verification = UserVerification.objects.filter(
203
                    username=request.user
204
                ).first()
205
            map_context = {
206
                "GOOGLE_MAPS_API_KEY": settings.GOOGLE_MAPS_API_KEY,
207
                "GOOGLE_MAP_ID": settings.GOOGLE_MAP_ID,
208
                "spot": new_spot,
209
                "recenter_after_post": True,
210
                "user_verification": user_verification,
211
            }
212

213
            return render(request, map_template_name, map_context)
214
        return render(request, self.template_name, {"form": form})
215

216

217
class ProfileSpotRedirectView(View):
218
    """Spot Redirect view"""
219

220
    def get(self, request: HttpRequest, parking_spot_id: str) -> HttpResponse:
221
        """Args:
222
            request (HttpRequest): http request object
223
            parking_spot_id (str): id of a given spot
224

225
        Returns:
226
            HttpResponse: redirects user to the selected spot on the map
227
        """
228
        map_template_name = "map/parking.html"
229
        redirect_spot = ParkingSpace.objects.get(parking_spot_id=parking_spot_id)
230
        map_context = {
231
            "GOOGLE_MAPS_API_KEY": settings.GOOGLE_MAPS_API_KEY,
232
            "GOOGLE_MAP_ID": settings.GOOGLE_MAP_ID,
233
            "spot": redirect_spot,
234
            "recenter_after_post": True,
235
        }
236
        return render(request, map_template_name, map_context)
237

238

239
class PeakTimeView(View):
240
    """Peak Time view"""
241

242
    def get(self, request: HttpRequest, parking_spot_id: str) -> HttpResponse:
243
        """Args:
244
            request (HttpRequest): http request object
245
            parking_spot_id (str): id of a given spot
246

247
        Returns:
248
            HttpResponse: returns the peak time of a spot
249
        """
250
        history = OccupancyHistory.objects.filter(parking_space=parking_spot_id)
251
        times = {}
252

253
        if history:
254
            for entry in history:
255
                date = entry.updated_at
256
                date = date.strptime(str(date), "%Y-%m-%d %H:%M:%S.%f")
257

258
                hour = date.strftime("%H")
259

260
                if hour in times:
261
                    times[hour] += 1
262
                else:
263
                    times[hour] = 1
264

265
            return JsonResponse(
266
                {"peak_time": str(max(times, key=times.get) + " o'clock")}
267
            )
268
        else:
269
            return JsonResponse({"peak_time": "Not enough past data."})
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc