diff options
author | Frankie B <git@diskfloppy.me> | 2024-06-11 18:02:01 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-06-11 18:02:01 +0100 |
commit | 0f52d80ca67a49258b235f5831163dd72fbd54cf (patch) | |
tree | 9c5cd36b6e0a233e09ac88a4409fb68c63e4781a /app | |
parent | a64bcc2c4639d5804b6dada23151bfcb8b198121 (diff) |
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
Diffstat (limited to 'app')
-rw-r--r-- | app/Http/Controllers/AdminBookmarksController.php | 15 | ||||
-rw-r--r-- | app/Http/Controllers/AdminGuestbookController.php | 34 | ||||
-rw-r--r-- | app/Http/Controllers/AdminImportController.php | 69 | ||||
-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 | 32 | ||||
-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/View/Components/CurrentTrack.php | 27 | ||||
-rw-r--r-- | app/View/Components/Layout.php | 26 | ||||
-rw-r--r-- | app/View/Components/Navbar.php | 27 | ||||
-rw-r--r-- | app/View/Components/TopTracks.php | 27 | ||||
-rw-r--r-- | app/View/Components/Track.php | 29 |
19 files changed, 549 insertions, 65 deletions
diff --git a/app/Http/Controllers/AdminBookmarksController.php b/app/Http/Controllers/AdminBookmarksController.php new file mode 100644 index 0000000..c7d8afd --- /dev/null +++ b/app/Http/Controllers/AdminBookmarksController.php @@ -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')); + } +} diff --git a/app/Http/Controllers/AdminGuestbookController.php b/app/Http/Controllers/AdminGuestbookController.php new file mode 100644 index 0000000..5ebf451 --- /dev/null +++ b/app/Http/Controllers/AdminGuestbookController.php @@ -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, + ]); + } +} diff --git a/app/Http/Controllers/AdminImportController.php b/app/Http/Controllers/AdminImportController.php new file mode 100644 index 0000000..dc32cec --- /dev/null +++ b/app/Http/Controllers/AdminImportController.php @@ -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)"); + } + } +} 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..3fad094 --- /dev/null +++ b/app/Http/Controllers/HomeController.php @@ -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() + ]); + } +} 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/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/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..a19db3b --- /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.navbar'); + } +} 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'); + } +} |