garlenko 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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