Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v7.18.2 #3490

Merged
merged 19 commits into from
Feb 16, 2024
Merged

v7.18.2 #3490

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
f994cf9
Add styling for speed limit sign
justyeethan Jun 30, 2023
8d1813c
Add environmental integration for python3 and upgrade python3 for che…
justyeethan Jul 14, 2023
fd5d549
Merge branch 'develop' of github.com:ProjectSidewalk/SidewalkWebpage …
justyeethan Jul 14, 2023
b992e3f
Revert back a script that is compatible with Python2 as the default
justyeethan Jul 14, 2023
bddd8f4
Complete label_clustering.py and address small issues with Shapely
justyeethan Jul 14, 2023
d38fdee
Merge branch 'develop' into 3099-python3-upgrade
misaugstad Feb 8, 2024
74ba9dc
updates Docker base image to support Python 3
misaugstad Feb 12, 2024
faeee61
removes code/css that we no longer use
misaugstad Feb 13, 2024
13c9501
updating README with dev env changes
misaugstad Feb 13, 2024
91afaff
Merge branch 'develop' into 3099-python3-upgrade
misaugstad Feb 13, 2024
afd7734
Merge pull request #3300 from ProjectSidewalk/3099-python3-upgrade
misaugstad Feb 13, 2024
f191278
modified URL to keep user on correct route
Feb 14, 2024
5cb5c96
Use localhost for the smtp relay; use a noreply from address
Feb 15, 2024
8393634
cleaning up old smtp relay info
misaugstad Feb 15, 2024
c9520bf
Merge pull request #3487 from ProjectSidewalk/use-local-mail-relay
misaugstad Feb 15, 2024
e24dbb9
Merge branch 'develop' into 3339-logging-in-removes-from-route
misaugstad Feb 16, 2024
2012404
Merge pull request #3485 from ProjectSidewalk/3339-logging-in-removes…
misaugstad Feb 16, 2024
61429a0
Merge branch 'master' of https://github.com/ProjectSidewalk/SidewalkW…
misaugstad Feb 16, 2024
d540278
7.18.1 -> 7.18.2
misaugstad Feb 16, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 16 additions & 18 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,35 +1,33 @@
FROM openjdk:8-jdk-buster
FROM eclipse-temurin:8u402-b06-jdk-focal

RUN apt-get update && apt-get upgrade -y

RUN curl -sL https://deb.nodesource.com/setup_14.x | bash -
RUN curl -sL https://deb.nodesource.com/setup_20.x | bash -

# Workaround because of bug in sbt from Debian.
# See https://github.com/sbt/sbt/issues/6614
# Workaround because of bug in sbt from Debian. See https://github.com/sbt/sbt/issues/6614.
RUN wget https://scala.jfrog.io/artifactory/debian/sbt-1.8.0.deb && \
apt-get install ./sbt-1.8.0.deb
apt-get install ./sbt-1.8.0.deb -y

RUN apt-get update && apt-get install -y \
RUN rm sbt-1.8.0.deb

RUN apt-get update && apt-get upgrade -y

RUN apt-get install -y \
unzip \
python-dev \
python-pip \
libblas-dev \
liblapack-dev \
gfortran \
python-numpy \
python-pandas \
python3-dev \
python3-pip \
nodejs && \
apt-get autoremove && \
apt-get clean

RUN pip install --upgrade pip
RUN pip install --upgrade setuptools

WORKDIR /opt
WORKDIR /home

COPY package.json ./
COPY requirements.txt ./

RUN pip install -r requirements.txt
# Python3 dependencies.
RUN python3 -m pip install --upgrade pip
RUN python3 -m pip install -r requirements.txt
RUN python3 -m pip install --upgrade setuptools

