Skip to content

Commit 5388c99

Browse files
committed
Deploy release comrun
1 parent 66b23dd commit 5388c99

File tree

4 files changed

+126
-1
lines changed

4 files changed

+126
-1
lines changed

app/com/horstmann/codecheck/Util.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -616,7 +616,7 @@ public static String toJsonString(Object obj) {
616616
}
617617
}
618618

619-
public static ObjectNode fromJsonString(String jsonString) throws JsonProcessingException {
619+
public static ObjectNode fromJsonString(String jsonString) throws JsonProcessingException, IOException {
620620
return (ObjectNode) mapper.readTree(jsonString);
621621
}
622622

app/controllers/Config.java

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package controllers;
2+
3+
import java.io.IOException;
4+
import java.io.InputStream;
5+
import java.sql.Connection;
6+
7+
import com.google.inject.Inject;
8+
import com.google.inject.Singleton;
9+
import com.horstmann.codecheck.ResourceLoader;
10+
11+
import play.db.Database;
12+
import play.db.Databases;
13+
14+
@Singleton public class Config implements ResourceLoader {
15+
@Inject private com.typesafe.config.Config config;
16+
@Inject private play.api.Environment playEnv;
17+
private Database db;
18+
19+
public InputStream loadResource(String path) throws IOException {
20+
return playEnv.classLoader().getResourceAsStream("public/resources/" + path);
21+
}
22+
public String getProperty(String key) {
23+
return config.hasPath(key) ? config.getString(key) : null;
24+
}
25+
public String getString(String key) { // TODO Why do we need both getString and getProperty?
26+
return getProperty(key);
27+
}
28+
public boolean hasPath(String key) {
29+
return getProperty(key) != null;
30+
}
31+
32+
// TODO: Thread safety
33+
public Connection getDatabaseConnection() {
34+
if (db == null) {
35+
String driver = config.getString("com.horstmann.corejava.sql.driver");
36+
String url = config.getString("com.horstmann.corejava.sql.url");
37+
db = Databases.createFrom(driver, url);
38+
}
39+
return db.getConnection();
40+
}
41+
}

app/controllers/Util.java

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package controllers;
2+
3+
import play.mvc.Http;
4+
5+
import java.time.Duration;
6+
7+
public class Util {
8+
public static String prefix(Http.Request request) {
9+
boolean secure = request.secure() || request.getHeaders().getAll("X-Forwarded-Proto").contains("https");
10+
/*
11+
One shouldn't have to do this, but with Google Cloud, X-Forwarded-For has two entries (e.g. [95.90.234.41, 130.211.33.19])
12+
and X-Forwarded-Proto has one ([https]). From
13+
https://github.com/playframework/playframework/blob/814f0c73f86eb0e85bcae7f2167c73a08fed9fd7/transport/server/play-server/src/main/scala/play/core/server/common/ForwardedHeaderHandler.scala
14+
line 204, Play doesn't conclude that the connection was secure.
15+
*/
16+
String prefix;
17+
if (request.host().equals("localhost")) {
18+
prefix = "../";
19+
long countSlash = request.uri().chars().filter(ch -> ch == '/').count() - 1;
20+
for (long i = 0; i < countSlash; ++i) {
21+
prefix += "../";
22+
}
23+
prefix = prefix.substring(0, prefix.length() - 1);
24+
}
25+
else {
26+
prefix = (secure ? "https://" : "http://") + request.host();
27+
}
28+
return prefix;
29+
}
30+
31+
public static Http.Cookie buildCookie(String name, String value) {
32+
return Http.Cookie.builder(name, value)
33+
.withPath("/")
34+
.withMaxAge(Duration.ofDays(180))
35+
.withSameSite(Http.Cookie.SameSite.STRICT)
36+
.build();
37+
}
38+
}

public/editProblem.js

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
window.addEventListener('DOMContentLoaded', () => {
2+
3+
let i = 1
4+
let done = false
5+
while (!done) {
6+
const deleteButton = document.getElementById('delete' + i)
7+
if (deleteButton == null)
8+
done = true
9+
else {
10+
deleteButton.addEventListener('click',
11+
function() {
12+
document.getElementById('filename' + i).setAttribute('value', '')
13+
document.getElementById('contents' + i).innerHTML = ''
14+
document.getElementById('item' + i).style.display = 'none'
15+
})
16+
i++
17+
}
18+
}
19+
let fileIndex = i
20+
document.getElementById('addfile').addEventListener('click',
21+
function() {
22+
let fileDiv = document.createElement('div')
23+
fileDiv.setAttribute('id', 'item' + fileIndex)
24+
fileDiv.innerHTML = '<p>File name: <input id="filename' + fileIndex + '" name="filename' + fileIndex
25+
+ '" size="25" type="text"/> <button id="delete' + fileIndex
26+
+'" type="button">Delete</button></p><p><textarea id="contents' + fileIndex + '" name="contents' + fileIndex
27+
+ '" rows="24" cols="80"/></textarea></p>'
28+
let addFile = document.getElementById('addfilecontainer')
29+
addFile.parentNode.insertBefore(fileDiv, addFile)
30+
31+
document.getElementById('delete' + fileIndex).addEventListener('click',
32+
function() {
33+
document.getElementById('filename' + fileIndex).setAttribute('value', '')
34+
document.getElementById('contents' + fileIndex).innerHTML = ''
35+
document.getElementById('item' + fileIndex).style.display = 'none'
36+
})
37+
fileIndex++
38+
})
39+
40+
document.getElementById('upload').disabled = document.getElementById('file').files.length === 0
41+
42+
document.getElementById('file').addEventListener('change', function() {
43+
document.getElementById('upload').disabled = document.getElementById('file').files.length === 0
44+
})
45+
46+
})

0 commit comments

Comments
 (0)