garlenko 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,68 @@
1
+ # Garlenko
2
+
3
+ ## Description
4
+
5
+ Well, Garlenko is a gem that do what other gems are trying to do: Fetch contact information from Gmail, Hotmail/Live and Yahoo.
6
+
7
+ We are not using Oauth. Instead the basic username/password combo, because for our particular case, we need that, and Oauth doesn't play the way we need.
8
+
9
+ ## Why another contact gem?
10
+
11
+ Basically because most implementations doesn't work, or doesn't provide test/specs. Garlenko is not magic, or is the best implementation, but if you provide a valid spec/credentials.yml, you can run the tests and be sure that they work properly before doing all the plumbing of setting up your app.
12
+
13
+ # How does it works?
14
+
15
+ Well... it depends.
16
+
17
+ For Gmail, we use gdata19. Simple, clean, although it uses roxml.
18
+
19
+ For Live, we use mechanize and nokogiri (tenderlove to the rescue). No simple API from the Microsoft guys, so we need to crawl it.
20
+
21
+ For Yahoo.... Just like Live, but with less scrapping.
22
+
23
+ # How does it works?
24
+
25
+ Well... it depends.
26
+
27
+ For Gmail, we use gdata19. Simple, clean, although it uses roxml.
28
+
29
+ For Live, we use mechanize and nokogiri (tenderlove to the rescue). No simple API from the Microsoft guys.
30
+
31
+ For Yahoo.... Ooops, there is no Yahoo version yet. Soon, I hope.
32
+
33
+ ## How can I be sure Garlenko works?
34
+
35
+ Just copy spec/credentials.yml.example to spec/credentials.yml, do bundle install, and then bundle exec rspec spec.
36
+
37
+ cp spec/credentials.yml.example spec/credentials.yml
38
+ # edit file
39
+ bundle install
40
+ bundle exec rspec spec
41
+
42
+ NOTE: This step is only necessary to see if the current version still works with the Gmail, Yahoo, or Live from today.
43
+
44
+ ## Usage
45
+
46
+ This is a sample for Gmail, but feel free to change it for Live (if you want to retrieve Microsoft Live/Hotmail contacts):
47
+
48
+ client = Garlenko::Gmail.new("somemail@gmail.com", "use-alpha-and-alter-case-1999")
49
+ contacts = client.contacts
50
+ [
51
+ {:name => "John", :email => "Doe" }
52
+ #...
53
+ ]
54
+
55
+
56
+ You can also get a client like this:
57
+
58
+ client = Garlenko.new(:gmail, "somemail@gmail.com", "use-alpha-and-alter-case-1999")
59
+
60
+ ## Hey, this piece of shit doesn't work!
61
+
62
+ Good to know.
63
+
64
+ Write a test, patch it, and send me a pull request. This a community driven project, so we are all resposable for this.
65
+
66
+ Help us keep it working.
67
+
68
+
@@ -0,0 +1,543 @@
1
+ <!DOCTYPE html public "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2
+ <html>
3
+ <head>
4
+
5
+
6
+ <style>
7
+ body {font:84.5% tahoma,arial,helvetica,clean,sans-serif;*font-size:small;*font:x-small;}
8
+ </style>
9
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
10
+
11
+
12
+
13
+ <link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/combo?2.7.0/build/reset-fonts-grids/reset-fonts-grids.css" />
14
+ <link rel="stylesheet" type="text/css" media="all" href="http://l.yimg.com/qa/sab/2.17.376/ar/eagle2_blue.css" />
15
+
16
+
17
+
18
+
19
+
20
+
21
+ <title>Yahoo! Contactos - pushkdevelopment</title>
22
+ <meta http-equiv="pics-label" content='(pics-1.1 "http://www.icra.org/ratingsv02.html" l gen true for "http://address.yahoo.com/yab/us" r ( nz 0 vz 0 lz 0 oz 0 ca 1))'>
23
+
24
+ <script type="text/javascript" language="JavaScript">
25
+ <!-- // <![CDATA[
26
+ if(typeof document.charset != "undefined" &&
27
+ document.charset != "UTF-8" &&
28
+ document.charset != "utf-8") {
29
+ document.charset = "UTF-8";
30
+ }
31
+ // ]]> -->
32
+ </script>
33
+ <script src="http://code.jquery.com/jquery-1.7.1.min.js" type="text/javascript" charset="utf-8"></script>
34
+ </head>
35
+ <body> <div id="masthead">
36
+ <!-- SpaceID=1181603055 loc=HEAD4 noad -->
37
+ <script language=javascript>
38
+ if(window.yzq_d==null)window.yzq_d=new Object();
39
+ window.yzq_d['BE_wpmKKISI-']='&U=12di3e6qa%2fN%3dBE_wpmKKISI-%2fC%3d-1%2fD%3dHEAD4%2fB%3d-1%2fV%3d0';
40
+ </script><noscript><img width=1 height=1 alt="" src="http://row.bc.yahoo.com/b?P=mT7WeWKKGQu6dFHJTul53QPdYooF5U7peeMABLe7&T=17cgedkrg%2fX%3d1323923940%2fE%3d1181603055%2fR%3darsocab%2fK%3d5%2fV%3d2.1%2fW%3dHR%2fY%3dAR%2fF%3d3312505131%2fH%3dc2VydmVJZD0ibVQ3V2VXS0tHUXU2ZEZISlR1bDUzUVBkWW9vRjVVN3BlZU1BQkxlNyIgdFN0bXA9IjEzMjM5MjM5NDA1ODMwNjkiIA--%2fQ%3d-1%2fS%3d1%2fJ%3d2B198A62&U=12di3e6qa%2fN%3dBE_wpmKKISI-%2fC%3d-1%2fD%3dHEAD4%2fB%3d-1%2fV%3d0"></noscript><!--QYZ ,;;;1181603055;;--><!-- SpaceID=1181603055 loc=HEAD3 noad -->
41
+ <script language=javascript>
42
+ if(window.yzq_d==null)window.yzq_d=new Object();
43
+ window.yzq_d['A0_wpmKKISI-']='&U=12dlq3v0b%2fN%3dA0_wpmKKISI-%2fC%3d-1%2fD%3dHEAD3%2fB%3d-1%2fV%3d0';
44
+ </script><noscript><img width=1 height=1 alt="" src="http://row.bc.yahoo.com/b?P=mT7WeWKKGQu6dFHJTul53QPdYooF5U7peeMABLe7&T=17bpqkvpd%2fX%3d1323923940%2fE%3d1181603055%2fR%3darsocab%2fK%3d5%2fV%3d2.1%2fW%3dHR%2fY%3dAR%2fF%3d136999312%2fH%3dc2VydmVJZD0ibVQ3V2VXS0tHUXU2ZEZISlR1bDUzUVBkWW9vRjVVN3BlZU1BQkxlNyIgdFN0bXA9IjEzMjM5MjM5NDA1ODMwNjkiIA--%2fQ%3d-1%2fS%3d1%2fJ%3d2B198A62&U=12dlq3v0b%2fN%3dA0_wpmKKISI-%2fC%3d-1%2fD%3dHEAD3%2fB%3d-1%2fV%3d0"></noscript><!--QYZ ,;;HEAD3;1181603055;;--><!-- Static Masthead -->
45
+ <form name="yhdr_form" id="masthead_form"
46
+ action="http://ar.search.yahoo.com/search"
47
+ target="_blank" accept-charset="utf-8">
48
+ <div id="ygma">
49
+ <input type="hidden" name="fr" value="ush1-add"/>
50
+ <input type="hidden" name="ei" value="utf-8"/>
51
+
52
+ <div id="masthead_row1">
53
+ <span class="masthead_search">
54
+ <img src="http://l.yimg.com/a/i/us/hdr/el/uh_crn2.gif"
55
+ id="img_crnr" border="0" height="14" width="13" align="bottom" alt=""
56
+ /><img src="http://l.yimg.com/a/i/e1/se/gr/stw2.gif" width="38" height="16" alt="Buscar en la Web">
57
+ <input type="text" name="p" size="12" title="Escribí tu búsqueda aquí" maxlength="100"/>
58
+ <input class="ygbt" type="submit" value="Buscar" title="Buscar"/>
59
+ </span>
60
+ <span class="masthead_link"><a href="http://ar.yahoo.com" target="_top">Yahoo!</a></span>
61
+ <span class="masthead_link"><a href="http://ar.my.yahoo.com" target="_top">Mi Yahoo!</a></span>
62
+ <span class="masthead_link"><a href="https://login.yahoo.com/config/mail?&.src=ym&.intl=ar/" target="_top">Correo</a></span>
63
+ <span class="masthead_link"><a href="http://ar.rd.yahoo.com/hp/topbar/my/*#" target="_top">Hacé de Yahoo! tu página de inicio</a></span>
64
+
65
+ </div>
66
+
67
+ <div id="masthead_row2">
68
+ <span id="masthead_logo"><a href="http://address.mail.yahoo.com/"><img id="ygmalogo" src="http://l.yimg.com/a/i/brand/purplelogo/mail/co/ar.gif" width="281" height="33" alt="Yahoo! Contactos"></a></span>
69
+ <div id="masthead_welcome1">Hola <span id="masthead_login">pushkdevelopment</span></div>
70
+ <div id="masthead_property_links">
71
+ <a href="http://address.mail.yahoo.com/" target="_top">Yahoo! Contactos - Inicio</a> - <a href="http://help.yahoo.com/l/ar/yahoo/contacts/" target="_top">Ayuda</a>
72
+ </div>
73
+ <div id="masthead_welcome2">
74
+ [<a href="http://login.yahoo.com/config/exit?.direct=2&.done=http://ar.yahoo.com&.src=ab&.intl=ar&.last=http://ar.address.yahoo.com" target="_top">Salir</a>, <a href="http://edit.yahoo.com/config/eval_profile?.done=http://ar.address.yahoo.com&.src=ab&.intl=ar" target="_top">Mi cuenta</a>] </div>
75
+ </div>
76
+ </div>
77
+ </form>
78
+ </div> <!-- end masthead -->
79
+ <div></div>
80
+
81
+ <div id="pimnav">
82
+ <div>
83
+ <ul id="apps">
84
+ <li class="first" id="mail"><a href="http://us.rd.yahoo.com/ab_us/pimnav/mail/*http://mail.yahoo.com" class="first">Correo</a></li>
85
+ <li id="addresses" class="selected"><a href="?.rand=777234791" class="first" id="qa_abtab1" ><em>Contactos</em></a></li>
86
+ <li id="calendar"><a href="http://us.rd.yahoo.com/ab_us/pimnav/mail/*http://calendar.yahoo.com/" class="first">Agenda</a></li>
87
+ <li class="last" id="notepad"><a href="http://us.rd.yahoo.com/ab_us/pimnav/mail/*http://notepad.yahoo.com/" class="first">Bloc&nbsp;de&nbsp;notas</a></li>
88
+ </ul>
89
+ </div>
90
+ </div>
91
+ <div id="doc3" class="yui-t2">
92
+ <div id="hd">
93
+ <script>
94
+ var kParams = {
95
+ src: '',
96
+ dotCrumb: '2bT3q04NQIW',
97
+ intl: 'ar',
98
+ partner: 'generic_intl',
99
+ filterId: '',
100
+ filterName: 'Todos los contactos',
101
+ landingSpaceId: '1181600055',
102
+ bucketSize: '30',
103
+ filterDef: {
104
+ allcontacts: 'All Contacts',
105
+ connections: 'Connections',
106
+ unfiled: 'Unfiled',
107
+ lastimported: 'Last Imported',
108
+ deleted: 'Deleted Contacts'
109
+ },
110
+ cdn_base: 'http://l.yimg.com/qa/sab/2.17.376/ar/',
111
+ cdn_base_css: 'http://l.yimg.com/qa/sab/2.17.376/ar/',
112
+ rtstart: '',
113
+ mrdCompose: 'http://mrd.mail.yahoo.com/compose'
114
+
115
+
116
+ }
117
+ </script>
118
+
119
+ <div class="clearfix"><!-- --></div>
120
+ <div class="social_toolbar colorC1 clearfix">
121
+ <noscript>
122
+ <div class="noscript_error">
123
+ <p>Se requiere JavaScript para ejecutar la nueva función de Contactos. Activá JavaScript o utilizá los <a href="?VPC=contact_list&amp;.rand=777234791">Contactos clásicos</a></p>
124
+ </div>
125
+ </noscript>
126
+ <!-- Buttons -->
127
+
128
+ <div id="social_btn_container">
129
+ <div id="social_filter_head_text" style="display:none;">Todos los contactos</div>
130
+ <span id="filterGroup"></span>
131
+ <div id="social_filter_menu" class="yuimenu colorC7 colorK3 fontT2">
132
+ <div class="bd colorC7">
133
+ <h6 class="lable socialFilterHeader fontBold">Vista:</h6>
134
+ <ul class="colorK3">
135
+ <li class="allcontacts " value="0" title="Todos los contactos"><a href="#" class="fontLink fontDarkGray">Todos los contactos</a></li>
136
+ <li class="unfiled " id="unfiled_filter" value="0" title="No clasificados"><a href="#" class="fontLink fontDarkGray">No clasificados</a></li>
137
+ <li class="lastimported " id="lastimported_filter" value="0" title="Última importación"><a href="#" class="fontLink fontDarkGray">Última importación</a></li>
138
+ </ul><ul class="fontT2 colorK3">
139
+ <li class="deleted" id="deleted_filter" value="0" title="Contactos eliminados"><a href="#" class="fontLink fontDarkGray">Contactos eliminados</a></li>
140
+
141
+ </ul>
142
+ </div>
143
+ </div>
144
+ <span id="contactGroup"></span>
145
+ <span id="cxnGroup"></span>
146
+ <span id="toolsGroup"></span>
147
+ <div id="toolsMenu" class="yuimenu colorK3">
148
+ <div class="bd colorC7">
149
+ <ul class="first-of-type fontT2 colorK3">
150
+
151
+ <li id="tool1" class="yuimenuitem"><a class="yuimenuitemlabel fontLink fontDarkGray" href="#">Imprimir…</a></li>
152
+ <li id="tool2" class="yuimenuitem"><a class="yuimenuitemlabel fontLink fontDarkGray" href="#">Importar…</a></li>
153
+ <li id="tool3" class="yuimenuitem"><a class="yuimenuitemlabel fontLink fontDarkGray" href="#">Exportar…</a></li>
154
+ <li id="tool4" class="yuimenuitem"><a class="yuimenuitemlabel fontLink fontDarkGray" href="#">Sincronizar aplicaciones</a></li>
155
+ <li id="tool5" class="yuimenuitem"><a class="yuimenuitemlabel fontLink fontDarkGray" href="#">Eliminar duplicados…</a></li>
156
+ </ul>
157
+
158
+ </div>
159
+ </div>
160
+ </div>
161
+ <div id="yab_help_con">
162
+ <a href="http://help.yahoo.com/l/ar/yahoo/contacts/" target="_blank" class="fontBold fontReverse">Ayuda</a>
163
+ </div>
164
+ </div>
165
+ </div>
166
+ <div id="main_bd" class="main_bd">
167
+ <div id="menu_container"></div>
168
+ <div id="contactlist_c" class="colorC3 yui-b">
169
+
170
+
171
+ <!-- Search Contact Input -->
172
+ <div id="social_search_container" class="colorC7 colorBK4">
173
+ <div class="abIcons magGlassIcon" ></div>
174
+ <div>
175
+ <nobr id="prompt_text" class="fontT2" title="Buscar contactos introduciendo el texto aquí">Buscar contactos...</nobr>
176
+ <input id="search_input" type="text" title="Buscar contactos introduciendo el texto aquí" />
177
+ </div>
178
+ <div id="clear_search" class="abIcons clearSearchIcon" title="Borrar texto de búsqueda"></div>
179
+ <div id="twirly_search" class="abIcons searchTwirly" style="display:none"></div>
180
+ <div id="search_ac_container" style="display:none"></div>
181
+ </div>
182
+
183
+ <div id="social_select_sort_head" class="colorC3 colorBK4">
184
+ <div id="social_chkbox_head" class="colorBK4">
185
+ <div id="clist_selectall" checked="false" class='abIcons chkBox_off'></div>
186
+ </div>
187
+ <div id="social_sort_head">
188
+ <div id="social_sort_head_text" class="fontT2 fontBold"></div>
189
+ <div class='abIcons sortIcon' style="display:none;"></div>
190
+ <div id='sort_arrow' class='abIcons arrowIcon'></div>
191
+ <div id='sort_twirly' style='display:none' class='abIcons sortTwirly'></div>
192
+ <div id="social_sort_menu" class="colorK3">
193
+ <div class="bd colorC7">
194
+ <h6 class="lable fontBold fontT2">Ordenar por:</h6>
195
+ <ul class="fontT2 colorK3">
196
+ <li value='1' class='selected'><a href='#' class='fontLink fontDarkGray'>Nombre</a></li> <li value='3' class=''><a href='#' class='fontLink fontDarkGray'>Apellido</a></li> <li value='6' class=''><a href='#' class='fontLink fontDarkGray'>Dirección de correo</a></li> </ul>
197
+ <ul class="fontT2 colorK3">
198
+ <li value="1" ><a href="#" class="fontLink fontDarkGray">Orden inverso</a></li>
199
+ </ul>
200
+ </div>
201
+ </div>
202
+ </div>
203
+ </div>
204
+
205
+ <div id="contactlist"></div>
206
+ <script type="text/javascript">
207
+ var InitialContacts = [{"guid":"","contactId":"50331649","contactName":"Juan Perez Robetto jjjjj","email":"hhh@hhh.com","emaillink":"http:\/\/mrd.mail.yahoo.com\/compose?To=hhh%40hhh.com","isConnection":false,"connection":"","displayImg":null,"msgrID":"","msgrStatus":"","isMsgrBuddy":false},{"guid":"","contactId":"50331650","contactName":"Roque Perez","email":"hhh@hhhh.com","emaillink":"http:\/\/mrd.mail.yahoo.com\/compose?To=hhh%40hhhh.com","isConnection":false,"connection":"","displayImg":null,"msgrID":"","msgrStatus":"","isMsgrBuddy":false}];
208
+ var InitialBucket = 0;
209
+ var InitialSortField = {'order':1, 'type':1};
210
+ var InitialCid = null;
211
+ var InitialRevID = 9;
212
+ var TotalABContacts = 2;
213
+ var ABRevCheckTime = 180;
214
+ var RetryListFetch = 0;
215
+ </script>
216
+
217
+ <div id="vResizer" class="colorC1" title="Hacé clic y arrastrá hacia la izquierda o derecha para cambiar el tamaño"><div id="grabber" class="abIcons grabberBarIcon"></div></div>
218
+ </div>
219
+ <div id="yui-main">
220
+ <div id="workspace_area" class="yui-b">
221
+ <div id="workspaceView" style="display:block">
222
+ <div id="notifications">
223
+
224
+
225
+ </div>
226
+
227
+ <div id="defaultWS" class="defaultWS" >
228
+ <div class="container">
229
+ <div id="yab-socialmain" class="container_text fontT1 fontDarkGray">
230
+ <h1 class="landing-title fontBold fontH1"><span>Contactos (<span id='total_contacts'>2</span>)</span></h1>
231
+ <ul class="text">
232
+ <li>Seleccioná un contacto para ver o editar sus datos.</li>
233
+ <li>Seleccioná varios contactos para enviar un correo a todos a la vez o para añadirlos a una categoría.</li>
234
+ <li>Filtrá tu lista de contactos con el menú desplegable (está arriba a la izquierda).</li>
235
+ </ul>
236
+ <div class="allcontact-info">
237
+ <div class="hd fontBold fontH2 colorC3 colorBK3">
238
+ Herramientas populares </div>
239
+ <div class="bd">
240
+ <ul>
241
+
242
+ <li class="clearfix">
243
+ <div class="allcontact-icon peoplemover"></div>
244
+ <div class="info-blk">
245
+ <p>Importá tus contactos de otras cuentas a Yahoo!</p>
246
+ <div class="info-link">
247
+ <a class="fontLink contact_import_landing_link" id="allcontact-peoplemover" href="#">» Importar contactos</a>
248
+ </div>
249
+ </div>
250
+ </li>
251
+
252
+ <li class="clearfix">
253
+ <div class="allcontact-icon fixdup"></div>
254
+ <div class="info-blk">
255
+ <p>Disfrutá de una lista de contactos limpia</p> <div class="info-link">
256
+ <a id="allcontact_fixdup" class="fontLink allcontact_fixdup" href="#">» Arreglar las entradas duplicadas</a>
257
+ </div>
258
+ </div>
259
+ </li>
260
+ <script type="text/javascript" charset="utf-8">
261
+ kParams.view_contact_id = '-999';
262
+ </script>
263
+ </ul>
264
+ </div>
265
+ <div class="ft"></div>
266
+ </div>
267
+ </div>
268
+ </div>
269
+ </div>
270
+
271
+ <div id='checkboxView' class='defaultWS' style='display:none'>
272
+ <div class="container">
273
+ <div class="container_text fontT1 fontDarkGray">
274
+ <h2 class="fontBold fontH1"><span id="selectedCount">1 contacto seleccionado</span></h2>
275
+ <ul>
276
+ <li>
277
+ <a href="#" id="email_contacts" class="send_email_multi fontLink">Enviar mensaje</a>
278
+ <span class="notalink">Enviar mensaje</span>
279
+ </li>
280
+ <ul id="max_email_msg" class="hidelinkmsgs" style="display:none">
281
+ <li id="invalid_email_msg" style="display:none"><div class="abIcons infoIcon"></div>Uno o más de los contactos seleccionados no tienen una dirección de correo electrónico. Estos contactos no recibirán el mensaje de correo electrónico.</li>
282
+ <li id="max_send_email" style="display:none"><div class="abIcons hazard"></div>Seleccionaste demasiados contactos para el mensaje. Por favor, deseleccioná uno o más contactos para continuar.</li>
283
+ </ul>
284
+
285
+ <li><span id="catChange"><a class="getcontactcat multicontact fontLink" href="#">Añadir a categoría</a></span></li>
286
+
287
+ <li style="display:none"><a href="#" id="print_contacts" class="fontLink">Imprimir datos de contacto</a></li>
288
+
289
+ <li style="display:none"><a href="#" class="fontLink">Fusionar como contacto individual</a></li>
290
+
291
+ <li style="display:none"><a href="#" class="fontLink">Enviar información de contacto</a></li>
292
+ <li style="display:none"><a href="#" class="fontLink">Enviar una tarjeta electrónica</a></li>
293
+
294
+
295
+ <li><a href="#" id="delete_contacts" class="deletecontacts multicontact fontLink">Borrar</a></li>
296
+ </ul>
297
+ </div>
298
+ </div>
299
+ </div>
300
+ </div>
301
+ <div id="cont_edit_dlg" class="social_dialog" style="visibility:hidden">
302
+ <div class="hd">
303
+ <span id="navaway_hd">Cambios no guardados</span>
304
+ </div>
305
+ <div class="bd">
306
+ <div class="abIcons infoIcon info"></div>
307
+ <div class="bd_text">
308
+ <span id="navaway_addedit_bd" class="dlg_text_hide">Estabas editando un contacto. ¿Querés guardar tus cambios?</span>
309
+ <span id="navaway_cat_bd" class="dlg_text_hide">Estabas editando una categoría. ¿Querés guardar tus cambios?</span>
310
+ </div>
311
+ </div>
312
+ <div class="ft actionButton">
313
+ <span class="yui-button yui-button-button">
314
+ <span class="first-child"><button id="saveEditAction" type="button" class="gradientImg actionBtnTile ">GUARDAR</button></span>
315
+ </span>
316
+ <span class="yui-button yui-button-button dontSaveBtn">
317
+ <span class="first-child"><button id="dSaveEditAction" type="button" class="gradientImg actionBtnTileSec ">NO GUARDAR</button></span>
318
+ </span>
319
+ <span class="cancel"><a href="#" id="cancelEditAction">Cancelar</a></span>
320
+ </div>
321
+ </div> </div>
322
+ </div>
323
+ <div id="wait_action_dlg" class="social_dialog" style="visibility:hidden">
324
+ <div class="hd">Espera por favor…</div>
325
+ <div class="bd">
326
+ <div id="waitTwirly" class="twirlyContainer">
327
+ <div class="waitTwirly"></div>
328
+ <p id="wait_action_text">Esperá…</p>
329
+ </div>
330
+ </div>
331
+ <div class="ft"></div>
332
+ </div>
333
+ </div>
334
+ </div>
335
+
336
+ <div id="delete_dlg" class="social_dialog" style="visibility:hidden">
337
+ <div class="hd">
338
+ <span class="del_single dlg_hide">¿Eliminar contacto?</span>
339
+ <span class="del_multi dlg_hide">¿Eliminar contactos?</span>
340
+ </div>
341
+ <div class="bd">
342
+ <span id='del_single_conn_dlg' class='del_single dlg_hide'><p class='dlgBodyHdr'><span class='contact_display_name'></span> es también un Amigo.</p><div style='padding-top:10px;padding-bottom:10px;'><ul><li>Al eliminar este contacto, lo eliminarás también de tus Amigos</li><li>El contacto no ha sido notificado</li><li>Dejarás de recibir las actualizaciones de contenido para este contacto</li><li>Dejarás de ver este contacto en tu lista de Messenger</li></ul></div><p class='dlgBodyQues'>¿Realmente querés eliminar este contacto?</p></span> <span id='del_single_msgr_dlg' class='del_single dlg_hide'><p class='dlgBodyHdr'><span class='contact_display_name'></span> también está incluido en tu lista de Messenger.</p><div style='padding-top:10px;padding-bottom:10px;'><p>Al eliminar este contacto, también lo eliminarás de la lista de Messenger.</p></div><p class='dlgBodyQues'>¿Realmente querés eliminar este contacto?</p></span> <span id='del_single_default_dlg' class='del_single dlg_hide'><p class='dlgBodyQues'>¿Querés eliminar a <span class='contact_display_name'></span> de tu contactos?</p></span> <span id='del_multi_conn_dlg' class='del_multi dlg_hide'><p class='dlgBodyHdr'>Al menos algunos de estos contactos son también Amigos.</p><div style='padding-top:10px;padding-bottom:10px;'><ul><li>Estos contactos se eliminarán de tus Amigos</li><li>Los contactos no serán notificados</li><li>Dejarás de recibir sus actualizaciones de contenido</li></ul><p>Además no seguirás viendo estos contactos en tu lista de Messenger.</p></div><p class='dlgBodyQues'>¿Querés eliminar <span class='contacts_text_count'></span> contacto(s)?</p></span> <span id='del_multi_msgr_dlg' class='del_multi dlg_hide'><p class='dlgBodyHdr'>Al menos algunos de estos contactos también están incluidos en la lista de Messenger.</p><div style='padding-top:10px;padding-bottom:10px;'><p>Al eliminar estos contactos, también los eliminarás de la lista de Messenger.</p></div><p class='dlgBodyQues'>¿Querés eliminar <span class='contacts_text_count'></span> contacto(s)?</p></span> <span id='del_multi_default_dlg' class='del_multi dlg_hide'><p class='dlgBodyQues'>¿Querés eliminar <span class='contacts_text_count'></span> contacto(s)?</p></span> </div>
343
+ <div class="ft">
344
+ <span class="delDialogBtns actionButton">
345
+ <span class="yui-button yui-button-button">
346
+ <span class="first-child"><button id="delSubmitAction" type="button" class="gradientImg actionBtnTile fontT2">ELIMINAR</button></span>
347
+ </span>
348
+ <span class="cancel"><a href="#" id="delCancelAction">Cancelar</a></span>
349
+ </span>
350
+ </div>
351
+ </div><div id="remove_conn_dlg" class="social_dialog" style="visibility:hidden">
352
+ <div class="hd">¿Eliminar amigo?</div>
353
+ <div class="bd">
354
+ <p class="dlgBodyHdr">Cuando elimines <span class='contact_display_name'></span> de tus Amigos:</p>
355
+ <div style="padding-top:10px;padding-bottom:10px;">
356
+ <p>* <span class='contact_display_name'></span> no será notificado</p>
357
+ <p>* <span class='contact_display_name'></span> no se seguirá mostrando como un amigo.</p>
358
+ <p>* No seguirás recibiendo Actualizaciones para <span class='contact_display_name'></span></p>
359
+ </div>
360
+ <p class="dlgBodyQues">¿Realmente querés eliminar <span class='contact_display_name'></span> de tus Amigos?</p>
361
+ </div>
362
+ <div class="ft actionButton">
363
+ <span class="yui-button yui-button-button">
364
+ <span class="first-child"><button id="remSubmitAction" type="button" class="gradientImg actionBtnTile fontT2">QUITAR</button></span>
365
+ </span>
366
+ <span class="cancel"><a href="#" id="remCancelAction">Cancelar</a></span>
367
+ </div>
368
+ </div><script>
369
+ kParams.invite_kiosk_css_uri = 'http://l.yimg.com/a/lib/pim/r/abook/kiosks/invite/1.1.76/invite_to_connect.css';
370
+ kParams.invite_kiosk_uri = 'http://l.yimg.com/a/lib/pim/r/abook/kiosks/invite/1.1.76/ar/invite_to_connect.js';
371
+ kParams.invite_kiosk_init = function(){var loader = YAHOO.LoadAddCxn.getInstance();loader.setConfig({"path":"http:\/\/l.yimg.com\/a\/lib\/pim\/r\/abook\/kiosks\/invite\/1.1.76\/","devmode":false,"customMessaging":0});loader.load([]);YAHOO.AddCxn.sender={givenName:"Push K",familyName:"Development",nickName:"Push K",nux:"0",guid:"ERPXY4AEFQMS7V46TFLDYBVVCQ"};YAHOO.AddCxn.conf={ip:"98.138.5.229",proxy:"/dc/ws/sd?",src:"ab",intl:"ar",spaceid_offset:"1000",wssid:"flnOg.pvyww",urlExtras:".gx=1",timeout:30000,enable_retrieve:1,maxRec:20};loader.LoadAndConfSuccessEvent.fire();; return loader;};
372
+ kParams.retrieve_css_uri ='http://l.yimg.com/a/lib/pim/r/abook/kiosks/retrieve/1.0.70/retrieve.css';
373
+ kParams.retrieve_kiosk_uri = 'http://l.yimg.com/a/lib/pim/r/abook/kiosks/retrieve/1.0.70/ar/retrieve.js';
374
+ kParams.retrieve_kiosk_init = function(){var loader = YAHOO.addressbook.LoadRetrieve.getInstance();loader.setConfig({"path":"http:\/\/l.yimg.com\/a\/lib\/pim\/r\/abook\/kiosks\/retrieve\/1.0.70\/","devmode":false});loader.FileLoadSuccessEvent.subscribe(function(e){YAHOO.addressbook.retrieve.conf={context:"name",categoriesJSURL:"/dc/ws/sd?/v1/user/ERPXY4AEFQMS7V46TFLDYBVVCQ/categories;count=5000;?_sc=false&wssid=flnOg.pvyww&.gx=1",contactsJSURL:"/dc/ws/sd?/v1/user/ERPXY4AEFQMS7V46TFLDYBVVCQ/contacts;out=name,nickname,displayname;count=5000;sort-fields=first;sort=asc?_sc=false&wssid=flnOg.pvyww&.gx=1",src:"ab",intl:"ar",timeout:"30000",wssid:"flnOg.pvyww",debug:false};loader.LoadAndConfSuccessEvent.fire();});loader.load([]);;return loader;};
375
+ </script><div id="footer">
376
+ <!-- SpaceID=1181603055 loc=FOOT9 noad -->
377
+ <!--QYZ ,;;;1181603055;;--></div>
378
+
379
+ <script type="text/javascript">
380
+ /**
381
+ * [Ticket 4693360]
382
+ * Check if the AB iframe is loaded in same domain. If Not framebust!
383
+ */
384
+ if(self.location.host != top.location.host) {
385
+ top.location.replace(self.location);
386
+ }
387
+
388
+ </script>
389
+
390
+ <script type="text/javascript">
391
+ function load_js_strings() {
392
+ (function(){if (!(YAHOO && YAHOO.addressbook && YAHOO.addressbook.Yala)){throw("Yala not defined!");}else{var Yala=YAHOO.addressbook.Yala;
393
+ Yala.register('INTL_YAB_NUM_CONTACTS', 'Tenés %s contactos.');
394
+ Yala.register('INTL_YAB_AB2_VIEW', 'Vista');
395
+ Yala.register('INTL_YAB_SUBHEAD_SEPARATOR', ':');
396
+ Yala.register('INTL_YAB_SORTMENU_SORTED', 'Ordenado');
397
+ Yala.register('INTL_YAB_SORTMENU_BY_FIRSTNAME', 'Nombre');
398
+ Yala.register('INTL_YAB_NUM_SELECTED_CONTACTS', 'Has seleccionado %s contactos.');
399
+ Yala.register('INTL_YAB_FILTERMENU_ALLCONTACTS', 'Todos los contactos');
400
+ Yala.register('INTL_YAB_FILTERMENU_DELETED', 'Contactos eliminados');
401
+ Yala.register('INTL_YAB_SEARCH_RESULT_HEAD', 'Resultados: (%s)');
402
+ Yala.register('INTL_YAB_NEW_CONTACT_NAME', '- Sin título -');
403
+ Yala.register('INTL_YAB_DTABLE_MSG_EMPTY', 'Sin contactos');
404
+ Yala.register('INTL_YAB_DTABLE_MSG_EMPTY_CONN', 'Ningún amigo');
405
+ Yala.register('INTL_YAB_DTABLE_MSG_LOADING', 'Cargando contactos');
406
+ Yala.register('INTL_YAB_DTABLE_CONTACT_LOADING', 'cargando…');
407
+ Yala.register('INTL_YAB_CONTACT_LIST_MOBILE_PHONE_SHORT', '%1$s (cel)');
408
+ Yala.register('INTL_YAB_CONTACT_LIST_HOME_PHONE_SHORT', '%1$s (cas)');
409
+ Yala.register('INTL_YAB_CATEGORY_EDIT_BUTTON_DONE', 'TERMINADO');
410
+ Yala.register('INTL_YAB_DETAILED_FIELD_CATEGORIES', 'Categorías:');
411
+ Yala.register('INTL_YAB_TOOLTIP_ADD', 'Añadí un contacto');
412
+ Yala.register('INTL_YAB_TOOLBAR_ADD_CONTACT', 'Añadir contacto');
413
+ Yala.register('INTL_YAB_TOOLBAR_ADD_CATEGORY', 'Añadir categoría');
414
+ Yala.register('INTL_YAB_TOOLBAR_ADD_CONNECTION', 'Añadir amigo');
415
+ Yala.register('INTL_YAB_TOOLBAR_BTN_MOREACTIONS', 'Herramientas');
416
+ Yala.register('INTL_YAB_CONNECTIONTOOL_BACK_TO_CONTACTS', 'Volver a Contactos');
417
+ Yala.register('INTL_YAB_FBIMPORT_BACK', 'Atrás');
418
+ Yala.register('INTL_YAB_TOOLTIP_BACK_TO_CONTACTS', 'Volver a la vista de libreta de contactos');
419
+ Yala.register('INTL_YAB_CONN_WS_HEADER_MULTI', 'Amigos (%s)');
420
+ Yala.register('INTL_YAB_CONN_WS_HEADER_SINGLE', 'Amigo (1)');
421
+ Yala.register('INTL_YAB_AB2_UNFILED', 'Sin clasificar');
422
+ Yala.register('INTL_YAB_CDETAIL_HEADER_CHANGE', 'Cambiar');
423
+ Yala.register('INTL_YAB_BTN_ADD_CATEGORIES', 'Añadir');
424
+ Yala.register('INTL_YAB_NO_CATEGORY_NAME_ERROR', 'Introducí un nombre de categoría para la nueva categoría que te gustaría crear');
425
+ Yala.register('INTL_YAB_FIELD_NEW_LABEL', 'Etiqueta nueva');
426
+ Yala.register('INTL_YAB_BUTTON_DELETE', 'Borrar');
427
+ Yala.register('INTL_YAB_BUTTON_CANCEL', 'Cancelar');
428
+ Yala.register('INTL_YAB_DELETE_CATEGORY_CONFIRM', 'Tenés <b>%s contacto(s)</b> en la <b>categoría %s.</b><p>Al eliminar esta categoría, no lo(s) eliminarás de tu Yahoo! Contactos.</p><p><b>¿Realmente querés eliminar esta categoría?</b></p>');
429
+ Yala.register('INTL_YAB_DELETE_CATEGORY_QUESTION', '¿Eliminar categoría?');
430
+ Yala.register('INTL_YAB_CATEGORY_NAME_EXISTS', 'El nombre de la categoría introducida ya existe. Volvé a intentarlo.');
431
+ Yala.register('INTL_YAB_CATEGORY_ADD_SUCCESS', 'La categoría se añadió correctamente.');
432
+ Yala.register('INTL_YAB_CATEGORY_EDIT_SUCCESS', 'El nombre de la categoría se editó correctamente.');
433
+ Yala.register('INTL_YAB_CATEGORY_NAME_TOO_LONG', 'El largo máximo del nombre de una categoría es de 15 caracteres. Introducí un nombre de categoría más corto.');
434
+ Yala.register('INTL_YAB_CONFIRM_EDIT_CANCEL', 'Se perderá cualquier cambio realizado durante la edición. ¿Estás seguro que querés continuar?');
435
+ Yala.register('INTL_YAB_CONFIRM_EDIT_CLOSE', 'Se perderá cualquier cambio realizado durante la modificación.');
436
+ Yala.register('INTL_YAB_CHKBOX_WS_HEADER_SINGLE', '1 contacto seleccionado');
437
+ Yala.register('INTL_YAB_CHKBOX_WS_HEADER_MULTI', '%s contactos seleccionados');
438
+ Yala.register('INTL_YAB_EDIT_WEBSITE_LABEL', 'Sitio web %s');
439
+ Yala.register('INTL_YAB_NEW_CATEGORY_TOOLTIP', 'Crear un nuevo nombre de categoría');
440
+ Yala.register('INTL_YAB_TYPE_NEW_CATEGORY', 'Nueva categoría');
441
+ Yala.register('INTL_YAB_NO_CATEGORY_NAME_ERROR', 'Introducí un nombre de categoría para la nueva categoría que te gustaría crear');
442
+ Yala.register('INTL_YAB_CATEGORY_ADD_ERRORMULTI_TEXT', 'Hubo un problema al añadir estos contactos a la(s) categoría(s). Intentalo de nuevo.');
443
+ Yala.register('INTL_YAB_CATEGORY_ADD_ERRORSINGLE_TEXT', 'Ha ocurrido un problema al añadir este contacto a las categorías. Intentalo de nuevo.');
444
+ Yala.register('INTL_YAB_NO_CONTACTS_HAVE_EMAILS', 'Ninguno de los contactos seleccionados tiene una dirección de correo electrónico o nombre de usuario de Yahoo. Seleccioná otros contactos e intentalo de nuevo.');
445
+ Yala.register('INTL_YAB_EMPTY_CATEGORY_DELETE', '¿Realmente querés eliminar esta categoría?');
446
+ Yala.register('INTL_YAB_EMPTY_DELETE_PROGRESS', 'Eliminando contactos…');
447
+ Yala.register('INTL_YAB_DELETE_CONTACT_PROGRESS', 'Eliminando el contacto…');
448
+ Yala.register('INTL_YAB_GENERIC_SOCDIR_OUTAGE_ERROR', 'Lo lamentamos. Es posible que algunas herramientas no funcionen debido a problemas técnicos. Intentalo de nuevo en otro momento.');
449
+ Yala.register('INTL_YAB_AB2_THERE_WAS_A_TEM', 'Hubo un problema temporal al acceder a tu libreta de Contactos. Por favor, intentalo de nuevo en 10 minutos. Si seguís viendo el mismo problema, ponete en contacto con nuestro departamento de Atención al Cliente. Gracias.');
450
+ Yala.register('INTL_YAB_EMPTY_DELETE_ERRORSINGLE_TEXT', 'Ha ocurrido un problema al intentar eliminar %s. Intentalo de nuevo.');
451
+ Yala.register('INTL_YAB_EMPTY_DELETE_ERRORMULTI_TEXT', 'Ha ocurrido un problema al intentar eliminar estos contactos. Intentalo de nuevo.');
452
+ Yala.register('INTL_YAB_TRASH_WS_RESTORE_ERROR', 'Ha ocurrido un problema al intentar restaurar %s. Intentalo de nuevo.');
453
+ Yala.register('INTL_YAB_TRASH_WS_RESTOREALL_ERROR', 'Ha ocurrido un problema al intentar restaurar estos contactos. Intentalo de nuevo.');
454
+ Yala.register('INTL_YAB_TRASH_WS_RESTORE_YIDERROR', 'Ha ocurrido un problema al intentar restaurar %1$s. Ya existe un contacto asociada al nombre de usuario de Messenger "%2$s".');
455
+ Yala.register('INTL_YAB_TRASH_WS_HEADER_SELMULTI', '%s contactos eliminados seleccionados');
456
+ Yala.register('INTL_YAB_TRASH_WS_HEADER_SELSINGLE', '%s contacto eliminado seleccionado');
457
+ Yala.register('INTL_YAB_RESTORE_CONTACT_PROGRESS', 'Restaurando contacto…');
458
+ Yala.register('INTL_YAB_RESTORE_CONTACTS_PROGRESS', 'Restaurando contactos…');
459
+ Yala.register('INTL_YAB_TRASH_WS_DELETEPERM_ERROR', 'Ha ocurrido un problema al intentar eliminar permanentemente %s. Intentalo de nuevo.');
460
+ Yala.register('INTL_YAB_TRASH_WS_DELETEPERMALL_ERROR', 'Ha ocurrido un problema al intentar eliminar permanentemente estos contactos. Intentalo de nuevo.');
461
+ Yala.register('INTL_YAB_SAVE_CONTACT_PROGRESS', 'Guardando contacto…');
462
+ Yala.register('INTL_YAB_REMOVE_CONNECTION_PROGRESS', 'Eliminar amigo…');
463
+ Yala.register('INTL_YAB_UPDATE_LIST_PROGRESS', 'Actualizando lista de contactos…');
464
+ Yala.register('INTL_YAB_FILTERMENU_CONNECTIONS', 'Amigos');
465
+ Yala.register('INTL_YAB_FILTERMENU_ALLCONTACTS', 'Todos los contactos');
466
+ Yala.register('INTL_YAB_FILTERMENU_DELETED', 'Contactos eliminados');
467
+ Yala.register('INTL_YAB_FILTERMENU_UNFILED', 'No clasificados');
468
+ Yala.register('INTL_YAB_FBIMPORT_LASTIMPORTED', 'Última importación');
469
+ Yala.register('INTL_YAB_TOO_MANY_INVITEES_ERROR', 'Has sobrepasado el número de destinatarios que podés invitar.');
470
+ Yala.register('INTL_YAB_DIALOG_UNSAVED_ADDEDIT_TEXT', 'Estabas editando un contacto. ¿Querés guardar tus cambios?');
471
+ Yala.register('INTL_YAB_DIALOG_UNSAVED_CATEGORY_TEXT', 'Estabas editando una categoría. ¿Querés guardar tus cambios?');
472
+ Yala.register('INTL_YAB_INVALID_INVITE_CONTACTS_MSG', 'Uno o más de los contactos seleccionados es un amigo o no tiene dirección de correo electrónico ni nombre de usuario de Y!Messenger. Estos contactos no recibirán una invitación.');
473
+ Yala.register('INTL_YAB_SEND_EMAIL_PROGRESS', 'Añadiendo los contactos a un nuevo correo…');
474
+ Yala.register('INTL_YAB_MAX_COUNT_INVITES_MSG', 'No podrás invitar a más de %s contactos a la vez.');
475
+ Yala.register('INTL_YAB_IS_SYSTEM_CATEGORY', 'El nombre de categoría introducido es un nombre especial que está siendo utilizado por el sistema. Intentá con otro nombre.');
476
+ Yala.register('INTL_YAB_CDETAIL_HEADER_TOOLTIP_TRASH', 'Eliminar este contacto');
477
+ Yala.register('INTL_YAB_BUTTON_EDIT', 'Modificar');
478
+ Yala.register('INTL_YAB_CDETAIL_HEADER_TOOLTIP_EDIT', 'Editar datos del contacto');
479
+ Yala.register('INTL_YAB_ADD_TO_CATEGORY_PROGRESS', 'Añadiendo el contacto a %s...');
480
+ Yala.register('INTL_YAB_ADD_TO_CATEGORY_MULTI_PROGRESS', 'Añadiendo los contactos a %s...');
481
+ Yala.register('INTL_YAB_ADD_TO_REMOVEFROMCAT_PROGRESS', 'Eliminando el contacto de %s...');
482
+ Yala.register('INTL_YAB_ADD_TO_REMOVEFROMCAT_MULTI_PROGRESS', 'Eliminando los contactos de %s...');
483
+ Yala.register('INTL_YAB_CONSUMERLIST_MANAGE_BTN', 'Administrar mis actualizaciones');
484
+ Yala.register('INTL_YAB_HSP_GET_UPDATES_FROM_OTHERS', 'Recibir actualizaciones de otros');
485
+ Yala.register('INTL_YAB_EDIT_EMAIL_LABEL', 'Correo %s');
486
+ Yala.register('INTL_YAB_EDIT_PRIMARY_EMAIL_LABEL', 'Dirección principal de correo electrónico');
487
+
488
+ }})()
489
+ }
490
+ </script>
491
+
492
+
493
+
494
+ <script src="http://yui.yahooapis.com/combo?2.7.0/build/utilities/utilities.js&2.7.0/build/container/container_core-min.js&2.7.0/build/menu/menu-min.js&2.7.0/build/json/json-min.js&3.1.1/build/yui/yui-min.js"></script>
495
+ <script src="http://l.yimg.com/qa/sab/2.17.376/ar/eagle2.js"></script>
496
+
497
+
498
+
499
+
500
+ <script type="text/javascript">
501
+ <!-- <CDATA[[
502
+ if(typeof CallDOMLoadedHandlers != "undefined"){
503
+ CallDOMLoadedHandlers();
504
+ }
505
+ // ]]> -->
506
+ </script>
507
+
508
+
509
+ </body>
510
+ <!--
511
+ // TS: 1323923940
512
+ // P: 1295.43
513
+
514
+ // T: 24.88
515
+
516
+ // B: 291.03
517
+ // BTX: 3
518
+ // Y: 909.44
519
+
520
+ // R: 21.42
521
+ // U: 0.01
522
+ // A: 21.31
523
+ // O: 0
524
+
525
+ -->
526
+
527
+
528
+ <!-- // RPPID:15855 --></html><script type="text/javascript">
529
+ var landingServerStats = {"version":"2.17.376","page_load":1296,"template_load":25,"backend":291,"yos":909,"remote_api":21,"udb_open":0,"opium":0,"adserver":21};
530
+ </script>
531
+ <script language=javascript>
532
+ if(window.yzq_p==null)document.write("<scr"+"ipt language=javascript src=http://l.yimg.com/d/lib/bc/bcr_2.0.5.js></scr"+"ipt>");
533
+ </script><script language=javascript>
534
+ if(window.yzq_p)yzq_p('P=mT7WeWKKGQu6dFHJTul53QPdYooF5U7peeMABLe7&T=177m962bk%2fX%3d1323923940%2fE%3d1181603055%2fR%3darsocab%2fK%3d5%2fV%3d1.1%2fW%3dJR%2fY%3dAR%2fF%3d1507333063%2fH%3dc2VydmVJZD0ibVQ3V2VXS0tHUXU2ZEZISlR1bDUzUVBkWW9vRjVVN3BlZU1BQkxlNyIgdFN0bXA9IjEzMjM5MjM5NDA1ODMwNjkiIA--%2fS%3d1%2fJ%3d2B198A62');
535
+ if(window.yzq_s)yzq_s();
536
+ </script><noscript><img width=1 height=1 alt="" src="http://row.bc.yahoo.com/b?P=mT7WeWKKGQu6dFHJTul53QPdYooF5U7peeMABLe7&T=17c8342ib%2fX%3d1323923940%2fE%3d1181603055%2fR%3darsocab%2fK%3d5%2fV%3d3.1%2fW%3dJR%2fY%3dAR%2fF%3d3471534006%2fH%3dc2VydmVJZD0ibVQ3V2VXS0tHUXU2ZEZISlR1bDUzUVBkWW9vRjVVN3BlZU1BQkxlNyIgdFN0bXA9IjEzMjM5MjM5NDA1ODMwNjkiIA--%2fQ%3d-1%2fS%3d1%2fJ%3d2B198A62"></noscript><script language=javascript>
537
+ (function(){window.xzq_p=function(R){M=R};window.xzq_svr=function(R){J=R};function F(S){var T=document;if(T.xzq_i==null){T.xzq_i=new Array();T.xzq_i.c=0}var R=T.xzq_i;R[++R.c]=new Image();R[R.c].src=S}window.xzq_sr=function(){var S=window;var Y=S.xzq_d;if(Y==null){return }if(J==null){return }var T=J+M;if(T.length>P){C();return }var X="";var U=0;var W=Math.random();var V=(Y.hasOwnProperty!=null);var R;for(R in Y){if(typeof Y[R]=="string"){if(V&&!Y.hasOwnProperty(R)){continue}if(T.length+X.length+Y[R].length<=P){X+=Y[R]}else{if(T.length+Y[R].length>P){}else{U++;N(T,X,U,W);X=Y[R]}}}}if(U){U++}N(T,X,U,W);C()};function N(R,U,S,T){if(U.length>0){R+="&al="}F(R+U+"&s="+S+"&r="+T)}function C(){window.xzq_d=null;M=null;J=null}function K(R){xzq_sr()}function B(R){xzq_sr()}function L(U,V,W){if(W){var R=W.toString();var T=U;var Y=R.match(new RegExp("\\\\(([^\\\\)]*)\\\\)"));Y=(Y[1].length>0?Y[1]:"e");T=T.replace(new RegExp("\\\\([^\\\\)]*\\\\)","g"),"("+Y+")");if(R.indexOf(T)<0){var X=R.indexOf("{");if(X>0){R=R.substring(X,R.length)}else{return W}R=R.replace(new RegExp("([^a-zA-Z0-9$_])this([^a-zA-Z0-9$_])","g"),"$1xzq_this$2");var Z=T+";var rv = f( "+Y+",this);";var S="{var a0 = '"+Y+"';var ofb = '"+escape(R)+"' ;var f = new Function( a0, 'xzq_this', unescape(ofb));"+Z+"return rv;}";return new Function(Y,S)}else{return W}}return V}window.xzq_eh=function(){if(E||I){this.onload=L("xzq_onload(e)",K,this.onload,0);if(E&&typeof (this.onbeforeunload)!=O){this.onbeforeunload=L("xzq_dobeforeunload(e)",B,this.onbeforeunload,0)}}};window.xzq_s=function(){setTimeout("xzq_sr()",1)};var J=null;var M=null;var Q=navigator.appName;var H=navigator.appVersion;var G=navigator.userAgent;var A=parseInt(H);var D=Q.indexOf("Microsoft");var E=D!=-1&&A>=4;var I=(Q.indexOf("Netscape")!=-1||Q.indexOf("Opera")!=-1)&&A>=4;var O="undefined";var P=2000})();
538
+ </script><script language=javascript>
539
+ if(window.xzq_svr)xzq_svr('http://csc.beap.ad.yieldmanager.net/');
540
+ if(window.xzq_p)xzq_p('i?bv=1.0.0&bs=(128m2frqu(gid$mT7WeWKKGQu6dFHJTul53QPdYooF5U7peeMABLe7,st$1323923940583069,v$1.0))&t=JR_3-DR_3');
541
+ if(window.xzq_s)xzq_s();
542
+ </script><noscript><img width=1 height=1 alt="" src="http://csc.beap.ad.yieldmanager.net/i?bv=1.0.0&bs=(128m2frqu(gid$mT7WeWKKGQu6dFHJTul53QPdYooF5U7peeMABLe7,st$1323923940583069,v$1.0))&t=JR_3-DR_3"></noscript>
543
+ <!-- web211.address.pim.ne1.yahoo.com compressed/chunked Wed Dec 14 20:38:59 PST 2011 -->
@@ -2,5 +2,7 @@ require 'mechanize'
2
2
  require 'nokogiri'
3
3
  require "garlenko/version"
4
4
  require "garlenko/base"
5
+ require "garlenko/crawler"
5
6
  require "garlenko/live"
6
7
  require "garlenko/gmail"
8
+ require "garlenko/yahoo"
@@ -5,6 +5,7 @@ module Garlenko
5
5
  case kind
6
6
  when :live then Live.new(username, password)
7
7
  when :gmail then Gmail.new(username, password)
8
+ when :yahoo then Yahoo.new(username, password)
8
9
  else
9
10
  raise "Invalid kind (#{kind})!"
10
11
  end
@@ -21,9 +22,18 @@ module Garlenko
21
22
  @connected = false
22
23
  end
23
24
 
25
+ def connect!
26
+ raise NotImplementedError
27
+ end
28
+
29
+ def contacts
30
+ raise NotImplementedError
31
+ end
32
+
24
33
  def connected?
25
34
  @connected
26
35
  end
36
+
27
37
  end
28
38
 
29
39
  end
@@ -0,0 +1,14 @@
1
+ module Garlenko
2
+
3
+ module Crawler
4
+
5
+ def agent
6
+ @agent ||= Mechanize.new { |agent|
7
+ agent.user_agent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)"
8
+ agent.follow_meta_refresh = true
9
+ }
10
+ end
11
+
12
+ end
13
+
14
+ end
@@ -2,18 +2,11 @@ module Garlenko
2
2
 
3
3
  class Live < Base
4
4
 
5
- attr_accessor :last_result
5
+ include Crawler
6
6
 
7
7
  LOGIN_URL = "https://mid.live.com/si/login.aspx"
8
8
  CONTACTS_URL = "http://mpeople.live.com"
9
9
 
10
- def agent
11
- @agent ||= Mechanize.new { |agent|
12
- agent.user_agent = 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)'
13
- agent.follow_meta_refresh = true
14
- }
15
- end
16
-
17
10
  def connect!(force_connect = false)
