Merge branch 'release/0.5.17'

This commit is contained in:
Jonny Barnes 2017-06-22 17:45:57 +01:00
commit aa126d728d
44 changed files with 4879 additions and 4500 deletions

View file

@ -14,6 +14,7 @@ addons:
packages:
- nginx
- realpath
- postgresql-9.6-postgis-2.3
artifacts:
s3_region: "eu-west-1"
paths:

View file

@ -62,29 +62,29 @@ class MicropubController extends Controller
// Log the request
Log::debug($request);
if ($tokenData->hasClaim('scope')) {
if (($request->input('h') == 'entry') || ($request->input('type')[0] == 'h-entry')) {
if (($request->input('h') == 'entry') || ($request->input('type.0') == 'h-entry')) {
if (stristr($tokenData->getClaim('scope'), 'create') === false) {
return $this->returnInsufficientScopeResponse();
}
$data = [];
$data['client-id'] = $tokenData->getClaim('client_id');
if ($request->header('Content-Type') == 'application/json') {
if (is_string($request->input('properties.content')[0])) {
$data['content'] = $request->input('properties.content')[0]; //plaintext content
if (is_string($request->input('properties.content.0'))) {
$data['content'] = $request->input('properties.content.0'); //plaintext content
}
if (is_array($request->input('properties.content')[0])
&& array_key_exists('html', $request->input('properties.content')[0])
if (is_array($request->input('properties.content.0'))
&& array_key_exists('html', $request->input('properties.content.0'))
) {
$data['content'] = $request->input('properties.content')[0]['html'];
$data['content'] = $request->input('properties.content.0.html');
}
$data['in-reply-to'] = $request->input('properties.in-reply-to')[0];
$data['in-reply-to'] = $request->input('properties.in-reply-to.0');
// check location is geo: string
if (is_string($request->input('properties.location.0'))) {
$data['location'] = $request->input('properties.location.0');
}
// check location is h-card
if (is_array($request->input('properties.location.0'))) {
if ($request->input('properties.location.0.type' === 'h-card')) {
if ($request->input('properties.location.0.type.0' === 'h-card')) {
try {
$place = $this->placeService->createPlaceFromCheckin($request->input('properties.location.0'));
$data['checkin'] = $place->longurl;
@ -93,7 +93,7 @@ class MicropubController extends Controller
}
}
}
$data['published'] = $request->input('properties.published')[0];
$data['published'] = $request->input('properties.published.0');
//create checkin place
if (array_key_exists('checkin', $request->input('properties'))) {
$data['swarm-url'] = $request->input('properties.syndication.0');
@ -374,7 +374,7 @@ class MicropubController extends Controller
//check post scope
if ($tokenData->hasClaim('scope')) {
if (stristr($token->getClaim('scope'), 'post') === false) {
if (stristr($tokenData->getClaim('scope'), 'create') === false) {
return $this->returnInsufficientScopeResponse();
}
//check media valid

View file

@ -2,16 +2,9 @@
namespace App\Http\Controllers;
use Twitter;
use HTMLPurifier;
use App\{Note, Tag};
use GuzzleHttp\Client;
use HTMLPurifier_Config;
use App\Note;
use Illuminate\Http\Request;
use Jonnybarnes\IndieWeb\Numbers;
use Illuminate\Filesystem\Filesystem;
use Illuminate\Support\Facades\Cache;
use Jonnybarnes\WebmentionsParser\Authorship;
// Need to sort out Twitter and webmentions!
@ -25,41 +18,13 @@ class NotesController extends Controller
*/
public function index(Request $request)
{
$notes = Note::orderBy('id', 'desc')->with('webmentions', 'place', 'media')->paginate(10);
foreach ($notes as $note) {
$replies = 0;
foreach ($note->webmentions as $webmention) {
if ($webmention->type == 'in-reply-to') {
$replies++;
}
}
$note->replies = $replies;
$note->twitter = $this->checkTwitterReply($note->in_reply_to);
$note->iso8601_time = $note->updated_at->toISO8601String();
$note->human_time = $note->updated_at->diffForHumans();
if ($note->location && ($note->place === null)) {
$pieces = explode(':', $note->location);
$latlng = explode(',', $pieces[0]);
$note->latitude = trim($latlng[0]);
$note->longitude = trim($latlng[1]);
$note->address = $this->reverseGeoCode((float) trim($latlng[0]), (float) trim($latlng[1]));
}
if ($note->place !== null) {
$lnglat = explode(' ', $note->place->location);
$note->latitude = $lnglat[1];
$note->longitude = $lnglat[0];
$note->address = $note->place->name;
$note->placeLink = '/places/' . $note->place->slug;
}
/*$mediaLinks = [];
foreach ($note->media()->get() as $media) {
$mediaLinks[] = $media->url;
}*/
}
$notes = Note::orderBy('id', 'desc')
->with('place', 'media', 'client')
->withCount(['webmentions As replies' => function ($query) {
$query->where('type', 'in-reply-to');
}])->paginate(10);
$homepage = ($request->path() == '/');
return view('notes.index', compact('notes', 'homepage'));
return view('notes.index', compact('notes'));
}
/**
@ -70,90 +35,9 @@ class NotesController extends Controller
*/
public function show($urlId)
{
$numbers = new Numbers();
$authorship = new Authorship();
$realId = $numbers->b60tonum($urlId);
$note = Note::find($realId);
$replies = [];
$reposts = [];
$likes = [];
$carbon = new \Carbon\Carbon();
foreach ($note->webmentions as $webmention) {
/*
reply->url |
reply->photo | Author
reply->name |
reply->source
reply->date
reply->reply
$note = Note::nb60($urlId)->with('webmentions')->first();
repost->url |
repost->photo | Author
repost->name |
repost->date
repost->source
like->url |
like->photo | Author
like->name |
*/
$microformats = json_decode($webmention->mf2, true);
$authorHCard = $authorship->findAuthor($microformats);
$content['url'] = $authorHCard['properties']['url'][0];
$content['photo'] = $this->createPhotoLink($authorHCard['properties']['photo'][0]);
$content['name'] = $authorHCard['properties']['name'][0];
switch ($webmention->type) {
case 'in-reply-to':
$content['source'] = $webmention->source;
if (isset($microformats['items'][0]['properties']['published'][0])) {
try {
$content['date'] = $carbon->parse(
$microformats['items'][0]['properties']['published'][0]
)->toDayDateTimeString();
} catch (\Exception $exception) {
$content['date'] = $webmention->updated_at->toDayDateTimeString();
}
} else {
$content['date'] = $webmention->updated_at->toDayDateTimeString();
}
$content['reply'] = $this->filterHTML(
$microformats['items'][0]['properties']['content'][0]['html']
);
$replies[] = $content;
break;
case 'repost-of':
$content['date'] = $carbon->parse(
$microformats['items'][0]['properties']['published'][0]
)->toDayDateTimeString();
$content['source'] = $webmention->source;
$reposts[] = $content;
break;
case 'like-of':
$likes[] = $content;
break;
}
}
$note->twitter = $this->checkTwitterReply($note->in_reply_to);
$note->iso8601_time = $note->updated_at->toISO8601String();
$note->human_time = $note->updated_at->diffForHumans();
if ($note->location && ($note->place === null)) {
$pieces = explode(':', $note->location);
$latlng = explode(',', $pieces[0]);
$note->latitude = trim($latlng[0]);
$note->longitude = trim($latlng[1]);
$note->address = $this->reverseGeoCode((float) trim($latlng[0]), (float) trim($latlng[1]));
}
if ($note->place !== null) {
$lnglat = explode(' ', $note->place->location);
$note->latitude = $lnglat[1];
$note->longitude = $lnglat[0];
$note->address = $note->place->name;
$note->placeLink = '/places/' . $note->place->slug;
}
return view('notes.show', compact('note', 'replies', 'reposts', 'likes'));
return view('notes.show', compact('note'));
}
/**
@ -164,12 +48,7 @@ class NotesController extends Controller
*/
public function redirect($decId)
{
$numbers = new Numbers();
$realId = $numbers->numto60($decId);
$url = config('app.url') . '/notes/' . $realId;
return redirect($url);
return redirect(config('app.url') . '/notes/' . (new Numbers())->numto60($decId));
}
/**
@ -183,180 +62,7 @@ class NotesController extends Controller
$notes = Note::whereHas('tags', function ($query) use ($tag) {
$query->where('tag', $tag);
})->get();
foreach ($notes as $note) {
$note->iso8601_time = $note->updated_at->toISO8601String();
$note->human_time = $note->updated_at->diffForHumans();
}
return view('notes.tagged', compact('notes', 'tag'));
}
/**
* Create the photo link.
*
* We shall leave twitter.com and twimg.com links as they are. Then we shall
* check for local copies, if that fails leave the link as is.
*
* @param string
* @return string
*/
public function createPhotoLink($url)
{
$host = parse_url($url, PHP_URL_HOST);
if ($host == 'pbs.twimg.com') {
//make sure we use HTTPS, we know twitter supports it
return str_replace('http://', 'https://', $url);
}
if ($host == 'twitter.com') {
if (Cache::has($url)) {
return Cache::get($url);
}
$username = parse_url($url, PHP_URL_PATH);
try {
$info = Twitter::getUsers(['screen_name' => $username]);
$profile_image = $info->profile_image_url_https;
Cache::put($url, $profile_image, 10080); //1 week
} catch (Exception $e) {
return $url; //not sure here
}
return $profile_image;
}
$filesystem = new Filesystem();
if ($filesystem->exists(public_path() . '/assets/profile-images/' . $host . '/image')) {
return '/assets/profile-images/' . $host . '/image';
}
return $url;
}
/**
* Twitter!!!
*
* @param string The reply to URL
* @return string | null
*/
private function checkTwitterReply($url)
{
if ($url == null) {
return;
}
if (mb_substr($url, 0, 20, 'UTF-8') !== 'https://twitter.com/') {
return;
}
$arr = explode('/', $url);
$tweetId = end($arr);
if (Cache::has($tweetId)) {
return Cache::get($tweetId);
}
try {
$oEmbed = Twitter::getOembed([
'id' => $tweetId,
'align' => 'center',
'omit_script' => true,
'maxwidth' => 550,
]);
} catch (\Exception $e) {
return;
}
Cache::put($tweetId, $oEmbed, ($oEmbed->cache_age / 60));
return $oEmbed;
}
/**
* Filter the HTML in a reply webmention.
*
* @param string The reply HTML
* @return string The filtered HTML
*/
private function filterHTML($html)
{
$config = HTMLPurifier_Config::createDefault();
$config->set('Cache.SerializerPath', storage_path() . '/HTMLPurifier');
$config->set('HTML.TargetBlank', true);
$purifier = new HTMLPurifier($config);
return $purifier->purify($html);
}
/**
* Do a reverse geocode lookup of a `lat,lng` value.
*
* @param float The latitude
* @param float The longitude
* @return string The location HTML
*/
public function reverseGeoCode(float $latitude, float $longitude): string
{
$latlng = $latitude . ',' . $longitude;
return Cache::get($latlng, function () use ($latlng, $latitude, $longitude) {
$guzzle = new Client();
$response = $guzzle->request('GET', 'https://nominatim.openstreetmap.org/reverse', [
'query' => [
'format' => 'json',
'lat' => $latitude,
'lon' => $longitude,
'zoom' => 18,
'addressdetails' => 1,
],
'headers' => ['User-Agent' => 'jonnybarnes.uk via Guzzle, email jonny@jonnybarnes.uk'],
]);
$json = json_decode($response->getBody());
if (isset($json->address->town)) {
$address = '<span class="p-locality">'
. $json->address->town
. '</span>, <span class="p-country-name">'
. $json->address->country
. '</span>';
Cache::forever($latlng, $address);
return $address;
}
if (isset($json->address->city)) {
$address = $json->address->city . ', ' . $json->address->country;
Cache::forever($latlng, $address);
return $address;
}
if (isset($json->address->county)) {
$address = '<span class="p-region">'
. $json->address->county
. '</span>, <span class="p-country-name">'
. $json->address->country
. '</span>';
Cache::forever($latlng, $address);
return $address;
}
$adress = '<span class="p-country-name">' . $json->address->country . '</span>';
Cache::forever($latlng, $address);
return $address;
});
}
private function getGeoJson($longitude, $latitude, $title, $icon)
{
$icon = $icon ?? 'marker';
return
"{
'type': 'FeatureCollection',
'features': [{
'type': 'Feature',
'geometry': {
'type': 'Point',
'coordinates': [$longitude, $latitude]
},
'properties': {
'title': '$title',
'icon': '$icon'
}
}]
}";
}
}

View file

@ -0,0 +1,42 @@
<?php
namespace App\Jobs;
use App\MicropubClient;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
class AddClientToDatabase implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected $client_id;
/**
* Create a new job instance.
*
* @return void
*/
public function __construct(string $client_id)
{
$this->client_id = $client_id;
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
if (MicropubClient::where('client_url', $this->client_id)->count() == 0) {
$client = MicropubClient::create([
'client_url' => $this->client_id,
'client_name' => $this->client_id, // default client name is the URL
]);
}
}
}

View file

@ -3,16 +3,14 @@
namespace App\Jobs;
use Mf2;
use App\Note;
use App\WebMention;
use GuzzleHttp\Client;
use App\{Note, WebMention};
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Jonnybarnes\WebmentionsParser\Parser;
use GuzzleHttp\Exception\RequestException;
use Illuminate\Contracts\Queue\ShouldQueue;
use App\Exceptions\RemoteContentNotFoundException;
use Illuminate\Queue\{InteractsWithQueue, SerializesModels};
class ProcessWebMention implements ShouldQueue
{

View file

@ -19,4 +19,14 @@ class MicropubClient extends Model
* @var array
*/
protected $fillable = ['client_url', 'client_name'];
/**
* Define the relationship with notes.
*
* @return void
*/
public function notes()
{
return $this->hasMany('App\Note', 'client_id', 'client_url');
}
}

View file

@ -2,7 +2,10 @@
namespace App;
use Cache;
use Twitter;
use Normalizer;
use GuzzleHttp\Client;
use Laravel\Scout\Searchable;
use Jonnybarnes\IndieWeb\Numbers;
use Illuminate\Database\Eloquent\Model;
@ -33,6 +36,16 @@ class Note extends Model
return $this->belongsToMany('App\Tag');
}
/**
* Define the relationship with clients.
*
* @var array?
*/
public function client()
{
return $this->belongsTo('App\MicropubClient', 'client_id', 'client_url');
}
/**
* Define the relationship with webmentions.
*
@ -96,17 +109,6 @@ class Note extends Model
];
}
/**
* A mutator to ensure that in-reply-to is always non-empty or null.
*
* @param string value
* @return string
*/
public function setInReplyToAttribute($value)
{
$this->attributes['in_reply_to'] = empty($value) ? null : $value;
}
/**
* Normalize the note to Unicode FORM C.
*
@ -168,6 +170,26 @@ class Note extends Model
return config('app.shorturl') . '/notes/' . $this->nb60id;
}
/**
* Get the ISO8601 value for mf2.
*
* @return string
*/
public function getIso8601Attribute()
{
return $this->updated_at->toISO8601String();
}
/**
* Get the ISO8601 value for mf2.
*
* @return string
*/
public function getHumandiffAttribute()
{
return $this->updated_at->diffForHumans();
}
/**
* Get the pubdate value for RSS feeds.
*
@ -179,26 +201,85 @@ class Note extends Model
}
/**
* Get the relavent client name assocaited with the client id.
* Get the latitude value.
*
* @return string|null
*/
public function getClientNameAttribute()
public function getLatitudeAttribute()
{
if ($this->client_id == null) {
if ($this->place !== null) {
$lnglat = explode(' ', $this->place->location);
return $lnglat[1];
}
if ($this->location !== null) {
$pieces = explode(':', $this->location);
$latlng = explode(',', $pieces[0]);
return trim($latlng[0]);
}
}
/**
* Get the longitude value.
*
* @return string|null
*/
public function getLongitudeAttribute()
{
if ($this->place !== null) {
$lnglat = explode(' ', $this->place->location);
return $lnglat[1];
}
if ($this->location !== null) {
$pieces = explode(':', $this->location);
$latlng = explode(',', $pieces[0]);
return trim($latlng[1]);
}
}
/**
* Get the address for a note. This is either a reverse geo-code from the
* location, or is derived from the associated place.
*
* @return string|null
*/
public function getAddressAttribute()
{
if ($this->place !== null) {
return $this->place->name;
}
if ($this->location !== null) {
return $this->reverseGeoCode((float) $this->latitude, (float) $this->longitude);
}
}
public function getTwitterAttribute()
{
if ($this->in_reply_to == null || mb_substr($this->in_reply_to, 0, 20, 'UTF-8') !== 'https://twitter.com/') {
return;
}
$name = MicropubClient::where('client_url', $this->client_id)->value('client_name');
if ($name == null) {
$url = parse_url($this->client_id);
if (isset($url['path'])) {
return $url['host'] . $url['path'];
}
return $url['host'];
$arr = explode('/', $url);
$tweetId = end($arr);
if (Cache::has($tweetId)) {
return Cache::get($tweetId);
}
try {
$oEmbed = Twitter::getOembed([
'id' => $tweetId,
'align' => 'center',
'omit_script' => true,
'maxwidth' => 550,
]);
} catch (\Exception $e) {
return;
}
Cache::put($tweetId, $oEmbed, ($oEmbed->cache_age / 60));
return $name;
return $oEmbed;
}
/**
@ -284,4 +365,61 @@ class Note extends Model
return $text;
}
/**
* Do a reverse geocode lookup of a `lat,lng` value.
*
* @param float The latitude
* @param float The longitude
* @return string The location HTML
*/
public function reverseGeoCode(float $latitude, float $longitude): string
{
$latlng = $latitude . ',' . $longitude;
return Cache::get($latlng, function () use ($latlng, $latitude, $longitude) {
$guzzle = new Client();
$response = $guzzle->request('GET', 'https://nominatim.openstreetmap.org/reverse', [
'query' => [
'format' => 'json',
'lat' => $latitude,
'lon' => $longitude,
'zoom' => 18,
'addressdetails' => 1,
],
'headers' => ['User-Agent' => 'jonnybarnes.uk via Guzzle, email jonny@jonnybarnes.uk'],
]);
$json = json_decode($response->getBody());
if (isset($json->address->town)) {
$address = '<span class="p-locality">'
. $json->address->town
. '</span>, <span class="p-country-name">'
. $json->address->country
. '</span>';
Cache::forever($latlng, $address);
return $address;
}
if (isset($json->address->city)) {
$address = $json->address->city . ', ' . $json->address->country;
Cache::forever($latlng, $address);
return $address;
}
if (isset($json->address->county)) {
$address = '<span class="p-region">'
. $json->address->county
. '</span>, <span class="p-country-name">'
. $json->address->country
. '</span>';
Cache::forever($latlng, $address);
return $address;
}
$adress = '<span class="p-country-name">' . $json->address->country . '</span>';
Cache::forever($latlng, $address);
return $address;
});
}
}

View file

@ -76,19 +76,6 @@ class Place extends Model
return $query->where($field, '<=', $distance)->orderBy($field);
}
/*
* Convert location to text.
*
* @param text $value
* @return text
*
public function getLocationAttribute($value)
{
$result = DB::select(DB::raw("SELECT ST_AsText('$value')"));
return $result[0]->st_astext;
}*/
/**
* Get the latitude from the `location` property.
*

View file

@ -4,6 +4,7 @@ declare(strict_types=1);
namespace App\Services;
use App\Jobs\AddClientToDatabase;
use Lcobucci\JWT\Signer\Hmac\Sha256;
use App\Exceptions\InvalidTokenException;
use Lcobucci\JWT\{Builder, Parser, Token};
@ -26,6 +27,7 @@ class TokenService
->set('nonce', bin2hex(random_bytes(8)))
->sign($signer, config('app.key'))
->getToken();
dispatch(new AddClientToDatabase($data['client_id']));
return (string) $token;
}

View file

@ -2,7 +2,14 @@
namespace App;
use Cache;
use Twitter;
use HTMLPurifier;
use Carbon\Carbon;
use HTMLPurifier_Config;
use Illuminate\Filesystem\Filesystem;
use Illuminate\Database\Eloquent\Model;
use Jonnybarnes\WebmentionsParser\Authorship;
class WebMention extends Model
{
@ -29,4 +36,112 @@ class WebMention extends Model
* @var array
*/
protected $guarded = ['id'];
/**
* Get the author of the webmention.
*
* @return array
*/
public function getAuthorAttribute()
{
$authorship = new Authorship();
$hCard = $authorship->findAuthor(json_decode($this->mf2, true));
if (array_key_exists('properties', $hCard) &&
array_key_exists('photo', $hCard['properties'])
) {
$hCard['properties']['photo'][0] = $this->createPhotoLink($hCard['properties']['photo'][0]);
}
return $hCard;
}
/**
* Get the published value for the webmention.
*
* @return string
*/
public function getPublishedAttribute()
{
$microformats = json_decode($this->mf2, true);
$carbon = new Carbon();
if (isset($microformats['items'][0]['properties']['published'][0])) {
try {
$published = $carbon->parse(
$microformats['items'][0]['properties']['published'][0]
)->toDayDateTimeString();
} catch (\Exception $exception) {
$published = $webmention->updated_at->toDayDateTimeString();
}
} else {
$published = $webmention->updated_at->toDayDateTimeString();
}
return $published;
}
/**
* Get the filteres HTML of a reply.
*
* @return strin|null
*/
public function getReplyAttribute()
{
$microformats = json_decode($this->mf2, true);
if (isset($microformats['items'][0]['properties']['content'][0]['html'])) {
return $this->filterHTML($microformats['items'][0]['properties']['content'][0]['html']);
}
}
/**
* Create the photo link.
*
* @param string
* @return string
*/
public function createPhotoLink(string $url): string
{
$url = normalize_url($url);
$host = parse_url($url, PHP_URL_HOST);
if ($host == 'pbs.twimg.com') {
//make sure we use HTTPS, we know twitter supports it
return str_replace('http://', 'https://', $url);
}
if ($host == 'twitter.com') {
if (Cache::has($url)) {
return Cache::get($url);
}
$username = parse_url($url, PHP_URL_PATH);
try {
$info = Twitter::getUsers(['screen_name' => $username]);
$profile_image = $info->profile_image_url_https;
Cache::put($url, $profile_image, 10080); //1 week
} catch (Exception $e) {
return $url; //not sure here
}
return $profile_image;
}
$filesystem = new Filesystem();
if ($filesystem->exists(public_path() . '/assets/profile-images/' . $host . '/image')) {
return '/assets/profile-images/' . $host . '/image';
}
return $url;
}
/**
* Filter the HTML in a reply webmention.
*
* @param string The reply HTML
* @return string The filtered HTML
*/
private function filterHTML($html)
{
$config = HTMLPurifier_Config::createDefault();
$config->set('Cache.SerializerPath', storage_path() . '/HTMLPurifier');
$config->set('HTML.TargetBlank', true);
$purifier = new HTMLPurifier($config);
return $purifier->purify($html);
}
}

View file

@ -1,6 +1,10 @@
# Changelog
## Version 0.5.16
## Version 0.5.17 (2017-06-22)
- Lots of code tidying, especially in the notes controller
- Fix issue#53 regarding uploading photos
## Version 0.5.16 (2017-06-17)
- Allow place `slug`s to be re-generated
- Add syndication links for swarm and instagram
- Move bio to its own template, next step database?

42
composer.lock generated
View file

@ -8,16 +8,16 @@
"packages": [
{
"name": "aws/aws-sdk-php",
"version": "3.29.2",
"version": "3.29.8",
"source": {
"type": "git",
"url": "https://github.com/aws/aws-sdk-php.git",
"reference": "1f19f74913a31fac8e98c24cef26040a16c88a33"
"reference": "c60a477ad5ba1b120d4d80cbddf97fbe36573996"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/1f19f74913a31fac8e98c24cef26040a16c88a33",
"reference": "1f19f74913a31fac8e98c24cef26040a16c88a33",
"url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/c60a477ad5ba1b120d4d80cbddf97fbe36573996",
"reference": "c60a477ad5ba1b120d4d80cbddf97fbe36573996",
"shasum": ""
},
"require": {
@ -84,7 +84,7 @@
"s3",
"sdk"
],
"time": "2017-06-09T18:57:25+00:00"
"time": "2017-06-19T19:14:37+00:00"
},
{
"name": "barnabywalters/mf-cleaner",
@ -1580,16 +1580,16 @@
},
{
"name": "laravel/framework",
"version": "v5.4.25",
"version": "v5.4.27",
"source": {
"type": "git",
"url": "https://github.com/laravel/framework.git",
"reference": "6bcc9b1f542b3deed16d51f6aa1fe318ab407c2a"
"reference": "66f5e1b37cbd66e730ea18850ded6dc0ad570404"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravel/framework/zipball/6bcc9b1f542b3deed16d51f6aa1fe318ab407c2a",
"reference": "6bcc9b1f542b3deed16d51f6aa1fe318ab407c2a",
"url": "https://api.github.com/repos/laravel/framework/zipball/66f5e1b37cbd66e730ea18850ded6dc0ad570404",
"reference": "66f5e1b37cbd66e730ea18850ded6dc0ad570404",
"shasum": ""
},
"require": {
@ -1705,7 +1705,7 @@
"framework",
"laravel"
],
"time": "2017-06-07T13:35:12+00:00"
"time": "2017-06-15T19:08:25+00:00"
},
{
"name": "laravel/scout",
@ -2144,16 +2144,16 @@
},
{
"name": "monolog/monolog",
"version": "1.22.1",
"version": "1.23.0",
"source": {
"type": "git",
"url": "https://github.com/Seldaek/monolog.git",
"reference": "1e044bc4b34e91743943479f1be7a1d5eb93add0"
"reference": "fd8c787753b3a2ad11bc60c063cff1358a32a3b4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/1e044bc4b34e91743943479f1be7a1d5eb93add0",
"reference": "1e044bc4b34e91743943479f1be7a1d5eb93add0",
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/fd8c787753b3a2ad11bc60c063cff1358a32a3b4",
"reference": "fd8c787753b3a2ad11bc60c063cff1358a32a3b4",
"shasum": ""
},
"require": {
@ -2174,7 +2174,7 @@
"phpunit/phpunit-mock-objects": "2.3.0",
"ruflin/elastica": ">=0.90 <3.0",
"sentry/sentry": "^0.13",
"swiftmailer/swiftmailer": "~5.3"
"swiftmailer/swiftmailer": "^5.3|^6.0"
},
"suggest": {
"aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB",
@ -2218,7 +2218,7 @@
"logging",
"psr-3"
],
"time": "2017-03-13T07:08:03+00:00"
"time": "2017-06-19T01:22:40+00:00"
},
{
"name": "mtdowling/cron-expression",
@ -2725,16 +2725,16 @@
},
{
"name": "psy/psysh",
"version": "v0.8.6",
"version": "v0.8.7",
"source": {
"type": "git",
"url": "https://github.com/bobthecow/psysh.git",
"reference": "7028d6d525fb183d50b249b7c07598e3d386b27d"
"reference": "be969b9dc89dcaefdb9a3117fa91fa38bca19f50"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/bobthecow/psysh/zipball/7028d6d525fb183d50b249b7c07598e3d386b27d",
"reference": "7028d6d525fb183d50b249b7c07598e3d386b27d",
"url": "https://api.github.com/repos/bobthecow/psysh/zipball/be969b9dc89dcaefdb9a3117fa91fa38bca19f50",
"reference": "be969b9dc89dcaefdb9a3117fa91fa38bca19f50",
"shasum": ""
},
"require": {
@ -2794,7 +2794,7 @@
"interactive",
"shell"
],
"time": "2017-06-04T10:34:20+00:00"
"time": "2017-06-20T12:51:31+00:00"
},
{
"name": "ramsey/uuid",

View file

@ -12,7 +12,7 @@ class WebMentionsTableSeeder extends Seeder
public function run()
{
$webmention = App\WebMention::create([
'source' => 'https://aaornpk.local/reply/1',
'source' => 'https://aaornpk.localhost/reply/1',
'target' => 'https://jonnybarnes.localhost/notes/D',
'commentable_id' => '13',
'commentable_type' => 'App\Note',

4430
package-lock.json generated Normal file

File diff suppressed because it is too large Load diff

View file

@ -6,23 +6,23 @@
"license": "CC0-1.0",
"dependencies": {
"alertify.js": "^1.0.12",
"mapbox-gl": "0.37.0",
"mapbox-gl": "^0.38.0",
"marked": "^0.3.6",
"normalize.css": "7.0.0",
"webStorage": "^1.2.2"
"normalize.css": "^7.0.0",
"webStorage": "^1.2.3"
},
"devDependencies": {
"babel-cli": "^6.18.0",
"babel-core": "^6.21.0",
"babel-loader": "7.0.0",
"babel-loader": "^7.1.0",
"babel-preset-env": "^1.2.2",
"babel-preset-es2015": "^6.18.0",
"babel-preset-latest": "^6.16.0",
"babel-runtime": "^6.20.0",
"lint-staged": "^3.2.1",
"lint-staged": "^4.0.0",
"pre-commit": "^1.1.3",
"stylelint-config-standard": "^16.0.0",
"webpack": "^2.2.0"
"webpack": "^3.0.0"
},
"scripts": {
"compress": "scripts/compress",

File diff suppressed because one or more lines are too long

View file

@ -1,2 +1,2 @@
!function(modules){function __webpack_require__(moduleId){if(installedModules[moduleId])return installedModules[moduleId].exports;var module=installedModules[moduleId]={i:moduleId,l:!1,exports:{}};return modules[moduleId].call(module.exports,module,module.exports,__webpack_require__),module.l=!0,module.exports}var installedModules={};__webpack_require__.m=modules,__webpack_require__.c=installedModules,__webpack_require__.i=function(value){return value},__webpack_require__.d=function(exports,name,getter){__webpack_require__.o(exports,name)||Object.defineProperty(exports,name,{configurable:!1,enumerable:!0,get:getter})},__webpack_require__.n=function(module){var getter=module&&module.__esModule?function(){return module.default}:function(){return module};return __webpack_require__.d(getter,"a",getter),getter},__webpack_require__.o=function(object,property){return Object.prototype.hasOwnProperty.call(object,property)},__webpack_require__.p="",__webpack_require__(__webpack_require__.s=8)}({8:function(module,exports,__webpack_require__){"use strict";var youtubeRegex=/watch\?v=([A-Za-z0-9\-_]+)\b/,spotifyRegex=/https\:\/\/play\.spotify\.com\/(.*)\b/,notes=document.querySelectorAll(".e-content"),_iteratorNormalCompletion=!0,_didIteratorError=!1,_iteratorError=void 0;try{for(var _step,_iterator=notes[Symbol.iterator]();!(_iteratorNormalCompletion=(_step=_iterator.next()).done);_iteratorNormalCompletion=!0){var note=_step.value,ytid=note.textContent.match(youtubeRegex);if(ytid){var ytcontainer=document.createElement("div");ytcontainer.classList.add("container");var ytiframe=document.createElement("iframe");ytiframe.classList.add("youtube"),ytiframe.setAttribute("src","https://www.youtube.com/embed/"+ytid[1]),ytiframe.setAttribute("frameborder",0),ytiframe.setAttribute("allowfullscreen","true"),ytcontainer.appendChild(ytiframe),note.appendChild(ytcontainer)}var spotifyid=note.textContent.match(spotifyRegex);if(spotifyid){var sid=spotifyid[1].replace("/",":"),siframe=document.createElement("iframe");siframe.classList.add("spotify"),siframe.setAttribute("src","https://embed.spotify.com/?uri=spotify:"+sid),siframe.setAttribute("frameborder",0),siframe.setAttribute("allowtransparency","true"),note.appendChild(siframe)}}}catch(err){_didIteratorError=!0,_iteratorError=err}finally{try{!_iteratorNormalCompletion&&_iterator.return&&_iterator.return()}finally{if(_didIteratorError)throw _iteratorError}}}});
!function(modules){function __webpack_require__(moduleId){if(installedModules[moduleId])return installedModules[moduleId].exports;var module=installedModules[moduleId]={i:moduleId,l:!1,exports:{}};return modules[moduleId].call(module.exports,module,module.exports,__webpack_require__),module.l=!0,module.exports}var installedModules={};__webpack_require__.m=modules,__webpack_require__.c=installedModules,__webpack_require__.d=function(exports,name,getter){__webpack_require__.o(exports,name)||Object.defineProperty(exports,name,{configurable:!1,enumerable:!0,get:getter})},__webpack_require__.n=function(module){var getter=module&&module.__esModule?function(){return module.default}:function(){return module};return __webpack_require__.d(getter,"a",getter),getter},__webpack_require__.o=function(object,property){return Object.prototype.hasOwnProperty.call(object,property)},__webpack_require__.p="",__webpack_require__(__webpack_require__.s=5)}({5:function(module,exports,__webpack_require__){"use strict";var youtubeRegex=/watch\?v=([A-Za-z0-9\-_]+)\b/,spotifyRegex=/https\:\/\/play\.spotify\.com\/(.*)\b/,notes=document.querySelectorAll(".e-content"),_iteratorNormalCompletion=!0,_didIteratorError=!1,_iteratorError=void 0;try{for(var _step,_iterator=notes[Symbol.iterator]();!(_iteratorNormalCompletion=(_step=_iterator.next()).done);_iteratorNormalCompletion=!0){var note=_step.value,ytid=note.textContent.match(youtubeRegex);if(ytid){var ytcontainer=document.createElement("div");ytcontainer.classList.add("container");var ytiframe=document.createElement("iframe");ytiframe.classList.add("youtube"),ytiframe.setAttribute("src","https://www.youtube.com/embed/"+ytid[1]),ytiframe.setAttribute("frameborder",0),ytiframe.setAttribute("allowfullscreen","true"),ytcontainer.appendChild(ytiframe),note.appendChild(ytcontainer)}var spotifyid=note.textContent.match(spotifyRegex);if(spotifyid){var sid=spotifyid[1].replace("/",":"),siframe=document.createElement("iframe");siframe.classList.add("spotify"),siframe.setAttribute("src","https://embed.spotify.com/?uri=spotify:"+sid),siframe.setAttribute("frameborder",0),siframe.setAttribute("allowtransparency","true"),note.appendChild(siframe)}}}catch(err){_didIteratorError=!0,_iteratorError=err}finally{try{!_iteratorNormalCompletion&&_iterator.return&&_iterator.return()}finally{if(_didIteratorError)throw _iteratorError}}}});
//# sourceMappingURL=links.js.map

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show more