| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | package Finance::Bitcoin::Feed::Site; | 
| 2 | 6 |  |  | 6 |  | 20754 | use strict; | 
|  | 6 |  |  |  |  | 8 |  | 
|  | 6 |  |  |  |  | 189 |  | 
| 3 |  |  |  |  |  |  |  | 
| 4 | 6 |  |  | 6 |  | 462 | use Mojo::Base 'Mojo::EventEmitter'; | 
|  | 6 |  |  |  |  | 7587 |  | 
|  | 6 |  |  |  |  | 36 |  | 
| 5 | 6 |  |  | 6 |  | 13879 | use AnyEvent; | 
|  | 6 |  |  |  |  | 24755 |  | 
|  | 6 |  |  |  |  | 3027 |  | 
| 6 |  |  |  |  |  |  |  | 
| 7 |  |  |  |  |  |  | our $VERSION = '0.03'; | 
| 8 |  |  |  |  |  |  |  | 
| 9 |  |  |  |  |  |  | has last_activity_at     => 0; | 
| 10 |  |  |  |  |  |  | has last_activity_period => 300; | 
| 11 |  |  |  |  |  |  | has 'timer'; | 
| 12 |  |  |  |  |  |  | has started => 0; | 
| 13 |  |  |  |  |  |  |  | 
| 14 |  |  |  |  |  |  | #override this attribute by real site name | 
| 15 |  |  |  |  |  |  | has site => ''; | 
| 16 |  |  |  |  |  |  |  | 
| 17 |  |  |  |  |  |  | sub new { | 
| 18 | 6 |  |  | 6 | 1 | 103 | my $class = shift; | 
| 19 | 6 |  |  |  |  | 77 | my $self  = $class->SUPER::new(@_); | 
| 20 | 6 |  |  |  |  | 100 | $self->on('timeout',  \&on_timeout); | 
| 21 | 6 |  |  |  |  | 100 | $self->on('data_out', \&on_data_out); | 
| 22 |  |  |  |  |  |  |  | 
| 23 |  |  |  |  |  |  | my $timer = AnyEvent->timer( | 
| 24 |  |  |  |  |  |  | after    => 0,       # first invoke ASAP | 
| 25 |  |  |  |  |  |  | interval => 1,       # then invoke every second | 
| 26 |  |  |  |  |  |  | cb       => sub {    # the callback to invoke | 
| 27 | 0 |  |  | 0 |  | 0 | $self->timer_call_back; | 
| 28 |  |  |  |  |  |  | }, | 
| 29 | 6 |  |  |  |  | 88 | ); | 
| 30 | 6 |  |  |  |  | 11196 | $self->timer($timer); | 
| 31 |  |  |  |  |  |  |  | 
| 32 | 6 |  |  |  |  | 46 | return $self; | 
| 33 |  |  |  |  |  |  | } | 
| 34 |  |  |  |  |  |  |  | 
| 35 |  |  |  |  |  |  | sub on_data_out { | 
| 36 | 8 |  |  | 8 | 1 | 505 | my $self = shift; | 
| 37 | 8 |  |  |  |  | 185 | $self->last_activity_at(time()); | 
| 38 | 8 |  |  |  |  | 187 | $self->emit('output', $self->site, @_); | 
| 39 |  |  |  |  |  |  | } | 
| 40 |  |  |  |  |  |  |  | 
| 41 |  |  |  |  |  |  | sub timer_call_back { | 
| 42 | 0 |  |  | 0 | 1 | 0 | my $self = shift; | 
| 43 | 0 | 0 |  |  |  | 0 | return unless $self->started; | 
| 44 | 0 | 0 |  |  |  | 0 | if ($self->is_timeout) { | 
| 45 | 0 |  |  |  |  | 0 | $self->emit('timeout'); | 
| 46 |  |  |  |  |  |  | } | 
| 47 |  |  |  |  |  |  |  | 
| 48 |  |  |  |  |  |  | } | 
| 49 |  |  |  |  |  |  |  | 
| 50 |  |  |  |  |  |  | sub set_timeout { | 
| 51 | 7 |  |  | 7 | 1 | 1268 | my $self = shift; | 
| 52 | 7 |  |  |  |  | 22 | $self->debug('set timeout...'); | 
| 53 | 7 |  |  |  |  | 168 | $self->last_activity_at(time - $self->last_activity_period - 100); | 
| 54 |  |  |  |  |  |  | } | 
| 55 |  |  |  |  |  |  |  | 
| 56 |  |  |  |  |  |  | sub is_timeout { | 
| 57 | 9 |  |  | 9 | 1 | 4288 | my $self = shift; | 
| 58 | 9 |  |  |  |  | 216 | return time() - $self->last_activity_at > $self->last_activity_period; | 
| 59 |  |  |  |  |  |  | } | 
| 60 |  |  |  |  |  |  |  | 
| 61 |  |  |  |  |  |  | sub on_timeout { | 
| 62 | 0 |  |  | 0 | 1 | 0 | my $self = shift; | 
| 63 |  |  |  |  |  |  |  | 
| 64 | 0 |  |  |  |  | 0 | $self->debug('reconnecting...'); | 
| 65 | 0 |  |  |  |  | 0 | $self->go; | 
| 66 |  |  |  |  |  |  | } | 
| 67 |  |  |  |  |  |  |  | 
| 68 |  |  |  |  |  |  | sub go { | 
| 69 | 11 |  |  | 11 | 1 | 1994 | my $self = shift; | 
| 70 | 11 |  |  |  |  | 250 | $self->debug("starting ", $self->site); | 
| 71 | 11 |  |  |  |  | 270 | $self->started(1); | 
| 72 | 11 |  |  |  |  | 289 | $self->last_activity_at(time()); | 
| 73 |  |  |  |  |  |  | } | 
| 74 |  |  |  |  |  |  |  | 
| 75 |  |  |  |  |  |  | sub debug { | 
| 76 | 37 |  |  | 37 | 1 | 171 | my $self = shift; | 
| 77 | 37 | 50 |  |  |  | 111 | if ($ENV{FINANCE_BITCOIN_FEED_DEBUG}) { | 
| 78 | 0 |  |  |  |  | 0 | say STDERR $self->site, "-------------------------"; | 
| 79 | 0 |  |  |  |  | 0 | say STDERR @_; | 
| 80 |  |  |  |  |  |  | } | 
| 81 |  |  |  |  |  |  | } | 
| 82 |  |  |  |  |  |  |  | 
| 83 |  |  |  |  |  |  | sub error { | 
| 84 | 5 |  |  | 5 | 1 | 19 | my $self = shift; | 
| 85 | 5 |  |  |  |  | 99 | say STDERR $self->site, "-------------------------"; | 
| 86 | 5 |  |  |  |  | 213 | say STDERR @_; | 
| 87 |  |  |  |  |  |  | } | 
| 88 |  |  |  |  |  |  |  | 
| 89 |  |  |  |  |  |  | 1; | 
| 90 |  |  |  |  |  |  |  | 
| 91 |  |  |  |  |  |  | __END__ | 
| 92 |  |  |  |  |  |  |  | 
| 93 |  |  |  |  |  |  | =head1 NAME | 
| 94 |  |  |  |  |  |  |  | 
| 95 |  |  |  |  |  |  | Finance::Bitcoin::Feed::Site - Base class of Finance::Bitcoin::Feed::Site::* modules | 
| 96 |  |  |  |  |  |  |  | 
| 97 |  |  |  |  |  |  |  | 
| 98 |  |  |  |  |  |  | =head1 SYNOPSIS | 
| 99 |  |  |  |  |  |  |  | 
| 100 |  |  |  |  |  |  | use Mojo::Base 'Finance::Bitcoin::Feed::Site'; | 
| 101 |  |  |  |  |  |  | has site => 'SITENAME'; | 
| 102 |  |  |  |  |  |  |  | 
| 103 |  |  |  |  |  |  |  | 
| 104 |  |  |  |  |  |  | sub go{ | 
| 105 |  |  |  |  |  |  | my $self = shift; | 
| 106 |  |  |  |  |  |  | #Dont' forget this line: | 
| 107 |  |  |  |  |  |  | $self->SUPER::go(); | 
| 108 |  |  |  |  |  |  | # connect the site | 
| 109 |  |  |  |  |  |  | # parse the data | 
| 110 |  |  |  |  |  |  | # and emit the data by call | 
| 111 |  |  |  |  |  |  | $self->emit('data_out', $currency, $price); | 
| 112 |  |  |  |  |  |  | } | 
| 113 |  |  |  |  |  |  |  | 
| 114 |  |  |  |  |  |  | =head1 DESCRIPTION | 
| 115 |  |  |  |  |  |  |  | 
| 116 |  |  |  |  |  |  | It is a base class. It set some helper attributes and methods, and have an timer event that can restart the connection. | 
| 117 |  |  |  |  |  |  | You just need to override the method 'go' to connect to the site. | 
| 118 |  |  |  |  |  |  |  | 
| 119 |  |  |  |  |  |  | =head1 ATTRIBUTES | 
| 120 |  |  |  |  |  |  |  | 
| 121 |  |  |  |  |  |  | This class  inherits all attributes from L<Mojo::EventEmitter> and add the following new ones: | 
| 122 |  |  |  |  |  |  |  | 
| 123 |  |  |  |  |  |  | =head2 last_activity_at | 
| 124 |  |  |  |  |  |  |  | 
| 125 |  |  |  |  |  |  | The time that the object receive the data from the server. | 
| 126 |  |  |  |  |  |  | It is mainly updated by the method 'on_data_out' | 
| 127 |  |  |  |  |  |  |  | 
| 128 |  |  |  |  |  |  | =head2 last_activity_period | 
| 129 |  |  |  |  |  |  |  | 
| 130 |  |  |  |  |  |  | if time() - last_activity_at > last_activity_period, then we think the site is disconnected. | 
| 131 |  |  |  |  |  |  |  | 
| 132 |  |  |  |  |  |  | =head2 timer | 
| 133 |  |  |  |  |  |  |  | 
| 134 |  |  |  |  |  |  | The timer event to restart the connection | 
| 135 |  |  |  |  |  |  |  | 
| 136 |  |  |  |  |  |  | =head2 started | 
| 137 |  |  |  |  |  |  |  | 
| 138 |  |  |  |  |  |  | The tag that shows the site is running. | 
| 139 |  |  |  |  |  |  |  | 
| 140 |  |  |  |  |  |  | =head2 site | 
| 141 |  |  |  |  |  |  |  | 
| 142 |  |  |  |  |  |  | The site name which will be print in the debug information. | 
| 143 |  |  |  |  |  |  |  | 
| 144 |  |  |  |  |  |  | =head1 METHODS | 
| 145 |  |  |  |  |  |  |  | 
| 146 |  |  |  |  |  |  | =head2 new | 
| 147 |  |  |  |  |  |  |  | 
| 148 |  |  |  |  |  |  | Create object and set some events and timer | 
| 149 |  |  |  |  |  |  |  | 
| 150 |  |  |  |  |  |  | =head2 on_data_out | 
| 151 |  |  |  |  |  |  |  | 
| 152 |  |  |  |  |  |  | the callback which will be called when receive the event 'data_out'. | 
| 153 |  |  |  |  |  |  | It will Then emit the event 'output' | 
| 154 |  |  |  |  |  |  |  | 
| 155 |  |  |  |  |  |  | The args of event data_out is: | 
| 156 |  |  |  |  |  |  |  | 
| 157 |  |  |  |  |  |  | my ($self, $timestamp, $site, $currency, $price) = @_; | 
| 158 |  |  |  |  |  |  |  | 
| 159 |  |  |  |  |  |  | The unit of timestamp is ms. | 
| 160 |  |  |  |  |  |  |  | 
| 161 |  |  |  |  |  |  | =head2 timer_call_back | 
| 162 |  |  |  |  |  |  |  | 
| 163 |  |  |  |  |  |  | The callback called by timer. It will emit event 'timeout' when timeout. | 
| 164 |  |  |  |  |  |  |  | 
| 165 |  |  |  |  |  |  | =head2 set_timeout | 
| 166 |  |  |  |  |  |  |  | 
| 167 |  |  |  |  |  |  | =head2 is_timeout | 
| 168 |  |  |  |  |  |  |  | 
| 169 |  |  |  |  |  |  | =head2 on_timeout | 
| 170 |  |  |  |  |  |  |  | 
| 171 |  |  |  |  |  |  | The callback of event 'timeout'. It will call method 'go' to restart the connection | 
| 172 |  |  |  |  |  |  |  | 
| 173 |  |  |  |  |  |  | =head2 go | 
| 174 |  |  |  |  |  |  |  | 
| 175 |  |  |  |  |  |  | Establish the connection. | 
| 176 |  |  |  |  |  |  |  | 
| 177 |  |  |  |  |  |  | =head2 debug | 
| 178 |  |  |  |  |  |  |  | 
| 179 |  |  |  |  |  |  | Print debug information if the envrionment variable 'FINANCE_BITCOIN_FEED_DEBUG' is set to true. | 
| 180 |  |  |  |  |  |  |  | 
| 181 |  |  |  |  |  |  | =head2 error | 
| 182 |  |  |  |  |  |  |  | 
| 183 |  |  |  |  |  |  | Print error information if there is error. | 
| 184 |  |  |  |  |  |  |  | 
| 185 |  |  |  |  |  |  | =head1 EVENTS | 
| 186 |  |  |  |  |  |  |  | 
| 187 |  |  |  |  |  |  | This class  inherits all events from L<Mojo::EventEmitter> and add the following new ones: | 
| 188 |  |  |  |  |  |  |  | 
| 189 |  |  |  |  |  |  | =head2 data_out | 
| 190 |  |  |  |  |  |  |  | 
| 191 |  |  |  |  |  |  | It will be emitted by the site module when the site module want to output the data. | 
| 192 |  |  |  |  |  |  |  | 
| 193 |  |  |  |  |  |  | =head2 output | 
| 194 |  |  |  |  |  |  |  | 
| 195 |  |  |  |  |  |  | It will be emit by this module when print out the data. You can listen on this event to get the output. | 
| 196 |  |  |  |  |  |  |  | 
| 197 |  |  |  |  |  |  | =head2 timeout | 
| 198 |  |  |  |  |  |  |  | 
| 199 |  |  |  |  |  |  | It will be emit when the timer watch that the connection is timeout | 
| 200 |  |  |  |  |  |  |  | 
| 201 |  |  |  |  |  |  | =head1 SEE ALSO | 
| 202 |  |  |  |  |  |  |  | 
| 203 |  |  |  |  |  |  | L<Mojo::EventEmitter> | 
| 204 |  |  |  |  |  |  |  | 
| 205 |  |  |  |  |  |  | L<Finance::Bitcoin::Feed> | 
| 206 |  |  |  |  |  |  |  | 
| 207 |  |  |  |  |  |  | =head1 AUTHOR | 
| 208 |  |  |  |  |  |  |  | 
| 209 |  |  |  |  |  |  | Chylli  C<< <chylli@binary.com> >> | 
| 210 |  |  |  |  |  |  |  |