| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | ########################################### | 
| 2 |  |  |  |  |  |  | package Net::Evernote::Simple; | 
| 3 |  |  |  |  |  |  | ########################################### | 
| 4 |  |  |  |  |  |  |  | 
| 5 | 1 |  |  | 1 |  | 31674 | use strict; | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 25 |  | 
| 6 | 1 |  |  | 1 |  | 5 | use warnings; | 
|  | 1 |  |  |  |  | 3 |  | 
|  | 1 |  |  |  |  | 25 |  | 
| 7 |  |  |  |  |  |  |  | 
| 8 | 1 |  |  | 1 |  | 520 | use Net::Evernote::Simple::EDAMUserStore::Constants; | 
|  | 1 |  |  |  |  | 3 |  | 
|  | 1 |  |  |  |  | 22 |  | 
| 9 | 1 |  |  | 1 |  | 652 | use Net::Evernote::Simple::EDAMUserStore::Types; | 
|  | 0 |  |  |  |  |  |  | 
|  | 0 |  |  |  |  |  |  | 
| 10 |  |  |  |  |  |  | use Net::Evernote::Simple::EDAMUserStore::UserStore; | 
| 11 |  |  |  |  |  |  | use Net::Evernote::Simple::EDAMNoteStore::NoteStore; | 
| 12 |  |  |  |  |  |  | use Net::Evernote::Simple::EDAMNoteStore::Types; | 
| 13 |  |  |  |  |  |  | use Net::Evernote::Simple::EDAMErrors::Types; | 
| 14 |  |  |  |  |  |  | use Net::Evernote::Simple::EDAMTypes::Types; | 
| 15 |  |  |  |  |  |  | use Log::Log4perl qw(:easy); | 
| 16 |  |  |  |  |  |  | use YAML qw( LoadFile ); | 
| 17 |  |  |  |  |  |  | use File::Basename; | 
| 18 |  |  |  |  |  |  | use File::Temp qw( tempfile ); | 
| 19 |  |  |  |  |  |  | use Thrift; | 
| 20 |  |  |  |  |  |  | use Thrift::HttpClient; | 
| 21 |  |  |  |  |  |  | use Thrift::BinaryProtocol; | 
| 22 |  |  |  |  |  |  | use Data::Dumper; | 
| 23 |  |  |  |  |  |  |  | 
| 24 |  |  |  |  |  |  | our $VERSION = "0.06"; | 
| 25 |  |  |  |  |  |  |  | 
| 26 |  |  |  |  |  |  | our $EN_DEV_TOKEN_PAGE = | 
| 27 |  |  |  |  |  |  | "http://dev.evernote.com/documentation/cloud/chapters/" . | 
| 28 |  |  |  |  |  |  | "Authentication.php#devtoken"; | 
| 29 |  |  |  |  |  |  |  | 
| 30 |  |  |  |  |  |  | ########################################### | 
| 31 |  |  |  |  |  |  | sub new { | 
| 32 |  |  |  |  |  |  | ########################################### | 
| 33 |  |  |  |  |  |  | my($class, %options) = @_; | 
| 34 |  |  |  |  |  |  |  | 
| 35 |  |  |  |  |  |  | my $self = { | 
| 36 |  |  |  |  |  |  | evernote_host => "www.evernote.com", | 
| 37 |  |  |  |  |  |  | dev_token           => undef, | 
| 38 |  |  |  |  |  |  | config_file         => undef, | 
| 39 |  |  |  |  |  |  | consumer_key        => undef, | 
| 40 |  |  |  |  |  |  | thrift_send_timeout => 10000, | 
| 41 |  |  |  |  |  |  | thrift_recv_timeout => 75000, | 
| 42 |  |  |  |  |  |  | %options, | 
| 43 |  |  |  |  |  |  | }; | 
| 44 |  |  |  |  |  |  |  | 
| 45 |  |  |  |  |  |  | bless $self, $class; | 
| 46 |  |  |  |  |  |  |  | 
| 47 |  |  |  |  |  |  | if( !defined $self->{ consumer_key } ) { | 
| 48 |  |  |  |  |  |  | ( my $dashed_pkg = __PACKAGE__ ) =~ s/::/-/g; | 
| 49 |  |  |  |  |  |  | $self->{ consumer_key } = lc $dashed_pkg; | 
| 50 |  |  |  |  |  |  | } | 
| 51 |  |  |  |  |  |  |  | 
| 52 |  |  |  |  |  |  | if( ! defined $self->{ config_file } ) { | 
| 53 |  |  |  |  |  |  | my( $home ) = glob "~"; | 
| 54 |  |  |  |  |  |  | $self->{ config_file } = "$home/.evernote.yml"; | 
| 55 |  |  |  |  |  |  | } | 
| 56 |  |  |  |  |  |  |  | 
| 57 |  |  |  |  |  |  | if( !defined $self->{ dev_token } ) { | 
| 58 |  |  |  |  |  |  | if( -f $self->{ config_file } ) { | 
| 59 |  |  |  |  |  |  | my $data = LoadFile $self->{ config_file }; | 
| 60 |  |  |  |  |  |  | if( exists $data->{ dev_token } ) { | 
| 61 |  |  |  |  |  |  | $self->{ dev_token } = $data->{ dev_token }; | 
| 62 |  |  |  |  |  |  | } | 
| 63 |  |  |  |  |  |  | } | 
| 64 |  |  |  |  |  |  | } | 
| 65 |  |  |  |  |  |  |  | 
| 66 |  |  |  |  |  |  | my $user_store_uri = | 
| 67 |  |  |  |  |  |  | "https://$self->{ evernote_host }/edam/user"; | 
| 68 |  |  |  |  |  |  |  | 
| 69 |  |  |  |  |  |  | my $http_client = $self->thrift_http_client( $user_store_uri ); | 
| 70 |  |  |  |  |  |  | my $protocol = | 
| 71 |  |  |  |  |  |  | Thrift::BinaryProtocol->new( $http_client ); | 
| 72 |  |  |  |  |  |  |  | 
| 73 |  |  |  |  |  |  | $self->{ client } = | 
| 74 |  |  |  |  |  |  | Net::Evernote::Simple::EDAMUserStore::UserStoreClient->new( $protocol ); | 
| 75 |  |  |  |  |  |  |  | 
| 76 |  |  |  |  |  |  | return $self; | 
| 77 |  |  |  |  |  |  | } | 
| 78 |  |  |  |  |  |  |  | 
| 79 |  |  |  |  |  |  | ########################################### | 
| 80 |  |  |  |  |  |  | sub init { | 
| 81 |  |  |  |  |  |  | ########################################### | 
| 82 |  |  |  |  |  |  | my( $self ) = @_; | 
| 83 |  |  |  |  |  |  |  | 
| 84 |  |  |  |  |  |  | if( $self->{ init_done } ) { | 
| 85 |  |  |  |  |  |  | return 1; | 
| 86 |  |  |  |  |  |  | } | 
| 87 |  |  |  |  |  |  |  | 
| 88 |  |  |  |  |  |  | if( !defined $self->{ dev_token } ) { | 
| 89 |  |  |  |  |  |  | LOGDIE "Developer token argument 'dev_token' missing. ", | 
| 90 |  |  |  |  |  |  | "Check $EN_DEV_TOKEN_PAGE on how to obtain one."; | 
| 91 |  |  |  |  |  |  | } | 
| 92 |  |  |  |  |  |  |  | 
| 93 |  |  |  |  |  |  | if( ! $self->version_check() ) { | 
| 94 |  |  |  |  |  |  | LOGDIE "Version check failed"; | 
| 95 |  |  |  |  |  |  | } | 
| 96 |  |  |  |  |  |  |  | 
| 97 |  |  |  |  |  |  | $self->{ init_done } = 1; | 
| 98 |  |  |  |  |  |  | } | 
| 99 |  |  |  |  |  |  |  | 
| 100 |  |  |  |  |  |  | ########################################### | 
| 101 |  |  |  |  |  |  | sub dev_token { | 
| 102 |  |  |  |  |  |  | ########################################### | 
| 103 |  |  |  |  |  |  | my( $self ) = @_; | 
| 104 |  |  |  |  |  |  |  | 
| 105 |  |  |  |  |  |  | return $self->{ dev_token }; | 
| 106 |  |  |  |  |  |  | } | 
| 107 |  |  |  |  |  |  |  | 
| 108 |  |  |  |  |  |  | ########################################### | 
| 109 |  |  |  |  |  |  | sub thrift_http_client { | 
| 110 |  |  |  |  |  |  | ########################################### | 
| 111 |  |  |  |  |  |  | my( $self, $uri ) = @_; | 
| 112 |  |  |  |  |  |  |  | 
| 113 |  |  |  |  |  |  | my $client = Thrift::HttpClient->new( $uri ); | 
| 114 |  |  |  |  |  |  |  | 
| 115 |  |  |  |  |  |  | # Timeouts can't be passed into Thrift::HttpClient's constructor, | 
| 116 |  |  |  |  |  |  | # so we set them manually here. Thrift's default values | 
| 117 |  |  |  |  |  |  | # are in the millisecond range and therefore completely out | 
| 118 |  |  |  |  |  |  | # of whack unless you have the Evernote server on your LAN. | 
| 119 |  |  |  |  |  |  | $client->setSendTimeout( $self->{ thrift_send_timeout } ); | 
| 120 |  |  |  |  |  |  | $client->setRecvTimeout( $self->{ thrift_recv_timeout } ); | 
| 121 |  |  |  |  |  |  |  | 
| 122 |  |  |  |  |  |  | return $client; | 
| 123 |  |  |  |  |  |  | } | 
| 124 |  |  |  |  |  |  |  | 
| 125 |  |  |  |  |  |  | ########################################### | 
| 126 |  |  |  |  |  |  | sub note_store { | 
| 127 |  |  |  |  |  |  | ########################################### | 
| 128 |  |  |  |  |  |  | my( $self ) = @_; | 
| 129 |  |  |  |  |  |  |  | 
| 130 |  |  |  |  |  |  | $self->init(); | 
| 131 |  |  |  |  |  |  |  | 
| 132 |  |  |  |  |  |  | my $note_store_uri; | 
| 133 |  |  |  |  |  |  |  | 
| 134 |  |  |  |  |  |  | eval { | 
| 135 |  |  |  |  |  |  | $note_store_uri = | 
| 136 |  |  |  |  |  |  | $self->{ client }->getNoteStoreUrl( $self->{ dev_token } ); | 
| 137 |  |  |  |  |  |  | }; | 
| 138 |  |  |  |  |  |  |  | 
| 139 |  |  |  |  |  |  | if( $@ ) { | 
| 140 |  |  |  |  |  |  | ERROR Dumper( $@ ); | 
| 141 |  |  |  |  |  |  | return undef; | 
| 142 |  |  |  |  |  |  | } | 
| 143 |  |  |  |  |  |  |  | 
| 144 |  |  |  |  |  |  | my $note_store_client = $self->thrift_http_client( $note_store_uri ); | 
| 145 |  |  |  |  |  |  |  | 
| 146 |  |  |  |  |  |  | my $note_store_protocol = Thrift::BinaryProtocol->new( | 
| 147 |  |  |  |  |  |  | $note_store_client ); | 
| 148 |  |  |  |  |  |  |  | 
| 149 |  |  |  |  |  |  | my $note_store = | 
| 150 |  |  |  |  |  |  | Net::Evernote::Simple::EDAMNoteStore::NoteStoreClient->new( | 
| 151 |  |  |  |  |  |  | $note_store_protocol ); | 
| 152 |  |  |  |  |  |  |  | 
| 153 |  |  |  |  |  |  | return $note_store; | 
| 154 |  |  |  |  |  |  | } | 
| 155 |  |  |  |  |  |  |  | 
| 156 |  |  |  |  |  |  | ########################################### | 
| 157 |  |  |  |  |  |  | sub version_check { | 
| 158 |  |  |  |  |  |  | ########################################### | 
| 159 |  |  |  |  |  |  | my( $self ) = @_; | 
| 160 |  |  |  |  |  |  |  | 
| 161 |  |  |  |  |  |  | eval { | 
| 162 |  |  |  |  |  |  | my $version_ok = | 
| 163 |  |  |  |  |  |  | $self->{ client }->checkVersion( $self->{ consumer_key }, | 
| 164 |  |  |  |  |  |  | Net::Evernote::Simple::EDAMUserStore::Constants::EDAM_VERSION_MAJOR, | 
| 165 |  |  |  |  |  |  | Net::Evernote::Simple::EDAMUserStore::Constants::EDAM_VERSION_MINOR, | 
| 166 |  |  |  |  |  |  | ); | 
| 167 |  |  |  |  |  |  |  | 
| 168 |  |  |  |  |  |  | INFO "Version check returned: $version_ok"; | 
| 169 |  |  |  |  |  |  | }; | 
| 170 |  |  |  |  |  |  |  | 
| 171 |  |  |  |  |  |  | if( $@ ) { | 
| 172 |  |  |  |  |  |  | LOGWARN Dumper( $@ ); | 
| 173 |  |  |  |  |  |  | $self->horrid_thrift_client_error_diagnostics( $self->{client} ); | 
| 174 |  |  |  |  |  |  | return 0; | 
| 175 |  |  |  |  |  |  | } | 
| 176 |  |  |  |  |  |  |  | 
| 177 |  |  |  |  |  |  | return 1; | 
| 178 |  |  |  |  |  |  | } | 
| 179 |  |  |  |  |  |  |  | 
| 180 |  |  |  |  |  |  | ########################################### | 
| 181 |  |  |  |  |  |  | sub horrid_thrift_client_error_diagnostics { | 
| 182 |  |  |  |  |  |  | ########################################### | 
| 183 |  |  |  |  |  |  | my( $self, $client ) = @_; | 
| 184 |  |  |  |  |  |  |  | 
| 185 |  |  |  |  |  |  | # Apparently, there's no way to figure out what went wrong at the | 
| 186 |  |  |  |  |  |  | # http level once a thrift call fails, except poking around in thrift's | 
| 187 |  |  |  |  |  |  | # internal structures. Oh, the humanity! | 
| 188 |  |  |  |  |  |  |  | 
| 189 |  |  |  |  |  |  | eval { | 
| 190 |  |  |  |  |  |  | my $in = $client->{input}->{trans}->{in}; | 
| 191 |  |  |  |  |  |  | $in->setpos(0); | 
| 192 |  |  |  |  |  |  | LOGWARN join '', <$in>; | 
| 193 |  |  |  |  |  |  | }; | 
| 194 |  |  |  |  |  |  |  | 
| 195 |  |  |  |  |  |  | if( $@ ) { | 
| 196 |  |  |  |  |  |  | LOGWARN "Unable to diagnose underlying error"; | 
| 197 |  |  |  |  |  |  | } | 
| 198 |  |  |  |  |  |  | } | 
| 199 |  |  |  |  |  |  |  | 
| 200 |  |  |  |  |  |  | 1; | 
| 201 |  |  |  |  |  |  |  | 
| 202 |  |  |  |  |  |  | __END__ |