]> nmode's Git Repositories - Fey/blob - lib/App/Fey.pm
c0778ab2ede342c99b79f96f124388ab303f3310
[Fey] / lib / App / Fey.pm
1 package App::Fey;
2
3 use strict;
4 use warnings;
5 use Exporter 'import';
6
7 our @EXPORT_OK = qw(fey);
8 our $version = '0.01';
9
10 sub new {
11 my ($class, $options) = @_;
12 my $config = do ($ENV{XDG_CONFIG_HOME} // "$ENV{HOME}/.config") . '/fey/config.pl';
13
14 my $self = {
15 mime_query => $options->{mime_query} // $config->{mime_query} // sub {
16 open my $mime_type, '-|', 'file', '--brief', '--mime-type', $_[0];
17 <$mime_type>;
18 },
19 contexts => $options->{contexts} // $config->{contexts} // { default => sub { 1 } },
20 targets => $options->{targets} // $config->{targets} // {}
21 };
22
23 bless $self, $class;
24 }
25
26 sub launch {
27 my $self = shift;
28 my $options = ref $_[0] ? shift : {};
29
30 die "No files or URIs specified.\n" unless @_;
31
32 if ($options->{single}) {
33 $self->_launch_single($options, @_);
34 } else {
35 $self->_launch($options, @_);
36 }
37 }
38
39 sub _launch {
40 my $self = shift;
41 my $options = shift;
42
43 if ($options->{fork}) {
44 for my $file_or_uri (@_) {
45 my $pid = fork;
46 next if $pid;
47
48 my $handler = $self->_get_handler($file_or_uri);
49 $handler->($file_or_uri) if $handler;
50 return;
51 }
52 } else {
53 for my $file_or_uri (@_) {
54 my $handler = $self->_get_handler($file_or_uri);
55 $handler->($file_or_uri) if $handler;
56 }
57 }
58 }
59
60 sub _launch_single {
61 my $self = shift;
62 my $options = shift;
63
64 if ($options->{fork}) {
65 my $pid = fork;
66 return if $pid;
67 }
68
69 my $handler = $self->_get_handler($_[0]);
70 $handler->(@_) if $handler;
71 }
72
73 sub _get_handler {
74 my $self = shift;
75
76 my $file_or_uri = $_[0] =~ m|^file://(.+)| ? $1 : $_[0];
77 my $mime_or_uri = -e $file_or_uri ? $self->{mime_query}->($file_or_uri) : $file_or_uri;
78
79 for my $target (@{ $self->{targets} }) {
80 for my $pattern (@{ $target->{patterns} }) {
81 if ($mime_or_uri =~ /$pattern/) {
82 my $associations = $target->{associations};
83 for my $context (keys %{ $associations }) {
84 if ($self->{contexts}->{$context}->()) {
85 return $associations->{$context};
86 }
87 }
88 }
89 }
90 }
91 }
92
93 sub fey {
94 App::Fey->new(ref $_[0] ? $_[0] : {})->launch(@_);
95 }