App-Filite-Client

 view release on metacpan or  search on metacpan

lib/App/Filite/Client.pm  view on Meta::CPAN

use 5.010001;
use strict;
use warnings;

package App::Filite::Client;

our $AUTHORITY = 'cpan:TOBYINK';
our $VERSION   = '0.001001';

use Carp qw( croak );
use File::XDG;
use Getopt::Long qw( GetOptionsFromArray );
use HTTP::Tiny;
use HTTP::Tiny::Multipart;
use JSON::PP qw( encode_json decode_json );
use MIME::Base64 qw( encode_base64 );
use Path::Tiny qw( path );

use Class::Tiny {
	password   => sub { croak "Missing option: password" },
	server     => sub { croak "Missing option: server" },
	useragent  => sub { shift->_build_useragent },
	errors     => sub { 0 },
};

use namespace::autoclean;

sub new_from_config {
	my ( $class ) = ( shift );
	
	state $xdg = File::XDG->new( name => 'filite-client', api => 1 );
	my $config_file = $ENV{FILITE_CLIENT_CONFIG} // $xdg->config_home->child( 'config.json' );
	if ( not ref $config_file ) {
		$config_file = path( $config_file );
	}
	croak "Expected config file: $config_file" unless $config_file->is_file;
	
	my $args = decode_json( $config_file->slurp_utf8 );
	my $self = $class->new( %$args );
	return $self;
}

sub _build_useragent {
	my ( $self ) = ( shift );
	my $auth = encode_base64( sprintf( 'admin:%s', $self->password ) );
	chomp $auth;
	return HTTP::Tiny->new(
		agent => sprintf( '%s/%s ', __PACKAGE__, $VERSION ),
		default_headers => { 'Authorization' => "Basic $auth" },
	);
}

sub _parse_opts {
	my ( $self, $args ) = ( shift, @_ );
	
	my $opts = {};
	GetOptionsFromArray(
		$args => $opts,
		'text|T',
		'file|F',
		'link|L',
		'highlight|H',
		'help|usage',
	);
	return $opts;
}

## no Test::Tabs
sub _print_usage {
	print <<"STDERR"; return 0;
filite-client: share via a filite server

Usage:
  filite-client -T [filename]
  filite-client -F [filename]
  filite-client -L [url]
  cat blah | filite-client [options]

Options:
  --text, -T         Share as text
  --file, -F         Share as file
  --link, -L         Share as link
  --highlight, -H    Syntax highligh text
  --help, --usage    Show this usage information

STDERR
}
## use Test::Tabs

sub execute {
	my ( $self, $args ) = ( shift, @_ );
	$args //= [ @ARGV ];
	my $opts = $self->_parse_opts( $args );
	$args = [ '-' ] unless @$args;
	
	if ( $opts->{help} ) {
		return $self->_print_usage;
	}
	
	for my $file ( @$args ) {
		my $url = $self->share( $file, $opts );
		print "$url\n";
	}
	
	$self->errors;

lib/App/Filite/Client.pm  view on Meta::CPAN

	
	return sprintf( '%s/%s', $endpoint, $self->_handle_response( $response ) );
}

1;

__END__

=pod

=encoding utf-8

=head1 NAME

App::Filite::Client - client library for Filite servers

=head1 SYNOPSIS

  my $client = App::Filite::Client->new_from_config;
  my $url = $client->share( 'path/to/file.txt' );
  print "Shared to $url\n";

=head1 DESCRIPTION

Share a file, chunk of text, or link via a Filite server.

Filite is a URL shortner, file sharer, and pastebin that you can self-host.

=head2 Config File

Configuration is via a JSON-formatted file usually named
F<< ~/.config/filite-client/config.json >> (see also L<File::XDG>),
though this can be overridden using the C<< FILITE_CLIENT_CONFIG >>
environment variable.

=head2 Constructors

=over

=item C<< new( %attrs ) >>

Moose-like constructor.

=item C<< new_from_config() >>

Load C<< %attrs >> from the config instead of as parameters.

=back

=head2 Attributes

All attributes are read-write.

=over

=item C<< server >> B<< Str >>

The filite server to share things via. This will typically be a URL
like "https://example.com/" or "http://example.net:8080".

=item C<< password >> B<< Str >>

Filite is a single user system so has a password but no username.

=item C<< useragent >> B<< Object >>

Can be set to a custom L<HTTP::Tiny> instance. Cannot be specified in
the config file.

=item C<< errors >> B<< Int >>

The number of errors which have been seen so far. It makes little
sense to set this in the constructor or config file.

=back

=head2 Methods

=over

=item C<< share( $filename, \%opts ) >>

Accepts C<text>, C<file>, C<link>, and C<highlight> options. All of these
options are booleans.

C<< $filename >> may be "-" to read from STDIN.

=item C<< share_text( $filename, \%opts ) >>

Accepts a C<highlight> option, which is a boolean.

C<< $filename >> may be "-" to read from STDIN.

=item C<< share_file( $filename, \%opts ) >>

The options are ignored.

C<< $filename >> may be "-" to read from STDIN.

=item C<< share_link( $url, \%opts ) >>

The options are ignored.

C<< $url >> may be "-" to read a URL from STDIN.

=item C<< execute( \@argv ) >>

Reads options and input filenames/URLs from C<< @argv >>, like processing
a command-line. If C<< @argv >> isn't given, then uses the global C<< @ARGV >>.

=back

=head1 BUGS

Please report any bugs to
L<https://github.com/tobyink/p5-app-filite-client/issues>.

=head1 SEE ALSO

L<https://github.com/raftario/filite>.

=head1 AUTHOR



( run in 0.908 second using v1.01-cache-2.11-cpan-e1769b4cff6 )