Package phones ::
Module com_lgax8600
|
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 """
16 Communicate with the LG AX8600 cell phone
17 """
18
19 import re
20 import time
21 import cStringIO
22 import sha
23 import datetime
24
25
26 import common
27 import commport
28 import fileinfo
29 import guihelper
30 import os
31 import copy
32 import com_lgvx4400
33 import p_brew
34 import p_lgax8600
35 import com_lgvx8100
36 import com_brew
37 import com_phone
38 import com_lg
39 import prototypes
40 import bpcalendar
41 import call_history
42 import sms
43 import memo
44 import playlist
45 import helpids
46
47
48
49
50 parentphone=com_lgvx8100.Phone
52 "Talk to LG AX-8600 cell phone"
53
54 desc="LG-AX8600"
55 helpid=helpids.ID_PHONE_LGAX8600
56 protocolclass=p_lgax8600
57 serialsname='lgax8600'
58
59 external_storage_root='mmc1/'
60
61 my_model='AX8600'
62
63 builtinringtones= ()
64 ringtonelocations= (
65
66
67 ( 'sounds', 'dload/lg_mysound.dat', 'dload/lg_mysoundsize.dat', 'brew/media/lk/ms', 150, 100, 0x402, 0, 0),
68
69
70
71 )
72
73 calendarlocation="sch/schedule.dat"
74 calendarexceptionlocation="sch/schexception.dat"
75 calenderrequiresreboot=1
76 memolocation="sch/memo.dat"
77
78 builtinwallpapers = ()
79 wallpaperlocations= (
80
81
82 ( 'images', 'dload/lg_image.dat', 'dload/lg_imagesize.dat', 'brew/media/lk/mp', 150 , 100, 0x400, 0, 0),
83
84
85
86
87 )
88
89
90 _rs_path='mmc1/'
91 _rs_ringers_path=_rs_path+'lg_media/other_sounds'
92 _rs_images_path=_rs_path+'lg_media/other_image'
93
94
95
96 media_info={ 'sounds': {
97 'localpath': 'brew/media/lk/ms',
98 'rspath': None,
99 'vtype': protocolclass.MEDIA_TYPE_SOUND,
100 'icon': protocolclass.MEDIA_IMAGE_DEFAULT_ICON,
101 'index': 150,
102 'maxsize': 100,
103 'indexfile': 'dload/lg_mysound.dat',
104 'sizefile': 'dload/lg_mysoundsize.dat',
105 'dunno': 0,
106 'date': False,
107 'dunno1': 0 },
108 'images': {
109 'localpath': 'brew/media/lk/mp',
110 'rspath': None,
111 'vtype': protocolclass.MEDIA_TYPE_IMAGE,
112 'icon': protocolclass.MEDIA_IMAGE_DEFAULT_ICON,
113 'index': 150,
114 'maxsize': 100,
115 'indexfile': 'dload/lg_image.dat',
116 'sizefile': 'dload/lg_imagesize.dat',
117 'dunno': 0,
118 'date': False,
119 'dunno1': 0 },
120
121
122
123
124
125
126
127
128
129
130 }
131
132
133
134 - def __init__(self, logtarget, commport):
138
139
141 self._DMv5=True
142 self._timeout = 30
143
147
151
152
153
154 - def getcallhistory(self, result):
155 res={}
156
157
158 if hasattr(self.protocolclass, 'this_takes_the_prize_for_the_most_brain_dead_call_history_file_naming_ive_seen'):
159 self._readhistoryfile("pim/missed_log.dat", 'Incoming', res)
160 self._readhistoryfile("pim/outgoing_log.dat", 'Missed', res)
161 self._readhistoryfile("pim/incoming_log.dat", 'Outgoing', res)
162 else:
163 self._readhistoryfile("pim/missed_log.dat", 'Missed', res)
164 self._readhistoryfile("pim/outgoing_log.dat", 'Outgoing', res)
165 self._readhistoryfile("pim/incoming_log.dat", 'Incoming', res)
166 self._readhistoryfile("pim/data_log.data", 'Data', res)
167 result['call_history']=res
168 return result
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
198 res={}
199
200 try:
201 buf=prototypes.buffer(self.getfilecontents(self.calendarexceptionlocation))
202 ex=self.protocolclass.scheduleexceptionfile()
203 ex.readfrombuffer(buf, logtitle="Calendar exceptions")
204 exceptions={}
205 for i in ex.items:
206 try:
207 exceptions[i.pos].append( (i.year,i.month,i.day) )
208 except KeyError:
209 exceptions[i.pos]=[ (i.year,i.month,i.day) ]
210 except com_brew.BrewNoSuchFileException:
211 exceptions={}
212
213
214 try:
215 buf=prototypes.buffer(self.getfilecontents(self.calendarlocation))
216 if len(buf.getdata())<3:
217
218 raise com_brew.BrewNoSuchFileException()
219 sc=self.protocolclass.schedulefile()
220 sc.readfrombuffer(buf, logtitle="Calendar")
221 for event in sc.events:
222
223
224 if event.pos==0:
225 continue
226 entry=bpcalendar.CalendarEntry()
227 entry.desc_loc=event.description
228 try:
229 entry.start=event.start
230 if self.protocolclass.CALENDAR_HAS_SEPARATE_END_TIME_AND_DATE:
231 if event.repeat[0] == 0:
232 entry.end = event.end_time
233 else:
234 _,_,_,hour,minute=event.end_time
235 year,month,day,_,_=event.end_date
236 entry.end=(year,month,day,hour,minute)
237 else:
238 entry.end=event.end
239 except ValueError:
240 continue
241 if event.alarmindex_vibrate&0x1:
242 entry.vibrate=0
243 else:
244 entry.vibrate=1
245 entry.repeat = self.makerepeat(event.repeat)
246 min=event.alarmminutes
247 hour=event.alarmhours
248 if min==0x64 or hour==0x64:
249 entry.alarm=None
250 else:
251 entry.alarm=hour*60+min
252 if self.protocolclass.CALENDAR_HAS_SEPARATE_END_TIME_AND_DATE:
253
254
255
256
257
258
259
260 try:
261 if (event.ringtone == 100):
262 entry.ringtone = common.basename(event.ringpath)
263 else:
264 entry.ringtone=self.builtinringtones[event.ringtone]
265 except:
266
267 if entry.alarm==None:
268 entry.ringtone='No Ring'
269 else:
270 entry.ringtone='Loud Beeps'
271 else:
272
273 if entry.alarm==None:
274 entry.ringtone='No Ring'
275 else:
276 entry.ringtone='Loud Beeps'
277
278 entry.snoozedelay=0
279
280 if event.repeat[3] and exceptions.has_key(event.pos):
281 for year, month, day in exceptions[event.pos]:
282 entry.suppress_repeat_entry(year, month, day)
283 res[entry.id]=entry
284
285 assert sc.numactiveitems==len(res)
286 except com_brew.BrewNoSuchFileException:
287 pass
288 result['calendar']=res
289 return result
290
292
293 pbook=fundamentals.get('phonebook', {})
294 wallpaper_index=fundamentals.get('wallpaper-index', {})
295 ringtone_index=fundamentals.get('ringtone-index', {})
296 r1={}
297 for k,e in pbook.items():
298 r1[e['bitpimserial']['id']]={ 'wallpaper': \
299 self._findmediainindex(wallpaper_index,
300 e['wallpaper'],
301 e['name'],
302 'wallpaper'),
303 'msgringtone': \
304 self._findmediainindex(ringtone_index,
305 e['msgringtone'],
306 e['name'],
307 'message ringtone')}
308 serialupdates=fundamentals.get("serialupdates", [])
309 r2={}
310 for bps, serials in serialupdates:
311 r2[serials['serial1']]=r1[bps['id']]
312 return r2
313
333
334
339
340 - def _write_path_index(self, pbentries, pbmediakey, media_index,
341 index_file, invalid_values):
361
362
364 _info=self.media_info.get(type, None)
365
366 if not _info:
367 return
368 _files={}
369 _local_dir=_info['localpath']
370
371 _rs_dir=_info['rspath']
372 _vtype=_info['vtype']
373 _icon=_info['icon']
374 _index=_info['index']
375 _maxsize=_info['maxsize']
376 _dunno=_info['dunno']
377 _dunno1=_info['dunno1']
378 indexfile=_info['indexfile']
379 sizefile=_info['sizefile']
380 _need_date=_info['date']
381 try:
382
383 _files=self.listfiles(_local_dir)
384 except (com_brew.BrewNoSuchDirectoryException,
385 com_brew.BrewBadPathnameException):
386 pass
387 try:
388 if _rs_dir:
389 _rs_files=self.listfiles(_rs_dir)
390
391 if type=='ringers':
392 self._mark_files(_files, _rs_files, _local_dir)
393 _files.update(_rs_files)
394 except (com_brew.BrewNoSuchDirectoryException,
395 com_brew.BrewBadPathnameException):
396
397 pass
398
399 if type=='ringers':
400 _keys=_files.keys()
401 for _key in _keys:
402 if not _files[_key]['size']:
403 del _files[_key]
404
405 _idx_keys={}
406 for _i in xrange(_index, _index+_maxsize):
407 _idx_keys[_i]=True
408
409 for _item in self.getindex(indexfile):
410 if _files.has_key(_item.filename):
411
412 _files[_item.filename]['index']=_item.index
413 _idx_keys[_item.index]=False
414
415 _idx_keys_list=[k for k,x in _idx_keys.items() if x]
416 _idx_keys_list.sort()
417 _idx_cnt=0
418
419 _file_list=[x for x in _files if not _files[x].get('index', None)]
420 _file_list.sort()
421
422 if len(_file_list)>len(_idx_keys_list):
423 _file_list=_file_list[:len(_idx_keys_list)]
424 for i in _file_list:
425 _files[i]['index']=_idx_keys_list[_idx_cnt]
426 _idx_cnt+=1
427
428 _res_list=[(x['index'],k) for k,x in _files.items() if x.get('index', None)]
429 _res_list.sort()
430 _res_list.reverse()
431
432
433 ifile=self.protocolclass.indexfile()
434 _file_size=0
435 for index,idx in _res_list:
436 _fs_size=_files[idx]['size']
437 ie=self.protocolclass.indexentry()
438 ie.index=index
439 ie.type=_vtype
440 ie.filename=idx
441 if _need_date:
442
443 _stat=self.statfile(_files[idx]['name'])
444 if _stat:
445 ie.date=_stat['datevalue']-time.timezone
446 ie.dunno=_dunno
447 ie.dunno1=_dunno1
448 ie.icon=_icon
449 ie.size=_fs_size
450
451 ifile.items.append(ie)
452 if not self._is_rs_file(idx):
453 _file_size+=_fs_size
454 buf=prototypes.buffer()
455
456 ifile.writetobuffer(buf, logtitle="Index file "+indexfile)
457 self.log("Writing index file "+indexfile+" for type "+type+" with "+`len(_res_list)`+" entries.")
458 self.writefile(indexfile, buf.getvalue())
459
460 if sizefile:
461 szfile=self.protocolclass.sizefile()
462 szfile.size=_file_size
463 buf=prototypes.buffer()
464 szfile.writetobuffer(buf, logtitle="Updated size file for "+type)
465 self.log("You are using a total of "+`_file_size`+" bytes for "+type)
466 self.writefile(sizefile, buf.getvalue())
467
468
469
484
485
491
498
507
508
509
510 parentprofile=com_lgvx8100.Profile
512 protocolclass=Phone.protocolclass
513 serialsname=Phone.serialsname
514
515 BP_Calendar_Version=3
516 phone_manufacturer='LG Electronics Inc'
517 phone_model='AX8600'
518
519 WALLPAPER_WIDTH=176
520 WALLPAPER_HEIGHT=220
521
522 MAX_WALLPAPER_BASENAME_LENGTH=32
523 WALLPAPER_FILENAME_CHARS="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_() ."
524 WALLPAPER_CONVERT_FORMAT="jpg"
525
526
527 DIALSTRING_CHARS="[^0-9PW#*]"
528
529 MAX_RINGTONE_BASENAME_LENGTH=32
530 RINGTONE_FILENAME_CHARS="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_() ."
531 RINGTONE_LIMITS= {
532 'MAXSIZE': 200000
533 }
534
535
536 imageorigins={}
537 imageorigins.update(common.getkv(parentprofile.stockimageorigins, "images"))
538
539
540
541
542
543 imagetargets={}
544
545
546 imagetargets.update(common.getkv(parentprofile.stockimagetargets, "wallpaper",
547 {'width': 176, 'height': 220, 'format': "JPEG"}))
548
549
550
551
552
553
556
557 ringtoneorigins=('ringers', 'sounds')
558 excluded_ringtone_origins=('ringers')
559 excluded_wallpaper_origins=('video')
560
561
564
565 - def QueryAudio(self, origin, currentextension, afi):
566 _max_size=self.RINGTONE_LIMITS['MAXSIZE']
567 setattr(afi, 'MAXSIZE', _max_size)
568
569 if afi.format in ("MIDI", "QCP", "PMD", "WMA"):
570 return currentextension, afi
571
572 if afi.format=="MP3":
573 if afi.channels==1 and 8<=afi.bitrate<=64 and 16000<=afi.samplerate<=22050:
574 return currentextension, afi
575
576 return ("mp3", fileinfo.AudioFileInfo(afi, **{'format': 'MP3',
577 'channels': 2,
578 'bitrate': 48,
579 'samplerate': 44100,
580 'MAXSIZE': _max_size }))
581
584
585
586 _supportedsyncs=(
587 ('phonebook', 'read', None),
588 ('calendar', 'read', None),
589 ('wallpaper', 'read', None),
590 ('ringtone', 'read', None),
591 ('call_history', 'read', None),
592
593 ('memo', 'read', None),
594 ('phonebook', 'write', 'OVERWRITE'),
595 ('calendar', 'write', 'OVERWRITE'),
596 ('wallpaper', 'write', 'MERGE'),
597 ('wallpaper', 'write', 'OVERWRITE'),
598 ('ringtone', 'write', 'MERGE'),
599 ('ringtone', 'write', 'OVERWRITE'),
600
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, 'details': 5 },
613 'email': 2,
614 'address': {
615 'type': 0, 'company': 0, 'street': 0, 'street2': 0,
616 'city': 0, 'state': 0, 'postalcode': 0, 'country': 0,
617 'details': 0 },
618 'url': 0,
619 'memo': 0,
620 'category': 1,
621 'wallpaper': 1,
622 'ringtone': 2,
623 'storage': 0,
624 },
625 'calendar': {
626 'description': True, 'location': False, 'allday': False,
627 'start': True, 'end': True, 'priority': False,
628 'alarm': True, 'vibrate': True,
629 'repeat': True,
630 'memo': False,
631 'category': False,
632 'wallpaper': False,
633 'ringtone': True,
634 },
635 'memo': {
636 'subject': True,
637 'date': True,
638 'secret': False,
639 'category': False,
640 'memo': True,
641 },
642 'todo': {
643 'summary': False,
644 'status': False,
645 'due_date': False,
646 'percent_complete': False,
647 'completion_date': False,
648 'private': False,
649 'priority': False,
650 'category': False,
651 'memo': False,
652 },
653 }
654