Package phones ::
Module com_lgvx8550
|
|
1
2
3
4
5
6
7
8
9
10
11
12 """
13 Communicate with the LG VX8550 cell phone.
14 """
15
16
17 import common
18 import com_brew
19 import bpcalendar
20 import prototypes
21 import com_lgvx8700
22 import com_lgvx8500
23 import p_lgvx8550
24 import p_brew
25 import helpids
26 import copy
27 import time
28 import os.path
29
30 DEBUG1=False
31
32 parentphone=com_lgvx8700.Phone
34 desc="LG-VX8550"
35 helpid=None
36 protocolclass=p_lgvx8550
37 serialsname='lgvx8550'
38
39 my_model='VX8550'
40
41 calendarringerlocation='sch/toolsRinger.dat'
42
44 _fw_version=self.get_firmware_version()[-1]
45 if self.my_model=='VX8550' and _fw_version>'3':
46
47 self._DMv5 = False
48 self._DMv6 = True
49 else:
50 self._DMv5 = True
51 self._DMv6 = False
52
53
54
55
56
57
58
59
60
75
92
98
109
111 """Reads the phonebook data. The L{getfundamentals} information will
112 already be in result."""
113
114 _speeds=self._get_speeddials()
115
116
117 self.log("Reading ICE entries")
118 _ices=self._build_ice_dict()
119
120 self.log("Reading phonebook entries")
121 pb_entries=self.readobject(self.protocolclass.pb_file_name,
122 self.protocolclass.pbfile,
123 logtitle='Reading phonebook entries')
124
125 self.log("Reading phone numbers")
126 pb_numbers=self.readobject(self.protocolclass.pn_file_name,
127 self.protocolclass.pnfile,
128 logtitle='Reading phonebook numbers')
129
130 self.log("Reading Ringtone IDs")
131 ring_pathf=self._get_path_index(self.protocolclass.RTPathIndexFile)
132 _rt_ids=self._build_media_dict(result, ring_pathf, 'ringtone-index')
133
134 self.log("Reading Picture IDs")
135 picid_pathf=self._get_path_index(self.protocolclass.WPPathIndexFile)
136 _wp_ids=self._build_media_dict(result, picid_pathf, 'wallpaper-index')
137
138 pbook={}
139 for _cnt in range(self.protocolclass.NUMPHONEBOOKENTRIES):
140 pb_entry=pb_entries.items[_cnt]
141 if not pb_entry.valid():
142 continue
143 try:
144 self.log("Parse entry "+`_cnt`+" - " + pb_entry.name)
145 pbook[_cnt]=self.extractphonebookentry(pb_entry, pb_numbers,
146 _speeds, _ices, result,
147 _rt_ids.get(ring_pathf.items[_cnt].pathname, None),
148 _wp_ids.get(picid_pathf.items[_cnt].pathname, None))
149
150 self.progress(_cnt, self.protocolclass.NUMPHONEBOOKENTRIES, pb_entry.name)
151 except common.PhoneBookBusyException:
152 raise
153 except Exception, e:
154
155 self.log('Failed to parse entry %d'%_cnt)
156 self.log('Exception %s raised'%`e`)
157 if __debug__:
158 raise
159
160 self.progress(self.protocolclass.NUMPHONEBOOKENTRIES,
161 self.protocolclass.NUMPHONEBOOKENTRIES,
162 "Phone book read completed")
163
164 result['phonebook']=pbook
165 cats=[]
166 for i in result['groups']:
167 if result['groups'][i]['name']!='No Group':
168 cats.append(result['groups'][i]['name'])
169 result['categories']=cats
170 return pbook
171
174 """Return a phonebook entry in BitPim format. This is called from getphonebook."""
175 res={}
176
177 res['serials']=[ {'sourcetype': self.serialsname,
178 'sourceuniqueid': fundamentals['uniqueserial'],
179 'serial1': entry.entry_number1,
180 'serial2': entry.entry_number1 } ]
181
182
183 res['names']=[ {'full': entry.name} ]
184
185
186 cat=fundamentals['groups'].get(entry.group, {'name': "No Group"})['name']
187 if cat!="No Group":
188 res['categories']=[ {'category': cat} ]
189
190
191 res['emails']=[]
192 for i in entry.emails:
193 if len(i.email):
194 res['emails'].append( {'email': i.email} )
195 if not len(res['emails']): del res['emails']
196
197
198 if entry.wallpaper!=self.protocolclass.NOWALLPAPER:
199 try:
200 if entry.wallpaper == 0x64:
201 paper = wp_name
202 else:
203 paper = fundamentals['wallpaper-index'][entry.wallpaper]['name']
204
205 if paper is None:
206 raise
207
208 res['wallpapers']=[ {'wallpaper': paper, 'use': 'call'} ]
209 except:
210 print "can't find wallpaper for index",entry.wallpaper
211
212
213 if entry.ringtone != self.protocolclass.NORINGTONE:
214 try:
215 if entry.ringtone == 0x64:
216 tone = rt_name
217 else:
218 tone = fundamentals['ringtone-index'][entry.ringtone]['name']
219
220 if tone is None:
221 raise
222
223 res['ringtones']=[ {'ringtone': tone, 'use': 'call'} ]
224 except:
225 print "can't find ringtone for index",entry.ringtone
226
227 res=self._assignpbtypeandspeeddialsbytype(entry, numbers, speeds, res)
228
229
230 res=self._assigniceentry(entry, numbers, ices, res)
231
232 return res
233
235
236 res['numbers']=[]
237
238 for i in range(self.protocolclass.NUMPHONENUMBERS):
239 if entry.numberindices[i].numberindex >= self.protocolclass.NUMPHONENUMBERENTRIES:
240
241 continue
242 _pnentry=numbers.items[entry.numberindices[i].numberindex]
243 num=_pnentry.phone_number
244
245 if len(num):
246 if _pnentry.malformed():
247 print "malformed phone number entry encountered"
248
249
250 num_type = entry.numbertypes[i].numbertype
251
252 t = self.protocolclass.numbertypetab[num_type]
253 if t[-1]=='2':
254 t=t[:-1]
255 res['numbers'].append({'number': num, 'type': t})
256
257 if speeds.has_key(entry.entry_number0) and \
258 speeds[entry.entry_number0].has_key(num_type):
259 res['numbers'][i]['speeddial']=speeds[entry.entry_number0][num_type]
260 return res
261
262 - def _assigniceentry(self, entry, numbers, ices, res):
263 if ices.has_key(entry.entry_number0):
264
265 res['ice']=[ { 'iceindex': ices[entry.entry_number0] } ]
266 return res
267
273
280
282 "Saves out the phonebook"
283 self.savegroups (data)
284
285 ring_pathf=self.protocolclass.PathIndexFile()
286 picid_pathf=self.protocolclass.PathIndexFile()
287
288
289 pbook = data.get('phonebook', {})
290 keys = pbook.keys ()
291 keys.sort ()
292
293 _rt_index=data.get('ringtone-index', {})
294 _wp_index=data.get('wallpaper-index', {})
295
296 entry_num0 = 0
297 entry_num1 = self._get_next_pb_id()
298 pb_entries = self.protocolclass.pbfile(model_name=self.my_model)
299 pn_entries = self.protocolclass.pnfile()
300
301 ice_entries = self.protocolclass.iceentryfile()
302 for i in range(self.protocolclass.NUMEMERGENCYCONTACTS):
303 ice_entries.items.append (self.protocolclass.iceentry())
304
305 speeddials={}
306
307 for i in keys:
308 pb_entries.items.append(self.make_entry (pn_entries, speeddials, ice_entries,
309 entry_num0, entry_num1, pbook[i],
310 data, ring_pathf,_rt_index,
311 picid_pathf, _wp_index))
312 entry_num0 += 1
313 if entry_num0 >= self.protocolclass.NUMPHONEBOOKENTRIES:
314 self.log ("Maximum number of phonebook entries reached")
315 break
316 if entry_num1==0xffffffff:
317 entry_num1=0
318 else:
319 entry_num1+=1
320
321
322 self.log ("Writing phonebook entries")
323 self.writeobject(self.protocolclass.pb_file_name,
324 pb_entries,
325 logtitle='Writing phonebook entries',
326 uselocalfs=DEBUG1)
327
328 self.log ("Writing phone numbers")
329 self.writeobject(self.protocolclass.pn_file_name,
330 pn_entries, logtitle='Writing phonebook numbers',
331 uselocalfs=DEBUG1)
332
333 self.log('Writing ringtone ID')
334 self.writeobject(self.protocolclass.RTPathIndexFile,
335 ring_pathf, logtitle='Writing ringtone paths',
336 uselocalfs=DEBUG1)
337
338 self.log('Writing picture ID')
339 self.writeobject(self.protocolclass.WPPathIndexFile,
340 picid_pathf, logtitle='Writing wallpaper paths',
341 uselocalfs=DEBUG1)
342
343
344 self.log('Writing ICE entries')
345 self.writeobject(self.protocolclass.ice_file_name,
346 ice_entries, logtitle='Writing ICE entries',
347 uselocalfs=DEBUG1)
348
349
350 req=self.protocolclass.speeddials()
351
352 req.speeddials.append(self.protocolclass.speeddial())
353
354 if speeddials.has_key(1):
355 req.speeddials.append(self.protocolclass.speeddial(entry=speeddials[1]['entry'],
356 number=speeddials[1]['type']))
357 else:
358 req.speeddials.append(self.protocolclass.speeddial(entry=1000,
359 number=6))
360 for i in range(2, self.protocolclass.NUMSPEEDDIALS):
361 sd=self.protocolclass.speeddial()
362 if speeddials.has_key(i):
363 sd.entry=speeddials[i]['entry']
364 sd.number=speeddials[i]['type']
365 req.speeddials.append(sd)
366
367 self.log('Writing speed dials')
368 self.writeobject(self.protocolclass.speed_file_name,
369 req, logtitle='Writing speed dials data',
370 uselocalfs=DEBUG1)
371
372
373 self._save_next_pb_id(entry_num1)
374 data["rebootphone"]=True
375
376 return data
377
378 - def make_pn_entry (self, phone_number, number_type, pn_id, pbpn_id, pe_id):
379 """ Create a non-blank pnfileentry frome a phone number string """
380 if len(phone_number) == 0:
381 raise
382
383 new_entry = self.protocolclass.pnfileentry(entry_tag=self.protocolclass.PB_NUMBER_SOR)
384 new_entry.pn_id = pn_id
385 new_entry.pe_id = pe_id
386 new_entry.phone_number = phone_number
387 new_entry.ntype = number_type
388 new_entry.pn_order = pbpn_id
389
390 return new_entry
391
392 - def make_ice_entry (self, ice_id, pb_id):
393 """ Create a iceentry from a pb_id and ice_id """
394 new_entry = self.protocolclass.iceentry()
395
396 new_entry.entry_assigned = 1
397 new_entry.entry_number = ice_id
398 new_entry.pb_index = pb_id
399
400 return new_entry
401
402 - def make_entry (self, pn_entries, speeddials, ice_entries,
403 entry_num0, entry_num1, pb_entry, data,
404 ring_pathf, rt_index, picid_pathf, wp_index):
405 """ Create a pbfileentry from a bitpim phonebook entry """
406 new_entry = self.protocolclass.pbfileentry(entry_tag=self.protocolclass.PB_ENTRY_SOR)
407
408 new_entry.entry_number0 = entry_num0
409 new_entry.entry_number1 = entry_num1
410
411 for key in pb_entry:
412 if key in ('emails', 'numbertypes'):
413 l = getattr (new_entry, key)
414 for item in pb_entry[key]:
415 l.append(item)
416 elif key == 'numbers':
417 l = getattr (new_entry, 'numberindices')
418 for i in range(0, self.protocolclass.NUMPHONENUMBERS):
419 new_pn_id = len (pn_entries.items)
420 if new_pn_id == self.protocolclass.NUMPHONENUMBERENTRIES:
421
422 self.log ("Maximum number of phone numbers reached")
423 break
424
425 try:
426 pn_entries.items.append(self.make_pn_entry (pb_entry[key][i],pb_entry['numbertypes'][i], new_pn_id, i, entry_num0))
427 l.append (new_pn_id)
428 except:
429 l.append (0xffff)
430 elif key == 'speeddials':
431 for _sd,_num_type in zip(pb_entry['speeddials'], pb_entry['numbertypes']):
432 if _sd is not None:
433 speeddials[_sd]={ 'entry': entry_num0,
434 'type': _num_type }
435 elif key == 'ice':
436
437 _ice = pb_entry['ice']
438 if _ice is not None and len(_ice) > 0:
439 _ice_entry = _ice[0]['iceindex']
440 ice_entries.items[_ice_entry] = self.make_ice_entry (_ice_entry, entry_num0)
441 elif key == 'ringtone':
442 new_entry.ringtone = self._findmediainindex(data['ringtone-index'], pb_entry['ringtone'], pb_entry['name'], 'ringtone')
443 try:
444 _filename = rt_index[new_entry.ringtone]['filename']
445 ring_pathf.items.append(self.protocolclass.PathIndexEntry(pathname=_filename))
446 new_entry.ringtone = 0x64
447 except:
448 ring_pathf.items.append(self.protocolclass.PathIndexEntry())
449 elif key == 'wallpaper':
450 new_entry.wallpaper = self._findmediainindex(data['wallpaper-index'], pb_entry['wallpaper'], pb_entry['name'], 'wallpaper')
451 try:
452 _filename = wp_index[new_entry.wallpaper]['filename']
453 picid_pathf.items.append(self.protocolclass.PathIndexEntry(pathname=_filename))
454 new_entry.wallpaper = 0x64
455 except:
456 picid_pathf.items.append(self.protocolclass.PathIndexEntry())
457 elif key in new_entry.getfields():
458 setattr (new_entry, key, pb_entry[key])
459
460 return new_entry
461
515
517 data.serial_number = '000000ca-00000000-00000000-' + fwversion
518 data.unknown3 = 0x01fb
519
521
522
523 eventsf = self.protocolclass.schedulefile()
524 exceptionsf = self.protocolclass.scheduleexceptionfile()
525 ringersf = self.protocolclass.scheduleringerfile()
526
527 cal=dict['calendar']
528 newcal={}
529
530 keys=[(x.start, k) for k,x in cal.items()]
531 keys.sort()
532
533 keys=keys[:self.protocolclass.NUMCALENDARENTRIES]
534
535 eventsf.numactiveitems=len(keys)
536 ringersf.numringers = 0
537 pos = 0
538
539 try:
540 req = p_brew.firmwarerequest()
541 res = self.sendbrewcommand(req, self.protocolclass.firmwareresponse)
542 _fwversion = res.firmware
543 except:
544 _fwversion = '00000000'
545
546
547 for (_,k) in keys:
548
549 entry=cal[k]
550 data=self.protocolclass.scheduleevent()
551
552 data.pos = pos * data.packet_size + 2
553 self._schedulecommon(entry, data)
554 alarm_set=self.setalarm(entry, data)
555 if alarm_set:
556 if entry.ringtone=="No Ring" and not entry.vibrate:
557 alarm_name="Low Beep Once"
558 else:
559 alarm_name=entry.ringtone
560 else:
561 alarm_name="No Ring"
562 for i in dict['ringtone-index']:
563 self.log ('ringtone ' + str(i) + ': ' + dict['ringtone-index'][i]['name'] + ' alarm-name = ' + alarm_name)
564 if dict['ringtone-index'][i]['name']==alarm_name:
565 if dict['ringtone-index'][i].get('filename', None):
566 data.ringtone = 100 + ringersf.numringers
567 ringersf.ringerpaths.append(dict['ringtone-index'][i]['filename'])
568 ringersf.numringers = ringersf.numringers + 1
569 else:
570
571 data.ringtone=i
572 break
573
574 self._scheduleexceptions(entry, data, exceptionsf)
575 self._scheduleextras(data, _fwversion)
576
577 entry=copy.copy(entry)
578 newcal[data.pos]=entry
579 eventsf.events.append(data)
580 pos = pos + 1
581
582 buf=prototypes.buffer()
583 eventsf.writetobuffer(buf, logtitle="New Calendar")
584 self.writefile(self.calendarlocation, buf.getvalue())
585 self.log("Your phone has to be rebooted due to the calendar changing")
586 dict["rebootphone"]=True
587
588 buf=prototypes.buffer()
589 exceptionsf.writetobuffer(buf, logtitle="Writing calendar exceptions")
590 self.writefile(self.calendarexceptionlocation, buf.getvalue())
591
592 buf = prototypes.buffer()
593 ringersf.writetobuffer(buf, logtitle="Writing calendar ringers")
594 self.writefile(self.calendarringerlocation, buf.getvalue())
595
596
597 dict['calendar']=newcal
598
599 return dict
600
601
602 parentprofile=com_lgvx8500.Profile
604 protocolclass=Phone.protocolclass
605 serialsname=Phone.serialsname
606
607 BP_Calendar_Version=3
608 phone_manufacturer='LG Electronics Inc'
609 phone_model='VX8550'
610
611 WALLPAPER_WIDTH=176
612 WALLPAPER_HEIGHT=220
613
614 imageorigins={}
615 imageorigins.update(common.getkv(parentprofile.stockimageorigins, "images"))
616 imageorigins.update(common.getkv(parentprofile.stockimageorigins, "video"))
617 imageorigins.update(common.getkv(parentprofile.stockimageorigins, "images(sd)"))
618 imageorigins.update(common.getkv(parentprofile.stockimageorigins, "video(sd)"))
619
620
621 imagetargets={}
622 imagetargets.update(common.getkv(parentprofile.stockimagetargets, "fullscreen",
623 {'width': 238, 'height': 246, 'format': "JPEG"}))
624 imagetargets.update(common.getkv(parentprofile.stockimagetargets, "wallpaper",
625 {'width': 240, 'height': 274, 'format': "JPEG"}))
626 imagetargets.update(common.getkv(parentprofile.stockimagetargets, "pictureid",
627 {'width': 120, 'height': 100, 'format': "JPEG"}))
628
629 _supportedsyncs=(
630 ('phonebook', 'read', None),
631 ('calendar', 'read', None),
632 ('wallpaper', 'read', None),
633 ('ringtone', 'read', None),
634 ('call_history', 'read', None),
635 ('sms', 'read', None),
636 ('memo', 'read', None),
637 ('phonebook', 'write', 'OVERWRITE'),
638 ('calendar', 'write', 'OVERWRITE'),
639 ('wallpaper', 'write', 'MERGE'),
640 ('wallpaper', 'write', 'OVERWRITE'),
641 ('ringtone', 'write', 'MERGE'),
642 ('ringtone', 'write', 'OVERWRITE'),
643 ('sms', 'write', 'OVERWRITE'),
644 ('memo', 'write', 'OVERWRITE'),
645 ('t9_udb', 'write', 'OVERWRITE'),
646 )
647 if __debug__:
648 _supportedsyncs+=(
649 ('t9_udb', 'read', 'OVERWRITE'),
650 )
651
652
654 """Converts the data to what will be used by the phone
655
656 @param data: contains the dict returned by getfundamentals
657 as well as where the results go"""
658 results={}
659
660 self.normalisegroups(helper, data)
661
662 for pbentry in data['phonebook']:
663 if len(results)==self.protocolclass.NUMPHONEBOOKENTRIES:
664 break
665 e={}
666 entry=data['phonebook'][pbentry]
667 try:
668
669 serial1=helper.getserial(entry.get('serials', []), self.serialsname, data['uniqueserial'], 'serial1', 0)
670 serial2=helper.getserial(entry.get('serials', []), self.serialsname, data['uniqueserial'], 'serial2', serial1)
671
672 e['serial1']=serial1
673 e['serial2']=serial2
674 for ss in entry["serials"]:
675 if ss["sourcetype"]=="bitpim":
676 e['bitpimserial']=ss
677 assert e['bitpimserial']
678
679
680 e['name']=helper.getfullname(entry.get('names', []),1,1,32)[0]
681
682
683 e['ice']=entry.get('ice', None)
684
685
686 cat=helper.makeone(helper.getcategory(entry.get('categories', []),0,1,32), None)
687 if cat is None:
688 e['group']=0
689 else:
690 key,value=self._getgroup(cat, data['groups'])
691 if key is not None:
692 e['group']=key
693 else:
694
695 e['group']=0
696
697
698 emails=helper.getemails(entry.get('emails', []) ,0,self.protocolclass.NUMEMAILS,48)
699 e['emails']=helper.filllist(emails, self.protocolclass.NUMEMAILS, "")
700
701
702
703 minnumbers=1
704 if len(emails): minnumbers=0
705 numbers=helper.getnumbers(entry.get('numbers', []),minnumbers,self.protocolclass.NUMPHONENUMBERS)
706 e['numbertypes']=[]
707 e['numbers']=[]
708 e['speeddials']=[]
709 for numindex in range(len(numbers)):
710 num=numbers[numindex]
711
712 b4=len(e['numbertypes'])
713 type=num['type']
714 for i,t in enumerate(self.protocolclass.numbertypetab):
715 if type==t:
716
717 if i in e['numbertypes'] and t[-1]!='2':
718 type+='2'
719 continue
720 e['numbertypes'].append(i)
721 break
722 if t=='none':
723 e['numbertypes'].append(i)
724 break
725 if len(e['numbertypes'])==b4:
726
727 helper.add_error_message('Number %s (%s/%s) not supported and ignored.'%
728 (num['number'], e['name'], num['type']))
729 continue
730
731 number=self.phonize(num['number'])
732 if len(number)==0:
733
734 continue
735 if len(number) > 48:
736
737 number=number[:48]
738 e['numbers'].append(number)
739
740 sd=num.get("speeddial", None)
741 if sd is not None and \
742 sd>=self.protocolclass.FIRSTSPEEDDIAL and \
743 sd<=self.protocolclass.LASTSPEEDDIAL:
744 e['speeddials'].append(sd)
745 else:
746 e['speeddials'].append(None)
747
748 if len(e['numbers'])<minnumbers:
749
750
751 helper.add_error_message("Name: %s. No suitable numbers or emails found" % e['name'])
752 continue
753 e['numbertypes']=helper.filllist(e['numbertypes'], self.protocolclass.NUMPHONENUMBERS, 0)
754 e['numbers']=helper.filllist(e['numbers'], self.protocolclass.NUMPHONENUMBERS, "")
755 e['speeddials']=helper.filllist(e['speeddials'], self.protocolclass.NUMPHONENUMBERS, None)
756
757
758 e['ringtone']=helper.getringtone(entry.get('ringtones', []), 'call', None)
759 e['wallpaper']=helper.getwallpaper(entry.get('wallpapers', []), 'call', None)
760
761 results[pbentry]=e
762
763 except helper.ConversionFailed:
764 continue
765
766 data['phonebook']=results
767 return data
768