File Coverage

blib/lib/WebService/Simplenote/Note.pm
Criterion Covered Total %
statement 62 62 100.0
branch 8 12 66.6
condition n/a
subroutine 15 15 100.0
pod n/a
total 85 89 95.5


line stmt bran cond sub pod time code
1             package WebService::Simplenote::Note;
2             $WebService::Simplenote::Note::VERSION = '0.2.2';
3             # ABSTRACT: represents an individual note
4              
5             # TODO: API support for tags
6              
7 2     2   91795 use v5.10;
  2         17  
8 2     2   521 use Moose;
  2         398303  
  2         16  
9 2     2   14964 use MooseX::Types::DateTime qw/DateTime/;
  2         582278  
  2         14  
10 2     2   5068 use WebService::Simplenote::Note::Meta::Types;
  2         3141  
  2         90  
11 2     2   1008 use WebService::Simplenote::Note::Meta::Attribute::Trait::NotSerialised;
  2         6  
  2         86  
12 2     2   1411 use Method::Signatures;
  2         118169  
  2         15  
13 2     2   939 use DateTime;
  2         5  
  2         53  
14 2     2   590 use JSON qw//;
  2         8997  
  2         39  
15 2     2   423 use Log::Any qw//;
  2         6998  
  2         38  
16 2     2   14 use namespace::autoclean;
  2         4  
  2         20  
