diff options
Diffstat (limited to 'app')
-rw-r--r-- | app/Http/Controllers/BookmarksController.php | 15 | ||||
-rw-r--r-- | app/Http/Controllers/CalculatorsController.php | 13 | ||||
-rw-r--r-- | app/Http/Controllers/ComputersController.php | 13 | ||||
-rw-r--r-- | app/Http/Controllers/GuestbookController.php | 49 | ||||
-rw-r--r-- | app/Http/Controllers/HomeController.php | 33 | ||||
-rw-r--r-- | app/Http/Controllers/MusicController.php | 69 | ||||
-rw-r--r-- | app/Http/Middleware/RateLimiter.php | 3 | ||||
-rw-r--r-- | app/Models/BookmarkCategory.php | 36 | ||||
-rw-r--r-- | app/Models/BookmarkSite.php | 35 | ||||
-rw-r--r-- | app/Models/GuestbookEntry.php | 50 | ||||
-rw-r--r-- | app/Models/User.php | 45 | ||||
-rw-r--r-- | app/Providers/AppServiceProvider.php | 13 | ||||
-rw-r--r-- | app/View/Components/CurrentTrack.php | 27 | ||||
-rw-r--r-- | app/View/Components/DiscordStatus.php | 68 | ||||
-rw-r--r-- | app/View/Components/Layout.php | 26 | ||||
-rw-r--r-- | app/View/Components/Navbar.php | 27 | ||||
-rw-r--r-- | app/View/Components/NeverSaid.php | 34 | ||||
-rw-r--r-- | app/View/Components/TohQuote.php | 35 | ||||
-rw-r--r-- | app/View/Components/TopTracks.php | 27 | ||||
-rw-r--r-- | app/View/Components/Track.php | 29 | ||||
-rw-r--r-- | app/View/Components/Weather.php | 50 |
21 files changed, 624 insertions, 73 deletions
diff --git a/app/Http/Controllers/BookmarksController.php b/app/Http/Controllers/BookmarksController.php new file mode 100644 index 0000000..56aacc7 --- /dev/null +++ b/app/Http/Controllers/BookmarksController.php @@ -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')); + } +} diff --git a/app/Http/Controllers/CalculatorsController.php b/app/Http/Controllers/CalculatorsController.php new file mode 100644 index 0000000..38a7a41 --- /dev/null +++ b/app/Http/Controllers/CalculatorsController.php @@ -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'); + } +} diff --git a/app/Http/Controllers/ComputersController.php b/app/Http/Controllers/ComputersController.php new file mode 100644 index 0000000..e16e70d --- /dev/null +++ b/app/Http/Controllers/ComputersController.php @@ -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'); + } +} diff --git a/app/Http/Controllers/GuestbookController.php b/app/Http/Controllers/GuestbookController.php index 70707d7..df726ef 100644 --- a/app/Http/Controllers/GuestbookController.php +++ b/app/Http/Controllers/GuestbookController.php @@ -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); + // } + } } diff --git a/app/Http/Controllers/HomeController.php b/app/Http/Controllers/HomeController.php new file mode 100644 index 0000000..e046d58 --- /dev/null +++ b/app/Http/Controllers/HomeController.php @@ -0,0 +1,33 @@ +<?php + +namespace App\Http\Controllers; + +use Illuminate\Support\Facades\Cache; +use Illuminate\Support\Facades\Config; +use Illuminate\Support\Facades\Http; +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(), + ]); + } +} diff --git a/app/Http/Controllers/MusicController.php b/app/Http/Controllers/MusicController.php new file mode 100644 index 0000000..5e31d86 --- /dev/null +++ b/app/Http/Controllers/MusicController.php @@ -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()); + } +} diff --git a/app/Http/Middleware/RateLimiter.php b/app/Http/Middleware/RateLimiter.php index 09eb0a9..821868f 100644 --- a/app/Http/Middleware/RateLimiter.php +++ b/app/Http/Middleware/RateLimiter.php @@ -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; diff --git a/app/Models/BookmarkCategory.php b/app/Models/BookmarkCategory.php new file mode 100644 index 0000000..a8bc8d2 --- /dev/null +++ b/app/Models/BookmarkCategory.php @@ -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(); + } + } +} diff --git a/app/Models/BookmarkSite.php b/app/Models/BookmarkSite.php new file mode 100644 index 0000000..3c9cc5d --- /dev/null +++ b/app/Models/BookmarkSite.php @@ -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(); + } + } +} diff --git a/app/Models/GuestbookEntry.php b/app/Models/GuestbookEntry.php new file mode 100644 index 0000000..f5e2de2 --- /dev/null +++ b/app/Models/GuestbookEntry.php @@ -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(); + } + } +} diff --git a/app/Models/User.php b/app/Models/User.php deleted file mode 100644 index 4d7f70f..0000000 --- a/app/Models/User.php +++ /dev/null @@ -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', - ]; -} diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 452e6b6..2209133 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -2,23 +2,20 @@ namespace App\Providers; +use Illuminate\Support\Facades\Config; use Illuminate\Support\ServiceProvider; +use PostHog\PostHog; -class AppServiceProvider extends ServiceProvider -{ +class AppServiceProvider extends ServiceProvider { /** * Register any application services. */ - public function register(): void - { + public function register(): void { // } /** * Bootstrap any application services. */ - public function boot(): void - { - // - } + public function boot(): void {} } diff --git a/app/View/Components/CurrentTrack.php b/app/View/Components/CurrentTrack.php new file mode 100644 index 0000000..337809a --- /dev/null +++ b/app/View/Components/CurrentTrack.php @@ -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'); + } +} diff --git a/app/View/Components/DiscordStatus.php b/app/View/Components/DiscordStatus.php new file mode 100644 index 0000000..3ad3a3b --- /dev/null +++ b/app/View/Components/DiscordStatus.php @@ -0,0 +1,68 @@ +<?php + +namespace App\View\Components; + +use Closure; +use Illuminate\Contracts\View\View; +use Illuminate\Support\Facades\Cache; +use Illuminate\Support\Facades\Config; +use Illuminate\Support\Facades\Http; +use Illuminate\View\Component; + +class DiscordStatus extends Component +{ + /** + * Create a new component instance. + */ + public function __construct() + { + // + } + + /** + * Returns current Discord presence from Lanyard API + * @return array|mixed + */ + public function getDiscordPresence(): mixed { + // If it's already cached just return that + if (Cache::has('discord_presence')) { + return Cache::get('discord_presence'); + } + + $response = Http::get('https://api.lanyard.rest/v1/users/' . Config::get('services.lanyard.user_id')); + $data = $response->json(); + if (!isset($data["data"])) return null; + $presence = $data["data"]; + Cache::put('discord_presence', $presence, now()->addSeconds(60)); + return $presence; + } + + public function getOnlineStatus(): ?array { + $presence = $this->getDiscordPresence(); + if ($presence == null) return null; + return match ($presence["discord_status"]) { + "online", "dnd" => [ + "text" => "online", + "color" => "#02c83a" + ], + "idle" => [ + "text" => "away", + "color" => "#d77c20" + ], + default => [ + "text" => "offline", + "color" => "#ca3329" + ], + }; + } + + /** + * Get the view / contents that represent the component. + */ + public function render(): View|Closure|string + { + return view('components.discord-status', [ + 'status' => $this->getOnlineStatus(), + ]); + } +} diff --git a/app/View/Components/Layout.php b/app/View/Components/Layout.php new file mode 100644 index 0000000..576d1a0 --- /dev/null +++ b/app/View/Components/Layout.php @@ -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'); + } +} diff --git a/app/View/Components/Navbar.php b/app/View/Components/Navbar.php new file mode 100644 index 0000000..7f119fe --- /dev/null +++ b/app/View/Components/Navbar.php @@ -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.navigation'); + } +} diff --git a/app/View/Components/NeverSaid.php b/app/View/Components/NeverSaid.php new file mode 100644 index 0000000..c9e1006 --- /dev/null +++ b/app/View/Components/NeverSaid.php @@ -0,0 +1,34 @@ +<?php + +namespace App\View\Components; + +use Closure; +use Illuminate\Contracts\View\View; +use Illuminate\View\Component; + +class NeverSaid extends Component +{ + /** + * Create a new component instance. + */ + public function __construct() + { + // + } + + function returnQuote(): array { + $quotes = config('quotes.neversaid'); + $index = rand(0, count($quotes) - 1); + return $quotes[$index]; + } + + /** + * Get the view / contents that represent the component. + */ + public function render(): View|Closure|string + { + return view('components.never-said', [ + "quote" => $this->returnQuote() + ]); + } +} diff --git a/app/View/Components/TohQuote.php b/app/View/Components/TohQuote.php new file mode 100644 index 0000000..a53d713 --- /dev/null +++ b/app/View/Components/TohQuote.php @@ -0,0 +1,35 @@ +<?php + +namespace App\View\Components; + +use Closure; +use Illuminate\Contracts\View\View; +use Illuminate\View\Component; + +class TohQuote extends Component +{ + /** + * Create a new component instance. + */ + public function __construct() + { + // + } + + function returnQuote(): array { + $quotes = config('quotes.toh'); + $index = rand(0, count($quotes) - 1); + return $quotes[$index]; + } + + + /** + * Get the view / contents that represent the component. + */ + public function render(): View|Closure|string + { + return view('components.toh-quote',[ + 'quote' => $this->returnQuote() + ]); + } +} diff --git a/app/View/Components/TopTracks.php b/app/View/Components/TopTracks.php new file mode 100644 index 0000000..768ce33 --- /dev/null +++ b/app/View/Components/TopTracks.php @@ -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'); + } +} diff --git a/app/View/Components/Track.php b/app/View/Components/Track.php new file mode 100644 index 0000000..b9f628f --- /dev/null +++ b/app/View/Components/Track.php @@ -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'); + } +} diff --git a/app/View/Components/Weather.php b/app/View/Components/Weather.php new file mode 100644 index 0000000..dcf3ff7 --- /dev/null +++ b/app/View/Components/Weather.php @@ -0,0 +1,50 @@ +<?php + +namespace App\View\Components; + +use Closure; +use Exception; +use Illuminate\Contracts\View\View; +use Illuminate\Support\Facades\Cache; +use Illuminate\Support\Facades\Config; +use Illuminate\Support\Facades\Http; +use Illuminate\View\Component; + +class Weather extends Component +{ + /** + * Create a new component instance. + */ + public function __construct() + { + // + } + + public function getWeatherData(): mixed { + // If it's already cached just return that + if (Cache::has('weather_data')) { + return Cache::get('weather_data'); + } + + try { + $response = Http::get('http://' . Config::get('services.weatherlink') . '/v1/current_conditions'); + $data = $response->json(); + $conditions = $data["data"]["conditions"]; + Cache::put('weather_data', $conditions, now()->addSeconds(60)); + return $conditions; + } catch (Exception $ex) { + return null; + } + + } + + /** + * Get the view / contents that represent the component. + */ + public function render(): View|Closure|string + { + return view('components.weather', [ + 'conditions' => $this->getWeatherData(), + ]); + } +} |