Merge MVC rewrite into master (#21)
* Just commit it all * Require auth * crap * Update homepage * Block AI scrapers * Update cache update script * Add dummy file * Remove unnecessary lastfm config var * Use withQueryParameters for LastFM API * Fix embeds * Update example env * Smard
This commit is contained in:
parent
a64bcc2c46
commit
0f52d80ca6
88 changed files with 1982 additions and 1661 deletions
|
@ -26,5 +26,3 @@ MEMCACHED_HOST=127.0.0.1
|
|||
|
||||
LASTFM_KEY=
|
||||
LASTFM_USER=
|
||||
LASTFM_TOP_TRACKS=10
|
||||
API_ROOT=http://127.0.0.1:3000
|
||||
|
|
15
app/Http/Controllers/AdminBookmarksController.php
Normal file
15
app/Http/Controllers/AdminBookmarksController.php
Normal file
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\BookmarkCategory;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class AdminBookmarksController extends Controller
|
||||
{
|
||||
public function show() : View {
|
||||
$categories = BookmarkCategory::with('sites')->get();
|
||||
return view('admin.bookmarks', compact('categories'));
|
||||
}
|
||||
}
|
34
app/Http/Controllers/AdminGuestbookController.php
Normal file
34
app/Http/Controllers/AdminGuestbookController.php
Normal file
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\GuestbookEntry;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\View\View;
|
||||
use UAParser\Parser;
|
||||
|
||||
class AdminGuestbookController extends Controller
|
||||
{
|
||||
function getGuestbookUniqueAddr(): int {
|
||||
$uniqueIpsCount = DB::table('guestbook__entries')->distinct()->count('ip');
|
||||
return $uniqueIpsCount;
|
||||
}
|
||||
|
||||
function getGuestbookEntriesCount(): int {
|
||||
$entryCount = DB::table('guestbook__entries')->count();
|
||||
return $entryCount;
|
||||
}
|
||||
public function show() : View {
|
||||
$guestbook_unique_addr = $this->getGuestbookUniqueAddr();
|
||||
$guestbook_entry_count = $this->getGuestbookEntriesCount();
|
||||
$entries = GuestbookEntry::selectEntries();
|
||||
$parser = Parser::create();
|
||||
|
||||
return view('admin.guestbook', [
|
||||
'guestbook_unique_addr' => $guestbook_unique_addr,
|
||||
'guestbook_entry_count' => $guestbook_entry_count,
|
||||
'entries' => $entries,
|
||||
'parser' => $parser,
|
||||
]);
|
||||
}
|
||||
}
|
69
app/Http/Controllers/AdminImportController.php
Normal file
69
app/Http/Controllers/AdminImportController.php
Normal file
|
@ -0,0 +1,69 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\BookmarkCategory;
|
||||
use App\Models\BookmarkSite;
|
||||
use App\Models\GuestbookEntry;
|
||||
use Exception;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class AdminImportController extends Controller
|
||||
{
|
||||
public function show() : View {
|
||||
return view('admin.import');
|
||||
}
|
||||
|
||||
public function submit(Request $request)
|
||||
{
|
||||
$request->validate([
|
||||
'data_file' => 'required|mimes:json',
|
||||
]);
|
||||
|
||||
$file = $request->file('data_file');
|
||||
$jsonContent = file_get_contents($file->getRealPath());
|
||||
$data = json_decode($jsonContent, true);
|
||||
$tables = [];
|
||||
foreach($data as $item) {
|
||||
if ($item['type'] !== "table") continue;
|
||||
$tables[$item['name']] = [
|
||||
'data' => $item['data'],
|
||||
'count' => count($item['data'])
|
||||
];
|
||||
|
||||
if ($item['name'] === "guestbook__entries") {
|
||||
GuestbookEntry::importGuestbookEntry($item['data']);
|
||||
}
|
||||
$this->import($item['data'], $item['name']);
|
||||
}
|
||||
return view('admin.import-success', ['tables' => $tables]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Imports the given data to the specified table
|
||||
*
|
||||
* @param array $data The data to import
|
||||
* @param string $table_name The name of the table to import to
|
||||
* @return void
|
||||
* @throws Exception Invalid table specified, to be replaced with custom exception
|
||||
*/
|
||||
public function import(array $data, string $table_name): void {
|
||||
switch ($table_name) {
|
||||
case 'guestbook__entries':
|
||||
GuestbookEntry::importGuestbookEntry($data);
|
||||
break;
|
||||
case 'bookmark__categories' :
|
||||
BookmarkCategory::importBookmarkCategory($data);
|
||||
break;
|
||||
case 'bookmark__sites':
|
||||
BookmarkSite::importBookmark($data);
|
||||
break;
|
||||
case 'guestbook__bans':
|
||||
break;
|
||||
default:
|
||||
// TODO: Replace with custom exception
|
||||
throw new Exception("Invalid table specified ($table_name)");
|
||||
}
|
||||
}
|
||||
}
|
15
app/Http/Controllers/BookmarksController.php
Normal file
15
app/Http/Controllers/BookmarksController.php
Normal file
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\BookmarkSite;
|
||||
use App\Models\BookmarkCategory;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class BookmarksController extends Controller
|
||||
{
|
||||
public function show() : View {
|
||||
$categories = BookmarkCategory::with('sites')->get();
|
||||
return view('bookmarks', compact('categories'));
|
||||
}
|
||||
}
|
13
app/Http/Controllers/CalculatorsController.php
Normal file
13
app/Http/Controllers/CalculatorsController.php
Normal file
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class CalculatorsController extends Controller
|
||||
{
|
||||
public function show() : View {
|
||||
return view('calculators');
|
||||
}
|
||||
}
|
13
app/Http/Controllers/ComputersController.php
Normal file
13
app/Http/Controllers/ComputersController.php
Normal file
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class ComputersController extends Controller
|
||||
{
|
||||
public function show() : View {
|
||||
return view('computers');
|
||||
}
|
||||
}
|
|
@ -2,37 +2,46 @@
|
|||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\GuestbookEntry;
|
||||
use Illuminate\Http\Request;
|
||||
use DB;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use UAParser\Parser;
|
||||
|
||||
class GuestbookController extends Controller {
|
||||
public function guestbook() {
|
||||
return view('pages.guestbook');
|
||||
public function show(): View {
|
||||
$entries = GuestbookEntry::selectEntries();
|
||||
$parser = Parser::create();
|
||||
|
||||
return view('guestbook')
|
||||
->with('entries', $entries)
|
||||
->with('parser', $parser);
|
||||
}
|
||||
|
||||
public function guestbookPost(Request $request) {
|
||||
/**
|
||||
* Creates a new guestbook entry
|
||||
*
|
||||
* @param Request $request
|
||||
* @return RedirectResponse
|
||||
* @throws ValidationException
|
||||
*/
|
||||
public function addEntry(Request $request): RedirectResponse {
|
||||
$this->validate($request, [
|
||||
'name' => 'required',
|
||||
'message' => 'required'
|
||||
]);
|
||||
|
||||
$matching_bans = DB::select('SELECT reason FROM guestbook__bans WHERE ip_address = ?', array($request->ip()));
|
||||
|
||||
if (!empty($matching_bans)) {
|
||||
return view('errors.guestbook-ipban')->with('reason', $matching_bans[0]->reason);
|
||||
}
|
||||
|
||||
DB::insert(
|
||||
'INSERT INTO guestbook__entries (name, timestamp, ip_address, agent, message) values (?, ?, ?, ?, ?)',
|
||||
[
|
||||
htmlspecialchars($request->get('name')),
|
||||
time(),
|
||||
$request->ip(),
|
||||
$request->userAgent(),
|
||||
htmlspecialchars($request->get('message'))
|
||||
]
|
||||
);
|
||||
|
||||
GuestbookEntry::insertGuestbookEntry($request);
|
||||
return back()->with('success', 'Entry submitted successfully!');
|
||||
}
|
||||
|
||||
public function banIP(string $addr) {
|
||||
// TODO: Add banning system
|
||||
// $matching_bans = DB::select('SELECT reason FROM guestbook__bans WHERE ip_address = ?', array($request->ip()));
|
||||
// if (!empty($matching_bans)) {
|
||||
// return view('errors.guestbook-ipban')->with('reason', $matching_bans[0]->reason);
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
|
32
app/Http/Controllers/HomeController.php
Normal file
32
app/Http/Controllers/HomeController.php
Normal file
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\View\View;
|
||||
use DateTime;
|
||||
|
||||
class HomeController extends Controller
|
||||
{
|
||||
/**
|
||||
* Returns age based on birthday date and current date (GMT)
|
||||
* @return int
|
||||
*/
|
||||
function returnAge(): int
|
||||
{
|
||||
date_default_timezone_set('Europe/London');
|
||||
$birthday = new DateTime("2005-06-07");
|
||||
$currentDate = DateTime::createFromFormat("Y-m-d", date("Y-m-d"));
|
||||
$age = $birthday->diff($currentDate);
|
||||
return $age->y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows home page
|
||||
* @return View
|
||||
*/
|
||||
public function show() : View {
|
||||
return view('home', [
|
||||
'age' => $this->returnAge()
|
||||
]);
|
||||
}
|
||||
}
|
69
app/Http/Controllers/MusicController.php
Normal file
69
app/Http/Controllers/MusicController.php
Normal file
|
@ -0,0 +1,69 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\Config;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class MusicController extends Controller
|
||||
{
|
||||
public function getCurrentTrack() {
|
||||
// If it's already cached just return that
|
||||
if (Cache::has('current_track')) {
|
||||
return Cache::get('current_track');
|
||||
}
|
||||
|
||||
$response = Http::withQueryParameters([
|
||||
'method' => 'user.getrecenttracks',
|
||||
'user' => Config::get('services.lastfm.user'),
|
||||
'format' => 'json',
|
||||
'nowplaying' => 'true',
|
||||
'api_key' => Config::get('services.lastfm.key')
|
||||
])->get('https://ws.audioscrobbler.com/2.0/');
|
||||
$data = $response->json();
|
||||
error_log($response->body());
|
||||
$track_data = $data["recenttracks"]["track"][0];
|
||||
$current_track = [
|
||||
'title' => $track_data["name"],
|
||||
'artist' => $track_data["artist"]["#text"],
|
||||
'url' => $track_data["url"],
|
||||
];
|
||||
Cache::put('current_track', $current_track, now()->addSeconds(15));
|
||||
return $current_track;
|
||||
}
|
||||
|
||||
public function getTopTracks() {
|
||||
// If it's already cached just return that
|
||||
if (Cache::has('top_tracks')) {
|
||||
return Cache::get('top_tracks');
|
||||
}
|
||||
|
||||
$response = Http::withQueryParameters([
|
||||
'method' => 'user.gettoptracks',
|
||||
'user' => Config::get('services.lastfm.user'),
|
||||
'format' => 'json',
|
||||
'period' => '1month',
|
||||
'limit' => 10,
|
||||
'api_key' => Config::get('services.lastfm.key')
|
||||
])->get('https://ws.audioscrobbler.com/2.0/');
|
||||
$data = $response->json();
|
||||
$topTracks = [];
|
||||
foreach ($data["toptracks"]["track"] as $track) {
|
||||
$topTracks[] = [
|
||||
'title' => $track["name"],
|
||||
'artist' => $track["artist"]["name"],
|
||||
'url' => $track["url"],
|
||||
'plays' => $track["playcount"],
|
||||
];
|
||||
}
|
||||
Cache::put('top_tracks', $topTracks, now()->addSeconds(15));
|
||||
return $topTracks;
|
||||
}
|
||||
public function show() : View {
|
||||
return view('music')
|
||||
->with('current_track', $this->getCurrentTrack())
|
||||
->with('top_tracks', $this->getTopTracks());
|
||||
}
|
||||
}
|
|
@ -16,6 +16,9 @@ class RateLimiter
|
|||
*/
|
||||
public function handle(Request $request, Closure $next): Response
|
||||
{
|
||||
if (auth()->check()) {
|
||||
return $next($request);
|
||||
}
|
||||
$ipAddress = $request->ip();
|
||||
$cacheKey = 'rate_limit_'.$ipAddress;
|
||||
|
||||
|
|
36
app/Models/BookmarkCategory.php
Normal file
36
app/Models/BookmarkCategory.php
Normal file
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class BookmarkCategory extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
protected $table = "bookmark__categories";
|
||||
protected $fillable = ['name'];
|
||||
|
||||
public function sites() {
|
||||
return $this->hasMany(BookmarkSite::class, 'category');
|
||||
}
|
||||
|
||||
public static function insertBookmarkCategory(string $name) {
|
||||
$newBookmarkCategory = new BookmarkCategory;
|
||||
$newBookmarkCategory->name = $name;
|
||||
$newBookmarkCategory->save();
|
||||
}
|
||||
public static function selectBookmarks(int $id) {
|
||||
$bookmarks = BookmarkSite::where('category', '=', $id)->firstOrFail();
|
||||
return $bookmarks;
|
||||
}
|
||||
|
||||
public static function importBookmarkCategory(array $data) {
|
||||
foreach ($data as $category) {
|
||||
$newBookmarkCategory = new BookmarkCategory;
|
||||
$newBookmarkCategory->name = $category['name'];
|
||||
$newBookmarkCategory->priority = intval($category['priority']);
|
||||
$newBookmarkCategory->save();
|
||||
}
|
||||
}
|
||||
}
|
35
app/Models/BookmarkSite.php
Normal file
35
app/Models/BookmarkSite.php
Normal file
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class BookmarkSite extends Model {
|
||||
use HasFactory;
|
||||
protected $table = "bookmark__sites";
|
||||
protected $fillable = ['name', 'description', 'url', 'category'];
|
||||
|
||||
public function category() {
|
||||
return $this->belongsTo(BookmarkCategory::class, 'category');
|
||||
}
|
||||
public static function insertBookmark(string $name, string $url, int $category) {
|
||||
$category = BookmarkCategory::where('id', $category)->firstOrFail();
|
||||
$newBookmark = new BookmarkSite;
|
||||
$newBookmark->name = $name;
|
||||
$newBookmark->url = $url;
|
||||
$newBookmark->category = $category->id;
|
||||
$newBookmark->save();
|
||||
}
|
||||
|
||||
public static function importBookmark(array $data) {
|
||||
foreach ($data as $site) {
|
||||
$newBookmark = new BookmarkSite;
|
||||
$newBookmark->name = $site['name'];
|
||||
$newBookmark->description = $site['description'];
|
||||
$newBookmark->url = $site['url'];
|
||||
$newBookmark->category = $site['category_id'];
|
||||
$newBookmark->save();
|
||||
}
|
||||
}
|
||||
}
|
50
app/Models/GuestbookEntry.php
Normal file
50
app/Models/GuestbookEntry.php
Normal file
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class GuestbookEntry extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
protected $table = "guestbook__entries";
|
||||
protected $fillable = ['name', 'message'];
|
||||
|
||||
/**
|
||||
* Creates a new guestbook entry.
|
||||
*
|
||||
* @param Request $request The HTTP POST request
|
||||
* @return void
|
||||
*/
|
||||
public static function insertGuestbookEntry(Request $request) {
|
||||
$newEntry = new GuestbookEntry;
|
||||
$newEntry->name = htmlspecialchars($request->get('name'));
|
||||
$newEntry->message = htmlspecialchars($request->get('message'));
|
||||
$newEntry->ip = $request->ip();
|
||||
$newEntry->agent = $request->userAgent();
|
||||
$newEntry->admin = auth()->check();
|
||||
$newEntry->save();
|
||||
}
|
||||
|
||||
public static function selectEntries() {
|
||||
$entries = GuestbookEntry::orderBy('created_at', 'desc')->get();
|
||||
return $entries;
|
||||
}
|
||||
|
||||
public static function importGuestbookEntry(array $data) {
|
||||
foreach ($data as $entry) {
|
||||
$dt = new \DateTime('@' . $entry['timestamp']);
|
||||
$newEntry = new GuestbookEntry;
|
||||
$newEntry->name = $entry['name'];
|
||||
$newEntry->ip = $entry['ip_address'];
|
||||
$newEntry->agent = $entry['agent'];
|
||||
$newEntry->admin = $entry['site_owner'];
|
||||
$newEntry->message = $entry['message'];
|
||||
$newEntry->created_at = $dt;
|
||||
$newEntry->updated_at = $dt;
|
||||
$newEntry->save();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
// use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
use Laravel\Sanctum\HasApiTokens;
|
||||
|
||||
class User extends Authenticatable
|
||||
{
|
||||
use HasApiTokens, HasFactory, Notifiable;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'email',
|
||||
'password',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be hidden for serialization.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $hidden = [
|
||||
'password',
|
||||
'remember_token',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast.
|
||||
*
|
||||
* @var array<string, string>
|
||||
*/
|
||||
protected $casts = [
|
||||
'email_verified_at' => 'datetime',
|
||||
'password' => 'hashed',
|
||||
];
|
||||
}
|
27
app/View/Components/CurrentTrack.php
Normal file
27
app/View/Components/CurrentTrack.php
Normal file
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
namespace App\View\Components;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\View\Component;
|
||||
|
||||
class CurrentTrack extends Component
|
||||
{
|
||||
public $track;
|
||||
/**
|
||||
* Create a new component instance.
|
||||
*/
|
||||
public function __construct($track)
|
||||
{
|
||||
$this->track = $track;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the view / contents that represent the component.
|
||||
*/
|
||||
public function render(): View|Closure|string
|
||||
{
|
||||
return view('components.current-track');
|
||||
}
|
||||
}
|
26
app/View/Components/Layout.php
Normal file
26
app/View/Components/Layout.php
Normal file
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
namespace App\View\Components;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\View\Component;
|
||||
|
||||
class Layout extends Component
|
||||
{
|
||||
/**
|
||||
* Create a new component instance.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the view / contents that represent the component.
|
||||
*/
|
||||
public function render(): View|Closure|string
|
||||
{
|
||||
return view('components.layout');
|
||||
}
|
||||
}
|
27
app/View/Components/Navbar.php
Normal file
27
app/View/Components/Navbar.php
Normal file
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
namespace App\View\Components;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\View\Component;
|
||||
|
||||
class Navbar extends Component
|
||||
{
|
||||
public $title;
|
||||
/**
|
||||
* Create a new component instance.
|
||||
*/
|
||||
public function __construct($title)
|
||||
{
|
||||
$this->title = $title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the view / contents that represent the component.
|
||||
*/
|
||||
public function render(): View|Closure|string
|
||||
{
|
||||
return view('components.navbar');
|
||||
}
|
||||
}
|
27
app/View/Components/TopTracks.php
Normal file
27
app/View/Components/TopTracks.php
Normal file
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
namespace App\View\Components;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\View\Component;
|
||||
|
||||
class TopTracks extends Component
|
||||
{
|
||||
public $tracks;
|
||||
/**
|
||||
* Create a new component instance.
|
||||
*/
|
||||
public function __construct($tracks)
|
||||
{
|
||||
$this->tracks = $tracks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the view / contents that represent the component.
|
||||
*/
|
||||
public function render(): View|Closure|string
|
||||
{
|
||||
return view('components.top-tracks');
|
||||
}
|
||||
}
|
29
app/View/Components/Track.php
Normal file
29
app/View/Components/Track.php
Normal file
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
namespace App\View\Components;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\View\Component;
|
||||
|
||||
class Track extends Component
|
||||
{
|
||||
public $track;
|
||||
public $count;
|
||||
/**
|
||||
* Create a new component instance.
|
||||
*/
|
||||
public function __construct($track, $count)
|
||||
{
|
||||
$this->track = $track;
|
||||
$this->count = $count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the view / contents that represent the component.
|
||||
*/
|
||||
public function render(): View|Closure|string
|
||||
{
|
||||
return view('components.track');
|
||||
}
|
||||
}
|
BIN
auth0
Executable file
BIN
auth0
Executable file
Binary file not shown.
|
@ -13,6 +13,7 @@
|
|||
"scrivo/highlight.php": "v9.18.1.10",
|
||||
"sentry/sentry-laravel": "^4.1",
|
||||
"spatie/laravel-honeypot": "^4.3",
|
||||
"spatie/laravel-html": "^3.4",
|
||||
"ua-parser/uap-php": "^3.9.14"
|
||||
},
|
||||
"require-dev": {
|
||||
|
|
757
composer.lock
generated
757
composer.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -37,6 +37,8 @@
|
|||
Configuration::CONFIG_CLIENT_ASSERTION_SIGNING_KEY => Configuration::get(Configuration::CONFIG_CLIENT_ASSERTION_SIGNING_KEY),
|
||||
Configuration::CONFIG_CLIENT_ASSERTION_SIGNING_ALGORITHM => Configuration::get(Configuration::CONFIG_CLIENT_ASSERTION_SIGNING_ALGORITHM),
|
||||
Configuration::CONFIG_PUSHED_AUTHORIZATION_REQUEST => Configuration::get(Configuration::CONFIG_PUSHED_AUTHORIZATION_REQUEST),
|
||||
Configuration::CONFIG_BACKCHANNEL_LOGOUT_CACHE => Configuration::get(Configuration::CONFIG_BACKCHANNEL_LOGOUT_CACHE),
|
||||
Configuration::CONFIG_BACKCHANNEL_LOGOUT_EXPIRES => Configuration::get(Configuration::CONFIG_BACKCHANNEL_LOGOUT_EXPIRES),
|
||||
],
|
||||
|
||||
'api' => [
|
||||
|
@ -53,4 +55,13 @@
|
|||
Configuration::CONFIG_TRANSIENT_STORAGE_ID => Configuration::get(Configuration::CONFIG_TRANSIENT_STORAGE_ID),
|
||||
],
|
||||
],
|
||||
|
||||
'routes' => [
|
||||
Configuration::CONFIG_ROUTE_INDEX => Configuration::get(Configuration::CONFIG_ROUTE_INDEX, '/'),
|
||||
Configuration::CONFIG_ROUTE_CALLBACK => Configuration::get(Configuration::CONFIG_ROUTE_CALLBACK, '/callback'),
|
||||
Configuration::CONFIG_ROUTE_LOGIN => Configuration::get(Configuration::CONFIG_ROUTE_LOGIN, '/login'),
|
||||
Configuration::CONFIG_ROUTE_AFTER_LOGIN => Configuration::get(Configuration::CONFIG_ROUTE_AFTER_LOGIN, '/'),
|
||||
Configuration::CONFIG_ROUTE_LOGOUT => Configuration::get(Configuration::CONFIG_ROUTE_LOGOUT, '/logout'),
|
||||
Configuration::CONFIG_ROUTE_AFTER_LOGOUT => Configuration::get(Configuration::CONFIG_ROUTE_AFTER_LOGOUT, '/'),
|
||||
],
|
||||
];
|
||||
|
|
|
@ -17,6 +17,5 @@
|
|||
'lastfm' => [
|
||||
'key' => env('LASTFM_KEY'),
|
||||
'user' => env('LASTFM_USER'),
|
||||
'toptracks' => env('LASTFM_TOP_TRACKS')
|
||||
]
|
||||
];
|
||||
|
|
23
database/factories/BookmarkCategoryFactory.php
Normal file
23
database/factories/BookmarkCategoryFactory.php
Normal file
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
namespace Database\Factories;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
|
||||
/**
|
||||
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\BookmarkCategory>
|
||||
*/
|
||||
class BookmarkCategoryFactory extends Factory
|
||||
{
|
||||
/**
|
||||
* Define the model's default state.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function definition(): array
|
||||
{
|
||||
return [
|
||||
'name' => $this->faker->word,
|
||||
];
|
||||
}
|
||||
}
|
27
database/factories/BookmarkSiteFactory.php
Normal file
27
database/factories/BookmarkSiteFactory.php
Normal file
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
namespace Database\Factories;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
use App\Models\BookmarkCategory;
|
||||
|
||||
/**
|
||||
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\BookmarkSite>
|
||||
*/
|
||||
class BookmarkSiteFactory extends Factory
|
||||
{
|
||||
/**
|
||||
* Define the model's default state.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function definition(): array
|
||||
{
|
||||
return [
|
||||
'name' => $this->faker->name,
|
||||
'description' => $this->faker->sentence,
|
||||
'url' => $this->faker->url,
|
||||
'category' => BookmarkCategory::factory(),
|
||||
];
|
||||
}
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('guestbook__bans', function (Blueprint $table) {
|
||||
$table->increments('id');
|
||||
$table->string('ip_address', 40);
|
||||
$table->string('reason', 50);
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('guestbook__bans');
|
||||
}
|
||||
};
|
|
@ -1,34 +0,0 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
// Check if table exists and is empty
|
||||
if (Schema::hasTable('bookmark__categories') && DB::table('bookmark__categories')->count() == 0) {
|
||||
// Insert placeholder categories
|
||||
DB::table('bookmark__categories')->insert([
|
||||
['name' => 'Friends\' Websites', 'priority' => 1],
|
||||
['name' => 'Cool Projects', 'priority' => 2],
|
||||
['name' => 'Other Cool Sites', 'priority' => 3],
|
||||
['name' => 'Miscellaneous Resources', 'priority' => 4]
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
//
|
||||
}
|
||||
};
|
|
@ -12,9 +12,9 @@
|
|||
public function up(): void
|
||||
{
|
||||
Schema::create('bookmark__categories', function (Blueprint $table) {
|
||||
$table->increments('id');
|
||||
$table->id();
|
||||
$table->string('name');
|
||||
$table->float('priority');
|
||||
$table->unsignedBigInteger('priority')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
|
@ -12,13 +12,15 @@
|
|||
public function up(): void
|
||||
{
|
||||
Schema::create('bookmark__sites', function (Blueprint $table) {
|
||||
$table->increments('id');
|
||||
$table->string('name', 50);
|
||||
$table->string('description', 150);
|
||||
$table->string('url', 100);
|
||||
$table->float('priority');
|
||||
$table->integer('category_id')->unsigned();
|
||||
$table->foreign('category_id')->references('id')->on('bookmark__categories');
|
||||
$table->id();
|
||||
$table->string('name');
|
||||
$table->text('description')->nullable();
|
||||
$table->string('url');
|
||||
$table->unsignedBigInteger('category');
|
||||
$table->foreign('category')
|
||||
->references('id')
|
||||
->on('bookmark__categories')
|
||||
->onDelete('cascade');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
@ -28,6 +30,6 @@ public function up(): void
|
|||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('bookmark__sites');
|
||||
Schema::dropIfExists('bookmarks');
|
||||
}
|
||||
};
|
|
@ -12,13 +12,12 @@
|
|||
public function up(): void
|
||||
{
|
||||
Schema::create('guestbook__entries', function (Blueprint $table) {
|
||||
$table->increments('id');
|
||||
$table->string('name', 255);
|
||||
$table->bigInteger('timestamp');
|
||||
$table->string('ip_address', 40);
|
||||
$table->string('agent', 2048)->default('Agent unavailable');
|
||||
$table->boolean('site_owner')->default(0);
|
||||
$table->string('message', 512);
|
||||
$table->id();
|
||||
$table->string('name');
|
||||
$table->string('ip');
|
||||
$table->string('agent');
|
||||
$table->longText('message');
|
||||
$table->boolean('admin');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
30
database/seeders/BookmarkCategoriesTableSeeder.php
Normal file
30
database/seeders/BookmarkCategoriesTableSeeder.php
Normal file
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use App\Models\BookmarkCategory;
|
||||
use App\Models\BookmarkSite;
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
class BookmarkCategoriesTableSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*/
|
||||
public function run(): void {
|
||||
// BookmarkCategory::factory()->count(5)->create()->each(function ($category) {
|
||||
// $category->sites()->saveMany(BookmarkSite::factory()->count(3)->make());
|
||||
// });
|
||||
$category = new BookmarkCategory([
|
||||
'name' => 'cool people',
|
||||
]);
|
||||
$category->save();
|
||||
$site = new BookmarkSite([
|
||||
'name' => 'campos',
|
||||
'description' => 'Cool brazilian dude, does programming and stuff',
|
||||
'url' => 'https://campos02.me/',
|
||||
'category' => 1,
|
||||
]);
|
||||
$site->save();
|
||||
}
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
// use Illuminate\Database\Console\Seeds\WithoutModelEvents;
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
class DatabaseSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Seed the application's database.
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
// \App\Models\User::factory(10)->create();
|
||||
|
||||
// \App\Models\User::factory()->create([
|
||||
// 'name' => 'Test User',
|
||||
// 'email' => 'test@example.com',
|
||||
// ]);
|
||||
}
|
||||
}
|
|
@ -111,6 +111,10 @@ .nav-wrapper {
|
|||
grid-row-gap: 0;
|
||||
}
|
||||
|
||||
.nav-wrapper div:nth-child(2) {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.theme-selector label {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
@ -226,7 +230,7 @@ table.computers td ul {
|
|||
padding-left: 20px;
|
||||
}
|
||||
|
||||
table.computers section-title {
|
||||
table.computers .section-title {
|
||||
text-decoration: underline;
|
||||
font-style: italic;
|
||||
font-weight: bold;
|
||||
|
@ -272,34 +276,46 @@ a {
|
|||
text-decoration: underline dotted;
|
||||
}
|
||||
|
||||
table.gb-entry-form tr td {
|
||||
table.form tr td {
|
||||
border: none;
|
||||
}
|
||||
|
||||
table.gb-entry-form tr td label {
|
||||
table.form tr td label {
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
table.gb-entry-form tr td span.text-danger {
|
||||
table.form tr td span.text-danger {
|
||||
padding-left: 5px;
|
||||
color: var(--warning);
|
||||
}
|
||||
|
||||
table.gb-entry-form tr td textarea,
|
||||
table.gb-entry-form tr td input,
|
||||
table.gb-entry-form tr td button{
|
||||
margin-bottom: 5px;
|
||||
margin-left: 10px;
|
||||
input.file {
|
||||
border: 0 !important;
|
||||
}
|
||||
|
||||
table.form tr td textarea,
|
||||
table.form tr td input,
|
||||
table.form tr td button,
|
||||
form.import input::file-selector-button,
|
||||
form.import button {
|
||||
background-color: var(--background);
|
||||
border: var(--foreground) solid 1px;
|
||||
}
|
||||
|
||||
table.gb-entry-form tr td button {
|
||||
table.form label {
|
||||
margin: 5px 0;
|
||||
}
|
||||
|
||||
form.import button,
|
||||
form.import input::file-selector-button,
|
||||
table.form tr td button {
|
||||
color: var(--foreground);
|
||||
background-color: var(--background-secondary);
|
||||
}
|
||||
|
||||
table.gb-entry-form tr td button:hover {
|
||||
form.import button:hover,
|
||||
form.import input::file-selector-button:hover,
|
||||
table.form tr td button:hover {
|
||||
color: var(--background);
|
||||
background-color: var(--foreground);
|
||||
}
|
||||
|
@ -318,7 +334,7 @@ table.gb-entry-form-container tr td ul {
|
|||
margin: 0;
|
||||
}
|
||||
|
||||
table.gb-entry-form tbody tr td textarea {
|
||||
table.form tbody tr td textarea {
|
||||
width: 210px;
|
||||
}
|
||||
|
||||
|
@ -490,20 +506,151 @@ #scheme-selector {
|
|||
}
|
||||
|
||||
|
||||
.music-top10 td {
|
||||
.music-top10 td,
|
||||
.music-top10 th {
|
||||
border: none;
|
||||
border-left: 1px dotted var(--foreground);
|
||||
padding: 2px 5px
|
||||
}
|
||||
|
||||
.music-top10 tr:nth-child(2) td {
|
||||
.music-top10 tr:nth-child(1) th {
|
||||
border-bottom: 1px dotted var(--foreground);
|
||||
}
|
||||
|
||||
.music-top10 tr:nth-child(3) td {
|
||||
.music-top10 tr:nth-child(2) td {
|
||||
padding-top: 5px;
|
||||
}
|
||||
|
||||
.music-top10 td:first-child {
|
||||
.music-top10 td:first-child,
|
||||
.music-top10 th:first-child {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.music-top10 tr th:first-child {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.music-top10 td {
|
||||
white-space: nowrap; text-overflow:ellipsis; overflow: hidden;
|
||||
}
|
||||
|
||||
.music-top10 tr td:first-child {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.music-top10 tr td:nth-child(2),
|
||||
.music-top10 tr td:nth-child(3) {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.current-track {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.current-track h2 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.info-section ul {
|
||||
list-style-position: inside;
|
||||
list-style-type: none;
|
||||
padding-left: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.info-section ul li:before {
|
||||
content: "◆ ";
|
||||
}
|
||||
|
||||
.info-section h2 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.info-section p {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.contact-section {
|
||||
display: grid;
|
||||
grid-template-rows: 1fr 1fr;
|
||||
}
|
||||
|
||||
.banner {
|
||||
padding: 5px;
|
||||
margin-top: 10px;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
grid-template-rows: 1fr;
|
||||
grid-column-gap: 0;
|
||||
grid-row-gap: 0;
|
||||
}
|
||||
|
||||
.banner div:nth-child(1) {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.banner div:nth-child(2) {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.red-banner {
|
||||
border: 3px solid var(--foreground);
|
||||
background-color: var(--background-secondary);
|
||||
}
|
||||
|
||||
.info-admin td,
|
||||
.info-admin th {
|
||||
border: 1px solid var(--foreground);
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.info-admin th {
|
||||
background-color: var(--background-secondary);
|
||||
}
|
||||
|
||||
.info-admin th.blank {
|
||||
border: none;
|
||||
background-color: var(--background);
|
||||
}
|
||||
|
||||
.info-admin button {
|
||||
border: 1px solid var(--foreground);
|
||||
background-color: var(--background);
|
||||
color: var(--foreground);
|
||||
}
|
||||
|
||||
.info-admin button:hover {
|
||||
background-color: var(--foreground);
|
||||
color: var(--background);
|
||||
}
|
||||
|
||||
.info-admin button:active {
|
||||
background-color: var(--background-secondary);
|
||||
color: var(--foreground);
|
||||
}
|
||||
|
||||
.info-admin-section h2 {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.fullwidth {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.fullwidth td:last-child {
|
||||
width: 0;
|
||||
}
|
||||
|
||||
.guestbook-message {
|
||||
text-wrap: wrap;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
td.diagonal-line {
|
||||
background: linear-gradient(to right bottom, var(--background) 0%,var(--background) 49.9%,var(--foreground) 50%,var(--foreground) 51%,var(--background) 51.1%,var(--background) 100%);
|
||||
}
|
||||
|
||||
form.import h2 {
|
||||
margin: 10px 0 5px 0;
|
||||
}
|
||||
|
||||
|
|
BIN
public/images/icons/home2/user-desktop.png
Normal file
BIN
public/images/icons/home2/user-desktop.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 780 B |
BIN
public/images/icons/nav/admin.png
Normal file
BIN
public/images/icons/nav/admin.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 705 B |
BIN
public/images/icons/nav/home2.png
Normal file
BIN
public/images/icons/nav/home2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
|
@ -1,31 +1,31 @@
|
|||
// Define an array of strings
|
||||
const neverSaid = [
|
||||
"<td style=\"width: 105px\"><strong>ASM:</strong></td> <td>The Director liked all the props we got today.</td>",
|
||||
"<td style=\"width: 105px\"><strong>PM:</strong></td> <td>Ah ha, a revolve. Terrific.</td>",
|
||||
"<td style=\"width: 105px\"><strong>Chippie:</strong></td> <td>I don't know, let's look at the ground plan.</td>",
|
||||
"<td style=\"width: 105px\"><strong>Set Designer:</strong></td> <td>Well, let's just have whatever is cheaper.</td>",
|
||||
"<td style=\"width: 105px\"><strong>Sound:</strong></td> <td>Better turn that down a bit. We don't want to deafen them.</td>",
|
||||
"<td style=\"width: 105px\"><strong>Director:</strong></td> <td>Sorry, my mistake.</td>",
|
||||
"<td style=\"width: 105px\"><strong>Electrics:</strong></td> <td>This equipment is more complicated than we need.</td>",
|
||||
"<td style=\"width: 105px\"><strong>Performer:</strong></td> <td>I really think my big scene should be cut.</td>",
|
||||
"<td style=\"width: 105px\"><strong>SM:</strong></td> <td>Can we doo that scene change again please?",
|
||||
"<td style=\"width: 105px\"><strong>LX designer:</strong></td> <td>Bit more light from those big chaps at the side. Yes that's right, the ones on stalks whatever they are called.</td>",
|
||||
"<td style=\"width: 105px\"><strong>Electrics:</strong></td> <td>All the equipment works perfectly.</td>",
|
||||
"<td style=\"width: 105px\"><strong>Musicians:</strong></td> <td>So what if that's the end of a call. Let's just finish this bit off.</td>",
|
||||
"<td style=\"width: 105px\"><strong>Wardrobe:</strong></td> <td>Now, when exactly is the first dress rehearsal?",
|
||||
"<td style=\"width: 105px\"><strong>Workshop:</strong></td> <td>I don't want anyone to know, but if you insist then yes, I admit it, I have just done an all-nighter.</td>",
|
||||
"<td style=\"width: 105px\"><strong>Performer:</strong></td> <td>This costume is so comfortable.</td>",
|
||||
"<td style=\"width: 105px\"><strong>Admin:</strong></td> <td>The level of overtime payments here are simply unacceptable. Our backstage staff deserve better.</td>",
|
||||
"<td style=\"width: 105px\"><strong>Box Office:</strong></td> <td>Comps? No problem.</td>",
|
||||
"<td style=\"width: 105px\"><strong>Set Designer:</strong></td> <td>You're right, it looks dreadful.</td>",
|
||||
"<td style=\"width: 105px\"><strong>Flyman:</strong></td> <td>No, my lips are sealed. What I may or may not have seen remains a secret.</td>",
|
||||
"<td style=\"width: 105px\"><strong>Electrics:</strong></td> <td>That had nothing to do with the computer, it was my fault.</td>",
|
||||
"<td style=\"width: 105px\"><strong>Crew:</strong></td> <td>No, no, I'm sure that's our job.</td>",
|
||||
"<td style=\"width: 105px\"><strong>SMgt:</strong></td> <td>Thanks, but I don't drink",
|
||||
"<td style=\"width: 105px\"><strong>Performer:</strong></td> <td>Let me stand down here with my back to the audience.</td>",
|
||||
"<td style=\"width: 105px\"><strong>Chippie:</strong></td> <td>I can't really manage those big fast power tools myself.</td>",
|
||||
"<td style=\"width: 105px\"><strong>Chippie:</strong></td> <td>I prefer to use these little hand drills.</td>",
|
||||
"<td style=\"width: 105px\"><strong>All:</strong></td> <td>Let's go and ask the Production Manager. He'll know.</td>"
|
||||
"<strong>ASM:</strong> The Director liked all the props we got today.",
|
||||
"<strong>PM:</strong> Ah ha, a revolve. Terrific.",
|
||||
"<strong>Chippie:</strong> I don't know, let's look at the ground plan.",
|
||||
"<strong>Set Designer:</strong> Well, let's just have whatever is cheaper.",
|
||||
"<strong>Sound:</strong> Better turn that down a bit. We don't want to deafen them.",
|
||||
"<strong>Director:</strong> Sorry, my mistake.",
|
||||
"<strong>Electrics:</strong> This equipment is more complicated than we need.",
|
||||
"<strong>Performer:</strong> I really think my big scene should be cut.",
|
||||
"<strong>SM:</strong> Can we do that scene change again please?",
|
||||
"<strong>LX designer:</strong> Bit more light from those big chaps at the side. Yes that's right, the ones on stalks whatever they are called.",
|
||||
"<strong>Electrics:</strong> All the equipment works perfectly.",
|
||||
"<strong>Musicians:</strong> So what if that's the end of a call. Let's just finish this bit off.",
|
||||
"<strong>Wardrobe:</strong> Now, when exactly is the first dress rehearsal?",
|
||||
"<strong>Workshop:</strong> I don't want anyone to know, but if you insist then yes, I admit it, I have just done an all-nighter.",
|
||||
"<strong>Performer:</strong> This costume is so comfortable.",
|
||||
"<strong>Admin:</strong> The level of overtime payments here are simply unacceptable. Our backstage staff deserve better.",
|
||||
"<strong>Box Office:</strong> Comps? No problem.",
|
||||
"<strong>Set Designer:</strong> You're right, it looks dreadful.",
|
||||
"<strong>Flyman:</strong> No, my lips are sealed. What I may or may not have seen remains a secret.",
|
||||
"<strong>Electrics:</strong> That had nothing to do with the computer, it was my fault.",
|
||||
"<strong>Crew:</strong> No, no, I'm sure that's our job.",
|
||||
"<strong>SMgt:</strong> Thanks, but I don't drink",
|
||||
"<strong>Performer:</strong> Let me stand down here with my back to the audience.",
|
||||
"<strong>Chippie:</strong> I can't really manage those big fast power tools myself.",
|
||||
"<strong>Chippie:</strong> I prefer to use these little hand drills.",
|
||||
"<strong>All:</strong> Let's go and ask the Production Manager. He'll know."
|
||||
]
|
||||
|
||||
// Generate a random index into the array
|
||||
|
|
|
@ -3,3 +3,19 @@ Disallow: /admin
|
|||
Disallow: /login
|
||||
Disallow: /js
|
||||
Disallow: /css
|
||||
|
||||
User-Agent: GPTBot
|
||||
Disallow: /
|
||||
|
||||
User-Agent: ChatGPT-User
|
||||
Disallow: /
|
||||
|
||||
User-Agent: Google-Extended
|
||||
Disallow: /
|
||||
|
||||
User-Agent: CCBot
|
||||
Disallow: /
|
||||
|
||||
User-Agent: PerplexityBot
|
||||
Disallow: /
|
||||
|
||||
|
|
35
resources/js/neverSaid.js
Normal file
35
resources/js/neverSaid.js
Normal file
|
@ -0,0 +1,35 @@
|
|||
// Define an array of strings
|
||||
const neverSaid = [
|
||||
"<td style=\"width: 105px\"><strong>ASM:</strong></td> <td>The Director liked all the props we got today.</td>",
|
||||
"<td style=\"width: 105px\"><strong>PM:</strong></td> <td>Ah ha, a revolve. Terrific.</td>",
|
||||
"<td style=\"width: 105px\"><strong>Chippie:</strong></td> <td>I don't know, let's look at the ground plan.</td>",
|
||||
"<td style=\"width: 105px\"><strong>Set Designer:</strong></td> <td>Well, let's just have whatever is cheaper.</td>",
|
||||
"<td style=\"width: 105px\"><strong>Sound:</strong></td> <td>Better turn that down a bit. We don't want to deafen them.</td>",
|
||||
"<td style=\"width: 105px\"><strong>Director:</strong></td> <td>Sorry, my mistake.</td>",
|
||||
"<td style=\"width: 105px\"><strong>Electrics:</strong></td> <td>This equipment is more complicated than we need.</td>",
|
||||
"<td style=\"width: 105px\"><strong>Performer:</strong></td> <td>I really think my big scene should be cut.</td>",
|
||||
"<td style=\"width: 105px\"><strong>SM:</strong></td> <td>Can we doo that scene change again please?",
|
||||
"<td style=\"width: 105px\"><strong>LX designer:</strong></td> <td>Bit more light from those big chaps at the side. Yes that's right, the ones on stalks whatever they are called.</td>",
|
||||
"<td style=\"width: 105px\"><strong>Electrics:</strong></td> <td>All the equipment works perfectly.</td>",
|
||||
"<td style=\"width: 105px\"><strong>Musicians:</strong></td> <td>So what if that's the end of a call. Let's just finish this bit off.</td>",
|
||||
"<td style=\"width: 105px\"><strong>Wardrobe:</strong></td> <td>Now, when exactly is the first dress rehearsal?",
|
||||
"<td style=\"width: 105px\"><strong>Workshop:</strong></td> <td>I don't want anyone to know, but if you insist then yes, I admit it, I have just done an all-nighter.</td>",
|
||||
"<td style=\"width: 105px\"><strong>Performer:</strong></td> <td>This costume is so comfortable.</td>",
|
||||
"<td style=\"width: 105px\"><strong>Admin:</strong></td> <td>The level of overtime payments here are simply unacceptable. Our backstage staff deserve better.</td>",
|
||||
"<td style=\"width: 105px\"><strong>Box Office:</strong></td> <td>Comps? No problem.</td>",
|
||||
"<td style=\"width: 105px\"><strong>Set Designer:</strong></td> <td>You're right, it looks dreadful.</td>",
|
||||
"<td style=\"width: 105px\"><strong>Flyman:</strong></td> <td>No, my lips are sealed. What I may or may not have seen remains a secret.</td>",
|
||||
"<td style=\"width: 105px\"><strong>Electrics:</strong></td> <td>That had nothing to do with the computer, it was my fault.</td>",
|
||||
"<td style=\"width: 105px\"><strong>Crew:</strong></td> <td>No, no, I'm sure that's our job.</td>",
|
||||
"<td style=\"width: 105px\"><strong>SMgt:</strong></td> <td>Thanks, but I don't drink",
|
||||
"<td style=\"width: 105px\"><strong>Performer:</strong></td> <td>Let me stand down here with my back to the audience.</td>",
|
||||
"<td style=\"width: 105px\"><strong>Chippie:</strong></td> <td>I can't really manage those big fast power tools myself.</td>",
|
||||
"<td style=\"width: 105px\"><strong>Chippie:</strong></td> <td>I prefer to use these little hand drills.</td>",
|
||||
"<td style=\"width: 105px\"><strong>All:</strong></td> <td>Let's go and ask the Production Manager. He'll know.</td>"
|
||||
]
|
||||
|
||||
// Generate a random index into the array
|
||||
const randomIndex = Math.floor(Math.random() * neverSaid.length);
|
||||
|
||||
// Use document.write to output the random string
|
||||
document.write(neverSaid[randomIndex]);
|
70
resources/js/schemeSwap.js
Normal file
70
resources/js/schemeSwap.js
Normal file
|
@ -0,0 +1,70 @@
|
|||
/**
|
||||
* Retrieves a cookies value
|
||||
* @param {string} cname Cookie name
|
||||
* @returns {string} Cookie value
|
||||
*/
|
||||
function getCookie(cname) {
|
||||
let name = cname + "=";
|
||||
let decodedCookie = decodeURIComponent(document.cookie);
|
||||
let ca = decodedCookie.split(';');
|
||||
for(let i = 0; i <ca.length; i++) {
|
||||
let c = ca[i];
|
||||
while (c.charAt(0) === ' ') {
|
||||
c = c.substring(1);
|
||||