Compare commits
4 Commits
1c57b538be
...
master
Author | SHA1 | Date | |
---|---|---|---|
5cf3c8d0c1 | |||
7b3210169a | |||
e34845ab24 | |||
400753a9a2 |
BIN
Public/assets/android-chrome-192x192.png
Normal file
After Width: | Height: | Size: 30 KiB |
BIN
Public/assets/android-chrome-512x512.png
Normal file
After Width: | Height: | Size: 171 KiB |
BIN
Public/assets/apple-touch-icon.png
Normal file
After Width: | Height: | Size: 30 KiB |
9
Public/assets/browserconfig.xml
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<browserconfig>
|
||||
<msapplication>
|
||||
<tile>
|
||||
<square150x150logo src="/assets/mstile-150x150.png?v=1"/>
|
||||
<TileColor>#a36490</TileColor>
|
||||
</tile>
|
||||
</msapplication>
|
||||
</browserconfig>
|
BIN
Public/assets/favicon-16x16.png
Normal file
After Width: | Height: | Size: 953 B |
BIN
Public/assets/favicon-32x32.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
Public/assets/favicon.ico
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
Public/assets/mstile-150x150.png
Normal file
After Width: | Height: | Size: 30 KiB |
1
Public/assets/site.webmanifest
Normal file
@ -0,0 +1 @@
|
||||
{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"}
|
@ -5,13 +5,13 @@
|
||||
<meta charset="utf-8"/>
|
||||
<meta name="robots" content="noindex"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0"/>
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png?v=1"/>
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/assets/icons/favicon-32x32.png?v=1"/>
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16x16.png?v=1"/>
|
||||
<link rel="manifest" href="/assets/icons/site.webmanifest?v=1"/>
|
||||
<link rel="shortcut icon" href="/assets/icons/favicon.ico?v=1"/>
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/assets/apple-touch-icon.png?v=1"/>
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/assets/favicon-32x32.png?v=1"/>
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/assets/favicon-16x16.png?v=1"/>
|
||||
<link rel="manifest" href="/assets/site.webmanifest?v=1"/>
|
||||
<link rel="shortcut icon" href="/assets/favicon.ico?v=1"/>
|
||||
<meta name="msapplication-TileColor" content="#da532c">
|
||||
<meta name="msapplication-config" content="/assets/icons/browserconfig.xml?v=1"/>
|
||||
<meta name="msapplication-config" content="/assets/browserconfig.xml?v=1"/>
|
||||
<meta name="theme-color" content="#ffffff"/>
|
||||
<link href="grid.css?v=2" rel="stylesheet"/>
|
||||
<meta name="author" content="Christoph Hagen"/>
|
||||
|
26
Readme.md
@ -51,31 +51,7 @@ Note: The data for the mosaic is currently not updated automatically, since Swif
|
||||
## Classifier training
|
||||
|
||||
The main server is running on Linux, which doesn't provide the CreateML framework required for classifier training.
|
||||
This has to be done on macOS using the `train.swift` script in the `Training` folder.
|
||||
It will:
|
||||
- Fetch the current image catalog by checking missing and changed images
|
||||
- Train a classifier on the image set
|
||||
- Increment the classifier version and upload the new model
|
||||
- Update the list of caps which can be recognized using the classifier
|
||||
- Create missing thumbnails for each cap for the cap grid
|
||||
|
||||
A configuration file is required to run the training, with a valid access token for the server:
|
||||
|
||||
```json
|
||||
{
|
||||
"imageDirectory": "../Public/images",
|
||||
"classifierModelPath": "../Public/classifier.mlmodel",
|
||||
"trainingIterations": 20,
|
||||
"serverPath": "https://mydomain.com/caps",
|
||||
"authenticationToken": "mysecretkey",
|
||||
}
|
||||
```
|
||||
|
||||
The configuration file `config.json` must be located in the folder from which the script is run.
|
||||
|
||||
```bash
|
||||
swift train.swift
|
||||
```
|
||||
This has to be done on macOS using the [Caps-Train](https://christophhagen.de/git/ch/Caps-Train) repository.
|
||||
|
||||
## Future work
|
||||
- Create thumbnails on the server using [JPEG](https://github.com/kelvin13/jpeg)
|
||||
|
@ -3,6 +3,7 @@
|
||||
"maxBodySize" : "2mb",
|
||||
"logPath": "\/var\/log\/caps/metrics",
|
||||
"serveFiles": true,
|
||||
"dataDirectory" : "/ch/data/caps",
|
||||
"writers" : [
|
||||
"auth_key_1"
|
||||
]
|
||||
|
@ -20,6 +20,20 @@ struct Config: Codable {
|
||||
/// Authentication tokens for remotes allowed to write
|
||||
let writers: [String]
|
||||
|
||||
/**
|
||||
The folder where the data should be stored.
|
||||
|
||||
If the folder is set to `nil`, then the `Resources` folder is used.
|
||||
*/
|
||||
let dataDirectory: String?
|
||||
|
||||
func customDataDirectory(or publicDirectory: String) -> URL {
|
||||
guard let dataDirectory else {
|
||||
return URL(fileURLWithPath: publicDirectory)
|
||||
}
|
||||
return URL(fileURLWithPath: dataDirectory)
|
||||
}
|
||||
|
||||
func logURL(possiblyRelativeTo resourcesDirectory: URL) -> URL {
|
||||
guard let logPath else {
|
||||
return resourcesDirectory.appendingPathComponent("logs")
|
||||
|
@ -31,7 +31,8 @@ func configure(_ app: Application) async throws {
|
||||
app.http.server.configuration.port = config.port
|
||||
app.routes.defaultMaxBodySize = .init(stringLiteral: config.maxBodySize)
|
||||
|
||||
server = CapServer(in: URL(fileURLWithPath: publicDirectory))
|
||||
let dataDirectory = config.customDataDirectory(or: publicDirectory)
|
||||
server = CapServer(in: dataDirectory)
|
||||
|
||||
provider = .init(observer: monitor, accessManager: config.writers)
|
||||
provider.asyncScheduler = asyncScheduler
|
||||
|