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);
|
||||
}
|
||||
if (c.indexOf(name) === 0) {
|
||||
return c.substring(name.length, c.length);
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets/creates a cookie
|
||||
* @param {string} cname Cookie name
|
||||
* @param {string} cvalue Cookie value
|
||||
* @param {number} exdays Cookie lifespan (days)
|
||||
*/
|
||||
function setCookie(cname, cvalue, exdays) {
|
||||
const d = new Date();
|
||||
d.setTime(d.getTime() + (exdays*24*60*60*1000));
|
||||
let expires = "expires="+ d.toUTCString();
|
||||
document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/;SameSite=Strict;Domain=.diskfloppy.me";
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a cookie exists
|
||||
* @param {string} cname Cookie name
|
||||
* @returns {boolean} If cookie exists or not
|
||||
*/
|
||||
function cookieExists(cname) {
|
||||
const cvalue = getCookie(cname);
|
||||
return cvalue !== "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Swaps the colorscheme
|
||||
* @param {string} scheme Color scheme ID
|
||||
*/
|
||||
function swapScheme(scheme) {
|
||||
setCookie("colorscheme", scheme, 90);
|
||||
document.getElementById("css-colorscheme").href = `/css/colorschemes/${scheme}.css`;
|
||||
console.log(`Set colorscheme to ${getCookie("colorscheme")}`)
|
||||
}
|
||||
|
||||
function setSchemeSelector() {
|
||||
if (!cookieExists("colorscheme")) {
|
||||
setCookie("colorscheme", "catppuccin-macchiato", 90);
|
||||
} else {
|
||||
const scheme = getCookie("colorscheme");
|
||||
const scheme_selector = document.getElementById("scheme-selector");
|
||||
if (scheme && scheme_selector) {
|
||||
for (let option of scheme_selector.options) {
|
||||
if (option.value === scheme) {
|
||||
option.selected = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
28
resources/views/admin/bookmarks.blade.php
Normal file
28
resources/views/admin/bookmarks.blade.php
Normal file
|
@ -0,0 +1,28 @@
|
|||
<x-layout>
|
||||
<x-slot:title>Admin | Bookmarks</x-slot:title>
|
||||
@foreach($categories as $category)
|
||||
<div class="info-section info-admin-section">
|
||||
<h2>{{ $category->name }}</h2>
|
||||
<table class="info-admin">
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Name</th>
|
||||
<th>Description</th>
|
||||
<th>URL</th>
|
||||
<th>Priority</th>
|
||||
<th class="blank"></th>
|
||||
</tr>
|
||||
@foreach($category->sites as $site)
|
||||
<tr>
|
||||
<td>{{ $site->id }}</td>
|
||||
<td>{{ $site->name }}</td>
|
||||
<td>{{ $site->description }}</td>
|
||||
<td>{{ $site->url }}</td>
|
||||
<td>{{ $site->priority }}</td>
|
||||
<td><a href="?action=delete&id={{ $site->id }}"><button>Delete</button></a></td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</table>
|
||||
</div>
|
||||
@endforeach
|
||||
</x-layout>
|
32
resources/views/admin/guestbook.blade.php
Normal file
32
resources/views/admin/guestbook.blade.php
Normal file
|
@ -0,0 +1,32 @@
|
|||
<x-layout>
|
||||
<x-slot:title>Admin | Guestbook</x-slot:title>
|
||||
<div class="info-section">
|
||||
<h2>Statistics</h2>
|
||||
<hr>
|
||||
<strong>Unique IP addresses:</strong> {{ $guestbook_unique_addr }}<br>
|
||||
<strong>Entries:</strong> {{ $guestbook_entry_count }}
|
||||
</div>
|
||||
<br>
|
||||
<div class="info-section">
|
||||
<h2>Entries</h2>
|
||||
<hr>
|
||||
<table class="info-admin fullwidth">
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Name</th>
|
||||
<th>IP Address</th>
|
||||
<th>Message</th>
|
||||
<th class="blank"></th>
|
||||
</tr>
|
||||
@foreach ($entries as $entry)
|
||||
<tr>
|
||||
<td>{{ $entry->id }}</td>
|
||||
<td>{{ $entry->name }}</td>
|
||||
<td>{{ $entry->ip }}</td>
|
||||
<td>{{ $entry->message }}</td>
|
||||
<td><a href="?action=delete&id={{ $entry->id }}"><button>Delete</button></a></td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</table>
|
||||
</div>
|
||||
</x-layout>
|
12
resources/views/admin/import-success.blade.php
Normal file
12
resources/views/admin/import-success.blade.php
Normal file
|
@ -0,0 +1,12 @@
|
|||
<x-layout>
|
||||
<x-slot:title>Admin | Import</x-slot:title>
|
||||
<div class="info-section">
|
||||
<h2>Imported data</h2>
|
||||
<hr>
|
||||
<ul>
|
||||
@foreach($tables as $name => $data)
|
||||
<li><strong>{{ ucwords(str_replace('__', ' ', $name)) }}:</strong> {{ $data['count'] }} record(s)</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
</x-layout>
|
18
resources/views/admin/import.blade.php
Normal file
18
resources/views/admin/import.blade.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<x-layout>
|
||||
<x-slot:title>Admin | Import</x-slot:title>
|
||||
<form class="import" action="{{ route('admin.import.submit') }}" method="post" enctype="multipart/form-data">
|
||||
@csrf
|
||||
<label for="data_file"><strong>File:</strong></label>
|
||||
<input class="file" type="file" name="data_file" accept=".json"><br>
|
||||
<h2>What to import:</h2>
|
||||
<input type="checkbox" name="guestbook__entries" checked>
|
||||
<label for="guestbook__entries">Guestbook Entries</label><br>
|
||||
<input type="checkbox" name="guestbook__bans" checked>
|
||||
<label for="guestbook__bans">Guestbook Bans</label><br>
|
||||
<input type="checkbox" name="guestbook__entries" checked>
|
||||
<label for="bookmark__categories">Bookmark Categories</label><br>
|
||||
<input type="checkbox" name="guestbook__entries" checked>
|
||||
<label for="bookmark_sites">Bookmark Sites</label><br>
|
||||
<button type="submit">Import</button>
|
||||
</form>
|
||||
</x-layout>
|
18
resources/views/bookmarks.blade.php
Normal file
18
resources/views/bookmarks.blade.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<x-layout>
|
||||
<x-slot:title>Bookmarks</x-slot:title>
|
||||
@foreach($categories as $category)
|
||||
<table class="info-table" role="presentation">
|
||||
<caption>
|
||||
<h2>{{ $category->name }}</h2>
|
||||
<hr>
|
||||
</caption>
|
||||
<tbody>
|
||||
@foreach($category->sites as $site)
|
||||
<tr>
|
||||
<td><a href="{{ $site->url }}">{{ $site->name }}</a> - {{ $site->description }}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
@endforeach
|
||||
</x-layout>
|
4
resources/views/components/current-track.blade.php
Normal file
4
resources/views/components/current-track.blade.php
Normal file
|
@ -0,0 +1,4 @@
|
|||
<div class="info-table current-track">
|
||||
<h2>Last/Current Track:</h2>
|
||||
<a href="{{ $track["url"] }}">{{ $track["title"] }} • {{ $track["artist"] }}</a><br>
|
||||
</div>
|
113
resources/views/components/layout.blade.php
Normal file
113
resources/views/components/layout.blade.php
Normal file
|
@ -0,0 +1,113 @@
|
|||
@php // Get colorscheme from cookie and apply immediately
|
||||
$colorscheme = request()->cookie('colorscheme', 'catppuccin-macchiato');
|
||||
@endphp
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<!-- Global -->
|
||||
<meta charset="utf-8">
|
||||
<meta property="og:type" content="website">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="theme-color" content="#333333">
|
||||
<link rel="stylesheet" href="{{ asset("/css/colorschemes/$colorscheme.css") }}" id="css-colorscheme"/>
|
||||
<link rel="stylesheet" href="{{ asset('/css/master.css') }}"/>
|
||||
<link rel="icon" type="image/png" href="{{ asset('/favicon-32x32.png') }}" sizes="32x32"/>
|
||||
<link rel="icon" type="image/png" href="{{ asset('/favicon-16x16.png') }}" sizes="16x16"/>
|
||||
<script src="{{ asset('/js/schemeSwap.js') }}"></script>
|
||||
{!! (intval(date('n')) == 12) ? '<script src="/js/christmas/snow.js"></script>' : '' !!}
|
||||
|
||||
<!-- Page-specific -->
|
||||
<title>{{ $title ?? 'Unknown' }} - diskfloppy.me</title>
|
||||
<meta property="og:title" content="diskfloppy.me | {{ $title }}">
|
||||
<meta property="og:image" content="/favicon-128x128.png">
|
||||
</head>
|
||||
<body onload="setSchemeSelector()">
|
||||
<div class="page">
|
||||
<div id="header" class="header">
|
||||
@if (auth()->check())
|
||||
<div class="banner red-banner">
|
||||
<div>
|
||||
<a href="/admin/guestbook">Guestbook</a> |
|
||||
<a href="/admin/bookmarks">Bookmarks</a> |
|
||||
<a href="/admin/import">Import</a>
|
||||
</div>
|
||||
<div><strong>Logged in as:</strong> {{ auth()->user()->name }} (<a href="/logout">logout</a>)</div>
|
||||
</div>
|
||||
@endif
|
||||
<x-navbar title="{{ $title }}"/>
|
||||
<hr>
|
||||
</div> <!-- header -->
|
||||
<div id="content" class="content" role="main">
|
||||
{{ $slot }}
|
||||
</div> <!-- content -->
|
||||
<div id="footer" class="footer">
|
||||
<hr>
|
||||
<div class="footer" role="contentinfo">
|
||||
<a href="https://dimden.dev/" class="button">
|
||||
<img src="https://dimden.dev/services/images/88x31.gif" width="88" height="31"
|
||||
class="pixel" alt="dimden.dev">
|
||||
</a>
|
||||
<a href="https://www.linux.org/" class="button">
|
||||
<img src="{{ URL::asset('images/buttons/linuxnow.gif') }}" width="88"
|
||||
class="pixel" height="31" alt="Linux NOW!">
|
||||
</a>
|
||||
<a href="https://www.vim.org/" class="button">
|
||||
<img src="{{ URL::asset('images/buttons/vim.gif') }}" width="88" height="31"
|
||||
class="pixel" alt="vim">
|
||||
</a>
|
||||
<a href="https://wave.webaim.org/" class="button">
|
||||
<img src="{{ URL::asset('images/buttons/evaluatedWAVE.png') }}" width="88" height="31"
|
||||
class="pixel" alt="Evaluated to be accessible!">
|
||||
</a>
|
||||
<a href="https://jigsaw.w3.org/css-validator/check/referer" class="button">
|
||||
<img src="{{ URL::asset('images/buttons/vcss-blue.gif') }}" width="88" height="31"
|
||||
class="pixel" alt="Valid CSS!">
|
||||
</a>
|
||||
<a href="https://wiby.me/" class="button">
|
||||
<img src="{{ URL::asset('images/buttons/wiby.gif') }}" width="88" height="31"
|
||||
class="pixel" alt="Wiby - Search Engine for the Classic Web">
|
||||
</a><br>
|
||||
This site is best viewed at 1024x768 with 16-bit color or better<br>
|
||||
© floppydisk 2021-{{ date('Y') }}, v{{ config('app.version') }} <a
|
||||
href="https://github.com/floppydisk05/diskfloppy.me">Source</a>,
|
||||
Served by {{ gethostname() }}<br>
|
||||
<label for="scheme-selector">Color Scheme:</label>
|
||||
<select onchange="swapScheme(this.value)" id="scheme-selector">
|
||||
<optgroup label="Misc">
|
||||
<option value="c64">C64</option>
|
||||
</optgroup>
|
||||
<optgroup label="Light">
|
||||
<option value="catppuccin-latte">Catppuccin Latte</option>
|
||||
<option value="gruvbox">Gruvbox</option>
|
||||
<option value="man-page">Man Page</option>
|
||||
<option value="papercolor-light">Papercolor Light</option>
|
||||
<option value="rose-pine-dawn">Rosé Pine Dawn</option>
|
||||
<option value="solarized-light">Solarized Light</option>
|
||||
<option value="terminal-basic">Terminal Basic</option>
|
||||
</optgroup>
|
||||
<optgroup label="Dark">
|
||||
<option value="catppuccin-frappe">Catppuccin Frappé</option>
|
||||
<option value="catppuccin-macchiato" selected="selected">Catppuccin Macchiato</option>
|
||||
<option value="catppuccin-mocha">Catppuccin Mocha</option>
|
||||
<option value="gruvbox-dark">Gruvbox Dark</option>
|
||||
<option value="gruvbox-material">Gruvbox Material</option>
|
||||
<option value="maia">Maia</option>
|
||||
<option value="mono-amber">Mono Amber</option>
|
||||
<option value="mono-cyan">Mono Cyan</option>
|
||||
<option value="mono-green">Mono Green</option>
|
||||
<option value="mono-red">Mono Red</option>
|
||||
<option value="mono-white">Mono White</option>
|
||||
<option value="mono-yellow">Mono Yellow</option>
|
||||
<option value="papercolor-dark">Papercolor Dark</option>
|
||||
<option value="rose-pine">Rosé Pine</option>
|
||||
<option value="rose-pine-moon">Rose Pine Moon</option>
|
||||
<option value="shel">Shel</option>
|
||||
<option value="slate">Slate</option>
|
||||
<option value="solarized-dark">Solarized Dark</option>
|
||||
</optgroup>
|
||||
</select><br>
|
||||
</div>
|
||||
</div> <!-- footer -->
|
||||
</div> <!-- page -->
|
||||
</body>
|
||||
</html>
|
28
resources/views/components/minimal-error.blade.php
Normal file
28
resources/views/components/minimal-error.blade.php
Normal file
|
@ -0,0 +1,28 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>{{ $title ?? '' }}</title>
|
||||
<link rel="stylesheet" href="{{ URL::asset ('css/minimal.css') }}"/>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Error {{ $code }} | <strong>{{ $message }}</strong></h1>
|
||||
<hr align="left">
|
||||
<p>Here, have a cat...</p>
|
||||
<img src="https://http.cat/{{ $code }}" width="500"><br><br>
|
||||
<p>If you believe this is a server error, contact the <a href="mailto:webmaster@diskfloppy.me">webmaster</a></p>
|
||||
<br>
|
||||
<h4>Diagnostic Info</h4>
|
||||
<table><tr><td>
|
||||
<code>
|
||||
Server: {{ gethostname() }}<br>
|
||||
Your IP: {{ Request::ip() }}<br>
|
||||
Root: {!! url('') !!}<br>
|
||||
Path: @if(Request::path() == "/")/@else/{{ Request::path() }}/@endif<br>
|
||||
Epoch: {{ now()->timestamp }}<br>
|
||||
Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:122.0) Gecko/20100101 Firefox/122.0 </code>
|
||||
</td></tr></table>
|
||||
<hr align="left">
|
||||
<p>© floppydisk 2021-2024</p>
|
||||
</body>
|
||||
</html>
|
0
resources/views/components/minimal.blade.php
Normal file
0
resources/views/components/minimal.blade.php
Normal file
18
resources/views/components/navbar.blade.php
Normal file
18
resources/views/components/navbar.blade.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<nav>
|
||||
<h1>diskfloppy.me | <strong>{{ $title }}</strong></h1>
|
||||
<div class="nav-wrapper">
|
||||
<div>
|
||||
<a href="/" title="Home"><img class="pixel" src="/images/icons/nav/home2.png" alt="Home" width="32" height="32"></a>
|
||||
<a href="//git.diskfloppy.me/" title="cgit"><img class="pixel" src="/images/icons/nav/repo.png" alt="cgit" width="32" height="32"></a>
|
||||
<a href="/pub/" title="Public Files"><img class="pixel" src="/images/icons/nav/pubfiles.png" alt="Public Files" width="32" height="32"></a>
|
||||
<a href="/computers/" title="Computers"><img class="pixel" src="/images/icons/nav/computers.png" alt="Computers" width="32" height="32"></a>
|
||||
<a href="/bookmarks/" title="Bookmarks"><img class="pixel" src="/images/icons/nav/bookmarks.png" alt="Bookmarks" width="32" height="32"></a>
|
||||
<a href="/guestbook/" title="Guestbook"><img class="pixel" src="/images/icons/nav/guestbook.png" alt="Guestbook" width="32" height="32"></a>
|
||||
<a href="//weather.diskfloppy.me/" title="Weather"><img class="pixel" src="/images/icons/nav/weather.png" alt="Weather" width="32" height="32"></a>
|
||||
<a href="/music/" title="Music"><img class="pixel" src="/images/icons/nav/music.png" alt="Music" width="32" height="32"></a>
|
||||
</div>
|
||||
<div>
|
||||
<a href="/login/" title="Admin Login"><img class="pixel" src="/images/icons/nav/admin.png" alt="Admin Login" width="32" height="32"></a>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
16
resources/views/components/top-tracks.blade.php
Normal file
16
resources/views/components/top-tracks.blade.php
Normal file
|
@ -0,0 +1,16 @@
|
|||
<table class="music-top10">
|
||||
<caption>
|
||||
<h2 style="margin-bottom: 5px">Top 10 Tracks (Last 30 days):</h2>
|
||||
</caption>
|
||||
<tr>
|
||||
<th><b>#</b></th>
|
||||
<th><b>Track</b></th>
|
||||
<th><b>Artist</b></th>
|
||||
<th><b>Plays</b></th>
|
||||
</tr>
|
||||
@php($count = 0)
|
||||
@foreach ($tracks as $track)
|
||||
@php($count++)
|
||||
<x-track :track="$track" :count="$count"/>
|
||||
@endforeach
|
||||
</table>
|
6
resources/views/components/track.blade.php
Normal file
6
resources/views/components/track.blade.php
Normal file
|
@ -0,0 +1,6 @@
|
|||
<tr>
|
||||
<td>{{ $count }}</td>
|
||||
<td><a href="{{ $track["url"] }}">{{ $track["title"] }}</a></td>
|
||||
<td>{{ $track["artist"] }}</td>
|
||||
<td>{{ $track["plays"] }}</td>
|
||||
</tr>
|
187
resources/views/computers.blade.php
Normal file
187
resources/views/computers.blade.php
Normal file
|
@ -0,0 +1,187 @@
|
|||
@extends('layouts.default')
|
||||
@section('title', 'Computers')
|
||||
@section('description', 'Computers I own or have owned.')
|
||||
@php
|
||||
// TODO: AMD whitebox, 745, D531, 1525, server, vaio, qosmio, packard bell
|
||||
@endphp
|
||||
@section('content')
|
||||
<table class="computers">
|
||||
<tr>
|
||||
<th>PICTURES</th>
|
||||
<th>SPECS & DESCRIPTION</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Random Whitebox</td>
|
||||
<td>
|
||||
<span class="section-title">Quick Specs</span>
|
||||
<ul>
|
||||
<li>486DX2 (50MHz)</li>
|
||||
<li>16MB RAM</li>
|
||||
<li>280MB HDD</li>
|
||||
<li>Windows NT 3.51</li>
|
||||
</ul>
|
||||
<p class="description">
|
||||
Had been monitoring the ventilation system in a school since the late 1990s,
|
||||
only stopped because the power supply internally exploded. Replaced the PSU with
|
||||
a standard ATX PSU and an ATX to AT adaptor and it sprung back to life.
|
||||
Motherboard is a Gigabyte GA486IM with 4 PCI slots, 4 ISA slots and 2 VLB slots.
|
||||
Has two identical ISA serial/parallel/game-port cards with one acting as the
|
||||
HDD/FDD controller. Also has a Realtek NIC with both RJ45 and BNC. GPU is a
|
||||
Cirrus Logic card and is astoundingly shit.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>2023 MacBook Pro 14"</td>
|
||||
<td>
|
||||
<span class="section-title">Quick Specs</span>
|
||||
<ul>
|
||||
<li>Apple M3 Pro</li>
|
||||
<li>18GB RAM</li>
|
||||
<li>500GB SSD</li>
|
||||
<li>macOS Sonoma</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>2018 MacBook Pro 13"</td>
|
||||
<td>
|
||||
<span class="section-title">Quick Specs</span>
|
||||
<ul>
|
||||
<li>Intel i5-8259U @ 2.3GHz</li>
|
||||
<li>Intel Iris Plus Graphics 655</li>
|
||||
<li>8GB RAM</li>
|
||||
<li>250GB SSD</li>
|
||||
<li>macOS Sonoma</li>
|
||||
</ul>
|
||||
<p class="description">
|
||||
Old main computer. Really like the touch bar, absolutely hate the butterfly
|
||||
keyboard.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>2012 Lenovo ThinkPad T430</td>
|
||||
<td>
|
||||
<span class="section-title">Quick Specs</span>
|
||||
<ul>
|
||||
<li>Intel Core i7</li>
|
||||
<li>16GB RAM</li>
|
||||
<li>Windows 7 Professional / NixOS</li>
|
||||
</ul>
|
||||
<p class="description">
|
||||
One of my main computers. Has been modified to use a classic keyboard instead of
|
||||
the stock Lenovo keyboard.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>2005 IBM ThinkPad X41T</td>
|
||||
<td>
|
||||
<span class="section-title">Quick Specs</span>
|
||||
<ul>
|
||||
<li>Intel Pentium M @ 1.6GHz</li>
|
||||
<li>Mobile Intel Express Chipset Family (128MB)</li>
|
||||
<li>1.5GB RAM</li>
|
||||
<li>40GB HDD</li>
|
||||
<li>Windows XP Tablet PC Edition</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>1999 Dell OptiPlex GX1</td>
|
||||
<td>
|
||||
<span class="section-title">Quick Specs</span>
|
||||
<ul>
|
||||
<li>Intel Pentium II (Deschutes) @ 400MHz</li>
|
||||
<li>ATI 3D Rage Pro (4MB)</li>
|
||||
<li>639MB</li>
|
||||
<li>40GB HDD</li>
|
||||
<li>MS-DOS 6.22 & WFW 3.10</li>
|
||||
</ul>
|
||||
<p class="description">
|
||||
Cool computer that uses Slot 1 CPUs. After a lot of trial and error I managed to
|
||||
max out the memory. Has a riser that sports 2 PCI and 2 ISA slots (one PCI and
|
||||
ISA share the same slot).
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>2003 IBM ThinkPad T40</td>
|
||||
<td>
|
||||
<span class="section-title">Quick Specs</span>
|
||||
<ul>
|
||||
<li>Intel Pentium M @ 1.3GHz</li>
|
||||
<li>ATI Mobility Radeon 7500 (32MB)</li>
|
||||
<li>1GB RAM</li>
|
||||
<li>30GB HDD</li>
|
||||
<li>Windows 2000 Professional</li>
|
||||
</ul>
|
||||
<p class="description">
|
||||
Useful laptop thanks to its parallel port. Has the ubiquitous GPU solder issues
|
||||
which I """"fixed"""" by jamming a CF card
|
||||
between the GPU chip and the keyboard.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>2010 HP Compaq Elite 8100</td>
|
||||
<td>
|
||||
<span class="section-title">Quick Specs</span>
|
||||
<ul>
|
||||
<li>Intel Core i7</li>
|
||||
<li>16GB RAM</li>
|
||||
<li>some SSD and an HDD</li>
|
||||
<li>Windows Vista Ultimate (64-bit)</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>2014 Mac mini</td>
|
||||
<td>
|
||||
<span class="section-title">Quick Specs</span>
|
||||
<ul>
|
||||
<li>Intel Core i5-4278U @ 2.6GHz</li>
|
||||
<li>Intel Iris Graphics</li>
|
||||
<li>8GB RAM</li>
|
||||
<li>1TB HDD</li>
|
||||
<li>VMware ESXi 6.7.0u3</li>
|
||||
</ul>
|
||||
<p class="description">
|
||||
Was used as my VM host for a few years. Has now been superseded by an
|
||||
actual 1U rack-mount server.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>1996 Fujitsu Milan</td>
|
||||
<td>
|
||||
<span class="section-title">Quick Specs</span>
|
||||
<ul>
|
||||
<li>Intel Pentium</li>
|
||||
<li>32MB RAM</li>
|
||||
<li>1215MB HDD</li>
|
||||
<li>Windows 98 SE</li>
|
||||
</ul>
|
||||
<p class="description">
|
||||
Was originally a family members' laptop. Unfortunately the HDD side of the
|
||||
HDD/FDD cable ripped while I was removing the drive to clean the computer.
|
||||
Still scouring eBay for a replacement cable (or more likely, an entire
|
||||
parts machine).
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>1999 Compaq Armada M300</td>
|
||||
<td>
|
||||
<span class="section-title">Quick Specs</span>
|
||||
<ul>
|
||||
<li>Intel Pentium III</li>
|
||||
</ul>
|
||||
<p class="description">
|
||||
Nice little laptop. Mysteriously dead.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@stop
|
|
@ -1,5 +1,4 @@
|
|||
@extends('errors::minimal')
|
||||
|
||||
@section('title', __('Unauthorized'))
|
||||
@section('code', '401')
|
||||
@section('message', __('Unauthorized'))
|
||||
<x-minimal-error>
|
||||
<x-slot:code>401</x-slot:code>
|
||||
<x-slot:message>Unauthorized</x-slot:message>
|
||||
</x-minimal-error>
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
@extends('errors::minimal')
|
||||
|
||||
@section('title', __('Payment Required'))
|
||||
@section('code', '402')
|
||||
@section('message', __('Payment Required'))
|
||||
<x-minimal-error>
|
||||
<x-slot:code>402</x-slot:code>
|
||||
<x-slot:message>Payment Required</x-slot:message>
|
||||
</x-minimal-error>
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
@extends('errors::minimal')
|
||||
|
||||
@section('title', __('Forbidden'))
|
||||
@section('code', '403')
|
||||
@section('message', __($exception->getMessage() ?: 'Forbidden'))
|
||||
<x-minimal-error>
|
||||
<x-slot:code>403</x-slot:code>
|
||||
<x-slot:message>{{__($exception->getMessage() ?: 'Forbidden')}}</x-slot:message>
|
||||
</x-minimal-error>
|
||||
|
|
|
@ -1,27 +1,4 @@
|
|||
@extends('errors::minimal')
|
||||
@section('content')
|
||||
|
||||
<h1>Error 404 | <strong>Page not found!</strong></h1>
|
||||
<hr align="left">
|
||||
<h2>The page <code class="addr">/{{ Request::path() }}/</code> doesn't exist! Did you mean...</h2>
|
||||
<ul>
|
||||
<li><a href="//www.diskfloppy.me/">diskfloppy.me</a></li>
|
||||
<li><a href="//git.diskfloppy.me/">git.diskfloppy.me</a></li>
|
||||
<li><a href="//weather.diskfloppy.me">weather.diskfloppy.me</a></li>
|
||||
<li><a href="//dl.diskfloppy.me/">dl.diskfloppy.me</a></li>
|
||||
<li><a href="https://status.diskfloppy.me">status.diskfloppy.me</a> (HTTPS Only)</li>
|
||||
<li><a href="gopher://diskfloppy.me">gopher://diskfloppy.me</a></li>
|
||||
</ul>
|
||||
<p>Still haven't found what you were looking for or believe this is a server error? Contact the <a href="mailto:webmaster@diskfloppy.me">webmaster</a>!</p>
|
||||
<br>
|
||||
<h4>Diagnostic Info</h4>
|
||||
<table><tr><td>
|
||||
<code>
|
||||
Server: {{ gethostname() }}<br>
|
||||
Your IP: {{ Request::ip() }}<br>
|
||||
Epoch: {{ now()->timestamp }}<br>
|
||||
Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:122.0) Gecko/20100101 Firefox/122.0 </code>
|
||||
</td></tr></table>
|
||||
<hr align="left">
|
||||
<p>© floppydisk 2021-2024</p>
|
||||
@endsection
|
||||
<x-minimal-error>
|
||||
<x-slot:code>404</x-slot:code>
|
||||
<x-slot:message>Page not found!</x-slot:message>
|
||||
</x-minimal-error>
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
@extends('errors::minimal')
|
||||
|
||||
@section('title', __('I\'m a teapot'))
|
||||
@section('code', '418')
|
||||
@section('message', __('I\'m a teapot'))
|
||||
<x-minimal-error>
|
||||
<x-slot:code>418</x-slot:code>
|
||||
<x-slot:message>I'm a teapot</x-slot:message>
|
||||
</x-minimal-error>
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
@extends('errors::minimal')
|
||||
|
||||
@section('title', __('Page Expired'))
|
||||
@section('code', '419')
|
||||
@section('message', __('Page Expired'))
|
||||
<x-minimal-error>
|
||||
<x-slot:code>419</x-slot:code>
|
||||
<x-slot:message>Page Expired</x-slot:message>
|
||||
</x-minimal-error>
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
@extends('errors::minimal')
|
||||
|
||||
@section('title', __('Too Many Requests'))
|
||||
@section('code', '429')
|
||||
@section('message', __('Too Many Requests'))
|
||||
<x-minimal-error>
|
||||
<x-slot:code>429</x-slot:code>
|
||||
<x-slot:message>Too Many Requests</x-slot:message>
|
||||
</x-minimal-error>
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
@extends('errors::minimal')
|
||||
|
||||
@section('title', __('Server Error'))
|
||||
@section('code', '500')
|
||||
@section('message', __('Server Error'))
|
||||
<x-minimal-error>
|
||||
<x-slot:code>500</x-slot:code>
|
||||
<x-slot:message>Server Error</x-slot:message>
|
||||
</x-minimal-error>
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
@extends('errors::minimal')
|
||||
|
||||
@section('title', __('Service Unavailable'))
|
||||
@section('code', '503')
|
||||
@section('message', __('Service Unavailable'))
|
||||
<x-minimal-error>
|
||||
<x-slot:code>503</x-slot:code>
|
||||
<x-slot:message>Service Unavailable</x-slot:message>
|
||||
</x-minimal-error>
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
@extends('layouts.minimal')
|
||||
@section('title', 'Error 401: Unauthorized User!')
|
||||
@section('content')
|
||||
<x-minimal>
|
||||
<x-slot:title>Error 401: Unauthorized User!</x-slot:title>
|
||||
<h1>{{ $error }}</h1>
|
||||
<hr>
|
||||
@if(isset($description))
|
||||
<p>{{ $description }}</p>
|
||||
@endif
|
||||
@stop
|
||||
</x-minimal>
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
@extends('layouts.minimal')
|
||||
@section('title', 'Error 403: IP Blocked!')
|
||||
@section('content')
|
||||
<x-minimal>
|
||||
<x-slot:title>Error 403: IP Blocked!</x-slot:title>
|
||||
<h1>Error 403: IP Blocked!</h1>
|
||||
<hr>
|
||||
<p>Your IP has been banned from submitting to the guestbook.</p>
|
||||
|
@ -9,4 +8,4 @@
|
|||
@endif
|
||||
<br>
|
||||
Click <a href="/guestbook">here</a> to go back to the guestbook.
|
||||
@stop
|
||||
</x-minimal>
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
@extends('layouts.minimal')
|
||||
@section('title', 'Error 429: Overclocking Detected!')
|
||||
@section('content')
|
||||
<x-minimal>
|
||||
<x-slot:title>Error 429: Overclocking Detected!</x-slot:title>
|
||||
<h1>Error 429: Overclocking Detected!</h1>
|
||||
<hr>
|
||||
<p>Whoa there! Your submissions are going at warp speed.</p>
|
||||
<p>Remember you can only submit an entry <u>once every hour</u>!</p>
|
||||
<br>
|
||||
Click <a href="/guestbook">here</a> to go back to the guestbook.
|
||||
@stop
|
||||
</x-minimal>
|
||||
|
|
|
@ -1,53 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<title>@yield('title')</title>
|
||||
|
||||
<!-- Styles -->
|
||||
<style>
|
||||
html, body {
|
||||
background-color: #fff;
|
||||
color: #636b6f;
|
||||
font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
|
||||
font-weight: 100;
|
||||
height: 100vh;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.full-height {
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
.flex-center {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.position-ref {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.content {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 36px;
|
||||
padding: 20px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="flex-center position-ref full-height">
|
||||
<div class="content">
|
||||
<div class="title">
|
||||
@yield('message')
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -1,21 +1,3 @@
|
|||
@extends('layouts.minimal')
|
||||
@section('content')
|
||||
<h1>Error @yield('code') | <strong>@yield('message')</strong></h1>
|
||||
<hr align="left">
|
||||
<p>Here, have a cat...</p>
|
||||
<img src="https://http.cat/@yield('code')" width="500"><br><br>
|
||||
<p>If you believe this is a server error, contact the <a href="mailto:webmaster@diskfloppy.me">webmaster</a></p>
|
||||
<br>
|
||||
<h4>Diagnostic Info</h4>
|
||||
<table><tr><td>
|
||||
<code>
|
||||
Server: {{ gethostname() }}<br>
|
||||
Your IP: {{ Request::ip() }}<br>
|
||||
Root: {!! url('') !!}<br>
|
||||
Path: /{{ Request::path() }}/<br>
|
||||
Epoch: {{ now()->timestamp }}<br>
|
||||
Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:122.0) Gecko/20100101 Firefox/122.0 </code>
|
||||
</td></tr></table>
|
||||
<hr align="left">
|
||||
<p>© floppydisk 2021-2024</p>
|
||||
@endsection
|
||||
<x-minimal>
|
||||
|
||||
</x-minimal>
|
||||
|
|
|
@ -1,27 +1,12 @@
|
|||
@extends('layouts.default')
|
||||
@section('title', 'Guestbook')
|
||||
@section('content')
|
||||
@php
|
||||
use UAParser\Parser;
|
||||
$parser = Parser::create();
|
||||
$db_alive = true;
|
||||
try {
|
||||
DB::connection()->getPdo();
|
||||
} catch (Exception $e) {
|
||||
$db_alive = false;
|
||||
}
|
||||
@endphp
|
||||
@if (!$db_alive)
|
||||
@include('components.errors.db-error')
|
||||
@else
|
||||
<br>
|
||||
<x-layout>
|
||||
<x-slot:title>Guestbook</x-slot:title>
|
||||
<table class="gb-entry-form-container" role="presentation">
|
||||
<tr>
|
||||
<td>
|
||||
<form method="POST" action="/guestbook">
|
||||
@csrf
|
||||
<x-honeypot/>
|
||||
<table class="gb-entry-form" role="presentation">
|
||||
<table class="form" role="presentation">
|
||||
<tr>
|
||||
<td>
|
||||
<label for="name"><strong>Name:</strong></label>
|
||||
|
@ -66,13 +51,6 @@
|
|||
|
||||
|
||||
<hr>
|
||||
@php
|
||||
$entries = DB::select('
|
||||
SELECT name, timestamp, message, agent
|
||||
FROM guestbook__entries
|
||||
ORDER BY id DESC
|
||||
');
|
||||
@endphp
|
||||
<h2>Entries <small>({{ count($entries) }} total)</small></h2>
|
||||
@foreach ($entries as $entry)
|
||||
@php
|
||||
|
@ -82,10 +60,10 @@
|
|||
<tr>
|
||||
<td>
|
||||
Submitted by <strong>{{ $entry->name }}</strong>
|
||||
on <strong>{{ gmdate('Y-m-d', $entry->timestamp) }}</strong>
|
||||
at <strong>{{ gmdate('h:i:s A (e)', $entry->timestamp) }}</strong>
|
||||
on <strong>{{ $entry->created_at->format('Y-m-d') }}</strong>
|
||||
at <strong>{{ $entry->created_at->format('h:i:s A (e)') }}</strong>
|
||||
<hr>
|
||||
{{ $entry->message }}
|
||||
<span class="guestbook-message">{{ $entry->message }}</span>
|
||||
<hr>
|
||||
@if($entry->agent === "Agent Unavailable")
|
||||
<address>Agent unavailable</address>
|
||||
|
@ -98,5 +76,4 @@
|
|||
</table>
|
||||
<br>
|
||||
@endforeach
|
||||
@endif
|
||||
@stop
|
||||
</x-layout>
|
45
resources/views/home.blade.php
Normal file
45
resources/views/home.blade.php
Normal file
|
@ -0,0 +1,45 @@
|
|||
<x-layout>
|
||||
<x-slot:title>Home</x-slot:title>
|
||||
<p>Hi! This is my personal homepage on the <strong>W</strong>orld <strong>W</strong>ide <strong>W</strong>eb.</p>
|
||||
|
||||
<div class="info-section">
|
||||
<h2>QuickFacts™</h2>
|
||||
<hr>
|
||||
<ul>
|
||||
<li>18 y/o, he/him, British</li>
|
||||
<li>Theatre Technician, "Web Developer" and NixOS User</li>
|
||||
<li>Loves ETC desks, prefers Generics to LEDs for some reason</li>
|
||||
<li>Has a crippling Soundcraft addiction</li>
|
||||
<li>Spends way too much time on his computer</li>
|
||||
<li>Favorite games: <a href="https://steamcommunity.com/id/floppydisk05/recommended/420530/">OneShot</a>, Minecraft, Stardew Valley, N++ and Starbound</li>
|
||||
<li><a href="http://wxqa.com/">CWOP</a> member</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="info-section">
|
||||
<h2>Interests</h2>
|
||||
<hr>
|
||||
<ul>
|
||||
<li><strong>Tech Theatre</strong> - Lighting, Stage Management, etc. (<a href="https://www.controlbooth.com/members/floppydisk.28673/">ControlBooth</a>)</li>
|
||||
<li><strong>Programming</strong> - HTML, CSS, JavaScript, C#, Java, PHP, Ruby, Python (<a href="https://github.com/floppydisk05">GitHub</a>)</li>
|
||||
<li><strong>Photography</strong> - <a href="https://www.flickr.com/photos/floppydisk/">Flickr</a></li>
|
||||
<li><strong>Gaming</strong> - <a href="https://steamcommunity.com/id/floppydisk05/">Steam Profile</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="info-section">
|
||||
<h2>Things they never said</h2>
|
||||
<hr>
|
||||
<p>
|
||||
<script type="text/javascript" src="{{ asset("/js/neverSaid.js") }}"></script>
|
||||
<noscript>Oops! You need JavaScript enabled to view this content.</noscript>
|
||||
</p>
|
||||
</div>
|
||||
<div class="info-section">
|
||||
<h2>Contact & social</h2>
|
||||
<hr>
|
||||
<p>
|
||||
<strong>E-mail:</strong> <a href="mailto:contact@diskfloppy.me">contact@diskfloppy.me</a><br>
|
||||
<strong>Mastodon:</strong> <a rel="me" href="https://c.im/@floppydisk">@floppydisk@c.im</a><br>
|
||||
<strong>Matrix:</strong> <a href="https://matrix.to/#/@floppydisk:arcticfoxes.net">@floppydisk:arcticfoxes.net</a>
|
||||
</p>
|
||||
</div>
|
||||
</x-layout>
|
|
@ -1,12 +0,0 @@
|
|||
<nav>
|
||||
<div>
|
||||
<a href="/">public home</a> |
|
||||
<a href="/admin">admin home</a> |
|
||||
<a href="/admin/guestbook">guestbook</a>
|
||||
@if (auth()->check())
|
||||
| ({{ auth()->user()->name }}) <a href="/logout">logout</a>
|
||||
@else
|
||||
| <a href="/login">login</a>
|
||||
@endif
|
||||
</div>
|
||||
</nav>
|
|
@ -25,7 +25,7 @@ class="pixel" alt="Valid CSS!">
|
|||
class="pixel" alt="Wiby - Search Engine for the Classic Web">
|
||||
</a><br>
|
||||
This site is best viewed at 1024x768 with 16-bit color or better<br>
|
||||
© floppydisk 2021-{{ date('Y') }}, v{{ config('app.version') }}, <a
|
||||
© floppydisk 2021-{{ date('Y') }}, v{{ config('app.version') }}@if(env('DEVEL'))-dev, @else, @endif<a
|
||||
href="https://github.com/floppydisk05/diskfloppy.me">Source</a>,
|
||||
Served by {{ gethostname() }}<br>
|
||||
<label for="scheme-selector">Color Scheme:</label>
|
||||
|
|
6
resources/views/music.blade.php
Normal file
6
resources/views/music.blade.php
Normal file
|
@ -0,0 +1,6 @@
|
|||
<x-layout>
|
||||
<x-slot:title>Music</x-slot:title>
|
||||
<x-current-track :track="$current_track"/>
|
||||
<hr>
|
||||
<x-top-tracks :tracks="$top_tracks"/>
|
||||
</x-layout>
|
|
@ -1,33 +0,0 @@
|
|||
@extends('layouts.minimal')
|
||||
@section('title', 'Delete confirm')
|
||||
@section('content')
|
||||
<h1>Delete Confirmation</h1>
|
||||
<hr>
|
||||
<p>Are you sure you want to delete this entry?</p>
|
||||
|
||||
<h3>Entry Details:</h3>
|
||||
<table class="gb-entry-details">
|
||||
<tr>
|
||||
<td><b>ID:</b></td>
|
||||
<td>{{ $entry->id }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Name:</b></td>
|
||||
<td>{{ $entry->name }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Date:</b></td>
|
||||
<td>{{ gmdate("H:i:s - Y-m-d", $entry->timestamp) }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Message:</b></td>
|
||||
<td>{{ $entry->message }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<form action="/admin/guestbook/delete" method="POST">
|
||||
@csrf
|
||||
<input type="hidden" name="id" value="{{ $entry->id }}">
|
||||
<button type="submit">Confirm Delete</button>
|
||||
</form>
|
||||
@stop
|
|
@ -1,32 +0,0 @@
|
|||
@extends('layouts.default-admin')
|
||||
@section('title', 'Guestbook')
|
||||
@section('content')
|
||||
@php
|
||||
$entries = DB::select('
|
||||
SELECT id, name, timestamp, message, ip_address
|
||||
FROM guestbook__entries
|
||||
ORDER BY id DESC
|
||||
');
|
||||
@endphp
|
||||
<h1>Entries <small>({{ count($entries) }} total)</small></h1>
|
||||
@foreach ($entries as $entry)
|
||||
<table class="gb-admin">
|
||||
<tr>
|
||||
<td>
|
||||
Name: {{ $entry->name }}<br>
|
||||
IP: {{ $entry->ip_address }}<br>
|
||||
Date: {{ gmdate("H:i:s - Y-m-d", $entry->timestamp) }}
|
||||
</td>
|
||||
<td class="gb-del">
|
||||
<a href="/admin/guestbook/delete?id={{ $entry->id }}">del</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="gb-message">
|
||||
<br>
|
||||
{{ htmlspecialchars($entry->message) }}
|
||||
</td>
|
||||
</tr></table>
|
||||
@endforeach
|
||||
@stop
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
@extends('layouts.default-admin')
|
||||
@section('title', 'Page Title')
|
||||
@section('description', 'Page description goes here')
|
||||
@php
|
||||
$user = auth()->user();
|
||||
@endphp
|
||||
@section('content')
|
||||
<p>You are logged in as {{ $user->name }} ({{ $user->email }})</p>
|
||||
@stop
|
|
@ -1,52 +0,0 @@
|
|||
@extends('layouts.default')
|
||||
@section('title', 'Bookmarks')
|
||||
@section('description', 'This is the personal homepage of floppydisk.')
|
||||
@section('content')
|
||||
@php
|
||||
$db_alive = true;
|
||||
try {
|
||||
DB::connection()->getPdo();
|
||||
} catch (Exception $e) {
|
||||
$db_alive = false;
|
||||
}
|
||||
@endphp
|
||||
@if (!$db_alive)
|
||||
@include('components.errors.db-error')
|
||||
@else
|
||||
@php
|
||||
$categories = DB::select('
|
||||
SELECT id, name
|
||||
FROM bookmark__categories
|
||||
ORDER BY priority ASC
|
||||
');
|
||||
@endphp
|
||||
|
||||
@foreach ($categories as $category)
|
||||
<table class="info-table" role="presentation">
|
||||
|
||||
<caption>
|
||||
<h2>{{ $category->name }}</h2>
|
||||
<hr>
|
||||
</caption>
|
||||
|
||||
@php
|
||||
$sites = DB::select(
|
||||
'
|
||||
SELECT name, url, description
|
||||
FROM bookmark__sites
|
||||
WHERE category_id = ? ORDER BY priority ASC
|
||||
',
|
||||
[$category->id],
|
||||
);
|
||||
@endphp
|
||||
@foreach ($sites as $site)
|
||||
<tr>
|
||||
<td><a href="{{ $site->url }}">{{ $site->name }}</a>
|
||||
- {{ $site->description }}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</table>
|
||||
<br>
|
||||
@endforeach
|
||||
@endif
|
||||
@stop
|
|
@ -1,7 +0,0 @@
|
|||
@extends('layouts.default')
|
||||
@section('title', 'Discord Bot')
|
||||
@section('description', '')
|
||||
@section('content')
|
||||
<p>The diskfloppy.me Discord bot blah blah blah blah blah</p>
|
||||
<p>Maybe I'll finish this page later idk</p>
|
||||
@stop
|
|
@ -1,442 +0,0 @@
|
|||
@extends('layouts.default')
|
||||
@section('title', 'Computers')
|
||||
@section('description', 'Computers I own or have owned.')
|
||||
@section('content')
|
||||
<table class="computers">
|
||||
<tr>
|
||||
<th>PICTURES</th>
|
||||
<th>SPECS & DESCRIPTION</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>2023 MacBook Pro 14"</td>
|
||||
<td>
|
||||
<section-title>Quick Specs</section-title>
|
||||
<ul>
|
||||
<li>Apple M3 Pro</li>
|
||||
<li>18GB RAM</li>
|
||||
<li>500GB SSD</li>
|
||||
<li>macOS Sonoma</li>
|
||||
</ul>
|
||||
<p class="description">WHAT</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>2018 MacBook Pro 13"</td>
|
||||
<td>
|
||||
<section-title>Quick Specs</section-title>
|
||||
<ul>
|
||||
<li>Intel i5-8259U @ 2.3GHz</li>
|
||||
<li>Intel Iris Plus Graphics 655</li>
|
||||
<li>8GB RAM</li>
|
||||
<li>250GB SSD</li>
|
||||
<li>macOS Sonoma</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>2012 Lenovo ThinkPad T430</td>
|
||||
<td>
|
||||
<section-title>Quick Specs</section-title>
|
||||
<ul>
|
||||
<li>Intel Core i7</li>
|
||||
<li>16GB RAM</li>
|
||||
<li>Windows 7 Professional</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>2005 IBM ThinkPad X41T</td>
|
||||
<td>
|
||||
<section-title>Quick Specs</section-title>
|
||||
<ul>
|
||||
<li>Intel Pentium M @ 1.6GHz</li>
|
||||
<li>Mobile Intel Express Chipset Family (128MB)</li>
|
||||
<li>1.5GB RAM</li>
|
||||
<li>40GB HDD</li>
|
||||
<li>Windows XP Tablet PC Edition</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>1999 Dell OptiPlex GX1</td>
|
||||
<td>
|
||||
<section-title>Quick Specs</section-title>
|
||||
<ul>
|
||||
<li>Intel Pentium II (Deschutes) @ 400MHz</li>
|
||||
<li>ATI 3D Rage Pro (4MB)</li>
|
||||
<li>639MB</li>
|
||||
<li>40GB HDD</li>
|
||||
<li>MS-DOS 6.22 & WFW 3.10</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>2003 IBM ThinkPad T40</td>
|
||||
<td>
|
||||
<section-title>Quick Specs</section-title>
|
||||
<ul>
|
||||
<li>Intel Pentium M @ 1.3GHz</li>
|
||||
<li>ATI Mobility Radeon 7500 (32MB)</li>
|
||||
<li>1GB RAM</li>
|
||||
<li>30GB HDD</li>
|
||||
<li>Windows 2000 Professional</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>2010 HP Compaq Elite 8100</td>
|
||||
<td>
|
||||
<section-title>Quick Specs</section-title>
|
||||
<ul>
|
||||
<li>Intel Core i7</li>
|
||||
<li>16GB RAM</li>
|
||||
<li>some SSD and an HDD</li>
|
||||
<li>Windows Vista Ultimate (64-bit)</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>2014 Mac mini</td>
|
||||
<td>
|
||||
<section-title>Quick Specs</section-title>
|
||||
<ul>
|
||||
<li>Intel Core i5-4278U @ 2.6GHz</li>
|
||||
<li>Intel Iris Graphics</li>
|
||||
<li>8GB RAM</li>
|
||||
<li>1TB HDD</li>
|
||||
<li>VMware ESXi 6.7.0u3</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>1996 Fujitsu Milan</td>
|
||||
<td>
|
||||
<section-title>Quick Specs</section-title>
|
||||
<ul>
|
||||
<li>Intel Pentium</li>
|
||||
<li>32MB RAM</li>
|
||||
<li>1215MB HDD</li>
|
||||
<li>Windows 98 SE</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>1999 Compaq Armada M300</td>
|
||||
<td>
|
||||
<section-title>Quick Specs</section-title>
|
||||
<ul>
|
||||
<li>Intel Pentium III</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<!--<table class="computer" role="presentation">
|
||||
<tr>
|
||||
<td colspan="2"><h2>Custom Build</h2><hr></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<table class="computer-specs">
|
||||
<tr>
|
||||
<td class="spec-title">OS:</td>
|
||||
<td class="spec">NixOS 22.11 / Windows 10 Pro</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-title">CPU:</td>
|
||||
<td class="spec">Intel i7-6700K (8-core) @ 4.0GHz</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-title">GPU:</td>
|
||||
<td class="spec">NVidia GTX 1060 (3GB)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-title">Memory:</td>
|
||||
<td class="spec">64GB</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-title">DISK0:</td>
|
||||
<td class="spec">SanDisk SSD Plus (120GB, Win10)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-title">DISK1:</td>
|
||||
<td class="spec">Crucial CT500MX500SSD1 (500GB, NixOS)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-title">DISK2:</td>
|
||||
<td class="spec">WDC WD20EZEAZ-00GGJB0 (2TB, Data)</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<table class="computer" role="presentation">
|
||||
<tr>
|
||||
<td colspan="2"><h2>MacBook Pro (2018)</h2><hr></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<table class="computer-specs">
|
||||
<tr>
|
||||
<td class="spec-title">OS:</td>
|
||||
<td class="spec">macOS 12.5.1</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-title">Display:</td>
|
||||
<td class="spec">2560x1600 (Retina)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-title">CPU:</td>
|
||||
<td class="spec">Intel i5-8259U (8-core) @ 2.3GHz</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-title">GPU:</td>
|
||||
<td class="spec">Intel Iris Plus Graphics 655</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-title">Memory:</td>
|
||||
<td class="spec">8GB</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-title">DISK:</td>
|
||||
<td class="spec">Apple SSD AP0256M (250GB)</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<table class="computer" role="presentation">
|
||||
<tr>
|
||||
<td colspan="2"><h2>Lenovo ThinkPad T430 (2012)</h2><hr></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<table class="computer-specs">
|
||||
<tr>
|
||||
<td class="spec-title">OS:</td>
|
||||
<td class="spec">NixOS 22.11 / Windows 7 Ultimate</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-title">CPU:</td>
|
||||
<td class="spec">Intel i7-3520M (4-core) @ 3.6GHz</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-title">GPU:</td>
|
||||
<td class="spec">Intel 3rd Gen Core processor Graphics Controllertd>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-title">Memory:</td>
|
||||
<td class="spec">16GB</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-title">DISK0:</td>
|
||||
<td class="spec">Crucial CT500MX500SSD1 (500GB, NixOS)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-title">DISK1:</td>
|
||||
<td class="spec">Crucial CT250MX500SSD1 (250GB, Win7)</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<table class="computer" role="presentation">
|
||||
<tr>
|
||||
<td colspan="2"><h2>IBM ThinkPad X41 (2005)</h2><hr></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<table class="computer-specs">
|
||||
<tr>
|
||||
<td class="spec-title">OS:</td>
|
||||
<td class="spec">Windows XP Tablet PC Edition (2005, SP3)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-title">CPU:</td>
|
||||
<td class="spec">Intel Pentium M (single-core) @ 1.6GHz</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-title">GPU:</td>
|
||||
<td class="spec">Mobile Intel 915GM/GMS 910GML Express Chipset Family (128MB)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-title">Memory:</td>
|
||||
<td class="spec">1.5GB</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-title">DISK:</td>
|
||||
<td class="spec">Hitachi HTC426040G9AT00 (40GB)</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<table class="computer" role="presentation">
|
||||
<tr>
|
||||
<td colspan="2"><h2>Dell OptiPlex GX1 (400L+, 1999)</h2><hr></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<table class="computer-specs">
|
||||
<tr>
|
||||
<td class="spec-title">OS:</td>
|
||||
<td class="spec">Windows 3.10 for Workgroups (DOS 6.22)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-title">CPU:</td>
|
||||
<td class="spec">Intel Pentium II (Deschutes) @ 400MHz</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-title">GPU:</td>
|
||||
<td class="spec">ATI 3D Rage Pro (4MB)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-title">Memory:</td>
|
||||
<td class="spec">639MB</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-title">DISK:</td>
|
||||
<td class="spec">Unknown</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<table class="computer" role="presentation">
|
||||
<tr>
|
||||
<td colspan="2"><h2>IBM ThinkPad T40 (2003)</h2><hr></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<table class="computer-specs">
|
||||
<tr>
|
||||
<td class="spec-title">OS:</td>
|
||||
<td class="spec">Windows XP Pro</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-title">CPU:</td>
|
||||
<td class="spec">Intel Pentium M (single-core) @ 1.3GHz</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-title">GPU:</td>
|
||||
<td class="spec">ATI Mobility Radeon 7500 (32MB)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-title">Memory:</td>
|
||||
<td class="spec">1GB</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-title">DISK:</td>
|
||||
<td class="spec">Fujitsu MHS2030AT (30GB)</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<table class="computer" role="presentation">
|
||||
<tr>
|
||||
<td colspan="2"><h2>HP Compaq Elite 8100 CMT</h2><hr></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<table class="computer-specs">
|
||||
<tr>
|
||||
<td class="spec-title">OS:</td>
|
||||
<td class="spec">Windows Vista 64-bit</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-title">CPU:</td>
|
||||
<td class="spec">Intel Core i7</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-title">GPU:</td>
|
||||
<td class="spec"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-title">Memory:</td>
|
||||
<td class="spec">16GB</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-title">DISK0:</td>
|
||||
<td class="spec">SanDisk SSD Plus (120GB, Win10)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-title">DISK1:</td>
|
||||
<td class="spec">Crucial CT500MX500SSD1 (500GB, NixOS)</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<table class="computer" role="presentation">
|
||||
<tr>
|
||||
<td colspan="2"><h2>Mac mini (2014)</h2><hr></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<table class="computer-specs">
|
||||
<tr>
|
||||
<td class="spec-title">OS:</td>
|
||||
<td class="spec">VMware ESXi 6.7.0u3</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-title">CPU:</td>
|
||||
<td class="spec">Intel i5-4278U (4-core) @ 2.6GHz</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-title">GPU:</td>
|
||||
<td class="spec">Intel Iris Graphics</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-title">Memory:</td>
|
||||
<td class="spec">8GB</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-title">DISK:</td>
|
||||
<td class="spec">Apple HDD HTS541 (1TB)</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<table class="computer" role="presentation">
|
||||
<tr>
|
||||
<td colspan="2"><h2>Fujitsu Milan (1996)</h2><hr></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<table class="computer-specs">
|
||||
<tr>
|
||||
<td class="spec-title">OS:</td>
|
||||
<td class="spec">Windows 98 SE</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-title">CPU:</td>
|
||||
<td class="spec">Intel Pentium</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-title">Memory:</td>
|
||||
<td class="spec">32MB</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="spec-title">DISK:</td>
|
||||
<td class="spec">IBM DPRA-21215 (1215MB)</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>-->
|
||||
<!--<table class="computer" role="presentation">
|
||||
<tr>
|
||||
<td colspan="2"><h2>Compaq Armada M300</h2><hr></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<table class="computer-specs">
|
||||
<tr>
|
||||
<td class="spec">TBD</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>-->
|
||||
@stop
|
|
@ -1,88 +0,0 @@
|
|||
@extends('layouts.default')
|
||||
@section('title', 'Home')
|
||||
@section('description', 'This is the personal homepage of floppydisk.')
|
||||
@section('content')
|
||||
|
||||
<p>Hi! This is my personal homepage on the <strong>W</strong>orld <strong>W</strong>ide <strong>W</strong>eb.</p>
|
||||
|
||||
<table class="info-table" role="presentation">
|
||||
<caption>
|
||||
<h2>QuickFacts™</h2>
|
||||
<hr>
|
||||
</caption>
|
||||
<tr>
|
||||
<td>◆ 18 y/o, he/him, British</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>◆ Theatre Technician, "Web Developer" and NixOS User</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>◆ Loves ETC desks, prefers Generics to LEDs for some reason</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>◆ Spends way too much time on his computer</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>◆ Favorite games: <a href="https://steamcommunity.com/id/floppydisk05/recommended/420530/">OneShot</a>, Minecraft, Stardew Valley, N++ and Starbound</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>◆ <a href="http://wxqa.com/">CWOP</a> member</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
|
||||
<table class="info-table" role="presentation">
|
||||
<caption>
|
||||
<h2>Interests</h2>
|
||||
<hr>
|
||||
</caption>
|
||||
<tr>
|
||||
<td>◆ <b>Tech Theatre</b></td>
|
||||
<td>- Lighting, Stage Management, etc. (<a href="https://www.controlbooth.com/members/floppydisk.28673/">ControlBooth</a>)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>◆ <b>Programming</b></td>
|
||||
<td>- HTML, CSS, JavaScript, C#, Java, PHP, Ruby, Python (<a href="https://github.com/floppydisk05">GitHub</a>)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>◆ <b>Photography</b></td>
|
||||
<td>- <a href="https://www.flickr.com/photos/floppydisk/">Flickr</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>◆ <b>Gaming</b></td>
|
||||
<td>- <a href="https://steamcommunity.com/id/floppydisk05/">Steam Profile</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
|
||||
<table class="info-table never-said" role="presentation">
|
||||
<caption>
|
||||
<h2>Things they never said</h2>
|
||||
<hr>
|
||||
</caption>
|
||||
<tr>
|
||||
<script type="text/javascript" src="/js/neverSaid.js"></script>
|
||||
<noscript><td>Oops! You need JavaScript enabled to view this content.</td></noscript>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
|
||||
<table class="info-table" role="presentation">
|
||||
<caption>
|
||||
<h2>Contact & social</h2>
|
||||
<hr>
|
||||
</caption>
|
||||
<tr>
|
||||
<td><strong>E-mail:</strong></td>
|
||||
<td><a href="mailto:contact@diskfloppy.me">contact@diskfloppy.me</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>Mastodon:</strong></td>
|
||||
<td><a rel="me" href="https://c.im/@floppydisk">@floppydisk@c.im</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>Matrix:</strong></td>
|
||||
<td><a href="https://matrix.to/#/@floppydisk:arcticfoxes.net">@floppydisk:arcticfoxes.net</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
@stop
|
|
@ -1,66 +0,0 @@
|
|||
@extends('layouts.default')
|
||||
@section('title', 'Music')
|
||||
@section('description', '')
|
||||
@section('content')
|
||||
@php
|
||||
|
||||
$cfg = app('config')->get('services')['lastfm'];
|
||||
$api_root = app('config')->get('app')['api_root'];
|
||||
|
||||
$api_alive = true;
|
||||
|
||||
try {
|
||||
$data = file_get_contents($api_root.'/lastfm/current');
|
||||
} catch (Exception $e) {
|
||||
$api_alive = false;
|
||||
}
|
||||
@endphp
|
||||
@if (!$api_alive)
|
||||
@include('components.errors.api-error')
|
||||
@else
|
||||
|
||||
@php
|
||||
$current_track = json_decode(file_get_contents($api_root . '/lastfm/current'));
|
||||
$top_tracks = json_decode(file_get_contents($api_root . '/lastfm/top'));
|
||||
$count = 0;
|
||||
@endphp
|
||||
<table class="info-table" role="presentation" width="100%">
|
||||
<tr>
|
||||
<td colspan="4">
|
||||
<h2>Last/Current Track:</h2>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="4">
|
||||
<a href="{{ $current_track->url }}">{{ $current_track->title }} • {{ $current_track->artist }}</a><br>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<hr>
|
||||
<table class="music-top10">
|
||||
<tr>
|
||||
<td colspan="4">
|
||||
<h2 style="margin-bottom: 5px">Top {{ $cfg['toptracks'] }} Tracks (Last 7 days)</h2>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align: right"><b>#</b></td>
|
||||
<td><b>Track</b></td>
|
||||
<td><b>Artist</b></td>
|
||||
<td><b>Plays</b></td>
|
||||
</tr>
|
||||
@foreach ($top_tracks as $track)
|
||||
@php $count++ @endphp
|
||||
@if ($count >= $cfg['toptracks']+1)
|
||||
@break
|
||||
@endif
|
||||
<tr>
|
||||
<td style="text-align: right">{{ $count }}</td>
|
||||
<td style="white-space: nowrap; text-overflow:ellipsis; overflow: hidden; max-width:1px;" width="50%"><a href="{{ $track->url }}">{{ $track->title }}</a></td>
|
||||
<td style="white-space: nowrap; text-overflow:ellipsis; overflow: hidden; max-width:1px;" width="50%">{{ $track->artist }}</td>
|
||||
<td>{{ $track->playcount }}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</table>
|
||||
@endif
|
||||
@stop
|
|
@ -1,16 +0,0 @@
|
|||
<?php $categories = app('config')->get('projects'); ?>
|
||||
@extends('layouts.default')
|
||||
@section('title', 'Projects')
|
||||
@section('description', 'My projects')
|
||||
@section('content')
|
||||
@foreach ($categories as $category)
|
||||
<h2>{{ $category['name']}}</h2>
|
||||
@foreach ($category['projects'] as $project)
|
||||
<div>
|
||||
<a href="{{ $project['url'] }}">{{ $project['name'] }}</a> - {{ $project['description'] }}<br>
|
||||
<b>Languages:</b> {{ implode(", ", $project['languages']) }}
|
||||
</div>
|
||||
<br>
|
||||
@endforeach
|
||||
@endforeach
|
||||
@stop
|
|
@ -1,6 +0,0 @@
|
|||
@extends('layouts.default')
|
||||
@section('title', 'Page Title')
|
||||
@section('description', 'Page description goes here')
|
||||
@section('content')
|
||||
<p>page content</p>
|
||||
@stop
|
|
@ -1,61 +0,0 @@
|
|||
@extends('layouts.default')
|
||||
@section('title', 'Weather')
|
||||
@section('description', 'Data from my weather station')
|
||||
@section('content')
|
||||
@php
|
||||
$api_root = app('config')->get('app')['api_root'];
|
||||
|
||||
function degreesToCompassDirection($degrees) {
|
||||
$cardinalDirections = [
|
||||
'N', 'NNE', 'NE', 'ENE', 'E', 'ESE', 'SE', 'SSE',
|
||||
'S', 'SSW', 'SW', 'WSW', 'W', 'WNW', 'NW', 'NNW', 'N'
|
||||
];
|
||||
return $cardinalDirections[round($degrees*16/360)];
|
||||
}
|
||||
|
||||
$api_alive = true;
|
||||
|
||||
try {
|
||||
$data = file_get_contents($api_root.'/weather');
|
||||
} catch (Exception $e) {
|
||||
$api_alive = false;
|
||||
}
|
||||
@endphp
|
||||
@if (!$api_alive)
|
||||
@include('components.errors.api-error')
|
||||
@else
|
||||
@php
|
||||
$data = json_decode(file_get_contents($api_root.'/weather'));
|
||||
$updated = gmdate('H:i Y-m-d', $data->updated);
|
||||
$data = $data->current;
|
||||
@endphp
|
||||
<table class="info-table" role="presentation">
|
||||
<caption>
|
||||
<h2>Local Weather</h2>
|
||||
<hr>
|
||||
</caption>
|
||||
<tr>
|
||||
<td><b>Wind Speed:</b></td>
|
||||
<td>{{ $data->wind->speed }} mph</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Wind Direction:</b></td>
|
||||
<td>{{ $data->wind->direction->degrees }}°, {{ $data->wind->direction->cardinal }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Temperature:</b></td>
|
||||
<td>{{ $data->temperature }}°C</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Rain Rate:</b></td>
|
||||
<td>{{ $data->rain_rate }} mm/hr</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Humidity:</b></td>
|
||||
<td>{{ $data->humidity }}%</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<small><i>(Last Update: {{ $updated }})</i></small>
|
||||
@endif
|
||||
@stop
|
109
routes/web.php
109
routes/web.php
|
@ -1,8 +1,15 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use App\Http\Controllers\AdminBookmarksController;
|
||||
use App\Http\Controllers\AdminGuestbookController;
|
||||
use App\Http\Controllers\AdminImportController;
|
||||
use App\Http\Controllers\BookmarksController;
|
||||
use App\Http\Controllers\CalculatorsController;
|
||||
use App\Http\Controllers\ComputersController;
|
||||
use App\Http\Controllers\GuestbookController;
|
||||
use App\Http\Controllers\HomeController;
|
||||
use App\Http\Controllers\MusicController;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use Illuminate\Support\Facades\View;
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
|
@ -15,87 +22,23 @@
|
|||
|
|
||||
*/
|
||||
|
||||
Route::get('/', function () {
|
||||
return View::make('pages.home');
|
||||
});
|
||||
|
||||
Route::get('/bookmarks', function () {
|
||||
return View::make('pages.bookmarks');
|
||||
});
|
||||
|
||||
Route::get('/projects', function () {
|
||||
return View::make('pages.projects');
|
||||
});
|
||||
|
||||
Route::get('/calculators', function () {
|
||||
return View::make('pages.calculators');
|
||||
});
|
||||
|
||||
Route::get('/computers', function () {
|
||||
return View::make('pages.computers');
|
||||
});
|
||||
|
||||
Route::get('/guestbook', 'App\Http\Controllers\GuestbookController@guestbook')
|
||||
->name('guestbook');
|
||||
|
||||
Route::post('/guestbook', 'App\Http\Controllers\GuestbookController@guestbookpost')
|
||||
->name('guestbookPost')
|
||||
Route::get('/', [HomeController::class, 'show']);
|
||||
Route::get('/bookmarks', [BookmarksController::class, 'show']);
|
||||
Route::get('/guestbook', [GuestbookController::class, 'show']);
|
||||
Route::post('/guestbook', [GuestbookController::class, 'addEntry'])
|
||||
->middleware('rate_limit');
|
||||
Route::get('/calculators', [CalculatorsController::class, 'show']);
|
||||
Route::get('/computers', [ComputersController::class, 'show']);
|
||||
Route::get('/music', [MusicController::class, 'show']);
|
||||
|
||||
Route::get('/weather', function () {
|
||||
return View::make('pages.weather');
|
||||
});
|
||||
|
||||
Route::get('/music', function () {
|
||||
return View::make('pages.music');
|
||||
});
|
||||
|
||||
Route::get('/bot', function () {
|
||||
return View::make('pages.bot');
|
||||
});
|
||||
|
||||
/* ------------------------------ Admin Routes ------------------------------ */
|
||||
|
||||
//Route::get('/admin', function () {
|
||||
// if (!auth()->check()) {
|
||||
// return View::make('errors.no-auth');
|
||||
// }
|
||||
// return View::make('pages.admin.index');
|
||||
//});
|
||||
//
|
||||
//Route::get('/admin/guestbook', function () {
|
||||
// if (!auth()->check()) {
|
||||
// return View::make('errors.no-auth');
|
||||
// }
|
||||
// return View::make('pages.admin.guestbook');
|
||||
//});
|
||||
//
|
||||
//Route::get('/admin/guestbook/delete', function () {
|
||||
// if (!auth()->check()) {
|
||||
// return View::make('errors.no-auth');
|
||||
// }
|
||||
//
|
||||
// $id = request()->input('id');
|
||||
// $entry = DB::table('guestbook__entries')->find($id);
|
||||
//
|
||||
// if ($entry) {
|
||||
// // Render a confirmation view
|
||||
// return View::make('pages.admin.guestbook-del-confirm', compact('entry'));
|
||||
// } else {
|
||||
// return View::make('errors.generic-error')
|
||||
// ->with('error', "Entry not found")
|
||||
// ->with('description', "The specified entry does not exist!");
|
||||
// }
|
||||
//});
|
||||
//
|
||||
//Route::post('/admin/guestbook/delete', function () {
|
||||
// if (!auth()->check()) {
|
||||
// return View::make('errors.no-auth');
|
||||
// }
|
||||
//
|
||||
// $id = request()->input('id');
|
||||
// DB::table('guestbook__entries')->where('id', $id)->delete();
|
||||
//
|
||||
// return back()->with('success', 'Entry deleted successfully!');
|
||||
//});
|
||||
// Admin pages
|
||||
Route::get('/admin/guestbook', [AdminGuestbookController::class, 'show'])
|
||||
->middleware('auth');
|
||||
Route::get('/admin/bookmarks', [AdminBookmarksController::class, 'show'])
|
||||
->middleware('auth');
|
||||
Route::get('/admin/import', [AdminImportController::class, 'show'])
|
||||
->middleware('auth');
|
||||
Route::post('/admin/import', [AdminImportController::class, 'submit'])
|
||||
->name('admin.import.submit')
|
||||
->middleware('auth');
|
||||
|
||||
|
|
|
@ -2,3 +2,4 @@ php artisan config:cache
|
|||
php artisan route:cache
|
||||
php artisan view:cache
|
||||
php artisan event:cache
|
||||
php artisan cache:clear
|
||||
|
|
Loading…
Reference in a new issue