Package phones :: Module com_lgvx11000
[hide private]
[frames] | no frames]

Source Code for Module phones.com_lgvx11000

  1  #!/usr/bin/env python 
  2   
  3  ### BITPIM 
  4  ### 
  5  ### Copyright (C) 2009 Nathan Hjelm <hjelmn@users.sourceforge.net> 
  6  ### 
  7  ### This program is free software; you can redistribute it and/or modify 
  8  ### it under the terms of the BitPim license as detailed in the LICENSE file. 
  9  ### 
 10  ### 
 11   
 12   
 13   
 14  """ 
 15  Communicate with the LG VX11000 cell phone. 
 16  """ 
 17   
 18  # BitPim modules 
 19  import common 
 20  import com_brew 
 21  import prototypes 
 22  import com_lgvx9700 
 23  import p_lgvx11000 
 24  import helpids 
 25  import sms 
 26  import field_color 
 27  import phonenumber 
 28  import wx 
 29  import database 
 30   
 31  DEBUG1=False 
 32   
 33  #------------------------------------------------------------------------------- 
 34  parentphone=com_lgvx9700.Phone 
35 -class Phone(parentphone):
36 desc="LG-VX11000 (enV Touch)" 37 helpid=helpids.ID_PHONE_LGVX11000 38 protocolclass=p_lgvx11000 39 serialsname='lgvx11000' 40 41 my_model='VX11000' 42 builtinringtones= ('Low Beep Once', 'Low Beeps', 'Loud Beep Once', 'Loud Beeps', 'Door Bell', 43 'VZW Default Tone', 'Basic Ring', 'Telephone Ring', 'Soft Ring', 'Simple Beep', 44 'Galaxy Beep', 'Bellution', 'Good Morning', 'Rodeo Clown', 'Voice Of The Nature', 45 'Latin Fever', 'Allure', 'Surf The Groove', 'Ride A Tiger', 'This Time', 46 'Deep Blue Calling', 'Fairy Palaces', 'Central Park', 'Balmy Climate', 'Spring Legend', 47 'East of Rain', 'No Ring',) 48 49 ringtonelocations= ( 50 # type index file default dir external dir max type index 51 ('ringers', 'dload/myringtone.dat','brew/mod/10889/ringtones', '', 100, 0x01, 100), 52 ( 'sounds', 'dload/mysound.dat', 'brew/mod/18067', '', 100, 0x02, None), 53 ( 'sounds(sd)', 'dload/sd_sound.dat', 'mmc1/my_sounds', '', 100, 0x02, None), 54 ( 'music', 'dload/efs_music.dat', 'my_music', '', 100, 0x104, None), 55 ( 'music(sd)', 'dload/sd_music.dat', 'mmc1/my_music', '', 100, 0x14, None), 56 ) 57 58 #add picture ids to list of wallpapers, seems to be new for this phone 59 wallpaperlocations= ( 60 # type index file default dir external dir max type Index 61 ( 'images', 'dload/image.dat', 'brew/mod/10888', '', 100, 0x00, 100), 62 ( 'images(sd)', 'dload/sd_image.dat', 'mmc1/my_pix', '', 100, 0x10, None), 63 ( 'video', 'dload/video.dat', 'brew/mod/10890', '', 100, 0x03, None), 64 ( 'video(sd)', 'dload/sd_video.dat', 'mmc1/my_flix', '', 100, 0x13, None), 65 ( 'picture ids','set_as_pic_id_dir/setas_pic_id.dat', 'set_as_pic_id_dir', '', 999, 0x00, None), 66 ) 67
68 - def setDMversion(self):
69 self._DMv5=False 70 self._DMv6=True 71 self._timeout=5 # Assume a quick timeout on newer phones
72
73 - def getphoneinfo(self, phone_info):
74 self.log('Getting Phone Info') 75 try: 76 s=self.getfilecontents('brew/version.txt') 77 if s[:7]==self.my_model: 78 phone_info.append('Manufacturer:', Profile.phone_manufacturer) 79 phone_info.append('Model:', self.my_model) 80 phone_info.append('Name:', self.desc[12:21]) 81 phone_info.append('ESN:', self.get_brew_esn()) 82 phone_info.append('Firmware Version:', self.get_firmware_version()) 83 #get the phone number from 'My Name Card' 84 namecard=self.getfilecontents2('pim/pbmyentry.dat', 208, 10) 85 phone_info.append('Phone Number:', phonenumber.format(namecard)) 86 except Exception, e: 87 pass 88 return
89 90 # Fundamentals: 91 # - get_esn - same as LG VX-8300 92 # - getgroups - new implementation here due to group picture ids and no 'No Group' on this phone 93 # - getwallpaperindices - LGUncountedIndexedMedia 94 # - getringtoneindices - LGUncountedIndexedMedia 95 # - DM Version - 6 96 # - phonebook - same as LG VX-8550, with some slight differences with picture ids, speed dials 97 # - SMS - same dir structure as the VX-8800 98
99 - def getgroups(self, results):
100 "Read groups" 101 # Reads groups that use explicit IDs 102 self.log("Reading group information") 103 g=self.readobject(self.protocolclass.pb_group_filename, 104 self.protocolclass.pbgroups, 105 'Reading groups data') 106 107 self.log("Reading Group Picture IDs") 108 group_picid_pathf=self._get_group_path_index(self.protocolclass.GroupWPPathIndexFile) 109 _groupwp_ids=self._build_media_dict(results, group_picid_pathf, 'wallpaper-index') 110 111 groups={} 112 for i in range(len(g.groups)): 113 _group = g.groups[i] 114 if _group.name: 115 try: 116 if _group.wallpaper == 0x64: 117 #indexes between _groupwp_ids and g.groups correspond to each other 118 #the group id does not match up to anything for group picture id purposes 119 paper = _groupwp_ids.get(group_picid_pathf.items[i].pathname, None) 120 else: 121 paper = self.protocolclass.NOWALLPAPER 122 123 if paper is None: 124 raise 125 126 groups[_group.groupid]= { 'name': _group.name, 'user_added': _group.user_added, 127 'wallpaper': paper } #groups can have wallpaper on this phone 128 except: 129 self.log("can't find wallpaper for group index: " + str(_group.groupid) + ": " + str(_group.name)) 130 131 results['groups'] = groups 132 return groups
133
134 - def savegroups(self, data):
135 groups=data.get('groups', {}) 136 keys=groups.keys() 137 keys.sort() 138 keys.reverse() 139 g=self.protocolclass.pbgroups() 140 141 wp_index=data.get('wallpaper-index', {}) 142 group_picid_pathf=self.protocolclass.GroupPicID_PathIndexFile() 143 144 #Don't write the no group entry, it doesn't exist on this phone! 145 for i in keys: 146 if not i: 147 continue #already wrote this one out 148 # now write the rest in reverse ID order 149 group_entry = groups[i] 150 new_entry = self.protocolclass.pbgroup(name=groups[i]['name'], groupid=i, user_added=groups[i].get('user_added', 1), wallpaper=0) 151 for key in group_entry: 152 if key == 'wallpaper': 153 if group_entry['wallpaper']==self.protocolclass.NOWALLPAPER: 154 new_entry.wallpaper = self._findmediainindex(data['wallpaper-index'], None, group_entry['name'], 'wallpaper') 155 else: 156 new_entry.wallpaper = self._findmediainindex(data['wallpaper-index'], group_entry['wallpaper'], group_entry['name'], 'wallpaper') 157 try: 158 _filename = wp_index[new_entry.wallpaper]['filename'] 159 group_picid_pathf.items.append(self.protocolclass.GroupPicID_PathIndexEntry(pathname=_filename)) 160 new_entry.wallpaper = 0x64 161 except: 162 group_picid_pathf.items.append(self.protocolclass.GroupPicID_PathIndexEntry()) 163 164 g.groups.append(new_entry) 165 166 #write group picture ids 167 self.log("Writing group picture ID") 168 self.writeobject(self.protocolclass.GroupWPPathIndexFile, 169 group_picid_pathf, logtitle='Writing group wallpaper paths', 170 uselocalfs=DEBUG1) 171 #write groups 172 self.writeobject(self.protocolclass.pb_group_filename, g, 173 logtitle='Writing phonebook groups', 174 uselocalfs=DEBUG1)
175
176 - def _build_favorites_dict(self):
177 if hasattr(self.protocolclass, 'favorites'): 178 self.log("Reading favorites") 179 # Return an favorites dict for building phone entries 180 _res={} 181 _favorites=self.readobject(self.protocolclass.favorites_file_name, 182 self.protocolclass.favorites, 183 logtitle='Reading favorites') 184 for _idx,_entry in enumerate(_favorites.items): 185 if _entry.has_pbentry (): 186 _res[_entry.pb_index]=_idx 187 return _res 188 else: 189 return None
190
191 - def _get_group_path_index(self, index_file):
192 buf = prototypes.buffer(self.getfilecontents(index_file)) 193 _path_file=self.protocolclass.GroupPicID_PathIndexFile(); 194 _path_file.readfrombuffer(buf, logtitle="Read group wallpaper path index: " + index_file) 195 return _path_file
196
197 - def getphonebook (self, result):
198 """Reads the phonebook data. The L{getfundamentals} information will 199 already be in result.""" 200 # Read speed dials first -- same file format as the VX-8100 201 _speeds=self._get_speeddials() 202 203 # Read the emergency contacts list 204 self.log("Reading ICE entries") 205 _ices=self._build_ice_dict() 206 207 # Read favorites (if available) 208 _favorites=self._build_favorites_dict () 209 210 self.log("Reading phonebook entries") 211 pb_entries=self.readobject(self.protocolclass.pb_file_name, 212 self.protocolclass.pbfile, 213 logtitle='Reading phonebook entries') 214 215 self.log("Reading phone numbers") 216 pb_numbers=self.readobject(self.protocolclass.pn_file_name, 217 self.protocolclass.pnfile, 218 logtitle='Reading phonebook numbers') 219 220 #handle errors people are having when pa_file doesn't exist 221 try: 222 # check for addresses support 223 if hasattr(self.protocolclass, 'pafile'): 224 self.log("Reading addresses") 225 pb_addresses = self.readobject(self.protocolclass.pa_file_name, 226 self.protocolclass.pafile, 227 logtitle='Reading addresses') 228 else: 229 pb_addresses = None 230 except: 231 pb_addresses = None 232 233 self.log("Reading Ringtone IDs") 234 ring_pathf=self._get_path_index(self.protocolclass.RTPathIndexFile) 235 _rt_ids=self._build_media_dict(result, ring_pathf, 'ringtone-index') 236 237 self.log("Reading Picture IDs") 238 picid_pathf=self._get_path_index(self.protocolclass.WPPathIndexFile) 239 _wp_ids=self._build_media_dict(result, picid_pathf, 'wallpaper-index') 240 241 pbook={} 242 for _cnt in range(self.protocolclass.NUMPHONEBOOKENTRIES): 243 pb_entry=pb_entries.items[_cnt] 244 if not pb_entry.valid(): 245 continue 246 try: 247 self.log("Parse entry "+`_cnt`+" - " + pb_entry.name) 248 pbook[_cnt]=self.extractphonebookentry(pb_entry, pb_numbers, pb_addresses, 249 _speeds, _ices, _favorites, result, 250 _rt_ids.get(ring_pathf.items[_cnt].pathname, None), 251 _wp_ids.get(picid_pathf.items[_cnt].pathname, None)) 252 253 self.progress(_cnt, self.protocolclass.NUMPHONEBOOKENTRIES, pb_entry.name) 254 except common.PhoneBookBusyException: 255 raise 256 except Exception, e: 257 # Something's wrong with this entry, log it and skip 258 self.log('Failed to parse entry %d'%_cnt) 259 self.log('Exception %s raised'%`e`) 260 if __debug__: 261 raise 262 263 self.progress(self.protocolclass.NUMPHONEBOOKENTRIES, 264 self.protocolclass.NUMPHONEBOOKENTRIES, 265 "Phone book read completed") 266 267 result['phonebook']=pbook 268 #add a simple list of categories to result dict 269 cats=[] 270 for i in result['groups']: 271 if result['groups'][i]['name']!='No Group': 272 cats.append(result['groups'][i]['name']) 273 result['categories']=cats 274 #add a simple list of categories with their wallpapers to result dict 275 group_wps=[] 276 for i in result['groups']: 277 groupinfo=result['groups'][i] 278 name=str(groupinfo.get('name')) 279 wp_name=str(groupinfo.get('wallpaper')) 280 group_wps.append(name+":"+wp_name) 281 result['group_wallpapers']=group_wps 282 return pbook
283
284 - def extractphonebookentry(self, entry, numbers, addresses, speeds, ices, favorites, fundamentals, 285 rt_name, wp_name):
286 """Return a phonebook entry in BitPim format. This is called from getphonebook.""" 287 res={} 288 # serials 289 res['serials']=[ {'sourcetype': self.serialsname, 290 'sourceuniqueid': fundamentals['uniqueserial'], 291 'serial1': entry.entry_number1, 292 'serial2': entry.entry_number1 } ] 293 294 # only one name 295 res['names']=[ {'full': entry.name} ] 296 297 # only one category 298 cat=fundamentals['groups'].get(entry.group, {'name': "No Group"})['name'] 299 if cat!="No Group": 300 res['categories']=[ {'category': cat} ] 301 302 # emails 303 res['emails']=[] 304 for i in entry.emails: 305 if len(i.email): 306 res['emails'].append( {'email': i.email} ) 307 if not len(res['emails']): del res['emails'] # it was empty 308 309 # wallpapers 310 if entry.wallpaper!=self.protocolclass.NOWALLPAPER: 311 try: 312 if entry.wallpaper == 0x64: 313 paper = wp_name 314 else: 315 paper = fundamentals['wallpaper-index'][entry.wallpaper]['name'] 316 317 if paper is None: 318 raise 319 320 res['wallpapers']=[ {'wallpaper': paper, 'use': 'call'} ] 321 except: 322 self.log("can't find wallpaper for index: " + str(entry.wallpaper)) 323 324 # ringtones 325 if entry.ringtone != self.protocolclass.NORINGTONE: 326 try: 327 if entry.ringtone == 0x64: 328 tone = rt_name 329 else: 330 tone = fundamentals['ringtone-index'][entry.ringtone]['name'] 331 332 if tone is None: 333 raise 334 335 res['ringtones']=[ {'ringtone': tone, 'use': 'call'} ] 336 except: 337 self.log("can't find ringtone for index: " + str(entry.ringtone)) 338 339 if addresses is not None and entry.addressindex != 0xffff: 340 for _address in addresses.items: 341 if _address.valid() and _address.index == entry.addressindex: 342 res['addresses'] = [ { 'street': _address.street, 343 'city': _address.city, 344 'state': _address.state, 345 'postalcode': _address.zip_code, 346 'country': _address.country }] 347 break 348 349 # assume we are like the VX-8100 in this regard -- looks correct 350 res=self._assignpbtypeandspeeddialsbytype(entry, numbers, speeds, res) 351 352 # assign the ICE entry to the associated contact to keep them in sync 353 res=self._assigniceentry(entry, numbers, ices, res) 354 355 # adding the favorite entry 356 res=self._assignfavoriteentry(entry, favorites, res) 357 358 return res
359
360 - def _assignfavoriteentry(self, entry, favorites, res):
361 if favorites.has_key(entry.entry_number0): 362 # this contact entry is an favorite entry 363 res['favorite']=[ { 'favoriteindex': favorites[entry.entry_number0] } ] 364 return res
365
366 - def savephonebook (self, data):
367 "Saves out the phonebook" 368 369 #take the simple list of categories with their wallpapers and add it to result dict 370 new_group_dict={} 371 group_wps=data.get('group_wallpapers', {}) 372 for i in range(len(group_wps)): 373 groupwp_entry=group_wps[i] 374 entry_list=groupwp_entry.split(":", 1) #split on colon a maximum of once 375 name=entry_list[0] 376 wp=entry_list[1] 377 for key in data['groups']: 378 group_entry=data['groups'][key] 379 if name==group_entry.get('name'): 380 group_entry['wallpaper']=wp 381 new_group_dict[key]=group_entry 382 data['groups']=new_group_dict 383 self.savegroups (data) 384 385 ring_pathf=self.protocolclass.PathIndexFile() 386 picid_pathf=self.protocolclass.PathIndexFile() 387 388 # the pbentry.dat will be overwritten so there is no need to delete entries 389 pbook = data.get('phonebook', {}) 390 keys = pbook.keys () 391 keys.sort () 392 393 _rt_index=data.get('ringtone-index', {}) 394 _wp_index=data.get('wallpaper-index', {}) 395 396 entry_num0 = 0 397 entry_num1 = self._get_next_pb_id() 398 pb_entries = self.protocolclass.pbfile(model_name=self.my_model) 399 pn_entries = self.protocolclass.pnfile() 400 401 # some phones store addresses as well 402 if hasattr(self.protocolclass, 'pafile'): 403 pa_entries = self.protocolclass.pafile() 404 else: 405 pa_entries = None 406 407 ice_entries = self.protocolclass.iceentryfile() 408 for i in range(self.protocolclass.NUMEMERGENCYCONTACTS): 409 ice_entries.items.append (self.protocolclass.iceentry()) 410 411 speeddials={} 412 413 # favorites can be groups or contacts. read favorites to preserve group favorites 414 if hasattr (self.protocolclass, 'favorites'): 415 favorites = self.readobject(self.protocolclass.favorites_file_name, 416 self.protocolclass.favorites, 417 logtitle='Reading favorites') 418 for _entry in favorites.items: 419 # all phonebook favorite will be invalid after writing the phonebook 420 # (except for entries we set) so delete all phonebook favorites 421 if _entry.fav_type == 1: 422 _entry.fav_type = 0xff 423 _entry.pb_index = 0xffff 424 else: 425 favorites = None 426 427 for i in keys: 428 pb_entries.items.append(self.make_entry (pn_entries, pa_entries, favorites, speeddials, 429 ice_entries, entry_num0, entry_num1, pbook[i], 430 data, ring_pathf,_rt_index, picid_pathf, _wp_index)) 431 entry_num0 += 1 432 if entry_num0 >= self.protocolclass.NUMPHONEBOOKENTRIES: 433 self.log ("Maximum number of phonebook entries reached") 434 break 435 if entry_num1==0xffffffff: 436 entry_num1=0 437 else: 438 entry_num1+=1 439 440 # write phonebook entries 441 self.log ("Writing phonebook entries") 442 self.writeobject(self.protocolclass.pb_file_name, 443 pb_entries, 444 logtitle='Writing phonebook entries', 445 uselocalfs=DEBUG1) 446 # write phone numbers 447 self.log ("Writing phone numbers") 448 self.writeobject(self.protocolclass.pn_file_name, 449 pn_entries, logtitle='Writing phonebook numbers', 450 uselocalfs=DEBUG1) 451 452 if pa_entries is not None: 453 # write addresses 454 self.log ("Writing addresses") 455 self.writeobject(self.protocolclass.pa_file_name, 456 pa_entries, logtitle="Writing addresses", 457 uselocalfs=DEBUG1) 458 459 # write ringtone index 460 self.log('Writing ringtone ID') 461 self.writeobject(self.protocolclass.RTPathIndexFile, 462 ring_pathf, logtitle='Writing ringtone paths', 463 uselocalfs=DEBUG1) 464 # write wallpaper index 465 self.log('Writing picture ID') 466 self.writeobject(self.protocolclass.WPPathIndexFile, 467 picid_pathf, logtitle='Writing wallpaper paths', 468 uselocalfs=DEBUG1) 469 470 # write ICE index 471 self.log('Writing ICE entries') 472 self.writeobject(self.protocolclass.ice_file_name, 473 ice_entries, logtitle='Writing ICE entries', 474 uselocalfs=DEBUG1) 475 476 # update speed dials 477 req=self.protocolclass.speeddials() 478 # slot 0 is always unused 479 req.speeddials.append(self.protocolclass.speeddial()) 480 # if empty, slot 1 is for voicemail 481 if speeddials.has_key(1): 482 answer = wx.MessageBox("You have assigned speed dial #1 in your PhoneBook.\nAre you sure you want to overwrite the 'Voicemail' speed dial?", "Caution overwriting speed dial", wx.YES_NO|wx.ICON_EXCLAMATION|wx.STAY_ON_TOP) 483 if answer == wx.YES: 484 req.speeddials.append(self.protocolclass.speeddial(entry=speeddials[1]['entry'],number=speeddials[1]['type'])) 485 else: 486 req.speeddials.append(self.protocolclass.speeddial(entry=1000,number=6)) 487 else: 488 req.speeddials.append(self.protocolclass.speeddial(entry=1000,number=6)) 489 490 for i in range(2, self.protocolclass.NUMSPEEDDIALS): 491 sd=self.protocolclass.speeddial() 492 if speeddials.has_key(i): 493 if i==411: 494 answer = wx.MessageBox("You have assigned speed dial #411 in your PhoneBook.\nAre you sure you want to overwrite the 'Directory Assistance' speed dial?", "Caution overwriting speed dial", wx.YES_NO|wx.ICON_EXCLAMATION|wx.STAY_ON_TOP) 495 if answer == wx.YES: 496 sd.entry=speeddials[i]['entry'] 497 sd.number=speeddials[i]['type'] 498 else: 499 req.speeddials.append(sd) 500 continue #they dont want to assign 411 so skip to next iteration 501 sd.entry=speeddials[i]['entry'] 502 sd.number=speeddials[i]['type'] 503 req.speeddials.append(sd) 504 505 self.log('Writing speed dials') 506 self.writeobject(self.protocolclass.speed_file_name, 507 req, logtitle='Writing speed dials data', 508 uselocalfs=DEBUG1) 509 510 if favorites is not None: 511 self.log('Writing favorites') 512 self.writeobject(self.protocolclass.favorites_file_name, 513 favorites, logtitle='Writing favorites', 514 uselocalfs=DEBUG1) 515 516 # update the next pbentries ID 517 self._save_next_pb_id(entry_num1) 518 data["rebootphone"]=True 519 520 return data
521
522 - def make_pa_entry (self, pb_entry, address_index, address):
523 new_entry = self.protocolclass.pafileentry(entry_tag=self.protocolclass.PA_ENTRY_SOR) 524 new_entry.index = address_index 525 new_entry.pb_entry = pb_entry 526 new_entry.street = address['street'] 527 new_entry.city = address['city'] 528 new_entry.state = address['state'] 529 new_entry.zip_code = address['postalcode'] 530 new_entry.country = address['country'] 531 532 return new_entry
533
534 - def make_entry (self, pn_entries, pa_entries, favorites, speeddials, ice_entries, 535 entry_num0, entry_num1, pb_entry, data, 536 ring_pathf, rt_index, picid_pathf, wp_index):
537 """ Create a pbfileentry from a bitpim phonebook entry """ 538 new_entry = self.protocolclass.pbfileentry(entry_tag=self.protocolclass.PB_ENTRY_SOR) 539 # entry IDs 540 new_entry.entry_number0 = entry_num0 541 new_entry.entry_number1 = entry_num1 542 543 for key in pb_entry: 544 if key in ('emails', 'numbertypes'): 545 l = getattr (new_entry, key) 546 for item in pb_entry[key]: 547 l.append(item) 548 elif key == 'numbers': 549 l = getattr (new_entry, 'numberindices') 550 for i in range(0, self.protocolclass.NUMPHONENUMBERS): 551 new_pn_id = len (pn_entries.items) 552 if new_pn_id == self.protocolclass.NUMPHONENUMBERENTRIES: 553 # this state should not be possible. should this raise an exception? 554 self.log ("Maximum number of phone numbers reached") 555 break 556 557 try: 558 pn_entries.items.append(self.make_pn_entry (pb_entry[key][i],pb_entry['numbertypes'][i], new_pn_id, i, entry_num0)) 559 l.append (new_pn_id) 560 except: 561 l.append (0xffff) 562 elif key == 'speeddials': 563 for _sd,_num_type in zip(pb_entry['speeddials'], pb_entry['numbertypes']): 564 if _sd is not None: 565 speeddials[_sd]={ 'entry': entry_num0, 566 'type': _num_type } 567 elif key == 'ice': 568 # In Case of Emergency 569 _ice = pb_entry['ice'] 570 if _ice is not None and len(_ice) > 0: 571 _ice_entry = _ice[0]['iceindex'] 572 ice_entries.items[_ice_entry] = self.make_ice_entry (_ice_entry, entry_num0) 573 elif key == 'favorite': 574 _favorite = pb_entry['favorite'] 575 if favorites is not None and _favorite is not None and len(_favorite) > 0: 576 favorites.items[_favorite[0]['favoriteindex']].fav_type = 1 # phone number 577 favorites.items[_favorite[0]['favoriteindex']].pb_index = entry_num0 # phone number 578 elif key == 'addresses': 579 _addresses = pb_entry['addresses'] 580 address_id = len (pa_entries.items) 581 if pa_entries is not None and _addresses is not None and len(_addresses) > 0: 582 new_entry.addressindex = address_id 583 pa_entries.items.append(self.make_pa_entry (entry_num0, address_id, _addresses[0])) 584 elif key == 'ringtone': 585 new_entry.ringtone = self._findmediainindex(data['ringtone-index'], pb_entry['ringtone'], pb_entry['name'], 'ringtone') 586 try: 587 _filename = rt_index[new_entry.ringtone]['filename'] 588 ring_pathf.items.append(self.protocolclass.PathIndexEntry(pathname=_filename)) 589 new_entry.ringtone = 0x64 590 except: 591 ring_pathf.items.append(self.protocolclass.PathIndexEntry()) 592 elif key == 'wallpaper': 593 new_entry.wallpaper = self._findmediainindex(data['wallpaper-index'], pb_entry['wallpaper'], pb_entry['name'], 'wallpaper') 594 try: 595 _filename = wp_index[new_entry.wallpaper]['filename'] 596 picid_pathf.items.append(self.protocolclass.PathIndexEntry(pathname=_filename)) 597 new_entry.wallpaper = 0x64 598 except: 599 picid_pathf.items.append(self.protocolclass.PathIndexEntry()) 600 elif key in new_entry.getfields(): 601 setattr (new_entry, key, pb_entry[key]) 602 603 return new_entry
604 605 #------------------------------------------------------------------------------- 606 parentprofile=com_lgvx9700.Profile
607 -class Profile(parentprofile):
608 protocolclass=Phone.protocolclass 609 serialsname=Phone.serialsname 610 611 BP_Calendar_Version=3 612 phone_manufacturer='LG Electronics Inc' 613 phone_model='VX11000' 614 # inside screen resolution 615 WALLPAPER_WIDTH = 800 616 WALLPAPER_HEIGHT = 480 617 618 ringtoneorigins=('ringers', 'sounds', 'sounds(sd)',' music', 'music(sd)') 619 excluded_ringtone_origins=('music', 'music(sd)') 620 621 # wallpaper origins that are not available for the contact assignment 622 excluded_wallpaper_origins=('video','video(sd)') 623 624 imageorigins={} 625 imageorigins.update(common.getkv(parentprofile.stockimageorigins, "images")) 626 imageorigins.update(common.getkv(parentprofile.stockimageorigins, "video")) 627 imageorigins.update(common.getkv(parentprofile.stockimageorigins, "images(sd)")) 628 imageorigins.update(common.getkv(parentprofile.stockimageorigins, "video(sd)")) 629 imageorigins.update(common.getkv(parentprofile.stockimageorigins, "picture ids")) 630 631 # our targets are the same for all origins 632 imagetargets={} 633 imagetargets.update(common.getkv(parentprofile.stockimagetargets, "outsidelcd", 634 {'width': 480, 'height': 800, 'format': "JPEG"})) 635 imagetargets.update(common.getkv(parentprofile.stockimagetargets, "wallpaper", 636 {'width': 800, 'height': 480, 'format': "JPEG"})) 637 imagetargets.update(common.getkv(parentprofile.stockimagetargets, "pictureid", 638 {'width': 320, 'height': 240, 'format': "JPEG"})) 639 640 _supportedsyncs=( 641 ('phonebook', 'read', None), # all phonebook reading 642 ('calendar', 'read', None), # all calendar reading 643 ('wallpaper', 'read', None), # all wallpaper reading 644 ('ringtone', 'read', None), # all ringtone reading 645 ('call_history', 'read', None),# all call history list reading 646 ('sms', 'read', None), # all SMS list reading 647 ('memo', 'read', None), # all memo list reading 648 ## ('phonebook', 'write', 'OVERWRITE'), # only overwriting phonebook 649 ('calendar', 'write', 'OVERWRITE'), # only overwriting calendar 650 ('wallpaper', 'write', 'MERGE'), # merge and overwrite wallpaper 651 ('wallpaper', 'write', 'OVERWRITE'), 652 ('ringtone', 'write', 'MERGE'), # merge and overwrite ringtone 653 ('ringtone', 'write', 'OVERWRITE'), 654 ('sms', 'write', 'OVERWRITE'), # all SMS list writing 655 ('memo', 'write', 'OVERWRITE'), # all memo list writing 656 ## ('playlist', 'read', 'OVERWRITE'), 657 ## ('playlist', 'write', 'OVERWRITE'), 658 ## ('t9_udb', 'write', 'OVERWRITE'), 659 ) 660 if __debug__: 661 _supportedsyncs+=( 662 ('t9_udb', 'read', 'OVERWRITE'), 663 ('t9_udb', 'write', 'OVERWRITE'), 664 ('playlist', 'read', None), 665 ('playlist', 'write', 'OVERWRITE'), 666 ('playlist', 'write', 'MERGE'), 667 ) 668 669 field_color_data={ 670 'phonebook': { 671 'name': { 672 'first': False, 'middle': False, 'last': False, 'full': 1, 673 'nickname': False, 'details': 1 }, 674 'number': { 675 'type': 5, 'speeddial': 5, 'number': 5, 676 'ringtone': False, 'wallpaper': False, 'details': 5 }, 677 'email': 2, 678 'email_details': { 679 'emailspeeddial': False, 'emailringtone': False, 680 'emailwallpaper': False }, 681 'address': { 682 'type': False, 'company': False, 'street': 1, 'street2': False, 683 'city': 1, 'state': 1, 'postalcode': 1, 'country': 1, 'details': 1 }, 684 'url': 0, 685 'memo': 0, 686 'category': 1, 687 'wallpaper': 1, 688 'group_wallpaper': 1, 689 #'wallpaper_type': False, 690 'ringtone': 1, 691 'storage': False, 692 'secret': False, 693 'ICE': 1, 694 'Favorite': 1, 695 }, 696 'calendar': { 697 'description': True, 'location': False, 'allday': False, 698 'start': True, 'end': True, 'priority': False, 699 'alarm': True, 'vibrate': True, 700 'repeat': True, 701 'memo': False, 702 'category': False, 703 'wallpaper': False, 704 'ringtone': True, 705 }, 706 'memo': { 707 'subject': False, 708 'date': True, 709 'secret': False, 710 'category': False, 711 'memo': True, 712 }, 713 'todo': { 714 'summary': False, 715 'status': False, 716 'due_date': False, 717 'percent_complete': False, 718 'completion_date': False, 719 'private': False, 720 'priority': False, 721 'category': False, 722 'memo': False, 723 }, 724 } 725 726
727 - def convertphonebooktophone(self, helper, data):
728 """Converts the data to what will be used by the phone 729 730 @param data: contains the dict returned by getfundamentals 731 as well as where the results go""" 732 results={} 733 734 self.normalisegroups(helper, data) 735 736 for pbentry in data['phonebook']: 737 if len(results)==self.protocolclass.NUMPHONEBOOKENTRIES: 738 break 739 e={} # entry out 740 entry=data['phonebook'][pbentry] # entry in 741 try: 742 # serials 743 serial1=helper.getserial(entry.get('serials', []), self.serialsname, data['uniqueserial'], 'serial1', 0) 744 serial2=helper.getserial(entry.get('serials', []), self.serialsname, data['uniqueserial'], 'serial2', serial1) 745 746 e['serial1']=serial1 747 e['serial2']=serial2 748 for ss in entry["serials"]: 749 if ss["sourcetype"]=="bitpim": 750 e['bitpimserial']=ss 751 assert e['bitpimserial'] 752 753 # name 754 e['name']=helper.getfullname(entry.get('names', []),1,1,32)[0] 755 756 # ice 757 e['ice']=entry.get('ice', None) 758 759 # favorites 760 e['favorite']=entry.get('favorite', None) 761 762 # address 763 e['addresses']=entry.get('addresses', None) 764 765 # categories/groups 766 cat=helper.makeone(helper.getcategory(entry.get('categories', []),0,1,32), None) 767 if cat is None: 768 e['group']=0 769 else: 770 key,value=self._getgroup(cat, data['groups']) 771 if key is not None: 772 e['group']=key 773 else: 774 # sorry no space for this category 775 e['group']=0 776 777 # email addresses 778 emails=helper.getemails(entry.get('emails', []) ,0,self.protocolclass.NUMEMAILS,48) 779 e['emails']=helper.filllist(emails, self.protocolclass.NUMEMAILS, "") 780 781 # phone numbers 782 # there must be at least one email address or phonenumber 783 minnumbers=1 784 if len(emails): minnumbers=0 785 numbers=helper.getnumbers(entry.get('numbers', []),minnumbers,self.protocolclass.NUMPHONENUMBERS) 786 e['numbertypes']=[] 787 e['numbers']=[] 788 e['speeddials']=[] 789 for numindex in range(len(numbers)): 790 num=numbers[numindex] 791 # deal with type 792 b4=len(e['numbertypes']) 793 type=num['type'] 794 for i,t in enumerate(self.protocolclass.numbertypetab): 795 if type==t: 796 # some voodoo to ensure the second home becomes home2 797 if i in e['numbertypes'] and t[-1]!='2': 798 type+='2' 799 continue 800 e['numbertypes'].append(i) 801 break 802 if t=='none': # conveniently last entry 803 e['numbertypes'].append(i) 804 break 805 if len(e['numbertypes'])==b4: 806 # we couldn't find a type for the number 807 helper.add_error_message('Number %s (%s/%s) not supported and ignored.'% 808 (num['number'], e['name'], num['type'])) 809 continue 810 # deal with number 811 number=self.phonize(num['number']) 812 if len(number)==0: 813 # no actual digits in the number 814 continue 815 if len(number) > 48: # get this number from somewhere sensible 816 # ::TODO:: number is too long and we have to either truncate it or ignore it? 817 number=number[:48] # truncate for moment 818 e['numbers'].append(number) 819 # deal with speed dial 820 sd=num.get("speeddial", None) 821 if sd is not None and \ 822 sd>=self.protocolclass.FIRSTSPEEDDIAL and \ 823 sd<=self.protocolclass.LASTSPEEDDIAL: 824 e['speeddials'].append(sd) 825 else: 826 e['speeddials'].append(None) 827 828 if len(e['numbers'])<minnumbers: 829 # we couldn't find any numbers 830 # for this entry, so skip it, entries with no numbers cause error 831 helper.add_error_message("Name: %s. No suitable numbers or emails found" % e['name']) 832 continue 833 e['numbertypes']=helper.filllist(e['numbertypes'], self.protocolclass.NUMPHONENUMBERS, 0) 834 e['numbers']=helper.filllist(e['numbers'], self.protocolclass.NUMPHONENUMBERS, "") 835 e['speeddials']=helper.filllist(e['speeddials'], self.protocolclass.NUMPHONENUMBERS, None) 836 837 # ringtones, wallpaper 838 e['ringtone']=helper.getringtone(entry.get('ringtones', []), 'call', None) 839 e['wallpaper']=helper.getwallpaper(entry.get('wallpapers', []), 'call', None) 840 841 results[pbentry]=e 842 843 except helper.ConversionFailed: 844 continue 845 846 data['phonebook']=results 847 return data
848