1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
|
package Mastodon::Types;
use strict;
use warnings;
our $VERSION = '0.017';
use Type::Library -base;
use Type::Utils -all;
use Types::Standard qw( Str HashRef Num );
use Types::Path::Tiny qw( File to_File);
use URI;
use DateTime;
use MIME::Base64;
use Class::Load qw( load_class );
duck_type 'UserAgent', [qw( get post delete )];
class_type 'URI', { class => 'URI' };
coerce 'URI', from Str, via {
s{^/+}{}g;
my $uri = URI->new((m{^https?://} ? q{} : 'https://') . $_);
$uri->scheme('https') unless $uri->scheme;
return $uri;
};
# We provide our own DateTime type because the Types::DateTime distribution
# is currently undermaintained
class_type 'DateTime', { class => 'DateTime' };
class_type 'HTTPResponse', { class => 'HTTP::Response' };
coerce 'DateTime',
from Num,
via { 'DateTime'->from_epoch( epoch => $_ ) }
from Str,
via {
require DateTime::Format::Strptime;
DateTime::Format::Strptime->new(
pattern => '%FT%T.%3N%Z',
on_error => 'croak',
)->parse_datetime($_);
};
# Validation here could be improved
# It is either a username if a local account, or a username@instance.tld
# but what characters are valid?
declare 'Acct', as Str;
declare 'Image',
as Str, where { m{^data:image/(?:png|jpeg);base64,[a-zA-Z0-9/+=\n]+$} };
coerce File, from Str, via {
require Path::Tiny;
return Path::Tiny::path( $_ );
};
coerce 'Image',
from File->coercibles,
via {
my $file = to_File($_);
require Image::Info;
require MIME::Base64;
my $type = lc Image::Info::image_type( $file->stringify )->{file_type};
my $img = "data:image/$type;base64,"
. MIME::Base64::encode_base64( $file->slurp_raw );
return $img;
};
# Entity types
my @entities = qw(
Status Account Instance Attachment Card Context Mention
Notification Relationship Report Results Error Tag Application
);
foreach my $name (@entities) {
class_type $name, { class => "Mastodon::Entity::$name" };
coerce $name, from HashRef, via {
load_class "Mastodon::Entity::$name";
"Mastodon::Entity::$name"->new($_);
};
}
role_type 'Entity', { role => 'Mastodon::Role::Entity' };
coerce 'Instance',
from Str,
via {
require Mastodon::Entity::Instance;
Mastodon::Entity::Instance->new({
uri => $_,
});
};
coerce 'Entity',
from HashRef,
via {
my $hash = $_;
my $entity;
use Try::Tiny;
foreach my $name (@entities) {
$entity = try {
load_class "Mastodon::Entity::$name";
"Mastodon::Entity::$name"->new($hash);
};
last if defined $entity;
}
return $entity;
};
1;
|