18
11
  return @connected unless !connected? or force_connect
19
12
  login_form = agent.get(LOGIN_URL).form('EmailPasswordForm')
@@ -38,6 +31,8 @@ module Garlenko
38
31
  contacts_so_far
39
32
  end
40
33
 
34
+ private
35
+
41
36
  def on_contacts_page(url, &block)
42
37
  unless url.nil?
43
38
  page = agent.get(url)
@@ -1,3 +1,3 @@
1
1
  module Garlenko
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -0,0 +1,62 @@
1
+ require 'json'
2
+
3
+ module Garlenko
4
+
5
+ class Yahoo < Base
6
+
7
+ LOGIN_URL = "https://login.yahoo.com/config/login_verify2"
8
+ CONTACTS_URL = "http://address.mail.yahoo.com/?.rand=930244936"
9
+ CONTACTS_LIST_URL ="http://address.mail.yahoo.com/?_src=&_crumb=crumb&sortfield=3&bucket=1&scroll=1&VPC=social_list&.r=time"
10
+
11
+ include Crawler
12
+
13
+ def connect!
14
+ login_form = agent.get(LOGIN_URL).form("login_form")
15
+ login_form.login = @username
16
+ login_form.passwd = @password
17
+ login_res = agent.submit(login_form, login_form.submits.first)
18
+ address_page = agent.get(CONTACTS_URL)
19
+ @connected = address_page.body.include?("masthead_welcome2")
20
+ end
21
+
22
+ def contacts
23
+ return @contacts if @contacts
24
+ connect! unless connected?
25
+ @contacts = []
26
+ @contacts = fetch_page(1, crumb_from(agent.get(CONTACTS_URL).body))
27
+ @contacts
28
+ end
29
+
30
+ private
31
+
32
+ def crumb_from(body)
33
+ body.to_s[/dotCrumb: '(.*?)'/][13...-1]
34
+ end
35
+
36
+ def fetch_page(page, crumb)
37
+ url = URI.parse(CONTACTS_LIST_URL.sub("_crumb=crumb","_crumb=#{crumb}").sub("time", Time.now.to_f.to_s.sub('.', '')[0...-2]))
38
+ data = agent.get(url, nil, CONTACTS_URL, {"X-Requested-With" => "XMLHttpRequest"}).body
39
+ contacts_data, total_contacts, current_page = parse_response(data)
40
+ contacts = parse_contacts_from(contacts_data) if contacts_data
41
+
42
+ if contacts.size < total_contacts
43
+ contacts += fetch_page(current_page + 1, crumb)
44
+ end
45
+ contacts
46
+ end
47
+
48
+ def parse_contacts_from(cs)
49
+ cs.map do |contact|
50
+ {:name => contact['contactName'], :email => contact['email'] }
51
+ end
52
+ end
53
+
54
+ def parse_response(data)
55
+ response = JSON.parse(data)['response']["ResultSet"]
56
+ total = response['TotalContacts'].to_i
57
+ page = response['FetchedBucket'].to_i
58
+ return response['Contacts'], total, page
59
+ end
60
+ end
61
+
62
+ end
@@ -50,4 +50,20 @@ describe Garlenko do
50
50
 
