PyXR

c:\projects\bitpim\src \ phones \ com_lgvx9800.py



0001 ### BITPIM
0002 ###
0003 ### Copyright (C) 2005 Joe Pham <djpham@bitpim.org>
0004 ###
0005 ### This program is free software; you can redistribute it and/or modify
0006 ### it under the terms of the BitPim license as detailed in the LICENSE file.
0007 ###
0008 ### $Id: com_lgvx9800.py 4305 2007-07-16 04:05:25Z djpham $
0009 
0010 """Communicate with the LG VX9800 cell phone
0011 """
0012 
0013 # standard modules
0014 import re
0015 import time
0016 import cStringIO
0017 import sha
0018 
0019 # my modules
0020 import common
0021 import commport
0022 import copy
0023 import com_lgvx4400
0024 import p_brew
0025 import p_lgvx9800
0026 import com_lgvx8100
0027 import com_brew
0028 import com_phone
0029 import com_lg
0030 import prototypes
0031 import bpcalendar
0032 import call_history
0033 import sms
0034 import memo
0035 import playlist
0036 import helpids
0037 
0038 class Phone(com_lgvx8100.Phone):
0039     "Talk to the LG VX9800 cell phone"
0040 
0041     desc="LG-VX9800"
0042     helpid=helpids.ID_PHONE_LGVX9800
0043     protocolclass=p_lgvx9800
0044     serialsname='lgvx9800'
0045     my_model='VX9800'
0046 
0047     builtinringtones= ('Low Beep Once', 'Low Beeps', 'Loud Beep Once', 'Loud Beeps', 'VZW Default Tone') + \
0048                       tuple(['Ringtone '+`n` for n in range(1,11)]) + \
0049                       ('No Ring',)
0050 
0051     ringtonelocations= (
0052         # type       index-file   size-file directory-to-use lowest-index-to-use maximum-entries type-major icon index_offset
0053         ( 'ringers', 'dload/my_ringtone.dat', 'dload/my_ringtonesize.dat', 'brew/16452/lk/mr', 100, 150, 0x201, 1, 0),
0054         # the sound index file uses the same index as the ringers, bitpim does not support this (yet)
0055         ( 'sounds', 'dload/mysound.dat', 'dload/mysoundsize.dat', 'brew/16452/ms', 100, 150, 0x402, 0, 151),
0056         )
0057 
0058     calendarlocation="sch/schedule.dat"
0059     calendarexceptionlocation="sch/schexception.dat"
0060     calenderrequiresreboot=0
0061     memolocation="sch/memo.dat"
0062 
0063     builtinwallpapers = () # none
0064 
0065     wallpaperlocations= (
0066         ( 'images', 'dload/image.dat', 'dload/imagesize.dat', 'brew/16452/mp', 100, 50, 0, 0, 0),
0067         ( 'video', 'dload/video.dat', None, 'brew/16452/mf', 1000, 50, 0x0304, 0, 0),
0068         )
0069 
0070     # for removable media (miniSD cards)
0071     _rs_path='mmc1/'
0072     _rs_ringers_path=_rs_path+'ringers'
0073     _rs_images_path=_rs_path+'images'
0074     media_info={ 'ringers': {
0075             'localpath': 'brew/16452/lk/mr',
0076             'rspath': _rs_ringers_path,
0077             'vtype': protocolclass.MEDIA_TYPE_RINGTONE,
0078             'icon': protocolclass.MEDIA_RINGTONE_DEFAULT_ICON,
0079             'index': 100,  # starting index
0080             'maxsize': 155,
0081             'indexfile': 'dload/my_ringtone.dat',
0082             'sizefile': 'dload/my_ringtonesize.dat',
0083             'dunno': 0, 'date': False,
0084         },
0085          'sounds': {
0086              'localpath': 'brew/16452/ms',
0087              'rspath': None,
0088              'vtype': protocolclass.MEDIA_TYPE_SOUND,
0089              'icon': protocolclass.MEDIA_IMAGE_DEFAULT_ICON,
0090              'index': 100,
0091              'maxsize': 155,
0092              'indexfile': 'dload/mysound.dat',
0093              'sizefile': 'dload/mysoundsize.dat',
0094              'dunno': 0, 'date': False },
0095          'images': {
0096              'localpath': 'brew/16452/mp',
0097              'rspath': _rs_images_path,
0098              'vtype': protocolclass.MEDIA_TYPE_IMAGE,
0099              'icon': protocolclass.MEDIA_IMAGE_DEFAULT_ICON,
0100              'index': 100,
0101              'maxsize': 155,
0102              'indexfile': 'dload/image.dat',
0103              'sizefile': 'dload/imagesize.dat',
0104              'dunno': 0, 'date': False },
0105          'video': {
0106              'localpath': 'brew/16452/mf',
0107              'rspath': None,
0108              'vtype': protocolclass.MEDIA_TYPE_VIDEO,
0109              'icon': protocolclass.MEDIA_VIDEO_DEFAULT_ICON,
0110              'index': 1000,
0111              'maxsize': 155,
0112              'indexfile': 'dload/video.dat',
0113              'sizefile': 'dload/videosize.dat',
0114              'dunno': 0, 'date': True },
0115          }
0116         
0117     def __init__(self, logtarget, commport):
0118         com_lgvx8100.Phone.__init__(self, logtarget, commport)
0119         p_brew.PHONE_ENCODING=self.protocolclass.PHONE_ENCODING
0120         self.mode=self.MODENONE
0121 
0122     def get_esn(self, data=None):
0123         # return the ESN of this phone
0124         return self.get_brew_esn()
0125 
0126     def get_detect_data(self, res):
0127         com_lgvx8100.Phone.get_detect_data(self, res)
0128         res[self.esn_file_key]=self.get_esn()
0129 
0130     # Fundamentals:
0131     #  - get_esn             - same as LG VX-8300
0132     #  - getgroups           - same as LG VX-8100
0133     #  - getwallpaperindices - LGNewIndexedMedia2
0134     #  - getrintoneindices   - LGNewIndexedMedia2
0135     #  - DM Version          - N/A
0136 
0137     # Media stuff---------------------------------------------------------------
0138     def _is_rs_file(self, filename):
0139         return filename.startswith(self._rs_path)
0140 
0141     def getmedia(self, maps, results, key):
0142         origins={}
0143         # signal that we are using the new media storage that includes the origin and timestamp
0144         origins['new_media_version']=1
0145 
0146         for type, indexfile, sizefile, directory, lowestindex, maxentries, typemajor, def_icon, idx_ofs  in maps:
0147             media={}
0148             for item in self.getindex(indexfile):
0149                 data=None
0150                 timestamp=None
0151                 try:
0152                     stat_res=self.statfile(item.filename)
0153                     if stat_res!=None:
0154                         timestamp=stat_res['date'][0]
0155                     if not self._is_rs_file(item.filename):
0156                         data=self.getfilecontents(item.filename, True)
0157                 except (com_brew.BrewNoSuchFileException,com_brew.BrewBadPathnameException,com_brew.BrewNameTooLongException):
0158                     self.log("It was in the index, but not on the filesystem")
0159                 except com_brew.BrewAccessDeniedException:
0160                     # firmware wouldn't let us read this file, just mark it then
0161                     self.log('Failed to read file: '+item.filename)
0162                     data=''
0163                 except:
0164                     if __debug__:
0165                         raise
0166                     self.log('Failed to read file: '+item.filename)
0167                     data=''
0168                 if data!=None:
0169                     media[common.basename(item.filename)]={ 'data': data, 'timestamp': timestamp}
0170             origins[type]=media
0171 
0172         results[key]=origins
0173         return results
0174 
0175     def _mark_files(self, local_files, rs_files, local_dir):
0176         # create empty local files as markers for remote files
0177         _empty_files=[common.basename(x) for x,_entry in local_files.items() \
0178                       if not _entry['size']]
0179         _remote_files=[common.basename(x) for x in rs_files]
0180         for _file in _remote_files:
0181             if _file not in _empty_files:
0182                 # mark this one
0183                 self.writefile(local_dir+'/'+_file, '')
0184         for _file in _empty_files:
0185             if _file not in _remote_files:
0186                 # remote file no longer exists, del the marker
0187                 self.rmfile(local_dir+'/'+_file)
0188                 
0189     def _write_index_file(self, type):
0190         _info=self.media_info.get(type, None)
0191         if not _info:
0192             return
0193         _files={}
0194         _local_dir=_info['localpath']
0195         _rs_dir=_info['rspath']
0196         _vtype=_info['vtype']
0197         _icon=_info['icon']
0198         _index=_info['index']
0199         _maxsize=_info['maxsize']
0200         _dunno=_info['dunno']
0201         indexfile=_info['indexfile']
0202         sizefile=_info['sizefile']
0203         _need_date=_info['date']
0204         try:
0205             _files=self.listfiles(_local_dir)
0206         except (com_brew.BrewNoSuchDirectoryException,
0207                 com_brew.BrewBadPathnameException):
0208             pass
0209         try:
0210             if _rs_dir:
0211                 _rs_files=self.listfiles(_rs_dir)
0212                 if type=='ringers':
0213                     self._mark_files(_files, _rs_files, _local_dir)
0214                 _files.update(_rs_files)
0215         except (com_brew.BrewNoSuchDirectoryException,
0216                 com_brew.BrewBadPathnameException):
0217             # dir does not exist, no media files available
0218             pass
0219         # del all the markers (empty files) ringers
0220         if type=='ringers':
0221             _keys=_files.keys()
0222             for _key in _keys:
0223                 if not _files[_key]['size']:
0224                     del _files[_key]
0225         # dict of all indices
0226         _idx_keys={}
0227         for _i in xrange(_index, _index+_maxsize):
0228             _idx_keys[_i]=True
0229         # assign existing indices
0230         for _item in self.getindex(indexfile):
0231             if _files.has_key(_item.filename):
0232                 _files[_item.filename]['index']=_item.index
0233                 _idx_keys[_item.index]=False
0234         # available new indices
0235         _idx_keys_list=[k for k,x in _idx_keys.items() if x]
0236         _idx_keys_list.sort()
0237         _idx_cnt=0
0238         # assign new indices
0239         _file_list=[x for x in _files if not _files[x].get('index', None)]
0240         _file_list.sort()
0241         if len(_file_list)>len(_idx_keys_list):
0242             _file_list=_file_list[:len(_idx_keys_list)]
0243         for i in _file_list:
0244             _files[i]['index']=_idx_keys_list[_idx_cnt]
0245             _idx_cnt+=1
0246         # (index, file name) list for writing
0247         _res_list=[(x['index'],k) for k,x in _files.items() if x.get('index', None)]
0248         _res_list.sort()
0249         _res_list.reverse()
0250         # writing the index file
0251         ifile=self.protocolclass.indexfile()
0252         _file_size=0
0253         for index,idx in _res_list:
0254             _fs_size=_files[idx]['size']
0255             ie=self.protocolclass.indexentry()
0256             ie.index=index
0257             ie.type=_vtype
0258             ie.filename=idx
0259             if _need_date:
0260                 # need to fill in the date value
0261                 _stat=self.statfile(_files[idx]['name'])
0262                 if _stat:
0263                     ie.date=_stat['datevalue']-time.timezone
0264             ie.dunno=_dunno
0265             ie.icon=_icon
0266             ie.size=_fs_size
0267             ifile.items.append(ie)
0268             if not self._is_rs_file(idx):
0269                 _file_size+=_fs_size
0270         buf=prototypes.buffer()
0271         ifile.writetobuffer(buf, logtitle="Index file "+indexfile)
0272         self.log("Writing index file "+indexfile+" for type "+type+" with "+`len(_res_list)`+" entries.")
0273         self.writefile(indexfile, buf.getvalue())
0274         # writing the size file
0275         if sizefile:
0276             szfile=self.protocolclass.sizefile()
0277             szfile.size=_file_size
0278             buf=prototypes.buffer()
0279             szfile.writetobuffer(buf, logtitle="Updated size file for "+type)
0280             self.log("You are using a total of "+`_file_size`+" bytes for "+type)
0281             self.writefile(sizefile, buf.getvalue())
0282 
0283     def savemedia(self, mediakey, mediaindexkey, maps, results, merge, reindexfunction):
0284         """Actually saves out the media
0285 
0286         @param mediakey: key of the media (eg 'wallpapers' or 'ringtones')
0287         @param mediaindexkey:  index key (eg 'wallpaper-index')
0288         @param maps: list index files and locations
0289         @param results: results dict
0290         @param merge: are we merging or overwriting what is there?
0291         @param reindexfunction: the media is re-indexed at the end.  this function is called to do it
0292         """
0293 
0294         # take copies of the lists as we modify them
0295         wp=results[mediakey].copy()  # the media we want to save
0296         wpi=results[mediaindexkey].copy() # what is already in the index files
0297 
0298         # remove builtins
0299         for k in wpi.keys():
0300             if wpi[k].get('origin', "")=='builtin':
0301                 del wpi[k]
0302 
0303         # build up list into init
0304         init={}
0305         for type,_,_,_,lowestindex,_,typemajor,_,_ in maps:
0306             init[type]={}
0307             for k in wpi.keys():
0308                 if wpi[k]['origin']==type:
0309                     index=k
0310                     name=wpi[k]['name']
0311                     fullname=wpi[k]['filename']
0312                     vtype=wpi[k]['vtype']
0313                     icon=wpi[k]['icon']
0314                     data=None
0315                     del wpi[k]
0316                     for w in wp.keys():
0317                         # does wp contain a reference to this same item?
0318                         if wp[w]['name']==name and wp[w]['origin']==type:
0319                             data=wp[w]['data']
0320                             del wp[w]
0321                     if not merge and data is None:
0322                         # delete the entry
0323                         continue
0324 ##                    assert index>=lowestindex
0325                     init[type][index]={'name': name, 'data': data, 'filename': fullname, 'vtype': vtype, 'icon': icon}
0326 
0327         # init now contains everything from wallpaper-index
0328         # wp contains items that we still need to add, and weren't in the existing index
0329         assert len(wpi)==0
0330         print init.keys()
0331         
0332         # now look through wallpapers and see if anything was assigned a particular
0333         # origin
0334         for w in wp.keys():
0335             o=wp[w].get("origin", "")
0336             if o is not None and len(o) and o in init:
0337                 idx=-1
0338                 while idx in init[o]:
0339                     idx-=1
0340                 init[o][idx]=wp[w]
0341                 del wp[w]
0342 
0343         # wp will now consist of items that weren't assigned any particular place
0344         # so put them in the first available space
0345         for type,_,_,_,lowestindex,maxentries,typemajor,def_icon,_ in maps:
0346             # fill it up
0347             for w in wp.keys():
0348                 if len(init[type])>=maxentries:
0349                     break
0350                 idx=-1
0351                 while idx in init[type]:
0352                     idx-=1
0353                 init[type][idx]=wp[w]
0354                 del wp[w]
0355 
0356         # time to write the files out
0357         for type, indexfile, sizefile, directory, lowestindex, maxentries,typemajor,def_icon,_  in maps:
0358             # get the index file so we can work out what to delete
0359             names=[init[type][x]['name'] for x in init[type]]
0360             for item in self.getindex(indexfile):
0361                 if common.basename(item.filename) not in names and \
0362                    not self._is_rs_file(item.filename):
0363                     self.log(item.filename+" is being deleted")
0364                     self.rmfile(item.filename)
0365             # fixup the indices
0366             fixups=[k for k in init[type].keys() if k<lowestindex]
0367             fixups.sort()
0368             for f in fixups:
0369                 for ii in xrange(lowestindex, lowestindex+maxentries):
0370                     # allocate an index
0371                     if ii not in init[type]:
0372                         init[type][ii]=init[type][f]
0373                         del init[type][f]
0374                         break
0375             # any left over?
0376             fixups=[k for k in init[type].keys() if k<lowestindex]
0377             for f in fixups:
0378                 self.log("There is no space in the index for "+type+" for "+init[type][f]['name'])
0379                 del init[type][f]
0380             # write each entry out
0381             for idx in init[type].keys():
0382                 entry=init[type][idx]
0383                 filename=entry.get('filename', directory+"/"+entry['name'])
0384                 entry['filename']=filename
0385                 fstat=self.statfile(filename)
0386                 if 'data' not in entry:
0387                     # must be in the filesystem already
0388                     if fstat is None:
0389                         self.log("Entry "+entry['name']+" is in index "+indexfile+" but there is no data for it and it isn't in the filesystem.  The index entry will be removed.")
0390                         del init[type][idx]
0391                         continue
0392                 # check len(data) against fstat->length
0393                 data=entry['data']
0394                 if data is None:
0395                     assert merge 
0396                     continue # we are doing an add and don't have data for this existing entry
0397                 if fstat is not None and len(data)==fstat['size']:
0398                     self.log("Not writing "+filename+" as a file of the same name and length already exists.")
0399                 else:
0400                     self.writefile(filename, data)
0401             # write out index
0402             self._write_index_file(type)
0403         return reindexfunction(results)
0404 
0405     # Phonebook stuff-----------------------------------------------------------
0406     def savephonebook(self, data):
0407         "Saves out the phonebook"
0408         res=com_lgvx8100.Phone.savephonebook(self, data)
0409         # fix up the Wallpaper ID issue
0410         _wp_paths=self.protocolclass.wallpaper_id_file()
0411         _path_entry=self.protocolclass.wallpaper_id()
0412         # clear out all entries
0413         for i in range(self.protocolclass.NUMPHONEBOOKENTRIES):
0414             _wp_paths.items.append(_path_entry)
0415         # go through each entry and update the wallpaper path
0416         _buf=prototypes.buffer(self.getfilecontents(
0417             self.protocolclass.pb_file_name))
0418         _pb_entries=self.protocolclass.pbfile()
0419         _pb_entries.readfrombuffer(_buf, logtitle="Read phonebook file "+self.protocolclass.pb_file_name)
0420         _wp_index=res.get('wallpaper-index', {})
0421         for _entry in _pb_entries.items:
0422             try:
0423                 if _entry.wallpaper==0 or _entry.wallpaper==0xffff:
0424                     # no picture ID assigned
0425                     continue
0426                 _filename=_wp_index[_entry.wallpaper]['filename']
0427                 if _filename:
0428                     _path_str=_filename+'\x00'
0429                     _path=self.protocolclass.wallpaper_id()
0430                     _path.path=_path_str
0431                     _wp_paths.items[_entry.entrynumber]=_path
0432             except:
0433                 if __debug__:
0434                     raise
0435         _buf=prototypes.buffer()
0436         _wp_paths.writetobuffer(_buf, logtitle="Updated wallpaper ids "+self.protocolclass.wallpaper_id_file_name)
0437         self.writefile(self.protocolclass.wallpaper_id_file_name,
0438                        _buf.getvalue())
0439 
0440     # SMS Stuff-----------------------------------------------------------------
0441     def _readsms(self):
0442         res={}
0443         # go through the sms directory looking for messages
0444         for item in self.listfiles("sms").values():
0445             folder=None
0446             for f,pat in self.protocolclass.SMS_PATTERNS.items():
0447                 if pat.match(item['name']):
0448                     folder=f
0449                     break
0450             if folder:
0451                 buf=prototypes.buffer(self.getfilecontents(item['name'], True))
0452                 self.logdata("SMS message file " +item['name'], buf.getdata())
0453             if folder=='Inbox':
0454                 sf=self.protocolclass.sms_in()
0455                 sf.readfrombuffer(buf, logtitle="SMS inbox item")
0456                 entry=self._getinboxmessage(sf)
0457                 res[entry.id]=entry
0458             elif folder=='Sent':
0459                 sf=self.protocolclass.sms_out()
0460                 sf.readfrombuffer(buf, logtitle="SMS sent item")
0461                 entry=self._getoutboxmessage(sf)
0462                 res[entry.id]=entry
0463             elif folder=='Saved':
0464                 sf=self.protocolclass.sms_saved()
0465                 sf.readfrombuffer(buf, logtitle="SMS saved item")
0466                 if sf.inboxmsg:
0467                     entry=self._getinboxmessage(sf.inbox)
0468                 else:
0469                     entry=self._getoutboxmessage(sf.outbox)
0470                 entry.folder=entry.Folder_Saved
0471                 res[entry.id]=entry
0472         return res 
0473 
0474     # Playlist stuff------------------------------------------------------------
0475     def _read_pl_list(self, file_name):
0476         _buf=prototypes.buffer(self.getfilecontents(file_name))
0477         _pl_index=self.protocolclass.playlistfile()
0478         _pl_index.readfrombuffer(_buf, logtitle="Read playlist "+file_name)
0479         _songs=[x.name[self.protocolclass.mp3_dir_len:] for x in _pl_index.items]
0480         _entry=playlist.PlaylistEntry()
0481         if file_name.endswith(self.protocolclass.pl_extension):
0482             _entry.name=file_name[self.protocolclass.pl_dir_len:\
0483                                   -self.protocolclass.pl_extension_len]            
0484         else:
0485             _entry.name=file_name[self.protocolclass.pl_dir_len:]
0486         _entry.songs=_songs
0487         return _entry
0488 
0489     def getplaylist(self, result):
0490         # return the mp3 playlists if available
0491         # first, read the list of all mp3 songs
0492         _mp3_list=[]
0493         try:
0494             _files=self.listfiles(self.protocolclass.mp3_dir)
0495             _file_list=_files.keys()
0496             _file_list.sort()
0497             _mp3_list=[x[self.protocolclass.mp3_dir_len:] for x in _file_list ]
0498         except:
0499             if __debug__:
0500                 raise
0501         result[playlist.masterlist_key]=_mp3_list
0502         # then read the playlist
0503         _pl_list=[]
0504         try:
0505             _files=self.listfiles(self.protocolclass.pl_dir)
0506             _file_list=_files.keys()
0507             _file_list.sort()
0508             for _f in _file_list:
0509                 _pl_list.append(self._read_pl_list(_f))
0510         except:
0511             if __debug__:
0512                 raise
0513         result[playlist.playlist_key]=_pl_list
0514         return result
0515 
0516     def _write_playlists(self, pl, all_songs):
0517         for _pl_item in pl:
0518             try:
0519                 _pl_file=self.protocolclass.playlistfile()
0520                 for _song in _pl_item.songs:
0521                     _song_name=self.protocolclass.mp3_dir+'/'+_song
0522                     if all_songs.has_key(_song_name):
0523                         _entry=self.protocolclass.playlistentry()
0524                         _entry.name=_song_name
0525                         _pl_file.items.append(_entry)
0526                 if len(_pl_file.items):
0527                     # don't write out an empty list
0528                     _buf=prototypes.buffer()
0529                     _file_name=self.protocolclass.pl_dir+'/'+_pl_item.name+\
0530                                 self.protocolclass.pl_extension
0531                     _pl_file.writetobuffer(_buf, logtitle="Updating playlist "+_file_name)
0532                     self.writefile(_file_name, _buf.getvalue())
0533             except:
0534                 if __debug__:
0535                     raise
0536 
0537     def saveplaylist(self, result, merge):
0538         # check to see if the pl_dir exist
0539         if not self.exists(self.protocolclass.pl_dir):
0540             self.log('Playlist dir does not exist. Bail')
0541             return result
0542         # get the list of available mp3 files
0543         _all_songs=self.listfiles(self.protocolclass.mp3_dir)
0544         # delete all existing playlists
0545         _files=self.listfiles(self.protocolclass.pl_dir)
0546         for _f in _files:
0547             try:
0548                 self.rmfile(_f)
0549             except:
0550                 if __debug__:
0551                     raise
0552         # update the new playlists
0553         self._write_playlists(result.get(playlist.playlist_key, []),
0554                               _all_songs)
0555         return result
0556 
0557 #-------------------------------------------------------------------------------
0558 parentprofile=com_lgvx8100.Profile
0559 class Profile(parentprofile):
0560     protocolclass=Phone.protocolclass
0561     serialsname=Phone.serialsname
0562 
0563     BP_Calendar_Version=3
0564     phone_manufacturer='LG Electronics Inc'
0565     phone_model='VX9800'
0566 
0567     WALLPAPER_WIDTH=320
0568     WALLPAPER_HEIGHT=256
0569     MAX_WALLPAPER_BASENAME_LENGTH=32
0570     WALLPAPER_FILENAME_CHARS="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789()_ .-"
0571     WALLPAPER_CONVERT_FORMAT="jpg"
0572 
0573     # the 9800 uses "W" for wait in the dialstring, it does not support "T"
0574     DIALSTRING_CHARS="[^0-9PW#*]"
0575    
0576     MAX_RINGTONE_BASENAME_LENGTH=32
0577     RINGTONE_FILENAME_CHARS="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789()_ .-"
0578 
0579     # there is an origin named 'aod' - no idea what it is for except maybe
0580     # 'all other downloads'
0581 
0582     # the vx8100 supports bluetooth for connectivity to the PC, define the "bluetooth_mgd_id"
0583     # to enable bluetooth discovery during phone detection
0584     # the bluetooth address starts with LG's the three-octet OUI, all LG phone
0585     # addresses start with this, it provides a way to identify LG bluetooth devices
0586     # during phone discovery
0587     # OUI=Organizationally Unique Identifier
0588     # see http://standards.ieee.org/regauth/oui/index.shtml for more info
0589     bluetooth_mfg_id="001256"
0590 
0591     # the 8100 doesn't have seperate origins - they are all dumped in "images"
0592     imageorigins={}
0593     imageorigins.update(common.getkv(parentprofile.stockimageorigins, "images"))
0594     imageorigins.update(common.getkv(parentprofile.stockimageorigins, "video"))
0595     def GetImageOrigins(self):
0596         return self.imageorigins
0597 
0598     ringtoneorigins=('ringers', 'sounds')
0599     excluded_ringtone_origins=('sounds')
0600     excluded_wallpaper_origins=('video')
0601 
0602     # our targets are the same for all origins
0603     imagetargets={}
0604     imagetargets.update(common.getkv(parentprofile.stockimagetargets, "wallpaper",
0605                                       {'width': 320, 'height': 230, 'format': "JPEG"}))
0606     imagetargets.update(common.getkv(parentprofile.stockimagetargets, "outsidelcd",
0607                                       {'width': 320, 'height': 198, 'format': "JPEG"}))
0608 
0609     def GetTargetsForImageOrigin(self, origin):
0610         return self.imagetargets
0611 
0612  
0613     def __init__(self):
0614         parentprofile.__init__(self)
0615 
0616     _supportedsyncs=(
0617         ('phonebook', 'read', None),   # all phonebook reading
0618         ('calendar', 'read', None),    # all calendar reading
0619         ('wallpaper', 'read', None),   # all wallpaper reading
0620         ('ringtone', 'read', None),    # all ringtone reading
0621         ('call_history', 'read', None),# all call history list reading
0622         ('sms', 'read', None),         # all SMS list reading
0623         ('memo', 'read', None),        # all memo list reading
0624         ('phonebook', 'write', 'OVERWRITE'),  # only overwriting phonebook
0625         ('calendar', 'write', 'OVERWRITE'),   # only overwriting calendar
0626         ('wallpaper', 'write', 'MERGE'),      # merge and overwrite wallpaper
0627         ('wallpaper', 'write', 'OVERWRITE'),
0628         ('ringtone', 'write', 'MERGE'),       # merge and overwrite ringtone
0629         ('ringtone', 'write', 'OVERWRITE'),
0630         ('sms', 'write', 'OVERWRITE'),        # all SMS list writing
0631         ('memo', 'write', 'OVERWRITE'),       # all memo list writing
0632         ('playlist', 'read', 'OVERWRITE'),
0633         ('playlist', 'write', 'OVERWRITE'),
0634         )
0635 

Generated by PyXR 0.9.4