RUN npm install
21 changes: 6 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ On Windows, we recommend [Windows Powershell](https://docs.microsoft.com/en-us/p
Successfully tagged projectsidewalk/web:latest
WARNING: Image for service web was built because it did not already exist.
To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.
root@[container-id]:/opt#
root@[container-id]:/home#
```

1. In a separate terminal, run the command below.
Expand All @@ -102,10 +102,10 @@ On Windows, we recommend [Windows Powershell](https://docs.microsoft.com/en-us/p

Running "watch" task
Waiting...
[info] Loading project definition from /opt/project
[info] Set current project to sidewalk-webpage (in build file:/opt/)
[info] Loading project definition from /home/project
[info] Set current project to sidewalk-webpage (in build file:/home/)
[success] Total time: 78 s, completed Dec 20, 2018 8:06:19 AM
[info] Updating {file:/opt/}root...
[info] Updating {file:/home/}root...
[info] Resolving it.geosolutions.jaiext.errordiffusion#jt-errordiffusion;1.0.8 .[info] Resolving org.fusesource.jansi#jansi;1.4 ...
[info] Done updating.

Expand Down Expand Up @@ -151,6 +151,7 @@ We recommend the [IntelliJ IDEA](https://www.jetbrains.com/idea/) IDE for develo
- public/javascripts/Gallery/build
- public/javascripts/Help/build
- public/javascripts/Progress/build
- public/javascripts/PSMap/build
- public/javascripts/SVLabel/build
- public/javascripts/SVValidate/build
1. We then recommend installing a few plugins. To do so, go to `File -> Settings`. Select the `Plugins` option on the left sidebar and then `Marketplace` (on top menubar). For each of the following plugins, enter their name in the "search area" (textfield next to magnifying glass), find the plugin, and click `Install`: [Play 2 Routes](https://plugins.jetbrains.com/plugin/10053-play-2-routes/), [i18n support](https://plugins.jetbrains.com/plugin/12981-i18n-support/), [HOCON](https://plugins.jetbrains.com/plugin/10481-hocon), and [Scala](https://plugins.jetbrains.com/plugin/1347-scala) (if you haven't already). You will then need to restart IntelliJ to install the plugins.
Expand All @@ -173,7 +174,7 @@ Database: sidewalk
1. If you make any changes to the views or other scala files, these changes will be automatically picked up by `sbt`. You'd need to reload the browser once the compilation finishes. For example, a change to `index.scala.html` file results in:

```
[info] Compiling 1 Scala source to /opt/target/scala-2.10/classes...
[info] Compiling 1 Scala source to /home/target/scala-2.10/classes...
[success] Compiled in 260s

--- (RELOAD) ---
Expand Down Expand Up @@ -204,13 +205,3 @@ Database: sidewalk

[success] Compiled in 5s
```

## Running the application remotely
NOTE: This has not been tested in a very long time and may not work.

To run the application remotely,

1. Use Play's dist tool to create jar files of the project (i,e., `activator dist`): https://www.playframework.com/documentation/2.3.x/ProductionDist
1. Upload the zip file to the web server
1. SSH into the server and unarchive the zip file (e.g., `unzip filename`).
1. Run `nohup bin/sidewalk-webpage -Dhttp.port=9000 &` ([reference](http://alvinalexander.com/scala/play-framework-deploying-application-production-server)). Sometimes the application tells you that port 9000 (i.e., default port for a Play app) is taken. To kill an application that is occupying the port, first identify the pid with the netstat command `netstat -tulpn | grep :9000` and then use the `kill` command.
2 changes: 1 addition & 1 deletion app/controllers/AttributeController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ class AttributeController @Inject() (implicit val env: Environment[User, Session
val submission = request.body.validate[AttributeFormats.ClusteringSubmission]
submission.fold(
errors => {
Logger.warn("Failed to parse JSON POST request for multi-user clustering results.")
Logger.warn("Failed to parse JSON POST request for single-user clustering results.")
Logger.info(Json.prettyPrint(request.body))
Future.successful(BadRequest(Json.obj("status" -> "Error", "message" -> JsError.toFlatJson(errors))))
},
Expand Down
4 changes: 2 additions & 2 deletions app/controllers/ForgotPasswordController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import models.user._
import play.api.i18n.Messages
import controllers.headers.ProvidesHeader
import models.daos.slick.DBTableDefinitions.UserTable
import play.api.Logger
import play.api.{Logger, Play}
import play.api.libs.concurrent.Execution.Implicits._
import scala.concurrent.Future
import play.api.libs.mailer._
Expand Down Expand Up @@ -57,7 +57,7 @@ class ForgotPasswordController @Inject() (

val resetEmail = Email(
Messages("reset.pw.email.reset.title"),
"Project Sidewalk <mlprojectsidewalk@gmail.com>",
s"Project Sidewalk <${Play.configuration.getString("noreply-email-address").get}>",
Seq(email),
bodyHtml = Some(views.html.emails.resetPasswordEmail(user, url).body)
)
Expand Down
4 changes: 2 additions & 2 deletions app/controllers/helper/AttributeControllerHelper.scala
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ object AttributeControllerHelper {
for ((userId, i) <- usersToUpdate.view.zipWithIndex) {
Logger.info(s"Finished ${f"${100.0 * i / nUsers}%1.2f"}% of users, next: $userId.")
val clusteringOutput =
Seq("python", "label_clustering.py", "--key", key, "--user_id", userId).!!
Seq("python3", "label_clustering.py", "--key", key, "--user_id", userId).!!
// Logger.info(clusteringOutput)
}
Logger.info("Finshed 100% of users!!\n")
Expand All @@ -85,7 +85,7 @@ object AttributeControllerHelper {
// Runs multi-user clustering within each region.
for ((regionId, i) <- regionIds.view.zipWithIndex) {
Logger.info(s"Finished ${f"${100.0 * i / nRegions}%1.2f"}% of regions, next: $regionId.")
val clusteringOutput = Seq("python", "label_clustering.py", "--key", key, "--region_id", regionId.toString).!!
val clusteringOutput = Seq("python3", "label_clustering.py", "--key", key, "--region_id", regionId.toString).!!
}
Logger.info("Finshed 100% of regions!!\n\n")
}
Expand Down
10 changes: 2 additions & 8 deletions app/views/clustering.scala.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ <h1>Clustering labels into attributes</h1>
<button id="btn-multi-user-clustering">Multi User Clustering</button>
<button id="btn-both-clustering">Single AND Multi User Clustering</button>
<br/>
<label for="hours-to-go-back">If updating only, (integer) hours to go back:</label>
<input id="hours-to-go-back" type="number">
<p id="clustering-status"></p>
</div>
</div>
Expand All @@ -22,11 +20,9 @@ <h1>Clustering labels into attributes</h1>
let singleUserButton = document.getElementById('btn-single-user-clustering');
singleUserButton.onclick = function() {
$( "#clustering-status" ).html( 'Running...' );
let hours = document.getElementById('hours-to-go-back').value
let hoursParam = hours ? `&hoursCutoff=${hours}` : '';
$.ajax({
type: "get",
url: "/runClustering?clusteringType=singleUser" + hoursParam,
url: "/runClustering?clusteringType=singleUser",
contentType: 'application/json; charset=utf-8',
success: function (data) {
$( "#clustering-status" ).html(
Expand Down Expand Up @@ -66,11 +62,9 @@ <h1>Clustering labels into attributes</h1>
let bothButton = document.getElementById('btn-both-clustering');
bothButton.onclick = function() {
$( "#clustering-status" ).html( 'Running...' );
let hours = document.getElementById('hours-to-go-back').value
let hoursParam = hours ? `&hoursCutoff=${hours}` : '';
$.ajax({
type: "get",
url: "/runClustering?clusteringType=both" + hoursParam,
url: "/runClustering?clusteringType=both",
contentType: 'application/json; charset=utf-8',
success: function (data) {
$( "#clustering-status" ).html(
Expand Down
6 changes: 5 additions & 1 deletion app/views/explore.scala.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@
@cityName = @{cityNameShort.getOrElse(Messages(s"city.name.$cityId"))}

@main(title, Some("/explore")) {
@navbar(user, Some("/explore"))
@if(userRoute.isDefined) {
@navbar(user, Some(s"/explore?routeId=${userRoute.get.routeId}&resumeRoute=true"))
} else {
@navbar(user, Some("/explore"))
}

<link rel="stylesheet" href='@routes.Assets.at("javascripts/SVLabel/build/SVLabel.css")'/>
<link rel="stylesheet" href='@routes.Assets.at("stylesheets/animate.css")'/>
Expand Down
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import play.PlayScala

name := """sidewalk-webpage"""

version := "7.18.1"
version := "7.18.2"

scalaVersion := "2.10.7"

Expand Down
25 changes: 15 additions & 10 deletions check_streets_for_imagery.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import requests
import pandas as pd
from pandas.io.json import json_normalize
import sys
import os
from shapely import wkb
Expand All @@ -15,7 +14,7 @@ def write_output(no_imagery_df, curr_street):

# If we aren't done, save the last street we were working on at the end to keep track of our progress.
if curr_street is not None:
no_imagery_df = no_imagery_df.append({'street_edge_id': curr_street.street_edge_id, 'region_id': curr_street.region_id}, ignore_index=True)
no_imagery_df = pd.concat([no_imagery_df, pd.DataFrame({'street_edge_id': curr_street.street_edge_id, 'region_id': curr_street.region_id}, index=[0])])

# Convert street_edge_id column from float to int.
no_imagery_df.street_edge_id = no_imagery_df.street_edge_id.astype('int32')
Expand All @@ -33,11 +32,12 @@ def redistribute_vertices(geom):
num_vert = 1
return LineString([geom.interpolate(float(n) / num_vert, normalized=True) for n in range(num_vert + 1)])

if __name__ == '__main__':

def main():
# Read google maps API key from env variable.
api_key = os.getenv('GOOGLE_MAPS_API_KEY')
if api_key is None:
print "Couldn't read GOOGLE_MAPS_API_KEY environment variable."
print("Couldn't read GOOGLE_MAPS_API_KEY environment variable.")
exit(1)

# Read street edge data from CSV.
Expand All @@ -47,7 +47,7 @@ def redistribute_vertices(geom):
street_data['id'] = range(1, n_streets + 1)

# Convert geom to Shapely format and add vertices approximately every 15 meters.
street_data['geom'] = map(lambda g: redistribute_vertices(wkb.loads(g, hex=True)), street_data['geom'].values)
street_data['geom'] = list(map(lambda g: redistribute_vertices(wkb.loads(g, hex=True)), list(street_data['geom'])))

# Create dataframe that will hold output data.
streets_with_no_imagery = pd.DataFrame(columns=['street_edge_id', 'region_id'])
Expand Down Expand Up @@ -80,13 +80,13 @@ def redistribute_vertices(geom):
except (requests.exceptions.RequestException, KeyboardInterrupt) as e:
write_output(streets_with_no_imagery, street)
exit(1)
first_endpoint_fail = json_normalize(first_endpoint.json()).status[0] == 'ZERO_RESULTS'
second_endpoint_fail = json_normalize(second_endpoint.json()).status[0] == 'ZERO_RESULTS'
first_endpoint_fail = pd.json_normalize(first_endpoint.json()).status[0] == 'ZERO_RESULTS'
second_endpoint_fail = pd.json_normalize(second_endpoint.json()).status[0] == 'ZERO_RESULTS'

# If no imagery at either endpoint, add to no imagery list and move on. If at least one has imagery, check many
# points along the street for imagery to figure out whether or not most of the street is missing imagery.
if first_endpoint_fail and second_endpoint_fail:
streets_with_no_imagery = streets_with_no_imagery.append({'street_edge_id': street.street_edge_id, 'region_id': street.region_id}, ignore_index=True)
streets_with_no_imagery = pd.concat([streets_with_no_imagery, pd.DataFrame({'street_edge_id': street.street_edge_id, 'region_id': street.region_id}, index=[0])])
else:
n_success = 0
n_fail = 0
Expand All @@ -101,7 +101,7 @@ def redistribute_vertices(geom):
except (requests.exceptions.RequestException, KeyboardInterrupt) as e:
write_output(streets_with_no_imagery, street)
exit(1)
response_status = json_normalize(response.json()).status[0]
response_status = pd.json_normalize(response.json()).status[0]
if response_status == 'ZERO_RESULTS':
n_fail += 1
else:
Expand All @@ -112,9 +112,14 @@ def redistribute_vertices(geom):
# looping through the points we meet one of those criteria (or we find that we will not be able to meet
# either criteria because there have already been enough points with imagery), we break out of the loop.
if n_fail >= 0.5 * n_coord or (n_fail >= 0.25 * n_coord and (first_endpoint_fail or second_endpoint_fail)):
streets_with_no_imagery = streets_with_no_imagery.append({'street_edge_id': street.street_edge_id, 'region_id': street.region_id}, ignore_index=True)
streets_with_no_imagery = pd.concat([streets_with_no_imagery, pd.DataFrame({'street_edge_id': street.street_edge_id, 'region_id': street.region_id}, index=[0])])
break
elif n_success > 0.75 * n_coord or (n_success > 0.5 * n_coord and not first_endpoint_fail and not second_endpoint_fail):
break
print() # Stops the overflow on new line

write_output(streets_with_no_imagery, None)


if __name__ == '__main__':
main()
9 changes: 4 additions & 5 deletions conf/application.conf
Original file line number Diff line number Diff line change
Expand Up @@ -127,11 +127,10 @@ scistarter-api-key = ${?SCISTARTER_API_KEY}

internal-api-key = ${?INTERNAL_API_KEY}

smtp.host="smtp-relay.brevo.com"
smtp.port=587
smtp.tls=true
smtp.user=${?SIDEWALK_EMAIL_ADDRESS}
smtp.password=${?SIDEWALK_EMAIL_PASSWORD}
smtp.host="localhost"
smtp.port=25
smtp.tls=false
noreply-email-address="noreply@cs.washington.edu"

# For the ability to save crops on the server
play.http.parser.maxDiskBuffer = 100MB
Expand Down
5 changes: 5 additions & 0 deletions conf/evolutions/default/215.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# --- !Ups
INSERT INTO version VALUES ('7.18.2', now(), 'Fixes password reset emails not sending and API data not updating.');

# --- !Downs
DELETE FROM version WHERE version_id = '7.18.2';
6 changes: 2 additions & 4 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,15 @@ services:
depends_on:
- db
volumes:
- "./:/opt/:delegated"
- "/opt/node_modules"
- "./:/home/:delegated"
- "/home/node_modules"
ports:
- "9000:9000"
platform: linux/x86_64
# platform: linux/arm64
environment:
- DATABASE_USER=sidewalk
- SIDEWALK_CITY_ID=DUMMY_CITY_ID
- SIDEWALK_EMAIL_ADDRESS=DUMMY_EMAIL_ADDRESS
- SIDEWALK_EMAIL_PASSWORD=DUMMY_EMAIL_PASSWORD
- MAPBOX_API_KEY=DUMMY_MAPBOX_API_KEY
- GOOGLE_MAPS_API_KEY=DUMMY_GOOGLE_API_KEY
- GOOGLE_MAPS_SECRET=DUMMY_GOOGLE_SECRET
Expand Down
Loading