]>
Commit | Line | Data |
---|---|---|
c1c9c817 MG |
1 | package Zeal::Docset; |
2 | ||
3 | use 5.014000; | |
4 | use strict; | |
5 | use warnings; | |
6 | ||
fb9b7e9f | 7 | our $VERSION = '0.000_003'; |
c1c9c817 MG |
8 | |
9 | use parent qw/Class::Accessor::Fast/; | |
10 | __PACKAGE__->mk_ro_accessors(qw/path plist dbh name id family/); | |
11 | ||
12 | use Carp qw/carp/; | |
13 | use Cwd qw/realpath/; | |
14 | use File::Spec::Functions qw/catfile catdir rel2abs/; | |
15 | use HTTP::Tiny; | |
16 | ||
17 | use DBI; | |
18 | use File::Slurp qw/read_file/; | |
19 | use Mac::PropertyList::SAX qw/parse_plist_file/; | |
20 | ||
21 | use Zeal::Document; | |
22 | ||
23 | sub new { | |
24 | my ($class, $path) = @_; | |
25 | $path = realpath $path; | |
26 | my $plpath = catfile $path, 'Contents', 'Info.plist'; | |
27 | my $dbpath = catfile $path, 'Contents', 'Resources', 'docSet.dsidx'; | |
28 | my $plist = parse_plist_file($plpath)->as_perl; | |
29 | carp 'This is not a Dash docset' unless $plist->{isDashDocset}; | |
30 | ||
31 | bless { | |
32 | path => $path, | |
33 | plist => $plist, | |
34 | dbh => DBI->connect("dbi:SQLite:dbname=$dbpath", '', ''), | |
35 | name => $plist->{CFBundleName}, | |
36 | id => $plist->{CFBundleIdentifier}, | |
37 | family => $plist->{DocSetPlatformFamily}, | |
38 | }, $class | |
39 | } | |
40 | ||
41 | sub _blessdocs { | |
42 | my ($self, $docsref) = @_; | |
04ee5ba7 MG |
43 | map { |
44 | my %hash = (%$_, docset => $self); | |
45 | ($hash{path}, $hash{anchor}) = split /#/s, $hash{path}; | |
46 | Zeal::Document->new(\%hash); | |
47 | } @$docsref; | |
c1c9c817 MG |
48 | } |
49 | ||
50 | sub fetch { | |
51 | my ($self, $path) = @_; | |
9f3addb5 | 52 | return HTTP::Tiny->new->get($path)->{content} if $path =~ /^http:/s; |
c1c9c817 MG |
53 | my $docroot = catdir $self->path, 'Contents', 'Resources', 'Documents'; |
54 | $path = rel2abs $path, $docroot; | |
55 | scalar read_file $path | |
56 | } | |
57 | ||
58 | sub query { | |
59 | my ($self, $cond) = @_; | |
60 | my $query = 'SELECT * FROM searchIndex WHERE name LIKE ?'; | |
61 | my $res = $self->dbh->selectall_arrayref($query, {Slice => {}}, $cond); | |
62 | my @results = $self->_blessdocs($res); | |
63 | wantarray ? @results : $results[0] | |
64 | } | |
65 | ||
66 | sub get { | |
67 | my ($self, $cond) = @_; | |
68 | $self->query($cond)->fetch | |
69 | } | |
70 | ||
71 | sub list { | |
72 | my ($self) = @_; | |
73 | my $query = 'SELECT * FROM searchIndex'; | |
74 | my $res = $self->dbh->selectall_arrayref($query, {Slice => {}}); | |
75 | $self->_blessdocs($res) | |
76 | } | |
77 | ||
78 | 1; | |
79 | __END__ | |
80 | ||
81 | =encoding utf-8 | |
82 | ||
83 | =head1 NAME | |
84 | ||
85 | Zeal::Docset - Class representing a Dash/Zeal docset | |
86 | ||
87 | =head1 SYNOPSIS | |
88 | ||
89 | use Zeal::Docset; | |
0469af4b MG |
90 | my $ds = Zeal::Docset->new('/home/mgv/docsets/Perl.docset'); |
91 | say $ds->$path; # /home/mgv/docsets/Perl.docset | |
92 | say $ds->name; # Perl | |
93 | say $ds->id; # perl | |
94 | say $ds->family; # perl | |
95 | ||
96 | # In SQL LIKE, % is .* and _ is . | |
97 | my @matches = $ds->query('perlopen%'); # finds perlopenbsd and perlopentut | |
98 | my $doc = $ds->query('perlsec'); # A Zeal::Document object for perlsec | |
99 | my $html = $ds->get('perls_c'); # HTML documentation of perlsec | |
100 | my @docs = $ds->list; # all documents | |
c1c9c817 MG |
101 | |
102 | =head1 DESCRIPTION | |
103 | ||
104 | Dash is an offline API documentation browser. Zeal::Docset is a class | |
105 | representing a Dash/Zeal docset. | |
106 | ||
107 | Available methods: | |
108 | ||
109 | =over | |
110 | ||
111 | =item Zeal::Docset->B<new>(I<$path>) | |
112 | ||
113 | Create a Zeal::Docset object from a given docset. I<$path> should be | |
114 | the path to a F<something.docset> directory. | |
115 | ||
116 | =item $ds->B<path> | |
117 | ||
118 | The path to the docset folder. | |
119 | ||
120 | =item $ds->B<plist> | |
121 | ||
122 | A hashref with the contents of Info.plist. | |
123 | ||
124 | =item $ds->B<dbh> | |
125 | ||
126 | A DBI database handle to the docSet.dsidx index. | |
127 | ||
128 | =item $ds->B<name> | |
129 | ||
130 | The name of this docset. Equivalent to | |
131 | C<< $ds->plist->{CFBundleName} >> | |
132 | ||
133 | =item $ds->B<id> | |
134 | ||
135 | The identifier of this docset. Equivalent to | |
136 | C<< $ds->plist->{CFBundleIdentifier} >> | |
137 | ||
138 | =item $ds->B<family> | |
139 | ||
140 | The family this docset belongs to. Dash uses this as the keyword for | |
141 | restricting searches to a particular family of docsets. Equivalent to | |
142 | C<< $ds->plist->{DocSetPlatformFamily} >> | |
143 | ||
144 | =item $ds->B<fetch>(I<$path>) | |
145 | ||
146 | Internal method for fetching the HTML content of a document. I<$path> | |
147 | is either the path to the document relative to C<< $ds->B<path> >> or | |
148 | a HTTP URL. | |
149 | ||
150 | =item $ds->B<query>(I<$cond>) | |
151 | ||
152 | In list context, return all documents (L<Zeal::Document> instances) | |
153 | matching I<$cond>. In scalar context, return one such document. | |
154 | I<$cond> is a SQL LIKE condition. | |
155 | ||
156 | =item $ds->B<get>(I<$cond>) | |
157 | ||
158 | The HTML content of one document that matches I<$cond>. | |
159 | I<$cond> is a SQL LIKE condition. | |
160 | ||
161 | This method is shorthand for C<< $ds->query(I<$cond>)->fetch >>. | |
162 | ||
163 | =item $ds->B<list> | |
164 | ||
165 | The list of all documents (L<Zeal::Document> instances) in this | |
166 | docset. | |
167 | ||
168 | =back | |
169 | ||
170 | =head1 SEE ALSO | |
171 | ||
172 | L<Zeal>, L<http://kapeli.com/dash>, L<http://zealdocs.org> | |
173 | ||
174 | =head1 AUTHOR | |
175 | ||
176 | Marius Gavrilescu, E<lt>marius@ieval.roE<gt> | |
177 | ||
178 | =head1 COPYRIGHT AND LICENSE | |
179 | ||
b19d9e9c | 180 | Copyright (C) 2014-2015 by Marius Gavrilescu |
c1c9c817 MG |
181 | |
182 | This library is free software; you can redistribute it and/or modify | |
183 | it under the same terms as Perl itself, either Perl version 5.20.1 or, | |
184 | at your option, any later version of Perl 5 you may have available. | |
185 | ||
186 | ||
187 | =cut |