Package phones ::
Module com_lglx570
|
|
1
2
3
4
5
6
7
8
9
10 """Communicate with the LG LX570 (Muziq) cell phone"""
11
12 import common
13 import com_brew
14 import com_lg
15 import com_lgvx4400
16 import p_lglx570
17 import prototypes
18 import helpids
19 import sms
20
21
22 parentphone=com_lgvx4400.Phone
23 -class Phone(com_brew.RealBrewProtocol2, parentphone):
24 "Talk to the LG LX570 (Muziq) cell phone"
25
26 desc="LG-LX570"
27 helpid=helpids.ID_PHONE_LGLX570
28 protocolclass=p_lglx570
29 serialsname='lglx570'
30 my_model='LX570'
31
32 builtinringtones=( 'Tone 1', 'Tone 2', 'Tone 3', 'Tone 4', 'Tone 5', 'Tone 6',
33 'Tone 7', 'Tone 8', 'Tone 9', 'Tone 10',
34 'Alert 1', 'Alert 2', 'Alert 3', 'Alert 4', 'Alert 5')
35 ringtonelocations=(
36
37 (0x1100, "setas/voicememoRingerIndex.map", "VoiceDB/All/Memos", "voice memo", 35),
38 (0x1200, "setas/mcRingerIndex.map", "melodyComposer", "my melodies", 20),
39 )
40 builtinimages=()
41 imagelocations=(
42
43 (0x600, "setas/dcamIndex.map", "Dcam/Wallet", "images", 255),
44 )
45 wallpaperdirs=('Dcam/Review', 'Dcam/Wallet')
46
47 - def __init__(self, logtarget, commport):
49
50
54
69
70
72
73 _res={}
74 _idx=1
75 for _dir in self.wallpaperdirs:
76 for _file in self.listfiles(_dir):
77 _res[_idx]={ 'name': common.basename(_file),
78 'filename': _file,
79 'origin': 'images' }
80 _idx+=1
81 results['wallpaper-index']=_res
82 return results
83
85
86 _media={}
87 for _wp in result.get('wallpaper-index', {}).values():
88 _media[_wp['name']]=self.getfilecontents(_wp['filename'], True)
89 result['wallpapers']=_media
90 return result
91
96
98
99
100 if name[-4:]=='.mid':
101
102 _new_name=name[:-4]
103 else:
104 _new_name=name
105 return _new_name.replace('.', '_')+'.mid'
106
121
123
124 _media_index=results.get('ringtone-index', {})
125 _media=results.get('ringtone', {})
126
127 _melodies_data={}
128 for _item in _media.values():
129 if _item.get('origin', None)=='my melodies':
130 _melodies_data[self._fix_melodies_filename(_item['name'])]=_item['data']
131
132 _indexfile=self.readobject(self.protocolclass.RT_MC_INDEX_FILENAME,
133 self.protocolclass.indexfile,
134 logtitle='Reading MC Index File',
135 uselocalfs=False)
136
137 self.log('Updating media files')
138 for _idx in range(_indexfile.numactiveitems):
139 _item=_indexfile.items[_idx]
140 if _item.name and _melodies_data.has_key(_item.name):
141
142 self._update_media_file(_item.name, _melodies_data[_item.name])
143
144 del _melodies_data[_item.name]
145
146 _empty_index=range(_indexfile.numactiveitems, len(_indexfile.items))
147 _available_media=_melodies_data.keys()
148 self.log('Adding new media files')
149 for _idx, _name in zip(_empty_index, _available_media):
150
151 _indexfile.items[_idx].name=_name
152
153 self._update_media_file(_name, _melodies_data[_name])
154
155 _indexfile.numactiveitems+=1
156
157 self.writeobject(self.protocolclass.RT_MC_INDEX_FILENAME,
158 _indexfile, logtitle='Writing new MC Index file',
159 uselocalfs=False)
160
161 self.getringtoneindices(results)
162 return results
163
164
180
181
182
184 "Saves out the phonebook"
185
186 progressmax=len(data['phonebook'].keys())
187
188
189
190
191
192
193 serialupdates=[]
194 existingpbook={}
195 self.mode=self.MODENONE
196 self.setmode(self.MODEBREW)
197 self.setmode(self.MODEPHONEBOOK)
198
199 req=self.protocolclass.pbinforequest()
200 res=self.sendpbcommand(req, self.protocolclass.pbinforesponse)
201 numexistingentries=res.numentries
202 if numexistingentries<0 or numexistingentries>1000:
203 self.log("The phone is lying about how many entries are in the phonebook so we are doing it the hard way")
204 numexistingentries=0
205 firstserial=None
206 loop=xrange(0,1000)
207 hardway=True
208 else:
209 self.log("There are %d existing entries" % (numexistingentries,))
210 progressmax+=numexistingentries
211 loop=xrange(0, numexistingentries)
212 hardway=False
213 progresscur=0
214
215 self.sendpbcommand(self.protocolclass.pbinitrequest(), self.protocolclass.pbinitresponse)
216 for i in loop:
217
218 if hardway:
219 numexistingentries+=1
220 progressmax+=1
221 req=self.protocolclass.pbreadentryrequest()
222 res=self.sendpbcommand(req, self.protocolclass.pbreadentryresponse)
223
224 entry={ 'number': res.entry.entrynumber, 'serial1': res.entry.serial1,
225 'serial2': res.entry.serial2, 'name': res.entry.name}
226 assert entry['serial1']==entry['serial2']
227 self.log("Reading entry "+`i`+" - "+entry['name'])
228 if hardway and firstserial is None:
229 firstserial=res.entry.serial1
230 existingpbook[i]=entry
231 self.progress(progresscur, progressmax, "existing "+entry['name'])
232
233 req=self.protocolclass.pbnextentryrequest()
234 res=self.sendpbcommand(req, self.protocolclass.pbnextentryresponse)
235 progresscur+=1
236 if hardway:
237
238 if res.serial==firstserial or res.serial==0:
239 break
240
241
242
243 pbook=data['phonebook']
244 dellist=[]
245 for i in range(0, numexistingentries):
246 ii=existingpbook[i]
247 serial=ii['serial1']
248 item=self._findserial(serial, pbook)
249 if item is None:
250 dellist.append(i)
251
252 progressmax+=len(dellist)
253
254
255 for i in dellist:
256 progresscur+=1
257 numexistingentries-=1
258 ii=existingpbook[i]
259 self.log("Deleting entry "+`i`+" - "+ii['name'])
260 req=self.protocolclass.pbdeleteentryrequest()
261 req.serial1=ii['serial1']
262 req.serial2=ii['serial2']
263 req.entrynumber=ii['number']
264 self.sendpbcommand(req, self.protocolclass.pbdeleteentryresponse)
265 self.progress(progresscur, progressmax, "Deleting "+ii['name'])
266
267 del existingpbook[i]
268
269
270 counter=0
271
272 keys=existingpbook.keys()
273 existingserials=[]
274 keys.sort()
275 for i in keys:
276 progresscur+=1
277 ii=pbook[self._findserial(existingpbook[i]['serial1'], pbook)]
278 self.log("Rewriting entry "+`i`+" - "+ii['name'])
279 self.progress(progresscur, progressmax, "Rewriting "+ii['name'])
280 entry=self.makeentry(counter, ii, data)
281 counter+=1
282 existingserials.append(existingpbook[i]['serial1'])
283 req=self.protocolclass.pbupdateentryrequest()
284 req.entry=entry
285 res=self.sendpbcommand(req, self.protocolclass.pbupdateentryresponse)
286 serialupdates.append( ( ii["bitpimserial"],
287 {'sourcetype': self.serialsname, 'serial1': res.serial1, 'serial2': res.serial1,
288 'sourceuniqueid': data['uniqueserial']})
289 )
290 assert ii['serial1']==res.serial1
291
292
293 keys=pbook.keys()
294 keys.sort()
295 for i in keys:
296 try:
297 ii=pbook[i]
298 if ii['serial1'] in existingserials:
299 continue
300 progresscur+=1
301 entry=self.makeentry(counter, ii, data)
302 counter+=1
303 self.log("Appending entry "+ii['name'])
304 self.progress(progresscur, progressmax, "Writing "+ii['name'])
305 req=self.protocolclass.pbappendentryrequest()
306 req.entry=entry
307 res=self.sendpbcommand(req, self.protocolclass.pbappendentryresponse)
308 serialupdates.append( ( ii["bitpimserial"],
309 {'sourcetype': self.serialsname, 'serial1': res.newserial, 'serial2': res.newserial,
310 'sourceuniqueid': data['uniqueserial']})
311 )
312 except:
313 self.log('Failed to write entry: '+ii['name'])
314 if __debug__:
315 raise
316 data["serialupdates"]=serialupdates
317 self.progress(progressmax, progressmax, "Rebooting phone")
318 data["rebootphone"]=True
319 return data
320
321 - def makeentry(self, counter, entry, data):
322 """Creates pbentry object
323
324 @param counter: The new entry number
325 @param entry: The phonebook object (as returned from convertphonebooktophone) that we
326 are using as the source
327 @param data: The main dictionary, which we use to get access to media indices amongst
328 other things
329 """
330 e=self.protocolclass.pbentry()
331 e.entrynumber=counter
332 for k in entry:
333
334 if k in ('emails', 'numbers', 'numbertypes', 'speeddials'):
335 l=getattr(e,k)
336 for item in entry[k]:
337 l.append(item)
338 elif k=='ringtone':
339 e.ringtone=self._findmediainindex(data['ringtone-index'], entry['ringtone'], entry['name'], 'ringtone')
340 elif k in e.getfields():
341
342 setattr(e,k,entry[k])
343 return e
344
345
346 - def _getquicktext(self):
347 quicks=[]
348 try:
349 sf=self.readobject(self.protocolclass.SMS_CANNED_FILENAME,
350 self.protocolclass.sms_canned_file,
351 logtitle="SMS quicktext file sms/mediacan000.dat",
352 uselocalfs=False)
353 for rec in sf.msgs:
354 if rec.msg:
355 quicks.append({ 'text': rec.msg,
356 'type': sms.CannedMsgEntry.user_type })
357 except com_brew.BrewNoSuchFileException:
358 pass
359 return quicks
360
373
394
419
420 - def _setquicktext(self, result):
421 sf=self.protocolclass.sms_canned_file()
422 quicktext=result.get('canned_msg', [])[:self.protocolclass.SMS_CANNED_MAX_ITEMS]
423 if quicktext:
424 for entry in quicktext:
425 msg_entry=self.protocolclass.sms_quick_text()
426 msg_entry.msg=entry['text'][:self.protocolclass.SMS_CANNED_MAX_LENGTH-1]
427 sf.msgs.append(msg_entry)
428 self.writeobject(self.protocolclass.SMS_CANNED_FILENAME,
429 sf, logtitle="Writing quicktext",
430 uselocalfs=False)
431
432
433 parentprofile=com_lgvx4400.Profile
435 protocolclass=Phone.protocolclass
436 serialsname=Phone.serialsname
437
438 BP_Calendar_Version=3
439 phone_manufacturer='LG Electronics Inc'
440 phone_model='LX570'
441
442
443 WALLPAPER_WIDTH=176
444 WALLPAPER_HEIGHT=220
445
446
447 imageorigins={}
448 imageorigins.update(common.getkv(parentprofile.stockimageorigins, "images"))
451
452 ringtoneorigins=('my melodies', 'voice memo')
453 excluded_ringtone_origins=('ringers', 'sounds', 'my melodies', 'voice memo')
454 excluded_wallpaper_origins=('images',)
455
456
457
458 imagetargets={}
459 imagetargets.update(common.getkv(parentprofile.stockimagetargets, "wallpaper",
460 {'width': 176, 'height': 220, 'format': "JPEG"}))
461 imagetargets.update(common.getkv(parentprofile.stockimagetargets, "outsidelcd",
462 {'width': 128, 'height': 160, 'format': "JPEG"}))
463
466
467
469 """Converts the data to what will be used by the phone
470
471 @param data: contains the dict returned by getfundamentals
472 as well as where the results go"""
473 results={}
474
475 self.normalisegroups(helper, data)
476
477 for pbentry in data['phonebook']:
478 if len(results)==self.protocolclass.NUMPHONEBOOKENTRIES:
479 break
480 e={}
481 entry=data['phonebook'][pbentry]
482 try:
483
484 serial1=helper.getserial(entry.get('serials', []), self.serialsname, data['uniqueserial'], 'serial1', 0)
485 serial2=helper.getserial(entry.get('serials', []), self.serialsname, data['uniqueserial'], 'serial2', serial1)
486
487 e['serial1']=serial1
488 e['serial2']=serial2
489 for ss in entry["serials"]:
490 if ss["sourcetype"]=="bitpim":
491 e['bitpimserial']=ss
492 assert e['bitpimserial']
493
494
495 e['name']=helper.getfullname(entry.get('names', []),1,1,22)[0]
496
497
498 cat=helper.makeone(helper.getcategory(entry.get('categories', []),0,1,22), None)
499 if cat is None:
500 e['group']=0
501 else:
502 key,value=self._getgroup(cat, data['groups'])
503 if key is not None:
504 e['group']=key
505 else:
506
507 e['group']=0
508
509
510 emails=helper.getemails(entry.get('emails', []) ,0,self.protocolclass.NUMEMAILS,48)
511 e['emails']=helper.filllist(emails, self.protocolclass.NUMEMAILS, "")
512
513
514 e['url']=helper.makeone(helper.geturls(entry.get('urls', []), 0,1,48), "")
515
516
517 e['memo']=helper.makeone(helper.getmemos(entry.get('memos', []), 0, 1, self.protocolclass.MEMOLENGTH-1), "")
518
519
520
521 minnumbers=1
522 if len(emails): minnumbers=0
523 numbers=helper.getnumbers(entry.get('numbers', []),minnumbers,self.protocolclass.NUMPHONENUMBERS)
524 e['numbertypes']=[]
525 e['numbers']=[]
526 e['speeddials']=[]
527 for numindex in range(len(numbers)):
528 num=numbers[numindex]
529
530 b4=len(e['numbertypes'])
531 type=num['type']
532 for i,t in enumerate(self.protocolclass.numbertypetab):
533 if type==t:
534
535 if i in e['numbertypes'] and t[-1]!='2':
536 type+='2'
537 continue
538 e['numbertypes'].append(i)
539 break
540 if t=='none':
541 e['numbertypes'].append(i)
542 break
543 if len(e['numbertypes'])==b4:
544
545 helper.add_error_message('Number %s (%s/%s) not supported and ignored.'%
546 (num['number'], e['name'], num['type']))
547 continue
548
549 number=self.phonize(num['number'])
550 if len(number)==0:
551
552 continue
553 if len(number)>48:
554
555 number=number[:48]
556 e['numbers'].append(number)
557
558 sd=num.get("speeddial", -1)
559 if self.protocolclass.NUMSPEEDDIALS:
560 if sd>=self.protocolclass.FIRSTSPEEDDIAL and sd<=self.protocolclass.LASTSPEEDDIAL:
561 e['speeddials'].append(sd)
562 else:
563 e['speeddials'].append(0xff)
564
565 if len(e['numbers'])<minnumbers:
566
567
568 helper.add_error_message("Name: %s. No suitable numbers or emails found" % e['name'])
569 continue
570 e['numbertypes']=helper.filllist(e['numbertypes'], 5, 0)
571 e['numbers']=helper.filllist(e['numbers'], 5, "")
572 e['speeddials']=helper.filllist(e['speeddials'], 5, 0xff)
573
574
575 e['ringtone']=helper.getringtone(entry.get('ringtones', []), 'call', None)
576
577
578 results[pbentry]=e
579
580 except helper.ConversionFailed:
581 continue
582
583 data['phonebook']=results
584 return data
585
586 _supportedsyncs=(
587 ('phonebook', 'read', None),
588
589 ('wallpaper', 'read', None),
590 ('ringtone', 'read', None),
591
592 ('sms', 'read', None),
593 ('memo', 'read', None),
594 ('phonebook', 'write', 'OVERWRITE'),
595
596
597
598 ('ringtone', 'write', 'MERGE'),
599
600 ('sms', 'write', 'OVERWRITE'),
601 ('memo', 'write', 'OVERWRITE'),
602
603
604 )
605
606 field_color_data={
607 'phonebook': {
608 'name': {
609 'first': 1, 'middle': 1, 'last': 1, 'full': 1,
610 'nickname': 0, 'details': 1 },
611 'number': {
612 'type': 5, 'speeddial': 5, 'number': 5,
613 'details': 5,
614 'ringtone': False, 'wallpaper': False },
615 'email': 3,
616 'email_details': {
617 'emailspeeddial': False, 'emailringtone': False,
618 'emailwallpaper': False },
619 'address': {
620 'type': 0, 'company': 0, 'street': 0, 'street2': 0,
621 'city': 0, 'state': 0, 'postalcode': 0, 'country': 0,
622 'details': 0 },
623 'url': 1,
624 'memo': 1,
625 'category': 1,
626 'wallpaper': 0,
627 'ringtone': 0,
628 'storage': 0,
629 },
630 'calendar': {
631 'description': False, 'location': False, 'allday': False,
632 'start': False, 'end': False, 'priority': False,
633 'alarm': False, 'vibrate': False,
634 'repeat': False,
635 'memo': False,
636 'category': False,
637 'wallpaper': False,
638 'ringtone': False,
639 },
640 'memo': {
641 'subject': False,
642 'date': False,
643 'secret': False,
644 'category': False,
645 'memo': True,
646 },
647 'todo': {
648 'summary': False,
649 'status': False,
650 'due_date': False,
651 'percent_complete': False,
652 'completion_date': False,
653 'private': False,
654 'priority': False,
655 'category': False,
656 'memo': False,
657 },
658 }
659