ForRo/app/Http/Controllers/LocationController.php

264 lines
10 KiB
PHP
Raw Normal View History

<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Location;
use Ramsey\Uuid\Uuid;
use Illuminate\Support\Facades\Auth;
use App\Models\Source;
class LocationController extends Controller
{
public function addLocation(Request $request)
{
$fields = $request->validate([
'name' => ['required'],
'url' => ['required'],
'description' => ['required'],
'tags' => ['required'],
]);
if ($fields) {
$examples = [];
$files = $request->files->get("loc_examples");
if ($request->hasfile('loc_examples')) {
foreach ($request->file('loc_examples') as $file) {
$path = $file->store('reference');
array_push($examples, ["path" => $path]);
}
}
$request->merge(['active' => true]);
$request->merge(['uuid' => Uuid::uuid4()]);
$request->merge(['images' => json_encode($examples)]);
$request->merge(['added_by' => Auth::user()->id]);
//NOTE: Laravel gets funky if sequencing isn't explicitly set
$new = Location::create($request->all());
if ($new) {
return back()->with('message', 'New Location Added. Take a break!');
} else {
return back()->withErrors([
'error' => 'Uh oh. There was an inssue',
]);
}
} else {
return back()->withErrors([
'error' => 'All fields are required',
]);
}
}
public function updateLocations()
{
$duplicates = 0;
$fresh = 0;
$missing = [];
$unified = [];
$cleanSources = [];
$sources = Source::where("active", true)->get();
//checks source url to make sure they valid
foreach ($sources as $source) {
if ($source->type == 'mastodon') {
$url = 'https://' . $source->url;
} else {
$url = $source->url;
}
if ($this->urlExists($url)) {
array_push($cleanSources, [
'url' => $source->url,
'token' => $source->token,
'type' => $source->type,
'format' => $source->format]);
} else {
var_dump($url);
array_push($missing, ['source' => $url]);
}
}
//valid source url get compiled for unified
foreach ($cleanSources as $source) {
//check url to make sure it's cool
//parsing for mastodon
if ($source['type'] == 'mastodon') {
$result = [];
if ($source['token'] == null) {
$result = \Mastodon::domain('https://' . $source['url'])
->get('/instance/domain_blocks');
} else {
$result = \Mastodon::domain('https://' . $source['url'])
->token($source['token'])
->get('/instance/domain_blocks');
}
foreach ($result as $item) {
$index = array_search($item['domain'], array_column($unified, 'url'));
if ($index) {
//if there is a match, update the count
if ($item['severity'] == "suspend" || $item['severity'] == "defederate") {
++$unified[$index]['block_count'];
} else {
++$unified[$index]['silence_count'];
}
} else {
$silence = 0;
$suspend = 0;
if ($item['severity'] == "suspend" || $item['severity'] == "defederate") {
++$suspend;
} else {
++$silence;
}
array_push($unified, [
'name' => $item['domain'],
'url' => $item['domain'],
'rating' => $item['severity'],
'comment' => $item['comment'],
'block_count' => $suspend,
'silence_count' => $silence,
]);
}
}
}
//parsing for custom csv
if ($source['type'] == 'custom' && $source['format'] == 'csv') {
$denylist = array_map('str_getcsv', file($source['url']));
foreach ($denylist as $item) {
$index = array_search($item[0], array_column($unified, 'url'));
if ($index) {
//if there is a match, update the count
if ($item[1] == "suspend" || $item['severity'] == "defederate") {
++$unified[$index]['block_count'];
} else {
++$unified[$index]['silence_count'];
}
} else {
$silence = 0;
$suspend = 0;
if ($item[1] == "suspend" || $item[1] == "defederate") {
++$suspend;
} else {
++$silence;
}
array_push($unified, [
'name' => $item[0],
'url' => $item[0],
'rating' => $item[1],
'comment' => $item[2],
'block_count' => $suspend,
'silence_count' => $silence,
]);
}
}
}
}
//TODO: maintenance script to set locations to inactive if they haven't been updated
// over 90 days
//$diff=date_diff($location->updated_at, new DateTime());
//$days = $diff->format("%R%a days")
//$interval = $location->updated_at->diff(new DateTime());
//$days = $interval->format("%a");
//get all locations and sort which are present in unified or not
/*
$sorted = [];
$listed = 0;
$notlisted = 0;
foreach (Location::all() as $location) {
if (array_search($location->url, array_column($unified, 'url'))) {
++$listed;
// locations present in unfied, so updated
array_push($sorted, [
'location' => $location,
'listed' => true
]);
} else {
++$notlisted;
//locations not present
array_push($sorted, [
'location' => $location,
'listed' => false
]);
}
};
*/
//once the unified list is created, update current entries or create fresh ones
foreach ($unified as $item) {
$location = Location::where("url", $item['url'])->first();
if ($location) {
++$duplicates;
//update block count for existing item
$location->block_count = $item['block_count'];
$location->silence_count = $item['silence_count'];
$location->actions_count = $item['block_count'] + $item['silence_count'];
if (($item['block_count'] + $item['silence_count']) < 2) {
$location->active = false;
}
//replace null with empty array
if ($location->images == null) {
$location->images = [];
};
$location->save();
} else {
// make new entries for instances not present
++$fresh;
$images = [];
$rating = ($item['rating'] == 'defederate') ? 'suspend' : $item['rating'];
$status = true;
if (($item['block_count'] + $item['silence_count']) < 2) {
$status = false;
}
$new = Location::create([
'uuid' => Uuid::uuid4(),
'name' => $item['url'],
'url' => $item['url'],
'description' => ($item['comment'] != null) ? $item['comment'] : "no description",
'active' => $status,
'rating' => $rating,
'added_by' => 1,
'tags' => 'poor moderation, hate speech',
'images' => json_encode($images),
'block_count' => $item['block_count'],
'silence_count' => $item['silence_count'],
'actions_cont' => $item['block_count'] + $item['silence_count']
]);
}
}
//TODO: Send update post to TBS social account
return back()->with('message', $duplicates . ' UPDATED - ' . $fresh . ' CREATED - ' . count($missing) . ' SOURCE(S) NOT CHECKED');
}
public function urlExists($url)
{
// Remove all illegal characters from a url
$url = filter_var($url, FILTER_SANITIZE_URL);
// Validate URI
if (
filter_var($url, FILTER_VALIDATE_URL) === false || // check only for http/https schemes.
!in_array(
strtolower(parse_url($url, PHP_URL_SCHEME)),
["http", "https"],
true
)
) {
return false;
} // Check that URL exists
$file_headers = @get_headers($url);
return !(!$file_headers || $file_headers[0] === "HTTP/1.1 404 Not Found");
}
}