You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
189 lines
5.5 KiB
189 lines
5.5 KiB
<?php
|
|
|
|
/* This is free and unencumbered software released into the public domain.
|
|
*
|
|
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
|
* distribute this software, either in source code form or as a compiled
|
|
* binary, for any purpose, commercial or non-commercial, and by any
|
|
* means.
|
|
*
|
|
* In jurisdictions that recognize copyright laws, the author or authors
|
|
* of this software dedicate any and all copyright interest in the
|
|
* software to the public domain. We make this dedication for the benefit
|
|
* of the public at large and to the detriment of our heirs and
|
|
* successors. We intend this dedication to be an overt act of
|
|
* relinquishment in perpetuity of all present and future rights to this
|
|
* software under copyright law.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
|
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
|
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
* OTHER DEALINGS IN THE SOFTWARE.
|
|
*
|
|
* For more information, please refer to <http://unlicense.org/>
|
|
*/
|
|
|
|
// Return source code
|
|
if(isset($_GET['source'])) {
|
|
header("Content-Type: text/plain");
|
|
die(file_get_contents(basename($_SERVER['PHP_SELF'])));
|
|
}
|
|
|
|
header("Content-Type: application/json");
|
|
|
|
/* vars.php should contain the following, but with your variables as needed:
|
|
*
|
|
* // Database constants for PostgreSQL database
|
|
* $DB_HOST = 'localhost';
|
|
* $DB_NAME = '<db name>';
|
|
* $DB_USER = '<db role name>';
|
|
* $DB_PASSWORD = '<db role password>';
|
|
*
|
|
* You also need to run the following SQL:
|
|
*
|
|
* CREATE TABLE words (
|
|
* id INT PRIMARY KEY,
|
|
* solution VARCHAR(5) NOT NULL,
|
|
* print_date VARCHAR(10) NOT NULL,
|
|
* days_since_launch INT,
|
|
* editor VARCHAR(64),
|
|
* access_count INT DEFAULT 0
|
|
* );
|
|
*
|
|
* CREATE TABLE update (
|
|
* time TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
* lock BOOL PRIMARY KEY DEFAULT TRUE,
|
|
* CONSTRAINT lock_unique CHECK(lock)
|
|
* );
|
|
*
|
|
* INSERT INTO update VALUES (NOW());
|
|
*/
|
|
require_once('vars.php');
|
|
|
|
//// Functions: ////
|
|
|
|
function get_words($date, $limit, $include) {
|
|
$query = "SELECT $include FROM words WHERE print_date>=$1 ORDER BY print_date ASC LIMIT $2";
|
|
$res = pg_query_params($query, [$date, $limit]) or die('Query failed: ' . pg_last_error());
|
|
|
|
if(pg_num_rows($res) == 0) {
|
|
return [
|
|
'status' => 'ERROR',
|
|
'message' => 'Already up to date'
|
|
];
|
|
}
|
|
|
|
while($row = pg_fetch_array($res, null, PGSQL_ASSOC)) {
|
|
$toint = ['id', 'days_since_launch', 'access_count'];
|
|
foreach($toint as $key) {
|
|
if(array_key_exists($key, $row))
|
|
$row[$key] = intval($row[$key]);
|
|
}
|
|
$words[] = $row;
|
|
}
|
|
|
|
$query = 'UPDATE words SET access_count=access_count+1 WHERE print_date>=$1';
|
|
pg_query_params($query, [$date]) or die('Query failed ' . pg_last_error());
|
|
|
|
// If just one column, do a straight array
|
|
if(!str_contains($include, ','))
|
|
$words = array_column($words, $include);
|
|
|
|
return $words;
|
|
}
|
|
|
|
function add_words($datestamp) {
|
|
$ret = false;
|
|
while(true) {
|
|
$date = date('Y-m-d', $datestamp);
|
|
$query = 'SELECT FROM words WHERE print_date=$1';
|
|
$res = pg_query_params($query, [$date]) or die('Query failed: ' . pg_last_error());
|
|
if(pg_num_rows($res) == 0) {
|
|
$content = file_get_contents("https://www.nytimes.com/svc/wordle/v2/$date.json");
|
|
if(!$content)
|
|
break;
|
|
|
|
$word = json_decode($content, true);
|
|
|
|
// Add word to database
|
|
$query = 'INSERT INTO words (id, solution, print_date, days_since_launch, editor) ' .
|
|
'VALUES ($1, UPPER($2), $3, $4, $5)';
|
|
$params = [
|
|
$word['id'],
|
|
$word['solution'],
|
|
$word['print_date'],
|
|
$word['days_since_launch'],
|
|
$word['editor']
|
|
];
|
|
pg_query_params($query, $params) or die('Query failed: ' . pg_last_error());
|
|
|
|
$ret = true; // (at least one) word added
|
|
}
|
|
|
|
$datestamp += 60 * 60 * 24;
|
|
}
|
|
|
|
return $ret;
|
|
}
|
|
|
|
//// Code start: ////
|
|
|
|
// Connect to the database
|
|
$dbc = pg_connect("host=$DB_HOST dbname=$DB_NAME user=$DB_USER password=$DB_PASSWORD")
|
|
or die('Could not connect: ' . pg_last_error());
|
|
|
|
// Check for words once a day
|
|
$res = pg_query('SELECT EXTRACT(EPOCH FROM time) AS time FROM update') or die('Query failed: ' . pg_last_error());
|
|
$cur_time = time();
|
|
$last_time = pg_fetch_array($res)['time'];
|
|
if($cur_time > $last_time + (60 * 60 * 24)) {
|
|
add_words($cur_time);
|
|
|
|
$query = 'UPDATE update SET time=TO_TIMESTAMP($1)';
|
|
pg_query_params($query, [$cur_time]) or die('Query failed: ' . pg_last_error());
|
|
}
|
|
|
|
// Get words
|
|
if($_GET['mode'] == 'mod.json') {
|
|
header('Content-Disposition: attachment; filename="mod.json"');
|
|
echo json_encode([
|
|
'words' => [
|
|
'order' => get_words('2021-06-19', 100000, 'id')
|
|
]
|
|
]);
|
|
} else {
|
|
// Check get vars
|
|
$date = $_GET['date'];
|
|
$limit = isset($_GET['limit']) ? intval($_GET['limit']) : 100;
|
|
$include = isset($_GET['include']) ? $_GET['include'] : 'id,solution,print_date,days_since_launch,editor';
|
|
|
|
if(!preg_match('/^\d{4}-\d{2}-\d{2}$/', $date)) {
|
|
die(json_encode([
|
|
'status' => 'ERROR',
|
|
'message' => 'Invalid date format (YYYY-MM-DD)'
|
|
]));
|
|
} else if($date < '2021-06-19') {
|
|
die(json_encode([
|
|
'status' => 'ERROR',
|
|
'message' => 'Date too early'
|
|
]));
|
|
} else if($limit <= 0) {
|
|
die(json_encode([
|
|
'status' => 'ERROR',
|
|
'message' => 'Invalid limit'
|
|
]));
|
|
} else if(!preg_match('/^[a-z,_]+$/', $include)) {
|
|
die(json_encode([
|
|
'status' => 'ERROR',
|
|
'message' => 'Invalid include'
|
|
]));
|
|
}
|
|
|
|
echo json_encode(get_words($date, $limit, $include));
|
|
}
|
|
|
|
pg_close($dbc);
|