17              
18             around BUILDARGS => sub {
19             my $orig = shift;
20             my $class = shift;
21              
22             if (@_ == 1 && !ref $_[0]) {
23             my $note = JSON->new->utf8->decode($_[0]);
24             return $class->$orig($note);
25             } else {
26             return $class->$orig(@_);
27             }
28             };
29              
30             has logger => (
31             is => 'ro',
32             isa => 'Object',
33             lazy => 1,
34             required => 1,
35             default => sub { return Log::Any->get_logger },
36             traits => [qw/NotSerialised/],
37             );
38              
39             # set by server
40             has key => (
41             is => 'rw',
42             isa => 'Str',
43             );
44              
45             # set by server
46             has ['sharekey', 'publishkey'] => (
47             is => 'ro',
48             isa => 'Str',
49             );
50              
51             has title => (
52             is => 'rw',
53             isa => 'Str',
54             );
55              
56             has deleted => (
57             is => 'rw',
58             isa => 'Bool',
59             lazy => 1,
60             default => 0,
61             );
62              
63             # XXX should default to DateTime->now?
64             has ['createdate', 'modifydate'] => (
65             is => 'rw',
66             isa => DateTime,
67             coerce => 1,
68             );
69              
70             # set by server
71             has ['syncnum', 'version', 'minversion'] => (
72             is => 'rw',
73             isa => 'Int',
74             );
75              
76             has tags => (
77             is => 'rw',
78             traits => ['Array'],
79             isa => 'ArrayRef[Str]',
80             default => sub { [] },
81             handles => {
82             add_tag => 'push',
83             join_tags => 'join',
84             has_tags => 'count',
85             has_no_tags => 'is_empty',
86             },
87             );
88              
89             has systemtags => (
90             is => 'rw',
91             traits => ['Array'],
92             isa => 'ArrayRef[SystemTags]',
93             default => sub { [] },
94             handles => {
95             set_markdown => [push => 'markdown'],
96             is_markdown => [first => sub {/^markdown/}],
97             set_pinned => [push => 'pinned'],
98             join_systags => 'join',
99             has_systags => 'count',
100             has_no_systags => 'is_empty',
101             },
102             );
103              
104             # XXX: always coerce to utf-8?
105             has content => (
106             is => 'rw',
107             isa => 'Str',
108             trigger => \&_get_title_from_content,
109             );
110              
111 2 50   2   3229 method serialise {
  1     1   3  
  1         4  
112 1         34 $self->logger->debug('Serialising note using: ', JSON->backend);
113 1         17 my $json = JSON->new;
114 1         7 $json->allow_blessed;
115 1         5 $json->convert_blessed;
116 1         10 my $serialised_note = $json->utf8->encode($self);
117              
118 1         10 return $serialised_note;
119             }
120              
121 2 50   2   1494 method TO_JSON {
  1     1   3  
  1         3  
122 1         2 my %hash;
123 1         7 for my $attr ($self->meta->get_all_attributes) {
124 14 100       425 next if $attr->does('NotSerialised');
125 13         1533 my $reader = $attr->get_read_method;
126 13 100       495 if (defined $self->$reader) {
127 7         180 $hash{$attr->name} = $self->$reader;
128             }
129             }
130              
131             # convert dates, if present
132 1 50       6 if (exists $hash{createdate}) {
133 1         71 $hash{createdate} = $self->createdate->epoch;
134             }
135              
136 1 50       11 if (exists $hash{modifydate}) {
137 1         30 $hash{modifydate} = $self->modifydate->epoch;
138             }
139              
140 1         17 return \%hash;
141             }
142              
143             sub _get_title_from_content {
144 2     2   4 my $self = shift;
145              
146 2         58 my $content = $self->content;
147              
148             # First line is title
149 2         4 $content =~ /(.+)/;
150 2         5 my $title = $1;
151              
152             # Strip prohibited characters
153             # XXX preferable encoding scheme?
154 2         5 chomp $title;
155              
156             # non-word chars to space
157 2         10 $title =~ s/\W/ /g;
158              
159             # trim leading and trailing spaces
160 2         7 $title =~ s/^\s+//;
161 2         7 $title =~ s/\s+$//;
162              
163 2         52 $self->title($title);
164              
165 2         47 return 1;
166             }
167              
168             __PACKAGE__->meta->make_immutable;
169              
170             1;
171              
172             __END__
173              
174             =pod
175              
176             =encoding UTF-8
177              
178             =for :stopwords Ioan Rogers Fletcher T. Penney github
179              
180             =head1 NAME
181              
182             WebService::Simplenote::Note - represents an individual note
183              
184             =head1 VERSION
185              
186             version 0.2.2
187              
188             =head1 SYNOPSIS
189              
190             use WebService::Simplenote::Note;
191              
192             my $note = WebService::Simplenote::Note->new(
193             content => "Some stuff",
194             );
195              
196             printf "[%s] %s\n %s\n",
197             $note->modifydate->iso8601,
198             $note->title,
199             $note->content;
200             }
201              
202             =head1 DESCRIPTION
203              
204             This class represents a note suitable for use with Simplenote. You should read the
205             L<Simplenote API|http://simplenoteapp.com/api/> docs for full details
206              
207             =head1 METHODS
208              
209             =over
210              
211             =item WebService::Simplenote::Note->new($args)
212              
213             The minimum required attribute to set is C<content>.
214              
215             =item add_tag($str)
216              
217             Push a new tag onto C<tags>.
218              
219             =item set_markdown
220              
221             Shortcut to set the C<markdown> system tag.
222              
223             =item set_pinned
224              
225             Shortcut to set the C<pinned> system tag.
226              
227             =back
228              
229             =head1 ATTRIBUTES
230              
231             =over
232              
233             =item logger
234              
235             L<Log::Any> logger
236              
237             =item key
238              
239             Server-set unique id for the note.
240              
241             =item title
242              
243             Simplenote doens't use titles, so we autogenerate one from the first line of content.
244              
245             =item deleted
246              
247             Boolean; is this note in the trash?
248              
249             =item createdate/modifydate
250              
251             Datetime objects
252              
253             =item tags
254              
255             Arrayref[Str]; user-generated tags.
256              
257             =item systemtags
258              
259             Arrayref[Str]; special tags.
260              
261             =item content
262              
263             The body of the note
264              
265             =head1 AUTHORS
266              
267             =over 4
268              
269             =item *
270              
271             Ioan Rogers <ioanr@cpan.org>
272              
273             =item *
274              
275             Fletcher T. Penney <owner@fletcherpenney.net>
276              
277             =back
278              
279             =head1 COPYRIGHT AND LICENSE
280              
281             This software is Copyright (c) 2021 by Ioan Rogers.
282              
283             This is free software, licensed under:
284              
285             The GNU General Public License, Version 2, June 1991
286              
287             =head1 BUGS AND LIMITATIONS
288              
289             You can make new bug reports, and view existing ones, through the
290             web interface at L<https://github.com/ioanrogers/WebService-Simplenote/issues>.
291              
292             =head1 SOURCE
293              
294             The development version is on github at L<https://github.com/ioanrogers/WebService-Simplenote>
295             and may be cloned from L<git://github.com/ioanrogers/WebService-Simplenote.git>
296              
297             =cut