0001 ### BITPIM 0002 ### 0003 ### Copyright (C) 2006 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_samsungschu740.py 4517 2007-12-23 05:23:36Z djpham $ 0009 0010 """Communicate with the Samsung SCH-U740 Phone""" 0011 0012 # System Modules 0013 import re 0014 import wx 0015 0016 # BitPim Modules 0017 0018 import call_history 0019 import common 0020 import com_brew 0021 import com_samsungscha950 as scha950 0022 import helpids 0023 import prototypes 0024 import p_samsungschu740 as p_schu740 0025 0026 parentphone=scha950.Phone 0027 class Phone(parentphone): 0028 desc='SCH-U740' 0029 helpid=helpids.ID_PHONE_SAMSUNGSCHU740 0030 protocolclass=p_schu740 0031 serialsname='schu740' 0032 0033 ringtone_noring_range='range_tones_preloaded_el_13' 0034 ringtone_default_range='range_tones_preloaded_el_01' 0035 builtin_ringtones={ 0036 'VZW Default Tone': ringtone_default_range, 0037 'Bell 1': 'range_tones_preloaded_el_02', 0038 'Bell 2': 'range_tones_preloaded_el_03', 0039 'Bell 3': 'range_tones_preloaded_el_04', 0040 'Melody 1': 'range_tones_preloaded_el_05', 0041 'Melody 2': 'range_tones_preloaded_el_06', 0042 'Melody 3': 'range_tones_preloaded_el_07', 0043 'Melody 4': 'range_tones_preloaded_el_08', 0044 'Melody 5': 'range_tones_preloaded_el_09', 0045 'Melody 6': 'range_tones_preloaded_el_10', 0046 'Beep Once': 'range_tones_preloaded_el_11', 0047 'No Ring': ringtone_noring_range, 0048 } 0049 # can we use Sounds as ringtones? 0050 builtin_sounds={} 0051 ## builtin_sounds={ 0052 ## 'Birthday': 'range_sound_preloaded_el_birthday', 0053 ## 'Crowd Roar': 'range_sound_preloaded_el_crowed_roar', 0054 ## 'Train': 'range_sound_preloaded_el_train', 0055 ## 'Rainforest': 'range_sound_preloaded_el_rainforest', 0056 ## 'Clapping': 'range_sound_preloaded_el_clapping', 0057 ## # same as ringtones ?? 0058 ## 'Sound Beep Once': 'range_sound_preloaded_el_beep_once', 0059 ## 'Sound No Ring': 'range_sound_preloaded_el_no_rings', 0060 ## } 0061 builtin_wallpapers={ 0062 'Preloaded1': 'range_f_wallpaper_preloaded_el_01', 0063 'Preloaded2': 'range_f_wallpaper_preloaded_el_02', 0064 'Preloaded3': 'range_f_wallpaper_preloaded_el_03', 0065 'Preloaded4': 'range_f_wallpaper_preloaded_el_04', 0066 'Preloaded5': 'range_f_wallpaper_preloaded_el_05', 0067 'Preloaded6': 'range_f_wallpaper_preloaded_el_06', 0068 'Preloaded7': 'range_f_wallpaper_preloaded_el_07', 0069 'Preloaded8': 'range_f_wallpaper_preloaded_el_08', 0070 } 0071 builtin_groups={ 0072 1: 'Business', 0073 2: 'Colleague', 0074 3: 'Family', 0075 4: 'Friends' 0076 } 0077 0078 my_model='SCH-U740/DM' 0079 my_manufacturer='SAMSUNG' 0080 detected_model='u740' 0081 0082 def __init__(self, logtarget, commport): 0083 "Calls all the constructors and sets initial modes" 0084 parentphone.__init__(self, logtarget, commport) 0085 global PBEntry 0086 self.pbentryclass=PBEntry 0087 0088 def _get_file_wallpaper_index(self, idx, result, 0089 indexfilename, origin): 0090 try: 0091 _buf=prototypes.buffer(self.getfilecontents(indexfilename)) 0092 except (com_brew.BrewNoSuchFileException, 0093 com_brew.BrewBadPathnameException, 0094 com_brew.BrewFileLockedException, 0095 com_brew.BrewAccessDeniedException): 0096 return idx 0097 except: 0098 if __debug__: 0099 raise 0100 return idx 0101 _index_file=self.protocolclass.RPictureIndexFile() 0102 _index_file.readfrombuffer(_buf) 0103 for _entry in _index_file.items: 0104 if _entry.pictype==self.protocolclass.PIC_TYPE_USERS: 0105 if _entry.pathname.startswith('/ff/'): 0106 _file_name=_entry.pathname[4:] 0107 else: 0108 _file_name=_entry.pathname 0109 result[idx]={ 'name': common.basename(_entry.pathname), 0110 'filename': _file_name, 0111 'origin': origin, 0112 } 0113 idx+=1 0114 return idx 0115 def get_wallpaper_index(self): 0116 _res={} 0117 _idx=self._get_builtin_wallpaper_index(0, _res) 0118 _idx=self._get_file_wallpaper_index(_idx, _res, 0119 self.protocolclass.PIC_INDEX_FILE_NAME, 0120 'images') 0121 _idx=self._get_file_wallpaper_index(_idx, _res, 0122 self.protocolclass.VIDEO_INDEX_FILE_NAME, 0123 'video') 0124 return _res 0125 0126 # Ringtone stuff 0127 def saveringtones(self, fundamentals, merge): 0128 """Save ringtones to the phone""" 0129 self.log('Writing ringtones to the phone') 0130 try: 0131 _del_list, _new_list=self._get_del_new_list('ringtone-index', 0132 'ringtone', 0133 merge, 0134 fundamentals) 0135 if __debug__: 0136 self.log('Delete list: '+','.join(_del_list)) 0137 self.log('New list: '+','.join(_new_list)) 0138 self._add_files('ringtone-index', 'ringtone', 0139 _new_list, fundamentals) 0140 self._update_media_index(self.protocolclass.WRingtoneIndexFile, 0141 self.protocolclass.WRingtoneIndexEntry, 0142 [self.protocolclass.RT_PATH], 0143 self.protocolclass.RT_EXCLUDED_FILES, 0144 self.protocolclass.RT_INDEX_FILE_NAME) 0145 self._update_media_index(self.protocolclass.WSoundsIndexFile, 0146 self.protocolclass.WSoundsIndexEntry, 0147 [self.protocolclass.SND_PATH], 0148 self.protocolclass.SND_EXCLUDED_FILES, 0149 self.protocolclass.SND_INDEX_FILE_NAME) 0150 fundamentals['rebootphone']=True 0151 except: 0152 if __debug__: 0153 raise 0154 return fundamentals 0155 0156 # Wallpaper stuff----------------------------------------------------------- 0157 def savewallpapers(self, fundamentals, merge): 0158 # send wallpapers to the phone 0159 """Save ringtones to the phone""" 0160 self.log('Writing wallpapers to the phone') 0161 try: 0162 _del_list, _new_list=self._get_del_new_list('wallpaper-index', 0163 'wallpapers', 0164 merge, 0165 fundamentals, 0166 ('video',)) 0167 if __debug__: 0168 self.log('Delete list: '+','.join(_del_list)) 0169 self.log('New list: '+','.join(_new_list)) 0170 self._add_files('wallpaper-index', 'wallpapers', 0171 _new_list, fundamentals) 0172 self._update_media_index(self.protocolclass.WPictureIndexFile, 0173 self.protocolclass.WPictureIndexEntry, 0174 [self.protocolclass.PIC_PATH], 0175 self.protocolclass.PIC_EXCLUDED_FILES, 0176 self.protocolclass.PIC_INDEX_FILE_NAME) 0177 fundamentals['rebootphone']=True 0178 except: 0179 if __debug__: 0180 raise 0181 return fundamentals 0182 0183 # Phonebook stuff----------------------------------------------------------- 0184 def _rescale_and_cache(self, wp, filename, idx, 0185 fundamentals): 0186 # rescale the wp and add it to the cache dir 0187 try: 0188 _data=self.getfilecontents(filename, True) 0189 _tmpname=common.gettempfilename('tmp') 0190 file(_tmpname, 'wb').write(_data) 0191 _img=wx.Image(_tmpname) 0192 if not _img.Ok(): 0193 self.log('Failed to understand image: '+filename) 0194 return 0195 _img.Rescale(128, 96) 0196 _img.SaveFile(_tmpname, wx.BITMAP_TYPE_JPEG) 0197 _newfilename='%(prefix)s/%(index)d.jpg'%\ 0198 { 'prefix': self.protocolclass.PB_WP_CACHE_PATH, 0199 'index': idx } 0200 _data=file(_tmpname, 'rb').read() 0201 self.writefile(_newfilename, _data) 0202 return _newfilename 0203 except: 0204 if __debug__: 0205 self.log('Failed to add cache image: '+wp) 0206 raise 0207 0208 def _add_wp_cache(self, wp, idx, fundamentals): 0209 # check to see if it already exists 0210 _wp_range=fundamentals.get('wallpaper-range', {}) 0211 # add this wallpaper into the cache dir 0212 _wp_index=fundamentals.get('wallpaper-index', {}) 0213 # look for the file name 0214 _filename=self._get_wp_filename(wp, _wp_index) 0215 if not _filename: 0216 # couldn't find the filename 0217 return 0218 # copy the image file, rescale, and put it in the cache dir 0219 _newfilename=self._rescale_and_cache(wp, _filename, idx, fundamentals) 0220 if _newfilename: 0221 # rescale successful, update the dict 0222 _wp_range[wp]='/ff/'+_newfilename 0223 _wp_range[wp]='/ff/%(filename)s|%(wpname)s'%\ 0224 { 'filename': _newfilename, 0225 'wpname': common.stripext(wp), 0226 } 0227 fundamentals['wallpaper-range']=_wp_range 0228 0229 # PBEntry class----------------------------------------------------------------- 0230 parentpbentry=scha950.PBEntry 0231 class PBEntry(parentpbentry): 0232 0233 def _build_memo(self, memo): 0234 if memo: 0235 self.pb.note=memo 0236 0237 def _build(self, entry): 0238 parentpbentry._build(self, entry) 0239 self._build_memo(entry.get('memos', [{}])[0].get('memo', None)) 0240 0241 def _extract_wallpaper(self, entry, p_class): 0242 if not self.pb.info&p_class.PB_FLG_WP: 0243 return 0244 _idx=self.pb.wallpaper.rfind('|')+1 0245 # really ugly hack here !!! 0246 _wp=self.pb.wallpaper[_idx:] 0247 if not _wp.startswith('Preloaded'): 0248 # assume that the name has extension .jpg 0249 _wp+='.jpg' 0250 0251 entry['wallpapers']=[{ 'wallpaper': _wp, 0252 'use': 'call' }] 0253 0254 def _extract_memo(self, entry, p_class): 0255 # extract the note portion from the phone into BitPim dict 0256 if self.pb.info&p_class.PB_FLG_NOTE: 0257 entry['memos']=[{ 'memo': self.pb.note }] 0258 0259 def getvalue(self): 0260 _entry=parentpbentry.getvalue(self) 0261 self._extract_memo(_entry, self.phone.protocolclass) 0262 return _entry 0263 0264 # Profile class----------------------------------------------------------------- 0265 parentprofile=scha950.Profile 0266 class Profile(parentprofile): 0267 serialsname=Phone.serialsname 0268 WALLPAPER_WIDTH=176 0269 WALLPAPER_HEIGHT=220 0270 # 128x96: outside LCD 0271 autodetect_delay=3 0272 usbids=( ( 0x04e8, 0x6640, 2),) 0273 deviceclasses=("serial",) 0274 BP_Calendar_Version=3 0275 # For phone detection 0276 phone_manufacturer=Phone.my_manufacturer 0277 phone_model=Phone.my_model 0278 # arbitrary ringtone file size limit 0279 RINGTONE_LIMITS= { 0280 'MAXSIZE': 100000 0281 } 0282 WALLPAPER_FILENAME_CHARS="abcdefghijklmnopqrstuvwxyz0123456789 ._:" 0283 RINGTONE_FILENAME_CHARS="abcdefghijklmnopqrstuvwxyz0123456789 ._:" 0284 0285 # fill in the list of ringtone/sound origins on your phone 0286 ringtoneorigins=('ringers', 'sounds') 0287 # ringtone origins that are not available for the contact assignment 0288 excluded_ringtone_origins=('sounds',) 0289 0290 imageorigins={} 0291 imageorigins.update(common.getkv(parentprofile.stockimageorigins, "images")) 0292 imageorigins.update(common.getkv(parentprofile.stockimageorigins, "video")) 0293 # wallpaper origins that are not available for the contact assignment 0294 excluded_wallpaper_origins=('video',) 0295 0296 # our targets are the same for all origins 0297 imagetargets={} 0298 imagetargets.update(common.getkv(parentprofile.stockimagetargets, "wallpaper", 0299 {'width': 220, 'height': 184, 'format': "JPEG"})) 0300 imagetargets.update(common.getkv(parentprofile.stockimagetargets, "pictureid", 0301 {'width': 128, 'height': 96, 'format': "JPEG"})) 0302 imagetargets.update(common.getkv(parentprofile.stockimagetargets, "outsidelcd", 0303 {'width': 128, 'height': 96, 'format': "JPEG"})) 0304 def GetTargetsForImageOrigin(self, origin): 0305 return self.imagetargets 0306 0307 def __init__(self): 0308 parentprofile.__init__(self) 0309 0310 _supportedsyncs=( 0311 ('phonebook', 'read', None), # all phonebook reading 0312 ('phonebook', 'write', 'OVERWRITE'), # only overwriting phonebook 0313 ('calendar', 'read', None), # all calendar reading 0314 ('calendar', 'write', 'OVERWRITE'), # only overwriting calendar 0315 ('ringtone', 'read', None), # all ringtone reading 0316 ('ringtone', 'write', 'MERGE'), 0317 ('wallpaper', 'read', None), # all wallpaper reading 0318 ('wallpaper', 'write', 'MERGE'), 0319 ('memo', 'read', None), # all memo list reading DJP 0320 ('memo', 'write', 'OVERWRITE'), # all memo list writing DJP 0321 ('call_history', 'read', None),# all call history list reading 0322 ('sms', 'read', None), # all SMS list reading DJP 0323 ) 0324 0325 field_color_data={ 0326 'phonebook': { 0327 'name': { 0328 'first': 1, 'middle': 1, 'last': 1, 'full': 1, 0329 'nickname': 0, 'details': 1 }, 0330 'number': { 0331 'type': 5, 'speeddial': 5, 'number': 5, 0332 'details': 5, 0333 'ringtone': False, 'wallpaper': False }, 0334 'email': 2, 0335 'email_details': { 0336 'emailspeeddial': False, 'emailringtone': False, 0337 'emailwallpaper': False }, 0338 'address': { 0339 'type': 0, 'company': 0, 'street': 0, 'street2': 0, 0340 'city': 0, 'state': 0, 'postalcode': 0, 'country': 0, 0341 'details': 0 }, 0342 'url': 0, 0343 'memo': 1, 0344 'category': 1, 0345 'wallpaper': 1, 0346 'ringtone': 1, 0347 'storage': 0, 0348 }, 0349 'calendar': { 0350 'description': True, 'location': True, 'allday': False, 0351 'start': True, 'end': True, 'priority': False, 0352 'alarm': True, 'vibrate': True, 0353 'repeat': True, 0354 'memo': False, 0355 'category': False, 0356 'wallpaper': False, 0357 'ringtone': True, 0358 }, 0359 'memo': { 0360 'subject': False, 0361 'date': False, 0362 'secret': False, 0363 'category': False, 0364 'memo': True, 0365 }, 0366 'todo': { 0367 'summary': False, 0368 'status': False, 0369 'due_date': False, 0370 'percent_complete': False, 0371 'completion_date': False, 0372 'private': False, 0373 'priority': False, 0374 'category': False, 0375 'memo': False, 0376 }, 0377 } 0378
Generated by PyXR 0.9.4