Better README.
Added images and checkboxes to the features section.
This commit is contained in:
parent
46b82a18b5
commit
98cd823999
11 changed files with 33 additions and 12 deletions
1
.idea/gradle.xml
generated
1
.idea/gradle.xml
generated
|
|
@ -5,6 +5,7 @@
|
||||||
<option name="linkedExternalProjectsSettings">
|
<option name="linkedExternalProjectsSettings">
|
||||||
<GradleProjectSettings>
|
<GradleProjectSettings>
|
||||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||||
|
<option name="gradleJvm" value="#JAVA_HOME" />
|
||||||
<option name="modules">
|
<option name="modules">
|
||||||
<set>
|
<set>
|
||||||
<option value="$PROJECT_DIR$" />
|
<option value="$PROJECT_DIR$" />
|
||||||
|
|
|
||||||
29
README.md
29
README.md
|
|
@ -1,17 +1,32 @@
|
||||||
# LivingRoom
|
# LivingRoom
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
This is a work-in-progress kinda of game launcher. LivingRoom is a server software that allows you to organize, display and distribute your catalog of games.
|
This is a work-in-progress kinda of game launcher. LivingRoom is a server software that allows you to organize, display and distribute your catalog of games.
|
||||||
|
|
||||||
The server includes a (working but very WIP) HTTP API for third-party clients and an web interface.
|
The server includes a (working but very WIP) HTTP API for third-party clients and a web interface.
|
||||||
|
|
||||||
## Features
|
|
||||||
|
|
||||||
- HTTP API (NO AUTHENTICATION YET)
|
## Features
|
||||||
- Web interface
|
### HTTP API
|
||||||
- User management
|
- [ ] Authentication
|
||||||
|
- [x] Library info
|
||||||
|
- [x] Game info
|
||||||
|
- [x] Downloads
|
||||||
|
- [ ] Resumable downloads
|
||||||
|
- [ ] User Management
|
||||||
|
- [ ] Search
|
||||||
|
|
||||||
|
### Web interface
|
||||||
|
- [x] Authentication
|
||||||
|
- [x] Game listing
|
||||||
|
- [x] Game page
|
||||||
|
- [x] Admin actions
|
||||||
|
- [x] Deindex game
|
||||||
|
- [x] Trigger new scan
|
||||||
|
- [x] Downloads (from the API)
|
||||||
|
- [x] User Management
|
||||||
|
|
||||||
## Stack
|
## Stack
|
||||||
|
|
||||||
- **Freemarker** for web rendering
|
- **Freemarker** for web rendering
|
||||||
- **Manual HTTP** handling
|
- **Manual HTTP** handling
|
||||||
- **SQLite** for storing game information
|
- **SQLite** for storing game information
|
||||||
BIN
media/screenshots/1.jpg
Normal file
BIN
media/screenshots/1.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 257 KiB |
|
|
@ -32,7 +32,7 @@ public class AppConfig {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void hashPlaintextPasswords() {
|
public void hashPlaintextPasswords() {
|
||||||
if (users == null) return; // safety check
|
if (users == null) return;
|
||||||
for (Map.Entry<String, UserConfig> entry : users.entrySet()) {
|
for (Map.Entry<String, UserConfig> entry : users.entrySet()) {
|
||||||
Logger.info("Hashing user password for %s.".formatted(entry.getKey()));
|
Logger.info("Hashing user password for %s.".formatted(entry.getKey()));
|
||||||
UserConfig user = entry.getValue();
|
UserConfig user = entry.getValue();
|
||||||
|
|
@ -42,7 +42,7 @@ public class AppConfig {
|
||||||
|
|
||||||
user.setSalt(salt);
|
user.setSalt(salt);
|
||||||
user.setHash(hash);
|
user.setHash(hash);
|
||||||
user.setPassword(null); // clear plaintext
|
user.setPassword(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ public class ConfigLoader {
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public static AppConfig load(String path) throws Exception {
|
public static AppConfig load(String path) throws Exception {
|
||||||
if (config != null) return config; // singleton
|
if (config != null) return config;
|
||||||
|
|
||||||
File file = new File(path);
|
File file = new File(path);
|
||||||
AppConfig appConfig;
|
AppConfig appConfig;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package org.adrianvictor.livingroom.http;
|
package org.adrianvictor.livingroom.http;
|
||||||
|
|
||||||
import org.adrianvictor.livingroom.http.handlers.*;
|
import org.adrianvictor.livingroom.http.handlers.*;
|
||||||
|
import org.adrianvictor.livingroom.web.pages.Remove;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ public class UserService {
|
||||||
Role role;
|
Role role;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
role = Role.valueOf(raw.getRole());
|
role = Role.valueOf(raw.getRole().toUpperCase());
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
role = Role.USER;
|
role = Role.USER;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ public class Pages {
|
||||||
map.put("game", new Game());
|
map.put("game", new Game());
|
||||||
map.put("logout", new Logout());
|
map.put("logout", new Logout());
|
||||||
map.put("scan", new Scan());
|
map.put("scan", new Scan());
|
||||||
|
map.put("remove", new Remove());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static HashMap<String, Page> getAll() {
|
public static HashMap<String, Page> getAll() {
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package org.adrianvictor.livingroom.web.pages;
|
||||||
|
|
||||||
import com.sun.net.httpserver.HttpExchange;
|
import com.sun.net.httpserver.HttpExchange;
|
||||||
import freemarker.template.Configuration;
|
import freemarker.template.Configuration;
|
||||||
|
import org.adrianvictor.livingroom.Logger;
|
||||||
import org.adrianvictor.livingroom.Main;
|
import org.adrianvictor.livingroom.Main;
|
||||||
import org.adrianvictor.livingroom.data.Database;
|
import org.adrianvictor.livingroom.data.Database;
|
||||||
import org.adrianvictor.livingroom.data.Indexer;
|
import org.adrianvictor.livingroom.data.Indexer;
|
||||||
|
|
@ -17,12 +18,14 @@ public class Remove implements Page {
|
||||||
public String result(Configuration cfg, String baseAddress, String path, Map<String, Object> data, HttpExchange exchange) {
|
public String result(Configuration cfg, String baseAddress, String path, Map<String, Object> data, HttpExchange exchange) {
|
||||||
String arg = path.split("/")[0];
|
String arg = path.split("/")[0];
|
||||||
if (arg == null) {
|
if (arg == null) {
|
||||||
|
Logger.info("Arg is null");
|
||||||
return QuickResponses.notFound();
|
return QuickResponses.notFound();
|
||||||
}
|
}
|
||||||
int id;
|
int id;
|
||||||
try {
|
try {
|
||||||
id = Integer.parseInt(arg);
|
id = Integer.parseInt(arg);
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
|
Logger.info("Cannot parse number");
|
||||||
return QuickResponses.notFound();
|
return QuickResponses.notFound();
|
||||||
}
|
}
|
||||||
Database.getInstance().remove(String.valueOf(id));
|
Database.getInstance().remove(String.valueOf(id));
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@
|
||||||
<p>${game["description"]}</p>
|
<p>${game["description"]}</p>
|
||||||
</div>
|
</div>
|
||||||
</#if>
|
</#if>
|
||||||
<#if userRole == "admin">Admin actions: <a href="/${webpref}/remove/${game["id"]}">deindex</a>, <a href="/${webpref}/scan">trigger new scan</a></#if>
|
<#if userRole == "admin"><p>Admin actions: <a href="/${webpref}/remove/${game["id"]}">deindex</a>, <a href="/${webpref}/scan">trigger new scan</a></p></#if>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
<header>
|
<header>
|
||||||
<h1><a href="/${webpref}/">LivingRoom</a></h1>
|
<h1><a href="/${webpref}/">LivingRoom</a></h1>
|
||||||
<p><#if username??>${username} (<a href="/${webpref}/logout">logout</a>)</#if></p>
|
<p><#if username??>${username} - ${userRole} (<a href="/${webpref}/logout">logout</a>)</#if></p>
|
||||||
</header>
|
</header>
|
||||||
Loading…
Add table
Add a link
Reference in a new issue