Initial commit.
This commit is contained in:
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
node_modules/
|
||||||
|
.vscode/
|
||||||
|
*.sqllite
|
||||||
|
testStuff/
|
||||||
|
chache.bin
|
||||||
|
key.cfg
|
334
index.js
Normal file
334
index.js
Normal file
@ -0,0 +1,334 @@
|
|||||||
|
const express = require("express");
|
||||||
|
const Eta = require("eta");
|
||||||
|
const fs = require("fs");
|
||||||
|
const request = require("request");
|
||||||
|
const imdb = require("imdb-api");
|
||||||
|
const sqlite3 = require("sqlite3");
|
||||||
|
const requestSync = require("sync-request");
|
||||||
|
var Config = require('config-js');
|
||||||
|
const app = express();
|
||||||
|
const port = 4000;
|
||||||
|
|
||||||
|
const initalTableSQL =
|
||||||
|
"CREATE TABLE `movieInfo` ( \
|
||||||
|
`id` INT NOT NULL, \
|
||||||
|
`movieID` VARCHAR(128), \
|
||||||
|
`movieTitel` VARCHAR(255), \
|
||||||
|
`place` INT zerofill, \
|
||||||
|
`type` INT zerofill, \
|
||||||
|
`posterUrl` VARCHAR(255) \
|
||||||
|
);";
|
||||||
|
|
||||||
|
const initalTableSQL2 =
|
||||||
|
"CREATE TABLE `apiChache` ( \
|
||||||
|
`imdbID` VARCHAR(128), \
|
||||||
|
`url` VARCHAR(255) \
|
||||||
|
);";
|
||||||
|
|
||||||
|
var responseBuffer = { allBufferd: [] };
|
||||||
|
|
||||||
|
responseBuffer = JSON.parse(fs.readFileSync("chache.bin", "utf8"));
|
||||||
|
|
||||||
|
var db = new sqlite3.Database("database.sqllite");
|
||||||
|
if (!fs.existsSync("database.sqllite")) {
|
||||||
|
console.log("Creating table.");
|
||||||
|
db.serialize(() => {
|
||||||
|
db.run(initalTableSQL);
|
||||||
|
//db.run(initalTableSQL2);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
db.close();
|
||||||
|
var db = new sqlite3.Database("database.sqllite");
|
||||||
|
|
||||||
|
var config = new Config('key.cfg');
|
||||||
|
|
||||||
|
|
||||||
|
async function doesMovieExistInDatabase(imdbID) {
|
||||||
|
console.warn(imdbID);
|
||||||
|
db.all(
|
||||||
|
"SELECT * FROM movieInfo WHERE movieID='" + imdbID + "'",
|
||||||
|
function (err, rows) {
|
||||||
|
console.log("!!!" + rows);
|
||||||
|
if (rows == undefined) {
|
||||||
|
console.log(false);
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
console.log(true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getBufferdResponse(type, imdbID) {
|
||||||
|
// Cover image
|
||||||
|
if (type == 1) {
|
||||||
|
db.all(
|
||||||
|
"SELECT * FROM apiChache WHERE imdbID=" + imdbID,
|
||||||
|
function (err, rows) {
|
||||||
|
// Okay, there is no result, lets ask the real api
|
||||||
|
if (rows == undefined) {
|
||||||
|
console.log("No chache");
|
||||||
|
var res = requestSync(
|
||||||
|
"GET",
|
||||||
|
"https://imdb-api.com/en/API/Posters//" + imdbID,
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
const jsonParsed = JSON.parse(res.body);
|
||||||
|
// Well frick, api limit reached
|
||||||
|
if (jsonParsed.errorMessage.includes("Maximum usage")) {
|
||||||
|
console.warn("API limit reached!");
|
||||||
|
|
||||||
|
return "https://tse2.mm.bing.net/th?id=OIP.SW4X5yWbxOMofUFxMwSTbAHaJQ&pid=Api"; // Return "No cover image"
|
||||||
|
console.log("unreachable");
|
||||||
|
} else {
|
||||||
|
// Cool, we got an response
|
||||||
|
posterUrl =
|
||||||
|
"https://tse2.mm.bing.net/th?id=OIP.SW4X5yWbxOMofUFxMwSTbAHaJQ&pid=Api"; // Just a fallback
|
||||||
|
if (jsonParsed.posters[0] != undefined) {
|
||||||
|
posterUrl = jsonParsed.posters[0].link;
|
||||||
|
// Lets save the response
|
||||||
|
db.run(
|
||||||
|
"INSERT INTO apiChache(imdbID, url) VALUES(?, ?)",
|
||||||
|
[imdbID, posterUrl],
|
||||||
|
(err) => {
|
||||||
|
if (err) {
|
||||||
|
return console.log(err.message);
|
||||||
|
}
|
||||||
|
console.log("Saved url to chache");
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// Return the url
|
||||||
|
return posterUrl;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// There is a result, lets return the result
|
||||||
|
return rows[0].url;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
app.use(express.static("static"));
|
||||||
|
|
||||||
|
app.get("/", function (req, res) {
|
||||||
|
// https://imdb-api.com/de/API/Posters//[ID HERE]
|
||||||
|
var buildString = "";
|
||||||
|
db.serialize(function () {
|
||||||
|
db.all("SELECT * FROM movieInfo ORDER BY movieTitel ASC;", function (err, rows) {
|
||||||
|
/* rows.forEach((row) => {
|
||||||
|
console.log(row.id + ": " + row.movieTitel);
|
||||||
|
//var posterLink = getBufferdResponse(1, row.movieID);
|
||||||
|
posterLink = row.posterUrl;
|
||||||
|
console.log(posterLink);
|
||||||
|
|
||||||
|
/*var res = requestSync(
|
||||||
|
"GET",
|
||||||
|
"https://imdb-api.com/en/API/Posters//" + row.movieID,
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
const jsonParsed = JSON.parse(res.body);
|
||||||
|
console.log(jsonParsed);
|
||||||
|
posterLink = "";
|
||||||
|
if (jsonParsed.posters[0] == undefined) {
|
||||||
|
posterLink =
|
||||||
|
"https://tse2.mm.bing.net/th?id=OIP.SW4X5yWbxOMofUFxMwSTbAHaJQ&pid=Api";
|
||||||
|
} else {
|
||||||
|
posterLink = jsonParsed.posters[0].link;
|
||||||
|
}*/
|
||||||
|
/*buildString +=
|
||||||
|
"<a href='/showDetails?id=" +
|
||||||
|
row.id +
|
||||||
|
"'><div style='width: 150px; float: left; padding: 5px;'><img src='" +
|
||||||
|
posterLink +
|
||||||
|
'\' style="width: 100%;"><br><center><b>' +
|
||||||
|
row.movieTitel +
|
||||||
|
"</b></center></div></a>";
|
||||||
|
|
||||||
|
});*/
|
||||||
|
|
||||||
|
console.log(rows)
|
||||||
|
const data = fs.readFileSync("template/bookshelf.html", "utf8");
|
||||||
|
res.send(Eta.render(data, {jsonRespo: JSON.stringify(rows)}));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get("/add", function (req, res) {
|
||||||
|
const data = fs.readFileSync("template/add.html", "utf8");
|
||||||
|
res.send(Eta.render(data, { isDisplay: false }));
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get("/delete", function (req, res) {
|
||||||
|
db.run(`DELETE FROM movieInfo WHERE id=?`, req.query["id"], function (err) {
|
||||||
|
if (err) {
|
||||||
|
return console.error(err.message);
|
||||||
|
}
|
||||||
|
console.log(`Row(s) deleted ${this.changes}`);
|
||||||
|
res.send("Done.");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get("/returnSaveResult", function (req, res) {
|
||||||
|
const data = fs.readFileSync("template/addToShelf.html", "utf8");
|
||||||
|
responseJson = responseBuffer[req.query["reponseID"]];
|
||||||
|
console.log(responseBuffer);
|
||||||
|
res.send(
|
||||||
|
Eta.render(data, {
|
||||||
|
id: responseJson.id,
|
||||||
|
cover: responseJson.coverImage,
|
||||||
|
titleByAPI: responseJson.titleByAPI,
|
||||||
|
ean: responseJson.ean,
|
||||||
|
isDisplay: true,
|
||||||
|
responseID: req.query["reponseID"],
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get("/showDetails", function (req, res) {
|
||||||
|
const data = fs.readFileSync("template/movieDetails.html", "utf8");
|
||||||
|
console.log( req.query["id"])
|
||||||
|
db.serialize(function () {
|
||||||
|
db.all(
|
||||||
|
"SELECT * FROM movieInfo WHERE movieID='" + req.query["id"] + "'",
|
||||||
|
function (err, rows) {
|
||||||
|
//+ req.params["id"]
|
||||||
|
row = rows[0];
|
||||||
|
console.log(row);
|
||||||
|
|
||||||
|
res.send(
|
||||||
|
Eta.render(data, {
|
||||||
|
internalID: row.id,
|
||||||
|
id: row.movieID,
|
||||||
|
cover: row.posterUrl,
|
||||||
|
titleByAPI: row.movieTitel,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
/*responseJson = responseBuffer[req.query["reponseID"]];
|
||||||
|
console.log(responseBuffer);
|
||||||
|
res.send(
|
||||||
|
Eta.render(data, {
|
||||||
|
id: responseJson.id,
|
||||||
|
cover: responseJson.coverImage,
|
||||||
|
titleByAPI: responseJson.titleByAPI,
|
||||||
|
ean: responseJson.ean,
|
||||||
|
isDisplay: true,
|
||||||
|
responseID: req.query["reponseID"]
|
||||||
|
})
|
||||||
|
);*/
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get("/apiCallBack", function (req, res) {
|
||||||
|
//console.log(req.query);
|
||||||
|
if (!responseBuffer.allBufferd.includes(req.query["ean"])) {
|
||||||
|
request(
|
||||||
|
"http://localhost:9999/?ean=" + req.query["ean"],
|
||||||
|
function (error, response, body) {
|
||||||
|
if (response.statusCode != 200) {
|
||||||
|
console.log("OH NO");
|
||||||
|
res.send({ state: "ERR_EAN_CONV_NO_200" });
|
||||||
|
} else {
|
||||||
|
var reqString =
|
||||||
|
"https://imdb-api.com/en/API/SearchTitle/" + config.get('keys.imdb') + "/" +
|
||||||
|
response.body;
|
||||||
|
request(reqString, function (error, response2, body) {
|
||||||
|
jsonBody = JSON.parse(response2.body);
|
||||||
|
console.log(response.body);
|
||||||
|
if (jsonBody.errorMessage.includes("Maximum usage")) {
|
||||||
|
res.send({ state: "ERR_IMDB_LIMIT_REACHED" });
|
||||||
|
} else {
|
||||||
|
jsonBody = jsonBody.results[0];
|
||||||
|
//const data = fs.readFileSync("template/addToShelf.html.html", "utf8");
|
||||||
|
timest = new Date().valueOf();
|
||||||
|
responseJson = {
|
||||||
|
state: "OK",
|
||||||
|
id: jsonBody.id,
|
||||||
|
coverImage: jsonBody.image,
|
||||||
|
titleByAPI: response.body,
|
||||||
|
ean: req.query["ean"],
|
||||||
|
reponseID: req.query["ean"],
|
||||||
|
};
|
||||||
|
responseBuffer[req.query["ean"]] = responseJson;
|
||||||
|
responseBuffer.allBufferd.push(req.query["ean"]);
|
||||||
|
|
||||||
|
// ToDo: Rewrite chache (and all pages!!!) to use ean instead of timeid
|
||||||
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
fs.writeFileSync("chache.bin", JSON.stringify(responseBuffer));
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
}
|
||||||
|
res.send(responseJson);
|
||||||
|
/* res.send(
|
||||||
|
Eta.render(data, {
|
||||||
|
id: jsonBody.id,
|
||||||
|
cover: jsonBody.image,
|
||||||
|
titleByAPI: response.body,
|
||||||
|
ean: req.query["ean"],
|
||||||
|
isDisplay: true,
|
||||||
|
})
|
||||||
|
);*/
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
console.log("Using chache");
|
||||||
|
responseJson = responseBuffer[req.query["ean"]];
|
||||||
|
res.send(responseJson);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get("/save", function (req, res) {
|
||||||
|
responseJson = responseBuffer[req.query["reponseID"]];
|
||||||
|
|
||||||
|
db.all(
|
||||||
|
"SELECT * FROM movieInfo WHERE movieID='" + responseJson.id + "'",
|
||||||
|
function (err, rows) {
|
||||||
|
console.log(rows);
|
||||||
|
if (rows == undefined || rows.length == 0) {
|
||||||
|
db.run(
|
||||||
|
"INSERT INTO movieInfo(id, movieID, movieTitel, place, type, posterUrl) VALUES(?, ?, ?, ?, ?, ?)",
|
||||||
|
[
|
||||||
|
new Date().valueOf(),
|
||||||
|
responseJson.id,
|
||||||
|
responseJson.titleByAPI,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
responseJson.coverImage,
|
||||||
|
],
|
||||||
|
(err) => {
|
||||||
|
if (err) {
|
||||||
|
return console.log(err.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
res.send({ status: "OK" });
|
||||||
|
} else {
|
||||||
|
res.send({ status: "ERR_ALREADY_EXIST" });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
//var res = request('POST', 'https://ssl.ofdb.de/view.php?page=suchergebnis', {
|
||||||
|
// json: {'SText': '4030521376748', 'Kat':'EAN'},
|
||||||
|
//});
|
||||||
|
|
||||||
|
//var temp2 = String(res.getBody('utf8'))
|
||||||
|
//temp = //temp.replace("<script>", "").replace("<html>", "").replace("\n", "").replace("\r", "").replace("\t", "")
|
||||||
|
//htmlBlock = htmlParser.parse(temp)
|
||||||
|
//temp2 = temp2.split(/\r?\n/)
|
||||||
|
//temp = temp.split('img src="https://ssl.ofdb.de/images/shim.gif" width="1" height="10" border="0" alt=""></td>')[0]
|
||||||
|
//console.log(temp2.find(checkForString))
|
||||||
|
|
||||||
|
app.listen(port, () => {
|
||||||
|
console.log(`Movie DB app listening at http://localhost:${port}`);
|
||||||
|
});
|
1795
package-lock.json
generated
Normal file
1795
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
32
package.json
Normal file
32
package.json
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
{
|
||||||
|
"name": "openmoviedb",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "An openmoviedb where you can save which movies you own.",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "openmoviedb"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"movie",
|
||||||
|
"imdb"
|
||||||
|
],
|
||||||
|
"author": "TheGreydiamond",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"config-js": "^1.1.14",
|
||||||
|
"eta": "^1.12.1",
|
||||||
|
"express": "^4.17.1",
|
||||||
|
"form-data": "^4.0.0",
|
||||||
|
"imdb-api": "^4.4.1",
|
||||||
|
"node-fetch": "^2.6.1",
|
||||||
|
"node-html-parser": "^3.1.2",
|
||||||
|
"quagga": "^0.12.1",
|
||||||
|
"request": "^2.88.2",
|
||||||
|
"sqlite3": "^5.0.2",
|
||||||
|
"sync-request": "^6.1.0"
|
||||||
|
}
|
||||||
|
}
|
56
python/eanConverter.py
Normal file
56
python/eanConverter.py
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
from http.server import BaseHTTPRequestHandler, HTTPServer
|
||||||
|
import time
|
||||||
|
import requests
|
||||||
|
|
||||||
|
hostName = "localhost"
|
||||||
|
serverPort = 9999
|
||||||
|
|
||||||
|
class MyServer(BaseHTTPRequestHandler):
|
||||||
|
def do_GET(self):
|
||||||
|
|
||||||
|
print(self.path)
|
||||||
|
if(self.path.startswith("/?ean=")):
|
||||||
|
print("EAN request")
|
||||||
|
|
||||||
|
eanCode = self.path.split("=")[1]
|
||||||
|
print(eanCode)
|
||||||
|
url = 'https://ssl.ofdb.de/view.php?page=suchergebnis'
|
||||||
|
myobj = {'SText': eanCode, 'Kat':'EAN'} #'4030521376748'
|
||||||
|
|
||||||
|
x = requests.post(url, data = myobj)
|
||||||
|
tme = x.text
|
||||||
|
try:
|
||||||
|
tme = tme.split('<div data-nx-container="inread"><!-- INREAD --></div>')[1]
|
||||||
|
tme = tme.split('img src="https://ssl.ofdb.de/images/shim.gif" width="1" height="10" border="0" alt=""></td>')[0]
|
||||||
|
tme = tme.split(',SHADOW,true)"><b>')[1]
|
||||||
|
tme = tme.split('</b></a><br>')[0]
|
||||||
|
tme = tme[:len(tme)-7]
|
||||||
|
except IndexError:
|
||||||
|
self.send_response(500)
|
||||||
|
self.send_header("Content-type", "text/html")
|
||||||
|
self.end_headers()
|
||||||
|
self.wfile.write(bytes("Invalid EAN", "utf-8"))
|
||||||
|
else:
|
||||||
|
self.send_response(200)
|
||||||
|
self.send_header("Content-type", "text/html")
|
||||||
|
self.end_headers()
|
||||||
|
self.wfile.write(bytes(tme, "utf-8"))
|
||||||
|
else:
|
||||||
|
self.send_response(404)
|
||||||
|
self.send_header("Content-type", "text/html")
|
||||||
|
self.end_headers()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
webServer = HTTPServer((hostName, serverPort), MyServer)
|
||||||
|
print("Server started http://%s:%s" % (hostName, serverPort))
|
||||||
|
|
||||||
|
try:
|
||||||
|
webServer.serve_forever()
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
pass
|
||||||
|
|
||||||
|
webServer.server_close()
|
||||||
|
print("Server stopped.")
|
427
static/css/normalize.css
vendored
Normal file
427
static/css/normalize.css
vendored
Normal file
@ -0,0 +1,427 @@
|
|||||||
|
/*! normalize.css v3.0.2 | MIT License | git.io/normalize */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. Set default font family to sans-serif.
|
||||||
|
* 2. Prevent iOS text size adjust after orientation change, without disabling
|
||||||
|
* user zoom.
|
||||||
|
*/
|
||||||
|
|
||||||
|
html {
|
||||||
|
font-family: sans-serif; /* 1 */
|
||||||
|
-ms-text-size-adjust: 100%; /* 2 */
|
||||||
|
-webkit-text-size-adjust: 100%; /* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove default margin.
|
||||||
|
*/
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* HTML5 display definitions
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Correct `block` display not defined for any HTML5 element in IE 8/9.
|
||||||
|
* Correct `block` display not defined for `details` or `summary` in IE 10/11
|
||||||
|
* and Firefox.
|
||||||
|
* Correct `block` display not defined for `main` in IE 11.
|
||||||
|
*/
|
||||||
|
|
||||||
|
article,
|
||||||
|
aside,
|
||||||
|
details,
|
||||||
|
figcaption,
|
||||||
|
figure,
|
||||||
|
footer,
|
||||||
|
header,
|
||||||
|
hgroup,
|
||||||
|
main,
|
||||||
|
menu,
|
||||||
|
nav,
|
||||||
|
section,
|
||||||
|
summary {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. Correct `inline-block` display not defined in IE 8/9.
|
||||||
|
* 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.
|
||||||
|
*/
|
||||||
|
|
||||||
|
audio,
|
||||||
|
canvas,
|
||||||
|
progress,
|
||||||
|
video {
|
||||||
|
display: inline-block; /* 1 */
|
||||||
|
vertical-align: baseline; /* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prevent modern browsers from displaying `audio` without controls.
|
||||||
|
* Remove excess height in iOS 5 devices.
|
||||||
|
*/
|
||||||
|
|
||||||
|
audio:not([controls]) {
|
||||||
|
display: none;
|
||||||
|
height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Address `[hidden]` styling not present in IE 8/9/10.
|
||||||
|
* Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22.
|
||||||
|
*/
|
||||||
|
|
||||||
|
[hidden],
|
||||||
|
template {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Links
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the gray background color from active links in IE 10.
|
||||||
|
*/
|
||||||
|
|
||||||
|
a {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Improve readability when focused and also mouse hovered in all browsers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
a:active,
|
||||||
|
a:hover {
|
||||||
|
outline: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Text-level semantics
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Address styling not present in IE 8/9/10/11, Safari, and Chrome.
|
||||||
|
*/
|
||||||
|
|
||||||
|
abbr[title] {
|
||||||
|
border-bottom: 1px dotted;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Address style set to `bolder` in Firefox 4+, Safari, and Chrome.
|
||||||
|
*/
|
||||||
|
|
||||||
|
b,
|
||||||
|
strong {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Address styling not present in Safari and Chrome.
|
||||||
|
*/
|
||||||
|
|
||||||
|
dfn {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Address variable `h1` font-size and margin within `section` and `article`
|
||||||
|
* contexts in Firefox 4+, Safari, and Chrome.
|
||||||
|
*/
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 2em;
|
||||||
|
margin: 0.67em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Address styling not present in IE 8/9.
|
||||||
|
*/
|
||||||
|
|
||||||
|
mark {
|
||||||
|
background: #ff0;
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Address inconsistent and variable font size in all browsers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
small {
|
||||||
|
font-size: 80%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prevent `sub` and `sup` affecting `line-height` in all browsers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
sub,
|
||||||
|
sup {
|
||||||
|
font-size: 75%;
|
||||||
|
line-height: 0;
|
||||||
|
position: relative;
|
||||||
|
vertical-align: baseline;
|
||||||
|
}
|
||||||
|
|
||||||
|
sup {
|
||||||
|
top: -0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub {
|
||||||
|
bottom: -0.25em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Embedded content
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove border when inside `a` element in IE 8/9/10.
|
||||||
|
*/
|
||||||
|
|
||||||
|
img {
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Correct overflow not hidden in IE 9/10/11.
|
||||||
|
*/
|
||||||
|
|
||||||
|
svg:not(:root) {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Grouping content
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Address margin not present in IE 8/9 and Safari.
|
||||||
|
*/
|
||||||
|
|
||||||
|
figure {
|
||||||
|
margin: 1em 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Address differences between Firefox and other browsers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
hr {
|
||||||
|
-moz-box-sizing: content-box;
|
||||||
|
box-sizing: content-box;
|
||||||
|
height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Contain overflow in all browsers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
pre {
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Address odd `em`-unit font size rendering in all browsers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
code,
|
||||||
|
kbd,
|
||||||
|
pre,
|
||||||
|
samp {
|
||||||
|
font-family: monospace, monospace;
|
||||||
|
font-size: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Forms
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Known limitation: by default, Chrome and Safari on OS X allow very limited
|
||||||
|
* styling of `select`, unless a `border` property is set.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. Correct color not being inherited.
|
||||||
|
* Known issue: affects color of disabled elements.
|
||||||
|
* 2. Correct font properties not being inherited.
|
||||||
|
* 3. Address margins set differently in Firefox 4+, Safari, and Chrome.
|
||||||
|
*/
|
||||||
|
|
||||||
|
button,
|
||||||
|
input,
|
||||||
|
optgroup,
|
||||||
|
select,
|
||||||
|
textarea {
|
||||||
|
color: inherit; /* 1 */
|
||||||
|
font: inherit; /* 2 */
|
||||||
|
margin: 0; /* 3 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Address `overflow` set to `hidden` in IE 8/9/10/11.
|
||||||
|
*/
|
||||||
|
|
||||||
|
button {
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Address inconsistent `text-transform` inheritance for `button` and `select`.
|
||||||
|
* All other form control elements do not inherit `text-transform` values.
|
||||||
|
* Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.
|
||||||
|
* Correct `select` style inheritance in Firefox.
|
||||||
|
*/
|
||||||
|
|
||||||
|
button,
|
||||||
|
select {
|
||||||
|
text-transform: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
|
||||||
|
* and `video` controls.
|
||||||
|
* 2. Correct inability to style clickable `input` types in iOS.
|
||||||
|
* 3. Improve usability and consistency of cursor style between image-type
|
||||||
|
* `input` and others.
|
||||||
|
*/
|
||||||
|
|
||||||
|
button,
|
||||||
|
html input[type="button"], /* 1 */
|
||||||
|
input[type="reset"],
|
||||||
|
input[type="submit"] {
|
||||||
|
-webkit-appearance: button; /* 2 */
|
||||||
|
cursor: pointer; /* 3 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Re-set default cursor for disabled elements.
|
||||||
|
*/
|
||||||
|
|
||||||
|
button[disabled],
|
||||||
|
html input[disabled] {
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove inner padding and border in Firefox 4+.
|
||||||
|
*/
|
||||||
|
|
||||||
|
button::-moz-focus-inner,
|
||||||
|
input::-moz-focus-inner {
|
||||||
|
border: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Address Firefox 4+ setting `line-height` on `input` using `!important` in
|
||||||
|
* the UA stylesheet.
|
||||||
|
*/
|
||||||
|
|
||||||
|
input {
|
||||||
|
line-height: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* It's recommended that you don't attempt to style these elements.
|
||||||
|
* Firefox's implementation doesn't respect box-sizing, padding, or width.
|
||||||
|
*
|
||||||
|
* 1. Address box sizing set to `content-box` in IE 8/9/10.
|
||||||
|
* 2. Remove excess padding in IE 8/9/10.
|
||||||
|
*/
|
||||||
|
|
||||||
|
input[type="checkbox"],
|
||||||
|
input[type="radio"] {
|
||||||
|
box-sizing: border-box; /* 1 */
|
||||||
|
padding: 0; /* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fix the cursor style for Chrome's increment/decrement buttons. For certain
|
||||||
|
* `font-size` values of the `input`, it causes the cursor style of the
|
||||||
|
* decrement button to change from `default` to `text`.
|
||||||
|
*/
|
||||||
|
|
||||||
|
input[type="number"]::-webkit-inner-spin-button,
|
||||||
|
input[type="number"]::-webkit-outer-spin-button {
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. Address `appearance` set to `searchfield` in Safari and Chrome.
|
||||||
|
* 2. Address `box-sizing` set to `border-box` in Safari and Chrome
|
||||||
|
* (include `-moz` to future-proof).
|
||||||
|
*/
|
||||||
|
|
||||||
|
input[type="search"] {
|
||||||
|
-webkit-appearance: textfield; /* 1 */
|
||||||
|
-moz-box-sizing: content-box;
|
||||||
|
-webkit-box-sizing: content-box; /* 2 */
|
||||||
|
box-sizing: content-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove inner padding and search cancel button in Safari and Chrome on OS X.
|
||||||
|
* Safari (but not Chrome) clips the cancel button when the search input has
|
||||||
|
* padding (and `textfield` appearance).
|
||||||
|
*/
|
||||||
|
|
||||||
|
input[type="search"]::-webkit-search-cancel-button,
|
||||||
|
input[type="search"]::-webkit-search-decoration {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define consistent border, margin, and padding.
|
||||||
|
*/
|
||||||
|
|
||||||
|
fieldset {
|
||||||
|
border: 1px solid #c0c0c0;
|
||||||
|
margin: 0 2px;
|
||||||
|
padding: 0.35em 0.625em 0.75em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. Correct `color` not being inherited in IE 8/9/10/11.
|
||||||
|
* 2. Remove padding so people aren't caught out if they zero out fieldsets.
|
||||||
|
*/
|
||||||
|
|
||||||
|
legend {
|
||||||
|
border: 0; /* 1 */
|
||||||
|
padding: 0; /* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove default vertical scrollbar in IE 8/9/10/11.
|
||||||
|
*/
|
||||||
|
|
||||||
|
textarea {
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Don't inherit the `font-weight` (applied by a rule above).
|
||||||
|
* NOTE: the default cannot safely be changed in Chrome and Safari on OS X.
|
||||||
|
*/
|
||||||
|
|
||||||
|
optgroup {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tables
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove most spacing between table cells.
|
||||||
|
*/
|
||||||
|
|
||||||
|
table {
|
||||||
|
border-collapse: collapse;
|
||||||
|
border-spacing: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
td,
|
||||||
|
th {
|
||||||
|
padding: 0;
|
||||||
|
}
|
487
static/css/skeleton.css
vendored
Normal file
487
static/css/skeleton.css
vendored
Normal file
@ -0,0 +1,487 @@
|
|||||||
|
/*
|
||||||
|
* Skeleton V2.0.4
|
||||||
|
* Copyright 2014, Dave Gamache
|
||||||
|
* www.getskeleton.com
|
||||||
|
* Free to use under the MIT license.
|
||||||
|
* http://www.opensource.org/licenses/mit-license.php
|
||||||
|
* 12/29/2014
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* Table of contents
|
||||||
|
––––––––––––––––––––––––––––––––––––––––––––––––––
|
||||||
|
- Grid
|
||||||
|
- Base Styles
|
||||||
|
- Typography
|
||||||
|
- Links
|
||||||
|
- Buttons
|
||||||
|
- Forms
|
||||||
|
- Lists
|
||||||
|
- Code
|
||||||
|
- Tables
|
||||||
|
- Spacing
|
||||||
|
- Utilities
|
||||||
|
- Clearing
|
||||||
|
- Media Queries
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* Grid
|
||||||
|
–––––––––––––––––––––––––––––––––––––––––––––––––– */
|
||||||
|
.container {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 960px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0 20px;
|
||||||
|
box-sizing: border-box; }
|
||||||
|
.column,
|
||||||
|
.columns {
|
||||||
|
width: 100%;
|
||||||
|
float: left;
|
||||||
|
box-sizing: border-box; }
|
||||||
|
|
||||||
|
/* For devices larger than 400px */
|
||||||
|
@media (min-width: 400px) {
|
||||||
|
.container {
|
||||||
|
width: 85%;
|
||||||
|
padding: 0; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* For devices larger than 550px */
|
||||||
|
@media (min-width: 550px) {
|
||||||
|
.container {
|
||||||
|
width: 80%; }
|
||||||
|
.column,
|
||||||
|
.columns {
|
||||||
|
margin-left: 4%; }
|
||||||
|
.column:first-child,
|
||||||
|
.columns:first-child {
|
||||||
|
margin-left: 0; }
|
||||||
|
|
||||||
|
.one.column,
|
||||||
|
.one.columns { width: 4.66666666667%; }
|
||||||
|
.two.columns { width: 13.3333333333%; }
|
||||||
|
.three.columns { width: 22%; }
|
||||||
|
.four.columns { width: 30.6666666667%; }
|
||||||
|
.five.columns { width: 39.3333333333%; }
|
||||||
|
.six.columns { width: 48%; }
|
||||||
|
.seven.columns { width: 56.6666666667%; }
|
||||||
|
.eight.columns { width: 65.3333333333%; }
|
||||||
|
.nine.columns { width: 74.0%; }
|
||||||
|
.ten.columns { width: 82.6666666667%; }
|
||||||
|
.eleven.columns { width: 91.3333333333%; }
|
||||||
|
.twelve.columns { width: 100%; margin-left: 0; }
|
||||||
|
|
||||||
|
.one-third.column { width: 30.6666666667%; }
|
||||||
|
.two-thirds.column { width: 65.3333333333%; }
|
||||||
|
|
||||||
|
.one-half.column { width: 48%; }
|
||||||
|
|
||||||
|
/* Offsets */
|
||||||
|
.offset-by-one.column,
|
||||||
|
.offset-by-one.columns { margin-left: 8.66666666667%; }
|
||||||
|
.offset-by-two.column,
|
||||||
|
.offset-by-two.columns { margin-left: 17.3333333333%; }
|
||||||
|
.offset-by-three.column,
|
||||||
|
.offset-by-three.columns { margin-left: 26%; }
|
||||||
|
.offset-by-four.column,
|
||||||
|
.offset-by-four.columns { margin-left: 34.6666666667%; }
|
||||||
|
.offset-by-five.column,
|
||||||
|
.offset-by-five.columns { margin-left: 43.3333333333%; }
|
||||||
|
.offset-by-six.column,
|
||||||
|
.offset-by-six.columns { margin-left: 52%; }
|
||||||
|
.offset-by-seven.column,
|
||||||
|
.offset-by-seven.columns { margin-left: 60.6666666667%; }
|
||||||
|
.offset-by-eight.column,
|
||||||
|
.offset-by-eight.columns { margin-left: 69.3333333333%; }
|
||||||
|
.offset-by-nine.column,
|
||||||
|
.offset-by-nine.columns { margin-left: 78.0%; }
|
||||||
|
.offset-by-ten.column,
|
||||||
|
.offset-by-ten.columns { margin-left: 86.6666666667%; }
|
||||||
|
.offset-by-eleven.column,
|
||||||
|
.offset-by-eleven.columns { margin-left: 95.3333333333%; }
|
||||||
|
|
||||||
|
.offset-by-one-third.column,
|
||||||
|
.offset-by-one-third.columns { margin-left: 34.6666666667%; }
|
||||||
|
.offset-by-two-thirds.column,
|
||||||
|
.offset-by-two-thirds.columns { margin-left: 69.3333333333%; }
|
||||||
|
|
||||||
|
.offset-by-one-half.column,
|
||||||
|
.offset-by-one-half.columns { margin-left: 52%; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Base Styles
|
||||||
|
–––––––––––––––––––––––––––––––––––––––––––––––––– */
|
||||||
|
/* NOTE
|
||||||
|
html is set to 62.5% so that all the REM measurements throughout Skeleton
|
||||||
|
are based on 10px sizing. So basically 1.5rem = 15px :) */
|
||||||
|
html {
|
||||||
|
font-size: 62.5%; }
|
||||||
|
body {
|
||||||
|
font-size: 1.5em; /* currently ems cause chrome bug misinterpreting rems on body element */
|
||||||
|
line-height: 1.6;
|
||||||
|
font-weight: 400;
|
||||||
|
font-family: "Raleway", "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||||
|
color: #222; }
|
||||||
|
|
||||||
|
|
||||||
|
/* Typography
|
||||||
|
–––––––––––––––––––––––––––––––––––––––––––––––––– */
|
||||||
|
h1, h2, h3, h4, h5, h6 {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
font-weight: 300; }
|
||||||
|
h1 { font-size: 4.0rem; line-height: 1.2; letter-spacing: -.1rem;}
|
||||||
|
h2 { font-size: 3.6rem; line-height: 1.25; letter-spacing: -.1rem; }
|
||||||
|
h3 { font-size: 3.0rem; line-height: 1.3; letter-spacing: -.1rem; }
|
||||||
|
h4 { font-size: 2.4rem; line-height: 1.35; letter-spacing: -.08rem; }
|
||||||
|
h5 { font-size: 1.8rem; line-height: 1.5; letter-spacing: -.05rem; }
|
||||||
|
h6 { font-size: 1.5rem; line-height: 1.6; letter-spacing: 0; }
|
||||||
|
|
||||||
|
/* Larger than phablet */
|
||||||
|
@media (min-width: 550px) {
|
||||||
|
h1 { font-size: 5.0rem; }
|
||||||
|
h2 { font-size: 4.2rem; }
|
||||||
|
h3 { font-size: 3.6rem; }
|
||||||
|
h4 { font-size: 3.0rem; }
|
||||||
|
h5 { font-size: 2.4rem; }
|
||||||
|
h6 { font-size: 1.5rem; }
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin-top: 0; }
|
||||||
|
|
||||||
|
|
||||||
|
/* Links
|
||||||
|
–––––––––––––––––––––––––––––––––––––––––––––––––– */
|
||||||
|
a {
|
||||||
|
color: #1EAEDB; }
|
||||||
|
a:hover {
|
||||||
|
color: #0FA0CE; }
|
||||||
|
|
||||||
|
|
||||||
|
/* Buttons
|
||||||
|
–––––––––––––––––––––––––––––––––––––––––––––––––– */
|
||||||
|
.button,
|
||||||
|
button,
|
||||||
|
input[type="submit"],
|
||||||
|
input[type="reset"],
|
||||||
|
input[type="button"] {
|
||||||
|
display: inline-block;
|
||||||
|
height: 38px;
|
||||||
|
padding: 0 30px;
|
||||||
|
color: #555;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 11px;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 38px;
|
||||||
|
letter-spacing: .1rem;
|
||||||
|
text-transform: uppercase;
|
||||||
|
text-decoration: none;
|
||||||
|
white-space: nowrap;
|
||||||
|
background-color: transparent;
|
||||||
|
border-radius: 4px;
|
||||||
|
border: 1px solid #bbb;
|
||||||
|
cursor: pointer;
|
||||||
|
box-sizing: border-box; }
|
||||||
|
.button:hover,
|
||||||
|
button:hover,
|
||||||
|
input[type="submit"]:hover,
|
||||||
|
input[type="reset"]:hover,
|
||||||
|
input[type="button"]:hover,
|
||||||
|
.button:focus,
|
||||||
|
button:focus,
|
||||||
|
input[type="submit"]:focus,
|
||||||
|
input[type="reset"]:focus,
|
||||||
|
input[type="button"]:focus {
|
||||||
|
color: #333;
|
||||||
|
border-color: #888;
|
||||||
|
outline: 0; }
|
||||||
|
.button.button-primary,
|
||||||
|
button.button-primary,
|
||||||
|
input[type="submit"].button-primary,
|
||||||
|
input[type="reset"].button-primary,
|
||||||
|
input[type="button"].button-primary {
|
||||||
|
color: #FFF;
|
||||||
|
background-color: #33C3F0;
|
||||||
|
border-color: #33C3F0; }
|
||||||
|
.button.button-primary:hover,
|
||||||
|
button.button-primary:hover,
|
||||||
|
input[type="submit"].button-primary:hover,
|
||||||
|
input[type="reset"].button-primary:hover,
|
||||||
|
input[type="button"].button-primary:hover,
|
||||||
|
.button.button-primary:focus,
|
||||||
|
button.button-primary:focus,
|
||||||
|
input[type="submit"].button-primary:focus,
|
||||||
|
input[type="reset"].button-primary:focus,
|
||||||
|
input[type="button"].button-primary:focus {
|
||||||
|
color: #FFF;
|
||||||
|
background-color: #1EAEDB;
|
||||||
|
border-color: #1EAEDB; }
|
||||||
|
|
||||||
|
|
||||||
|
/* Forms
|
||||||
|
–––––––––––––––––––––––––––––––––––––––––––––––––– */
|
||||||
|
input[type="email"],
|
||||||
|
input[type="number"],
|
||||||
|
input[type="search"],
|
||||||
|
input[type="text"],
|
||||||
|
input[type="tel"],
|
||||||
|
input[type="url"],
|
||||||
|
input[type="password"],
|
||||||
|
textarea,
|
||||||
|
select {
|
||||||
|
height: 38px;
|
||||||
|
padding: 6px 10px; /* The 6px vertically centers text on FF, ignored by Webkit */
|
||||||
|
background-color: #fff;
|
||||||
|
border: 1px solid #D1D1D1;
|
||||||
|
border-radius: 4px;
|
||||||
|
box-shadow: none;
|
||||||
|
box-sizing: border-box; }
|
||||||
|
/* Removes awkward default styles on some inputs for iOS */
|
||||||
|
input[type="email"],
|
||||||
|
input[type="number"],
|
||||||
|
input[type="search"],
|
||||||
|
input[type="text"],
|
||||||
|
input[type="tel"],
|
||||||
|
input[type="url"],
|
||||||
|
input[type="password"],
|
||||||
|
textarea {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
-moz-appearance: none;
|
||||||
|
appearance: none; }
|
||||||
|
textarea {
|
||||||
|
min-height: 65px;
|
||||||
|
padding-top: 6px;
|
||||||
|
padding-bottom: 6px; }
|
||||||
|
input[type="email"]:focus,
|
||||||
|
input[type="number"]:focus,
|
||||||
|
input[type="search"]:focus,
|
||||||
|
input[type="text"]:focus,
|
||||||
|
input[type="tel"]:focus,
|
||||||
|
input[type="url"]:focus,
|
||||||
|
input[type="password"]:focus,
|
||||||
|
textarea:focus,
|
||||||
|
select:focus {
|
||||||
|
border: 1px solid #33C3F0;
|
||||||
|
outline: 0; }
|
||||||
|
label,
|
||||||
|
legend {
|
||||||
|
display: block;
|
||||||
|
margin-bottom: .5rem;
|
||||||
|
font-weight: 600; }
|
||||||
|
fieldset {
|
||||||
|
padding: 0;
|
||||||
|
border-width: 0; }
|
||||||
|
input[type="checkbox"],
|
||||||
|
input[type="radio"] {
|
||||||
|
display: inline; }
|
||||||
|
label > .label-body {
|
||||||
|
display: inline-block;
|
||||||
|
margin-left: .5rem;
|
||||||
|
font-weight: normal; }
|
||||||
|
|
||||||
|
|
||||||
|
/* Lists
|
||||||
|
–––––––––––––––––––––––––––––––––––––––––––––––––– */
|
||||||
|
ul {
|
||||||
|
list-style: circle inside; }
|
||||||
|
ol {
|
||||||
|
list-style: decimal inside; }
|
||||||
|
ol, ul {
|
||||||
|
padding-left: 0;
|
||||||
|
margin-top: 0; }
|
||||||
|
ul ul,
|
||||||
|
ul ol,
|
||||||
|
ol ol,
|
||||||
|
ol ul {
|
||||||
|
margin: 1.5rem 0 1.5rem 3rem;
|
||||||
|
font-size: 90%; }
|
||||||
|
li {
|
||||||
|
margin-bottom: 1rem; }
|
||||||
|
|
||||||
|
|
||||||
|
/* Code
|
||||||
|
–––––––––––––––––––––––––––––––––––––––––––––––––– */
|
||||||
|
code {
|
||||||
|
padding: .2rem .5rem;
|
||||||
|
margin: 0 .2rem;
|
||||||
|
font-size: 90%;
|
||||||
|
white-space: nowrap;
|
||||||
|
background: #F1F1F1;
|
||||||
|
border: 1px solid #E1E1E1;
|
||||||
|
border-radius: 4px; }
|
||||||
|
pre > code {
|
||||||
|
display: block;
|
||||||
|
padding: 1rem 1.5rem;
|
||||||
|
white-space: pre; }
|
||||||
|
|
||||||
|
|
||||||
|
/* Tables
|
||||||
|
–––––––––––––––––––––––––––––––––––––––––––––––––– */
|
||||||
|
th,
|
||||||
|
td {
|
||||||
|
padding: 12px 15px;
|
||||||
|
text-align: left;
|
||||||
|
border-bottom: 1px solid #E1E1E1; }
|
||||||
|
th:first-child,
|
||||||
|
td:first-child {
|
||||||
|
padding-left: 0; }
|
||||||
|
th:last-child,
|
||||||
|
td:last-child {
|
||||||
|
padding-right: 0; }
|
||||||
|
|
||||||
|
|
||||||
|
/* Spacing
|
||||||
|
–––––––––––––––––––––––––––––––––––––––––––––––––– */
|
||||||
|
button,
|
||||||
|
.button {
|
||||||
|
margin-bottom: 1rem; }
|
||||||
|
input,
|
||||||
|
textarea,
|
||||||
|
select,
|
||||||
|
fieldset {
|
||||||
|
margin-bottom: 1.5rem; }
|
||||||
|
pre,
|
||||||
|
blockquote,
|
||||||
|
dl,
|
||||||
|
figure,
|
||||||
|
table,
|
||||||
|
p,
|
||||||
|
ul,
|
||||||
|
ol,
|
||||||
|
form {
|
||||||
|
margin-bottom: 2.5rem; }
|
||||||
|
|
||||||
|
|
||||||
|
/* Utilities
|
||||||
|
–––––––––––––––––––––––––––––––––––––––––––––––––– */
|
||||||
|
.u-full-width {
|
||||||
|
width: 100%;
|
||||||
|
box-sizing: border-box; }
|
||||||
|
.u-max-full-width {
|
||||||
|
max-width: 100%;
|
||||||
|
box-sizing: border-box; }
|
||||||
|
.u-pull-right {
|
||||||
|
float: right; }
|
||||||
|
.u-pull-left {
|
||||||
|
float: left; }
|
||||||
|
|
||||||
|
|
||||||
|
/* Misc
|
||||||
|
–––––––––––––––––––––––––––––––––––––––––––––––––– */
|
||||||
|
hr {
|
||||||
|
margin-top: 3rem;
|
||||||
|
margin-bottom: 3.5rem;
|
||||||
|
border-width: 0;
|
||||||
|
border-top: 1px solid #E1E1E1; }
|
||||||
|
|
||||||
|
|
||||||
|
/* Clearing
|
||||||
|
–––––––––––––––––––––––––––––––––––––––––––––––––– */
|
||||||
|
|
||||||
|
/* Self Clearing Goodness */
|
||||||
|
.container:after,
|
||||||
|
.row:after,
|
||||||
|
.u-cf {
|
||||||
|
content: "";
|
||||||
|
display: table;
|
||||||
|
clear: both; }
|
||||||
|
|
||||||
|
|
||||||
|
/* Media Queries
|
||||||
|
–––––––––––––––––––––––––––––––––––––––––––––––––– */
|
||||||
|
/*
|
||||||
|
Note: The best way to structure the use of media queries is to create the queries
|
||||||
|
near the relevant code. For example, if you wanted to change the styles for buttons
|
||||||
|
on small devices, paste the mobile query code up in the buttons section and style it
|
||||||
|
there.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* Larger than mobile */
|
||||||
|
@media (min-width: 400px) {}
|
||||||
|
|
||||||
|
/* Larger than phablet (also point when grid becomes active) */
|
||||||
|
@media (min-width: 550px) {}
|
||||||
|
|
||||||
|
/* Larger than tablet */
|
||||||
|
@media (min-width: 750px) {}
|
||||||
|
|
||||||
|
/* Larger than desktop */
|
||||||
|
@media (min-width: 1000px) {}
|
||||||
|
|
||||||
|
/* Larger than Desktop HD */
|
||||||
|
@media (min-width: 1200px) {}
|
||||||
|
|
||||||
|
|
||||||
|
.lds-grid {
|
||||||
|
display: inline-block;
|
||||||
|
position: relative;
|
||||||
|
width: 80px;
|
||||||
|
height: 80px;
|
||||||
|
}
|
||||||
|
.lds-grid div {
|
||||||
|
position: absolute;
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: #dfc;
|
||||||
|
animation: lds-grid 1.2s linear infinite;
|
||||||
|
}
|
||||||
|
.lds-grid div:nth-child(1) {
|
||||||
|
top: 8px;
|
||||||
|
left: 8px;
|
||||||
|
animation-delay: 0s;
|
||||||
|
}
|
||||||
|
.lds-grid div:nth-child(2) {
|
||||||
|
top: 8px;
|
||||||
|
left: 32px;
|
||||||
|
animation-delay: -0.4s;
|
||||||
|
}
|
||||||
|
.lds-grid div:nth-child(3) {
|
||||||
|
top: 8px;
|
||||||
|
left: 56px;
|
||||||
|
animation-delay: -0.8s;
|
||||||
|
}
|
||||||
|
.lds-grid div:nth-child(4) {
|
||||||
|
top: 32px;
|
||||||
|
left: 8px;
|
||||||
|
animation-delay: -0.4s;
|
||||||
|
}
|
||||||
|
.lds-grid div:nth-child(5) {
|
||||||
|
top: 32px;
|
||||||
|
left: 32px;
|
||||||
|
animation-delay: -0.8s;
|
||||||
|
}
|
||||||
|
.lds-grid div:nth-child(6) {
|
||||||
|
top: 32px;
|
||||||
|
left: 56px;
|
||||||
|
animation-delay: -1.2s;
|
||||||
|
}
|
||||||
|
.lds-grid div:nth-child(7) {
|
||||||
|
top: 56px;
|
||||||
|
left: 8px;
|
||||||
|
animation-delay: -0.8s;
|
||||||
|
}
|
||||||
|
.lds-grid div:nth-child(8) {
|
||||||
|
top: 56px;
|
||||||
|
left: 32px;
|
||||||
|
animation-delay: -1.2s;
|
||||||
|
}
|
||||||
|
.lds-grid div:nth-child(9) {
|
||||||
|
top: 56px;
|
||||||
|
left: 56px;
|
||||||
|
animation-delay: -1.6s;
|
||||||
|
}
|
||||||
|
@keyframes lds-grid {
|
||||||
|
0%, 100% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
}
|
BIN
static/images/favicon.png
Normal file
BIN
static/images/favicon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
5
static/jquery-1.11.3.min.js
vendored
Normal file
5
static/jquery-1.11.3.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
18
static/test.html
Normal file
18
static/test.html
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<h1>Testpage</h1>
|
||||||
|
<div style="width: 150px; float: left; padding: 5px;">
|
||||||
|
<img src="https://imdb-api.com/images/original/MV5BNjM0NTc0NzItM2FlYS00YzEwLWE0YmUtNTA2ZWIzODc2OTgxXkEyXkFqcGdeQXVyNTgwNzIyNzg@._V1_Ratio0.6800_AL_.jpg" style="width: 100%;">
|
||||||
|
<br>
|
||||||
|
<center><b>Txt</b></center>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="width: 150px; float: left; padding: 5px;">
|
||||||
|
<img src="https://imdb-api.com/images/original/MV5BNjM0NTc0NzItM2FlYS00YzEwLWE0YmUtNTA2ZWIzODc2OTgxXkEyXkFqcGdeQXVyNTgwNzIyNzg@._V1_Ratio0.6800_AL_.jpg" style="width: 100%;">
|
||||||
|
<br>
|
||||||
|
<center><b>Txt 2</b></center>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="width: 150px; float: left; padding: 5px;">
|
||||||
|
<img src="https://imdb-api.com/images/original/MV5BNjM0NTc0NzItM2FlYS00YzEwLWE0YmUtNTA2ZWIzODc2OTgxXkEyXkFqcGdeQXVyNTgwNzIyNzg@._V1_Ratio0.6800_AL_.jpg" style="width: 100%;">
|
||||||
|
<br>
|
||||||
|
<center><b>Txt 3</b></center>
|
||||||
|
</div>
|
206
static/video.js
Normal file
206
static/video.js
Normal file
@ -0,0 +1,206 @@
|
|||||||
|
var videoElement = document.querySelector('video');
|
||||||
|
var canvas = document.getElementById('pcCanvas');
|
||||||
|
var mobileCanvas = document.getElementById('mobileCanvas');
|
||||||
|
var ctx = canvas.getContext('2d');
|
||||||
|
var mobileCtx = mobileCanvas.getContext('2d');
|
||||||
|
var videoSelect = document.querySelector('select#videoSource');
|
||||||
|
var videoOption = document.getElementById('videoOption');
|
||||||
|
var buttonGo = document.getElementById('go');
|
||||||
|
var barcode_result = document.getElementById('dbr');
|
||||||
|
|
||||||
|
var isPaused = false;
|
||||||
|
var videoWidth = 640,
|
||||||
|
videoHeight = 480;
|
||||||
|
var mobileVideoWidth = 240,
|
||||||
|
mobileVideoHeight = 320;
|
||||||
|
var isPC = true;
|
||||||
|
|
||||||
|
var ZXing = null;
|
||||||
|
var decodePtr = null;
|
||||||
|
|
||||||
|
var tick = function () {
|
||||||
|
if (window.ZXing) {
|
||||||
|
ZXing = ZXing();
|
||||||
|
decodePtr = ZXing.Runtime.addFunction(decodeCallback);
|
||||||
|
} else {
|
||||||
|
setTimeout(tick, 10);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
tick();
|
||||||
|
|
||||||
|
var decodeCallback = function (ptr, len, resultIndex, resultCount) {
|
||||||
|
var result = new Uint8Array(ZXing.HEAPU8.buffer, ptr, len);
|
||||||
|
console.log(String.fromCharCode.apply(null, result));
|
||||||
|
barcode_result.textContent = String.fromCharCode.apply(null, result);
|
||||||
|
buttonGo.disabled = false;
|
||||||
|
if (isPC) {
|
||||||
|
canvas.style.display = 'block';
|
||||||
|
} else {
|
||||||
|
mobileCanvas.style.display = 'block';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// check devices
|
||||||
|
function browserRedirect() {
|
||||||
|
var deviceType;
|
||||||
|
var sUserAgent = navigator.userAgent.toLowerCase();
|
||||||
|
var bIsIpad = sUserAgent.match(/ipad/i) == "ipad";
|
||||||
|
var bIsIphoneOs = sUserAgent.match(/iphone os/i) == "iphone os";
|
||||||
|
var bIsMidp = sUserAgent.match(/midp/i) == "midp";
|
||||||
|
var bIsUc7 = sUserAgent.match(/rv:1.2.3.4/i) == "rv:1.2.3.4";
|
||||||
|
var bIsUc = sUserAgent.match(/ucweb/i) == "ucweb";
|
||||||
|
var bIsAndroid = sUserAgent.match(/android/i) == "android";
|
||||||
|
var bIsCE = sUserAgent.match(/windows ce/i) == "windows ce";
|
||||||
|
var bIsWM = sUserAgent.match(/windows mobile/i) == "windows mobile";
|
||||||
|
if (bIsIpad || bIsIphoneOs || bIsMidp || bIsUc7 || bIsUc || bIsAndroid || bIsCE || bIsWM) {
|
||||||
|
deviceType = 'phone';
|
||||||
|
} else {
|
||||||
|
deviceType = 'pc';
|
||||||
|
}
|
||||||
|
return deviceType;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (browserRedirect() == 'pc') {
|
||||||
|
isPC = true;
|
||||||
|
} else {
|
||||||
|
isPC = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// stackoverflow: http://stackoverflow.com/questions/4998908/convert-data-uri-to-file-then-append-to-formdata/5100158
|
||||||
|
function dataURItoBlob(dataURI) {
|
||||||
|
// convert base64/URLEncoded data component to raw binary data held in a string
|
||||||
|
var byteString;
|
||||||
|
if (dataURI.split(',')[0].indexOf('base64') >= 0)
|
||||||
|
byteString = atob(dataURI.split(',')[1]);
|
||||||
|
else
|
||||||
|
byteString = unescape(dataURI.split(',')[1]);
|
||||||
|
|
||||||
|
// separate out the mime component
|
||||||
|
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
|
||||||
|
|
||||||
|
// write the bytes of the string to a typed array
|
||||||
|
var ia = new Uint8Array(byteString.length);
|
||||||
|
for (var i = 0; i < byteString.length; i++) {
|
||||||
|
ia[i] = byteString.charCodeAt(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Blob([ia], {
|
||||||
|
type: mimeString
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// add button event
|
||||||
|
buttonGo.onclick = function () {
|
||||||
|
if (isPC) {
|
||||||
|
canvas.style.display = 'none';
|
||||||
|
} else {
|
||||||
|
mobileCanvas.style.display = 'none';
|
||||||
|
}
|
||||||
|
|
||||||
|
isPaused = false;
|
||||||
|
scanBarcode();
|
||||||
|
buttonGo.disabled = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
// scan barcode
|
||||||
|
function scanBarcode() {
|
||||||
|
barcode_result.textContent = "";
|
||||||
|
|
||||||
|
if (ZXing == null) {
|
||||||
|
buttonGo.disabled = false;
|
||||||
|
alert("Barcode Reader is not ready!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var data = null,
|
||||||
|
context = null,
|
||||||
|
width = 0,
|
||||||
|
height = 0,
|
||||||
|
dbrCanvas = null;
|
||||||
|
|
||||||
|
if (isPC) {
|
||||||
|
context = ctx;
|
||||||
|
width = videoWidth;
|
||||||
|
height = videoHeight;
|
||||||
|
dbrCanvas = canvas;
|
||||||
|
} else {
|
||||||
|
context = mobileCtx;
|
||||||
|
width = mobileVideoWidth;
|
||||||
|
height = mobileVideoHeight;
|
||||||
|
dbrCanvas = mobileCanvas;
|
||||||
|
}
|
||||||
|
|
||||||
|
context.drawImage(videoElement, 0, 0, width, height);
|
||||||
|
|
||||||
|
var vid = document.getElementById("video");
|
||||||
|
console.log("video width: " + vid.videoWidth + ", height: " + vid.videoHeight);
|
||||||
|
var barcodeCanvas = document.createElement("canvas");
|
||||||
|
barcodeCanvas.width = vid.videoWidth;
|
||||||
|
barcodeCanvas.height = vid.videoHeight;
|
||||||
|
var barcodeContext = barcodeCanvas.getContext('2d');
|
||||||
|
var imageWidth = vid.videoWidth, imageHeight = vid.videoHeight;
|
||||||
|
barcodeContext.drawImage(videoElement, 0, 0, imageWidth, imageHeight);
|
||||||
|
// read barcode
|
||||||
|
var imageData = barcodeContext.getImageData(0, 0, imageWidth, imageHeight);
|
||||||
|
var idd = imageData.data;
|
||||||
|
var image = ZXing._resize(imageWidth, imageHeight);
|
||||||
|
console.time("decode barcode");
|
||||||
|
for (var i = 0, j = 0; i < idd.length; i += 4, j++) {
|
||||||
|
ZXing.HEAPU8[image + j] = idd[i];
|
||||||
|
}
|
||||||
|
var err = ZXing._decode_any(decodePtr);
|
||||||
|
console.timeEnd('decode barcode');
|
||||||
|
console.log("error code", err);
|
||||||
|
if (err == -2) {
|
||||||
|
setTimeout(scanBarcode, 30);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// https://github.com/samdutton/simpl/tree/gh-pages/getusermedia/sources
|
||||||
|
var videoSelect = document.querySelector('select#videoSource');
|
||||||
|
|
||||||
|
navigator.mediaDevices.enumerateDevices()
|
||||||
|
.then(gotDevices).then(getStream).catch(handleError);
|
||||||
|
|
||||||
|
videoSelect.onchange = getStream;
|
||||||
|
|
||||||
|
function gotDevices(deviceInfos) {
|
||||||
|
for (var i = deviceInfos.length - 1; i >= 0; --i) {
|
||||||
|
var deviceInfo = deviceInfos[i];
|
||||||
|
var option = document.createElement('option');
|
||||||
|
option.value = deviceInfo.deviceId;
|
||||||
|
if (deviceInfo.kind === 'videoinput') {
|
||||||
|
option.text = deviceInfo.label || 'camera ' +
|
||||||
|
(videoSelect.length + 1);
|
||||||
|
videoSelect.appendChild(option);
|
||||||
|
} else {455
|
||||||
|
console.log('Found one other kind of source/device: ', deviceInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getStream() {
|
||||||
|
buttonGo.disabled = false;
|
||||||
|
if (window.stream) {
|
||||||
|
window.stream.getTracks().forEach(function(track) {
|
||||||
|
track.stop();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
var constraints = {
|
||||||
|
video: {
|
||||||
|
deviceId: {exact: videoSelect.value}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
navigator.mediaDevices.getUserMedia(constraints).
|
||||||
|
then(gotStream).catch(handleError);
|
||||||
|
}
|
||||||
|
|
||||||
|
function gotStream(stream) {
|
||||||
|
window.stream = stream; // make stream available to console
|
||||||
|
videoElement.srcObject = stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleError(error) {
|
||||||
|
console.log('Error: ', error);
|
||||||
|
}
|
36
static/zxing.js
Normal file
36
static/zxing.js
Normal file
File diff suppressed because one or more lines are too long
211
template/add.html
Normal file
211
template/add.html
Normal file
@ -0,0 +1,211 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<!-- Basic Page Needs
|
||||||
|
–––––––––––––––––––––––––––––––––––––––––––––––––– -->
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<title>OpenMovieDB - Bookshelf</title>
|
||||||
|
<meta name="description" content="OpenMovieDB - Bookshelf" />
|
||||||
|
<meta name="author" content="TheGreydiamond" />
|
||||||
|
|
||||||
|
<!-- Mobile Specific Metas
|
||||||
|
–––––––––––––––––––––––––––––––––––––––––––––––––– -->
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
|
||||||
|
<!-- FONT
|
||||||
|
–––––––––––––––––––––––––––––––––––––––––––––––––– -->
|
||||||
|
<link
|
||||||
|
href="//fonts.googleapis.com/css?family=Raleway:400,300,600"
|
||||||
|
rel="stylesheet"
|
||||||
|
type="text/css"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- CSS
|
||||||
|
–––––––––––––––––––––––––––––––––––––––––––––––––– -->
|
||||||
|
<link rel="stylesheet" href="css/normalize.css" />
|
||||||
|
<link rel="stylesheet" href="css/skeleton.css" />
|
||||||
|
<style>
|
||||||
|
|
||||||
|
/* In order to place the tracking correctly */
|
||||||
|
canvas.drawing, canvas.drawingBuffer {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<!-- Favicon
|
||||||
|
–––––––––––––––––––––––––––––––––––––––––––––––––– -->
|
||||||
|
<link rel="icon" type="image/png" href="images/favicon.png" />
|
||||||
|
<script src="https://kit.fontawesome.com/d7b80a780b.js" crossorigin="anonymous"></script>
|
||||||
|
<script src="https://cdn.rawgit.com/serratus/quaggaJS/0420d5e0/dist/quagga.min.js"></script>
|
||||||
|
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="one-half column" style="margin-top: 15%" id="mainCont">
|
||||||
|
<h4>OpenMovieDB - Add a new movie</h4>
|
||||||
|
<!-- Div to show the scanner -->
|
||||||
|
<% if(it.isDisplay == true) { %>
|
||||||
|
<%= it.titleByAPI %><br>
|
||||||
|
<%= it.id %><br>
|
||||||
|
<img src="<%= it.cover %>" alt="Cover image" style="height: 200px;"></img><br>
|
||||||
|
<button onclick="saveToLibary()"> Add to libary</button>
|
||||||
|
<% } else{ %>
|
||||||
|
<div id="scanner-container"></div>
|
||||||
|
<input type="button" id="btn" value="Start/Stop the scanner" />
|
||||||
|
<div id="currentEAN">EAN: Waiting for valid EAN...</div>
|
||||||
|
<button onclick="sendEanConvRequest()" disabled id="searchBtn"> <i class="fas fa-search"></i>Search</button>
|
||||||
|
<button onclick="window.location.href = '/'"><i class="fas fa-home"></i> Back to home</button>
|
||||||
|
<% } %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- Include the image-diff library -->
|
||||||
|
|
||||||
|
<script>
|
||||||
|
setTimeout(function(){
|
||||||
|
document.getElementById("btn").style.backgroundColor = "rgba(255, 0, 0, 0.5)";
|
||||||
|
document.getElementById("searchBtn").style.backgroundColor = "rgba(10, 10, 10, 0.5);"
|
||||||
|
}, 20)
|
||||||
|
|
||||||
|
var _scannerIsRunning = false;
|
||||||
|
|
||||||
|
function startScanner() {
|
||||||
|
Quagga.init({
|
||||||
|
inputStream: {
|
||||||
|
name: "Live",
|
||||||
|
type: "LiveStream",
|
||||||
|
target: document.querySelector('#scanner-container'),
|
||||||
|
constraints: {
|
||||||
|
width: 480,
|
||||||
|
height: 320,
|
||||||
|
facingMode: "environment"
|
||||||
|
},
|
||||||
|
},
|
||||||
|
decoder: {
|
||||||
|
readers: [
|
||||||
|
"code_128_reader",
|
||||||
|
"ean_reader",
|
||||||
|
"ean_8_reader",
|
||||||
|
"code_39_reader",
|
||||||
|
"code_39_vin_reader",
|
||||||
|
"codabar_reader",
|
||||||
|
"upc_reader",
|
||||||
|
"upc_e_reader",
|
||||||
|
"i2of5_reader"
|
||||||
|
],
|
||||||
|
debug: {
|
||||||
|
showCanvas: false,
|
||||||
|
showPatches: false,
|
||||||
|
showFoundPatches: false,
|
||||||
|
showSkeleton: false,
|
||||||
|
showLabels: false,
|
||||||
|
showPatchLabels: false,
|
||||||
|
showRemainingPatchLabels: false,
|
||||||
|
boxFromPatches: {
|
||||||
|
showTransformed: false,
|
||||||
|
showTransformedBox: false,
|
||||||
|
showBB: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
}, function (err) {
|
||||||
|
if (err) {
|
||||||
|
console.log(err);
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("Initialization finished. Ready to start");
|
||||||
|
Quagga.start();
|
||||||
|
|
||||||
|
// Set flag to is running
|
||||||
|
_scannerIsRunning = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
/*Quagga.onProcessed(function (result) {
|
||||||
|
//var drawingCtx = Quagga.canvas.ctx.overlay,
|
||||||
|
//drawingCanvas = Quagga.canvas.dom.overlay;
|
||||||
|
|
||||||
|
/*if (result) {
|
||||||
|
if (result.boxes) {
|
||||||
|
drawingCtx.clearRect(0, 0, parseInt(drawingCanvas.getAttribute("width")), parseInt(drawingCanvas.getAttribute("height")));
|
||||||
|
result.boxes.filter(function (box) {
|
||||||
|
return box !== result.box;
|
||||||
|
}).forEach(function (box) {
|
||||||
|
Quagga.ImageDebug.drawPath(box, { x: 0, y: 1 }, drawingCtx, { color: "green", lineWidth: 2 });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.box) {
|
||||||
|
Quagga.ImageDebug.drawPath(result.box, { x: 0, y: 1 }, drawingCtx, { color: "#00F", lineWidth: 2 });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.codeResult && result.codeResult.code) {
|
||||||
|
Quagga.ImageDebug.drawPath(result.line, { x: 'x', y: 'y' }, drawingCtx, { color: 'red', lineWidth: 3 });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});*/
|
||||||
|
|
||||||
|
|
||||||
|
Quagga.onDetected(function (result) {
|
||||||
|
console.log("Barcode detected and processed : [" + result.codeResult.code + "]", result);
|
||||||
|
if(String(result.codeResult.code).length == 13){
|
||||||
|
document.getElementById("currentEAN").innerHTML = "EAN: " + result.codeResult.code
|
||||||
|
console.log(result.codeResult.code)
|
||||||
|
document.getElementById("searchBtn").style.backgroundColor = "color: #555;"
|
||||||
|
document.getElementById("searchBtn").disabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Start/stop scanner
|
||||||
|
document.getElementById("btn").addEventListener("click", function () {
|
||||||
|
if (_scannerIsRunning) {
|
||||||
|
document.getElementById("btn").style.backgroundColor = "rgba(255, 0, 0, 0.5)";
|
||||||
|
Quagga.stop();
|
||||||
|
} else {
|
||||||
|
document.getElementById("btn").style.backgroundColor = "rgba(0, 255, 0, 0.5)";
|
||||||
|
startScanner();
|
||||||
|
}
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
function sendEanConvRequest(){
|
||||||
|
curEan = document.getElementById("currentEAN").innerHTML
|
||||||
|
curEan = curEan.replace("EAN: ", "")
|
||||||
|
document.getElementById("mainCont").innerHTML = "<h4>OpenMovieDB - Add a new movie</h4><center><div class=\"lds-grid\"><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div></div><br><i>Searching database...</i></center>";
|
||||||
|
if(curEan[0] == "0"){
|
||||||
|
curEan = curEan.substring(1);
|
||||||
|
}
|
||||||
|
url = "/apiCallBack?ean=" + curEan;
|
||||||
|
//window.open(url)
|
||||||
|
$.get(url,function(data,status) {
|
||||||
|
var respon = JSON.parse(data)
|
||||||
|
if(respon.state == "OK"){
|
||||||
|
url = "/returnSaveResult?reponseID=" + respon.reponseID;
|
||||||
|
window.location.href = url
|
||||||
|
}else{
|
||||||
|
// alert("An error with the api occured.")
|
||||||
|
document.getElementById("mainCont").innerHTML = "<h4>OpenMovieDB - Add a new movie</h4><center><i style='color: #cc0000; font-size: 100px;' class=\"fas fa-exclamation-circle\"></i><br>Ohno, the API returned an error. Errorcode: <br> <code>" + respon.state + "</code><br><br><button onclick=\"window.location.href = '/'\"><i class=\"fas fa-home\"></i> Back to home</button></center>"
|
||||||
|
}
|
||||||
|
console.log(data);
|
||||||
|
},'html');
|
||||||
|
//alert(curEan)
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveToLibary(){
|
||||||
|
url = "/save?ean=<%= it.ean %>";
|
||||||
|
|
||||||
|
$.get(url,function(data,status) { console.log(data); console.log(status) },'html');
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
133
template/addToShelf.html
Normal file
133
template/addToShelf.html
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<!-- Basic Page Needs
|
||||||
|
–––––––––––––––––––––––––––––––––––––––––––––––––– -->
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<title>OpenMovieDB - Bookshelf</title>
|
||||||
|
<meta name="description" content="OpenMovieDB - Bookshelf" />
|
||||||
|
<meta name="author" content="TheGreydiamond" />
|
||||||
|
|
||||||
|
<!-- Mobile Specific Metas
|
||||||
|
–––––––––––––––––––––––––––––––––––––––––––––––––– -->
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
|
||||||
|
<!-- FONT
|
||||||
|
–––––––––––––––––––––––––––––––––––––––––––––––––– -->
|
||||||
|
<link
|
||||||
|
href="//fonts.googleapis.com/css?family=Raleway:400,300,600"
|
||||||
|
rel="stylesheet"
|
||||||
|
type="text/css"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- CSS
|
||||||
|
–––––––––––––––––––––––––––––––––––––––––––––––––– -->
|
||||||
|
<link rel="stylesheet" href="css/normalize.css" />
|
||||||
|
<link rel="stylesheet" href="css/skeleton.css" />
|
||||||
|
<style>
|
||||||
|
#overlay {
|
||||||
|
position: fixed;
|
||||||
|
display: none;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background-color: rgba(0,0,0,0.5);
|
||||||
|
z-index: 2;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
#overlay2 {
|
||||||
|
position: fixed;
|
||||||
|
display: none;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background-color: rgba(0,0,0,0.5);
|
||||||
|
z-index: 2;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
#text{
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
font-size: 50px;
|
||||||
|
color: white;
|
||||||
|
transform: translate(-50%,-50%);
|
||||||
|
-ms-transform: translate(-50%,-50%);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<!-- Favicon
|
||||||
|
–––––––––––––––––––––––––––––––––––––––––––––––––– -->
|
||||||
|
<link rel="icon" type="image/png" href="images/favicon.png" />
|
||||||
|
<script src="https://kit.fontawesome.com/d7b80a780b.js" crossorigin="anonymous"></script>
|
||||||
|
<script src="https://cdn.rawgit.com/serratus/quaggaJS/0420d5e0/dist/quagga.min.js"></script>
|
||||||
|
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="overlay" onclick="off()">
|
||||||
|
<div id="text"><svg class='checkmark' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 52 52'><circle class='checkmark__circle ' cx='26' cy='26' r='25' fill='none'/><path class='checkmark__check' fill='none' d='M14.1 27.2l7.1 7.2 16.7-16.8'/></svg><style>.checkmark__circle { stroke-dasharray: 166; stroke-dashoffset: 166; stroke-width: 2; stroke-miterlimit: 10; stroke: #7ac142; fill: none; animation: stroke 0.6s cubic-bezier(0.65, 0, 0.45, 1) forwards;}.checkmark { width: 56px; height: 56px; border-radius: 50%; display: block; stroke-width: 2; stroke: #fff; stroke-miterlimit: 10; margin: 10% auto; box-shadow: inset 0px 0px 0px #7ac142; animation: fill .4s ease-in-out .4s forwards, scale .3s ease-in-out .9s both;}.checkmark__check { transform-origin: 50% 50%; stroke-dasharray: 48; stroke-dashoffset: 48; animation: stroke 0.3s cubic-bezier(0.65, 0, 0.45, 1) 0.8s forwards;}@keyframes stroke { 100% { stroke-dashoffset: 0; }}@keyframes scale { 0%, 100% { transform: none; } 50% { transform: scale3d(1.1, 1.1, 1); }}@keyframes fill { 100% { box-shadow: inset 0px 0px 0px 30px #7ac142; }}</style></div>
|
||||||
|
</div>
|
||||||
|
<div id="overlay2" onclick="off()">
|
||||||
|
<div id="text"><h1>!</h1><red>This movie already exists in the DB.</red></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="one-half column" style="margin-top: 15%" id="mainCont">
|
||||||
|
<h4>OpenMovieDB - Add a new movie</h4>
|
||||||
|
<div style="width: 300px;">
|
||||||
|
<img src="<%= it.cover %>" alt="Cover image" style="width: 100%;"></img><br>
|
||||||
|
<center><%= it.titleByAPI %><br><i><%= it.id %></i></center>
|
||||||
|
</div>
|
||||||
|
<button onclick="saveToLibary()" class="button-primary" id="addToBtn"> Add to libary</button>
|
||||||
|
<button onclick="window.location.href = '/'"><i class="fas fa-home"></i> Back to home</button>
|
||||||
|
<button
|
||||||
|
|
||||||
|
onclick="window.location.href = '/add'"
|
||||||
|
>
|
||||||
|
<i class="fas fa-plus"></i> Add new movie</button
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- Include the image-diff library -->
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function on() {
|
||||||
|
document.getElementById("overlay").style.display = "block";
|
||||||
|
}
|
||||||
|
function on2() {
|
||||||
|
document.getElementById("overlay2").style.display = "block";
|
||||||
|
}
|
||||||
|
|
||||||
|
function off() {
|
||||||
|
document.getElementById("overlay").style.display = "none";
|
||||||
|
document.getElementById("overlay2").style.display = "none";
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveToLibary(){
|
||||||
|
url = "/save?reponseID=<%= it.ean %>";
|
||||||
|
document.getElementById("addToBtn").remove();
|
||||||
|
$.get(url,function(data,status) {
|
||||||
|
console.log(JSON.parse(data))
|
||||||
|
if(JSON.parse(data).status == "OK"){
|
||||||
|
on();
|
||||||
|
}else{
|
||||||
|
console.log("exist")
|
||||||
|
on2()
|
||||||
|
}
|
||||||
|
},'html');
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
90
template/bookshelf.html
Normal file
90
template/bookshelf.html
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<!-- Basic Page Needs
|
||||||
|
–––––––––––––––––––––––––––––––––––––––––––––––––– -->
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<title>OpenMovieDB - Bookshelf</title>
|
||||||
|
<meta name="description" content="OpenMovieDB - Bookshelf" />
|
||||||
|
<meta name="author" content="TheGreydiamond" />
|
||||||
|
|
||||||
|
<!-- Mobile Specific Metas
|
||||||
|
–––––––––––––––––––––––––––––––––––––––––––––––––– -->
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
|
||||||
|
<!-- FONT
|
||||||
|
–––––––––––––––––––––––––––––––––––––––––––––––––– -->
|
||||||
|
<link
|
||||||
|
href="//fonts.googleapis.com/css?family=Raleway:400,300,600"
|
||||||
|
rel="stylesheet"
|
||||||
|
type="text/css"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- CSS
|
||||||
|
–––––––––––––––––––––––––––––––––––––––––––––––––– -->
|
||||||
|
<link rel="stylesheet" href="css/normalize.css" />
|
||||||
|
<link rel="stylesheet" href="css/skeleton.css" />
|
||||||
|
|
||||||
|
<!-- Favicon
|
||||||
|
–––––––––––––––––––––––––––––––––––––––––––––––––– -->
|
||||||
|
<link rel="icon" type="image/png" href="images/favicon.png" />
|
||||||
|
<script
|
||||||
|
src="https://kit.fontawesome.com/d7b80a780b.js"
|
||||||
|
crossorigin="anonymous"
|
||||||
|
></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<!-- Primary Page Layout
|
||||||
|
–––––––––––––––––––––––––––––––––––––––––––––––––– -->
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
|
||||||
|
<div class="eleven column" style="margin-top: 15%">
|
||||||
|
<h4>OpenMovieDB - Bookshelf</h4>
|
||||||
|
<div style="float: right; top: -20px;">
|
||||||
|
<input class="u-full-width" type="text" placeholder="Search" id="search">
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
class="button-primary"
|
||||||
|
onclick="window.location.href = '/add'"
|
||||||
|
>
|
||||||
|
<i class="fas fa-plus"></i> Add new movie</button
|
||||||
|
><br />
|
||||||
|
<div id="listOfMovies"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
ser = document.getElementById("search");
|
||||||
|
ser.addEventListener("input", updateValue);
|
||||||
|
json = <%~ it.jsonRespo %>;
|
||||||
|
function updateValue(e) {
|
||||||
|
console.log(e.target.value)
|
||||||
|
outList = [];
|
||||||
|
i = 0;
|
||||||
|
elem = document.getElementById("listOfMovies");
|
||||||
|
elem.innerHTML = ""
|
||||||
|
while(i < json.length){
|
||||||
|
currenElm = json[i]
|
||||||
|
if(currenElm.movieTitel.toLowerCase().replace("(", "").replace(")", "").includes(e.target.value.toLowerCase())){
|
||||||
|
console.log(currenElm.movieID)
|
||||||
|
elem.innerHTML += "<a href='/showDetails?id=" + currenElm.movieID + "'><div style='width: 150px; float: left; padding: 5px;'><img src='" + currenElm.posterUrl + '\' style="width: 100%;"><br><center><b>' + currenElm.movieTitel + "</b></center></div></a>"
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
i = 0;
|
||||||
|
elem = document.getElementById("listOfMovies")
|
||||||
|
while(i < json.length){
|
||||||
|
currenElm = json[i]
|
||||||
|
elem.innerHTML += "<a href='/showDetails?id=" + currenElm.movieID + "'><div style='width: 150px; float: left; padding: 5px;'><img src='" + currenElm.posterUrl + '\' style="width: 100%;"><br><center><b>' + currenElm.movieTitel + "</b></center></div></a>"
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
<!-- End Document
|
||||||
|
–––––––––––––––––––––––––––––––––––––––––––––––––– -->
|
||||||
|
</body>
|
||||||
|
</html>
|
138
template/index.html
Normal file
138
template/index.html
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<script src="https://cdn.rawgit.com/serratus/quaggaJS/0420d5e0/dist/quagga.min.js"></script>
|
||||||
|
<head>
|
||||||
|
<title></title>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<style>
|
||||||
|
/* In order to place the tracking correctly */
|
||||||
|
canvas.drawing, canvas.drawingBuffer {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<%= it.titleByAPI %><br>
|
||||||
|
<%= it.id %><br>
|
||||||
|
<img src="<%= it.cover %>" alt="Cover image" style="height: 200px;"></img>
|
||||||
|
<!-- Div to show the scanner -->
|
||||||
|
<div id="scanner-container"></div>
|
||||||
|
<input type="button" id="btn" value="Start/Stop the scanner" />
|
||||||
|
<div id="currentEAN">Waiting for proper EAN..</div>
|
||||||
|
<button onclick="sendEanConvRequest()"> Search</button>
|
||||||
|
|
||||||
|
<!-- Include the image-diff library -->
|
||||||
|
|
||||||
|
<script>
|
||||||
|
var _scannerIsRunning = false;
|
||||||
|
|
||||||
|
function startScanner() {
|
||||||
|
Quagga.init({
|
||||||
|
inputStream: {
|
||||||
|
name: "Live",
|
||||||
|
type: "LiveStream",
|
||||||
|
target: document.querySelector('#scanner-container'),
|
||||||
|
constraints: {
|
||||||
|
width: 480,
|
||||||
|
height: 320,
|
||||||
|
facingMode: "environment"
|
||||||
|
},
|
||||||
|
},
|
||||||
|
decoder: {
|
||||||
|
readers: [
|
||||||
|
"code_128_reader",
|
||||||
|
"ean_reader",
|
||||||
|
"ean_8_reader",
|
||||||
|
"code_39_reader",
|
||||||
|
"code_39_vin_reader",
|
||||||
|
"codabar_reader",
|
||||||
|
"upc_reader",
|
||||||
|
"upc_e_reader",
|
||||||
|
"i2of5_reader"
|
||||||
|
],
|
||||||
|
debug: {
|
||||||
|
showCanvas: true,
|
||||||
|
showPatches: true,
|
||||||
|
showFoundPatches: true,
|
||||||
|
showSkeleton: true,
|
||||||
|
showLabels: true,
|
||||||
|
showPatchLabels: true,
|
||||||
|
showRemainingPatchLabels: true,
|
||||||
|
boxFromPatches: {
|
||||||
|
showTransformed: true,
|
||||||
|
showTransformedBox: true,
|
||||||
|
showBB: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
}, function (err) {
|
||||||
|
if (err) {
|
||||||
|
console.log(err);
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("Initialization finished. Ready to start");
|
||||||
|
Quagga.start();
|
||||||
|
|
||||||
|
// Set flag to is running
|
||||||
|
_scannerIsRunning = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
Quagga.onProcessed(function (result) {
|
||||||
|
var drawingCtx = Quagga.canvas.ctx.overlay,
|
||||||
|
drawingCanvas = Quagga.canvas.dom.overlay;
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
if (result.boxes) {
|
||||||
|
drawingCtx.clearRect(0, 0, parseInt(drawingCanvas.getAttribute("width")), parseInt(drawingCanvas.getAttribute("height")));
|
||||||
|
result.boxes.filter(function (box) {
|
||||||
|
return box !== result.box;
|
||||||
|
}).forEach(function (box) {
|
||||||
|
Quagga.ImageDebug.drawPath(box, { x: 0, y: 1 }, drawingCtx, { color: "green", lineWidth: 2 });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.box) {
|
||||||
|
Quagga.ImageDebug.drawPath(result.box, { x: 0, y: 1 }, drawingCtx, { color: "#00F", lineWidth: 2 });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.codeResult && result.codeResult.code) {
|
||||||
|
Quagga.ImageDebug.drawPath(result.line, { x: 'x', y: 'y' }, drawingCtx, { color: 'red', lineWidth: 3 });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
Quagga.onDetected(function (result) {
|
||||||
|
console.log("Barcode detected and processed : [" + result.codeResult.code + "]", result);
|
||||||
|
if(String(result.codeResult.code).length == 13){
|
||||||
|
document.getElementById("currentEAN").innerHTML = result.codeResult.code
|
||||||
|
console.log(result.codeResult.code)
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Start/stop scanner
|
||||||
|
document.getElementById("btn").addEventListener("click", function () {
|
||||||
|
if (_scannerIsRunning) {
|
||||||
|
Quagga.stop();
|
||||||
|
} else {
|
||||||
|
startScanner();
|
||||||
|
}
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
function sendEanConvRequest(){
|
||||||
|
url = "/apiCallBack?ean=" + document.getElementById("currentEAN").innerHTML;
|
||||||
|
window.open(url)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
126
template/movieDetails.html
Normal file
126
template/movieDetails.html
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<!-- Basic Page Needs
|
||||||
|
–––––––––––––––––––––––––––––––––––––––––––––––––– -->
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<title>OpenMovieDB - Bookshelf</title>
|
||||||
|
<meta name="description" content="OpenMovieDB - Bookshelf" />
|
||||||
|
<meta name="author" content="TheGreydiamond" />
|
||||||
|
|
||||||
|
<!-- Mobile Specific Metas
|
||||||
|
–––––––––––––––––––––––––––––––––––––––––––––––––– -->
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
|
||||||
|
<!-- FONT
|
||||||
|
–––––––––––––––––––––––––––––––––––––––––––––––––– -->
|
||||||
|
<link
|
||||||
|
href="//fonts.googleapis.com/css?family=Raleway:400,300,600"
|
||||||
|
rel="stylesheet"
|
||||||
|
type="text/css"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- CSS
|
||||||
|
–––––––––––––––––––––––––––––––––––––––––––––––––– -->
|
||||||
|
<link rel="stylesheet" href="css/normalize.css" />
|
||||||
|
<link rel="stylesheet" href="css/skeleton.css" />
|
||||||
|
<style>
|
||||||
|
#overlay {
|
||||||
|
position: fixed;
|
||||||
|
display: none;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background-color: rgba(0,0,0,0.5);
|
||||||
|
z-index: 2;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
#overlay2 {
|
||||||
|
position: fixed;
|
||||||
|
display: none;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background-color: rgba(0,0,0,0.5);
|
||||||
|
z-index: 2;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
#text{
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
font-size: 50px;
|
||||||
|
color: white;
|
||||||
|
transform: translate(-50%,-50%);
|
||||||
|
-ms-transform: translate(-50%,-50%);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<!-- Favicon
|
||||||
|
–––––––––––––––––––––––––––––––––––––––––––––––––– -->
|
||||||
|
<link rel="icon" type="image/png" href="images/favicon.png" />
|
||||||
|
<script src="https://kit.fontawesome.com/d7b80a780b.js" crossorigin="anonymous"></script>
|
||||||
|
<script src="https://cdn.rawgit.com/serratus/quaggaJS/0420d5e0/dist/quagga.min.js"></script>
|
||||||
|
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="overlay" onclick="off()">
|
||||||
|
<div id="text"><svg class='checkmark' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 52 52'><circle class='checkmark__circle ' cx='26' cy='26' r='25' fill='none'/><path class='checkmark__check' fill='none' d='M14.1 27.2l7.1 7.2 16.7-16.8'/></svg><style>.checkmark__circle { stroke-dasharray: 166; stroke-dashoffset: 166; stroke-width: 2; stroke-miterlimit: 10; stroke: #7ac142; fill: none; animation: stroke 0.6s cubic-bezier(0.65, 0, 0.45, 1) forwards;}.checkmark { width: 56px; height: 56px; border-radius: 50%; display: block; stroke-width: 2; stroke: #fff; stroke-miterlimit: 10; margin: 10% auto; box-shadow: inset 0px 0px 0px #7ac142; animation: fill .4s ease-in-out .4s forwards, scale .3s ease-in-out .9s both;}.checkmark__check { transform-origin: 50% 50%; stroke-dasharray: 48; stroke-dashoffset: 48; animation: stroke 0.3s cubic-bezier(0.65, 0, 0.45, 1) 0.8s forwards;}@keyframes stroke { 100% { stroke-dashoffset: 0; }}@keyframes scale { 0%, 100% { transform: none; } 50% { transform: scale3d(1.1, 1.1, 1); }}@keyframes fill { 100% { box-shadow: inset 0px 0px 0px 30px #7ac142; }}</style></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="overlay2" onclick="off()">
|
||||||
|
<div id="text">Do you really want to remove this movie?<br>
|
||||||
|
<button onclick="sureDelete()" style="background-color: rgba(174, 255, 128, 0.699)"><i class="fas fa-trash"></i> Yes</button>
|
||||||
|
<button onclick="off()" style="background-color: rgba(255, 95, 95, 0.719)"><i class="fas fa-times"></i> No</button>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="one-half column" style="margin-top: 10%" id="mainCont">
|
||||||
|
<h4>OpenMovieDB - Moviedetails</h4>
|
||||||
|
<div style="width: 300px;">
|
||||||
|
<img src="<%= it.cover %>" alt="Cover image" style="width: 100%;"></img><br>
|
||||||
|
<center><%= it.titleByAPI %><br><i><%= it.id %></i></center>
|
||||||
|
</div>
|
||||||
|
<button onclick="handelDelete()" id="delBtn"><i class="fas fa-trash"></i> Delete</button>
|
||||||
|
<button onclick="window.location.href = '/'"><i class="fas fa-home"></i> Back to home</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
|
||||||
|
function on() {
|
||||||
|
document.getElementById("overlay").style.display = "block";
|
||||||
|
}
|
||||||
|
|
||||||
|
function off() {
|
||||||
|
document.getElementById("overlay").style.display = "none";
|
||||||
|
document.getElementById("overlay2").style.display = "none";
|
||||||
|
}
|
||||||
|
|
||||||
|
function sureDelete(){
|
||||||
|
console.log("Deleting movie")
|
||||||
|
url = "/delete?id=<%= it.internalID %>";
|
||||||
|
document.getElementById("delBtn").remove();
|
||||||
|
$.get(url,function(data,status) { console.log(data); console.log(status); on(); setTimeout(function(){window.location.href = '/';}, 1000); },'html');
|
||||||
|
}
|
||||||
|
|
||||||
|
function handelDelete(){
|
||||||
|
document.getElementById("overlay2").style.display = "block";
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
26
testEANconver.js
Normal file
26
testEANconver.js
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*const FormData = require('form-data');
|
||||||
|
const http = require('http');
|
||||||
|
|
||||||
|
const form = new FormData();
|
||||||
|
form.append('SText', '4010884546217');
|
||||||
|
form.append('Kat', 'EAN');
|
||||||
|
const uploadResponse = fetch("https://ssl.ofdb.de/view.php?page=suchergebnis", {method: 'POST', body: form });
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
console.log(uploadResponse)
|
||||||
|
}, 500);
|
||||||
|
*/
|
||||||
|
|
||||||
|
const { URLSearchParams } = require('url');
|
||||||
|
const fetch = require('node-fetch');
|
||||||
|
|
||||||
|
const params = new URLSearchParams();
|
||||||
|
params.append('SText', '4010884546217');
|
||||||
|
params.append('Kat', 'EAN');
|
||||||
|
|
||||||
|
fetch('https://ssl.ofdb.de/view.php?page=suchergebnis', { method: 'POST', body: params })
|
||||||
|
.then(res => console.log(res.statusCode))
|
Reference in New Issue
Block a user