51
51
  it_should_behave_like "any consumer"
52
52
  end
53
+
54
+
55
+ context "against Yahoo" do
56
+
57
+ let(:garlenko) do
58
+ yahoo = load_credentials.yahoo
59
+ Garlenko.new :yahoo, yahoo["username"], yahoo['password']
60
+ end
61
+
62
+ it "should construct a valid garlenko consumer" do
63
+ garlenko.should be_a_kind_of(Garlenko::Yahoo)
64
+ end
65
+
66
+ it_should_behave_like "any consumer"
67
+ end
68
+
53
69
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: garlenko
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -13,7 +13,7 @@ date: 2011-12-15 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: mechanize
16
- requirement: &70274506739960 !ruby/object:Gem::Requirement
16
+ requirement: &70292328838260 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70274506739960
24
+ version_requirements: *70292328838260
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: nokogiri
27
- requirement: &70274506738660 !ruby/object:Gem::Requirement
27
+ requirement: &70292328837060 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70274506738660
35
+ version_requirements: *70292328837060
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: gdata_19
38
- requirement: &70274506758120 !ruby/object:Gem::Requirement
38
+ requirement: &70292328851260 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: 1.1.3
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *70274506758120
46
+ version_requirements: *70292328851260
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: rspec
49
- requirement: &70274506768040 !ruby/object:Gem::Requirement
49
+ requirement: &70292328862240 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: 2.0.0
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *70274506768040
57
+ version_requirements: *70292328862240
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: guard-rspec
60
- requirement: &70274506766420 !ruby/object:Gem::Requirement
60
+ requirement: &70292328860520 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: '0'
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *70274506766420
68
+ version_requirements: *70292328860520
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: growl
71
- requirement: &70274506763520 !ruby/object:Gem::Requirement
71
+ requirement: &70292328857640 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
@@ -76,7 +76,7 @@ dependencies:
76
76
  version: '0'
77
77
  type: :development
78
78
  prerelease: false
79
- version_requirements: *70274506763520
79
+ version_requirements: *70292328857640
80
80
  description: ! "contacts importer from Live (Hotmail), Gmail, and\n Yahoo, using
81
81
  mechanize and nokogiri. "
82
82
  email:
@@ -88,13 +88,17 @@ files:
88
88
  - .gitignore
89
89
  - Gemfile
90
90
  - Guardfile
91
+ - README.md
91
92
  - Rakefile
93
+ - contacts.html
92
94
  - garlenko.gemspec
93
95
  - lib/garlenko.rb
94
96
  - lib/garlenko/base.rb
97
+ - lib/garlenko/crawler.rb
95
98
  - lib/garlenko/gmail.rb
96
99
  - lib/garlenko/live.rb
97
100
  - lib/garlenko/version.rb
101
+ - lib/garlenko/yahoo.rb
98
102
  - spec/credentials.yml.example
99
103
  - spec/lib/garlenko_spec.rb
100
104
  - spec/spec_helper.rb