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

Source Code for Module phones.com_samsungschu740

  1  ### BITPIM 
  2  ### 
  3  ### Copyright (C) 2006 Joe Pham <djpham@bitpim.org> 
  4  ### 
  5  ### This program is free software; you can redistribute it and/or modify 
  6  ### it under the terms of the BitPim license as detailed in the LICENSE file. 
  7  ### 
  8  ### $Id: com_samsungschu740.py 4777 2010-01-07 03:24:27Z djpham $ 
  9   
 10  """Communicate with the Samsung SCH-U740 Phone""" 
 11   
 12  # System Modules 
 13  import re 
 14  import wx 
 15   
 16  # BitPim Modules 
 17   
 18  import call_history 
 19  import common 
 20  import com_brew 
 21  import com_samsungscha950 as scha950 
 22  import helpids 
 23  import prototypes 
 24  import p_samsungschu740 as p_schu740 
 25   
 26  parentphone=scha950.Phone 
27 -class Phone(parentphone):
28 desc='SCH-U740' 29 helpid=helpids.ID_PHONE_SAMSUNGSCHU740 30 protocolclass=p_schu740 31 serialsname='schu740' 32 33 ringtone_noring_range='range_tones_preloaded_el_13' 34 ringtone_default_range='range_tones_preloaded_el_01' 35 builtin_ringtones={ 36 'VZW Default Tone': ringtone_default_range, 37 'Bell 1': 'range_tones_preloaded_el_02', 38 'Bell 2': 'range_tones_preloaded_el_03', 39 'Bell 3': 'range_tones_preloaded_el_04', 40 'Melody 1': 'range_tones_preloaded_el_05', 41 'Melody 2': 'range_tones_preloaded_el_06', 42 'Melody 3': 'range_tones_preloaded_el_07', 43 'Melody 4': 'range_tones_preloaded_el_08', 44 'Melody 5': 'range_tones_preloaded_el_09', 45 'Melody 6': 'range_tones_preloaded_el_10', 46 'Beep Once': 'range_tones_preloaded_el_11', 47 'No Ring': ringtone_noring_range, 48 } 49 # can we use Sounds as ringtones? 50 builtin_sounds={} 51 ## builtin_sounds={ 52 ## 'Birthday': 'range_sound_preloaded_el_birthday', 53 ## 'Crowd Roar': 'range_sound_preloaded_el_crowed_roar', 54 ## 'Train': 'range_sound_preloaded_el_train', 55 ## 'Rainforest': 'range_sound_preloaded_el_rainforest', 56 ## 'Clapping': 'range_sound_preloaded_el_clapping', 57 ## # same as ringtones ?? 58 ## 'Sound Beep Once': 'range_sound_preloaded_el_beep_once', 59 ## 'Sound No Ring': 'range_sound_preloaded_el_no_rings', 60 ## } 61 builtin_wallpapers={ 62 'Preloaded1': 'range_f_wallpaper_preloaded_el_01', 63 'Preloaded2': 'range_f_wallpaper_preloaded_el_02', 64 'Preloaded3': 'range_f_wallpaper_preloaded_el_03', 65 'Preloaded4': 'range_f_wallpaper_preloaded_el_04', 66 'Preloaded5': 'range_f_wallpaper_preloaded_el_05', 67 'Preloaded6': 'range_f_wallpaper_preloaded_el_06', 68 'Preloaded7': 'range_f_wallpaper_preloaded_el_07', 69 'Preloaded8': 'range_f_wallpaper_preloaded_el_08', 70 } 71 builtin_groups={ 72 1: 'Business', 73 2: 'Colleague', 74 3: 'Family', 75 4: 'Friends' 76 } 77 78 my_model='SCH-U740/DM' 79 my_manufacturer='SAMSUNG' 80 detected_model='u740' 81
82 - def __init__(self, logtarget, commport):
83 "Calls all the constructors and sets initial modes" 84 parentphone.__init__(self, logtarget, commport) 85 global PBEntry 86 self.pbentryclass=PBEntry
87
88 - def _get_file_wallpaper_index(self, idx, result, 89 indexfilename, origin):
90 try: 91 _buf=prototypes.buffer(self.getfilecontents(indexfilename)) 92 except (com_brew.BrewNoSuchFileException, 93 com_brew.BrewBadPathnameException, 94 com_brew.BrewFileLockedException, 95 com_brew.BrewAccessDeniedException): 96 return idx 97 except: 98 if __debug__: 99 raise 100 return idx 101 _index_file=self.protocolclass.RPictureIndexFile() 102 _index_file.readfrombuffer(_buf) 103 for _entry in _index_file.items: 104 if _entry.pictype==self.protocolclass.PIC_TYPE_USERS: 105 if _entry.pathname.startswith('/ff/'): 106 _file_name=_entry.pathname[4:] 107 else: 108 _file_name=_entry.pathname 109 result[idx]={ 'name': common.basename(_entry.pathname), 110 'filename': _file_name, 111 'origin': origin, 112 } 113 idx+=1 114 return idx
115 - def get_wallpaper_index(self):
116 _res={} 117 _idx=self._get_builtin_wallpaper_index(0, _res) 118 _idx=self._get_file_wallpaper_index(_idx, _res, 119 self.protocolclass.PIC_INDEX_FILE_NAME, 120 'images') 121 _idx=self._get_file_wallpaper_index(_idx, _res, 122 self.protocolclass.VIDEO_INDEX_FILE_NAME, 123 'video') 124 return _res
125 126 # Ringtone stuff
127 - def saveringtones(self, fundamentals, merge):
128 """Save ringtones to the phone""" 129 self.log('Writing ringtones to the phone') 130 try: 131 _del_list, _new_list=self._get_del_new_list('ringtone-index', 132 'ringtone', 133 merge, 134 fundamentals) 135 if __debug__: 136 self.log('Delete list: '+','.join(_del_list)) 137 self.log('New list: '+','.join(_new_list)) 138 self._add_files('ringtone-index', 'ringtone', 139 _new_list, fundamentals) 140 self._update_media_index(self.protocolclass.WRingtoneIndexFile, 141 self.protocolclass.WRingtoneIndexEntry, 142 [self.protocolclass.RT_PATH], 143 self.protocolclass.RT_EXCLUDED_FILES, 144 self.protocolclass.RT_INDEX_FILE_NAME) 145 self._update_media_index(self.protocolclass.WSoundsIndexFile, 146 self.protocolclass.WSoundsIndexEntry, 147 [self.protocolclass.SND_PATH], 148 self.protocolclass.SND_EXCLUDED_FILES, 149 self.protocolclass.SND_INDEX_FILE_NAME) 150 fundamentals['rebootphone']=True 151 except: 152 if __debug__: 153 raise 154 return fundamentals
155 156 # Wallpaper stuff-----------------------------------------------------------
157 - def savewallpapers(self, fundamentals, merge):
158 # send wallpapers to the phone 159 """Save ringtones to the phone""" 160 self.log('Writing wallpapers to the phone') 161 try: 162 _del_list, _new_list=self._get_del_new_list('wallpaper-index', 163 'wallpapers', 164 merge, 165 fundamentals, 166 ('video',)) 167 if __debug__: 168 self.log('Delete list: '+','.join(_del_list)) 169 self.log('New list: '+','.join(_new_list)) 170 self._add_files('wallpaper-index', 'wallpapers', 171 _new_list, fundamentals) 172 self._update_media_index(self.protocolclass.WPictureIndexFile, 173 self.protocolclass.WPictureIndexEntry, 174 [self.protocolclass.PIC_PATH], 175 self.protocolclass.PIC_EXCLUDED_FILES, 176 self.protocolclass.PIC_INDEX_FILE_NAME) 177 fundamentals['rebootphone']=True 178 except: 179 if __debug__: 180 raise 181 return fundamentals
182 183 # Phonebook stuff-----------------------------------------------------------
184 - def _rescale_and_cache(self, wp, filename, idx, 185 fundamentals):
186 # rescale the wp and add it to the cache dir 187 try: 188 _data=self.getfilecontents(filename, True) 189 _tmpname=common.gettempfilename('tmp') 190 file(_tmpname, 'wb').write(_data) 191 _img=wx.Image(_tmpname) 192 if not _img.Ok(): 193 self.log('Failed to understand image: '+filename) 194 return 195 _img.Rescale(self.protocolclass.PB_WP_CACHE_WIDTH, 196 self.protocolclass.PB_WP_CACHE_HEIGHT) 197 _img.SaveFile(_tmpname, wx.BITMAP_TYPE_JPEG) 198 _newfilename='%(prefix)s/%(index)d.jpg'%\ 199 { 'prefix': self.protocolclass.PB_WP_CACHE_PATH, 200 'index': idx } 201 _data=file(_tmpname, 'rb').read() 202 self.writefile(_newfilename, _data) 203 return _newfilename 204 except: 205 if __debug__: 206 self.log('Failed to add cache image: '+wp) 207 raise
208
209 - def _add_wp_cache(self, wp, idx, fundamentals):
210 # check to see if it already exists 211 _wp_range=fundamentals.get('wallpaper-range', {}) 212 # add this wallpaper into the cache dir 213 _wp_index=fundamentals.get('wallpaper-index', {}) 214 # look for the file name 215 _filename=self._get_wp_filename(wp, _wp_index) 216 if not _filename: 217 # couldn't find the filename 218 return 219 # copy the image file, rescale, and put it in the cache dir 220 _newfilename=self._rescale_and_cache(wp, _filename, idx, fundamentals) 221 if _newfilename: 222 # rescale successful, update the dict 223 _wp_range[wp]='/ff/'+_newfilename 224 _wp_range[wp]='/ff/%(filename)s|%(wpname)s'%\ 225 { 'filename': _newfilename, 226 'wpname': common.stripext(wp), 227 } 228 fundamentals['wallpaper-range']=_wp_range
229 230 # CalendarEntry class----------------------------------------------------------- 231 parentcalendarentry=scha950.CalendarEntry
232 -class CalendarEntry(parentcalendarentry):
233 pass
234 235 236 # PBEntry class----------------------------------------------------------------- 237 parentpbentry=scha950.PBEntry
238 -class PBEntry(parentpbentry):
239
240 - def _build_memo(self, memo):
241 if memo: 242 self.pb.note=memo
243
244 - def _build(self, entry):
245 parentpbentry._build(self, entry) 246 self._build_memo(entry.get('memos', [{}])[0].get('memo', None))
247
248 - def _extract_wallpaper(self, entry, p_class):
249 if not self.pb.has_wallpaper: 250 return 251 _idx=self.pb.wallpaper.rfind('|')+1 252 # really ugly hack here !!! 253 _wp=self.pb.wallpaper[_idx:] 254 if not _wp.startswith('Preloaded'): 255 # assume that the name has extension .jpg 256 _wp+='.jpg' 257 258 entry['wallpapers']=[{ 'wallpaper': _wp, 259 'use': 'call' }]
260
261 - def _extract_memo(self, entry, p_class):
262 # extract the note portion from the phone into BitPim dict 263 if self.pb.has_note: 264 entry['memos']=[{ 'memo': self.pb.note }]
265
266 - def getvalue(self):
267 _entry=parentpbentry.getvalue(self) 268 self._extract_memo(_entry, self.phone.protocolclass) 269 return _entry
270 271 # Profile class----------------------------------------------------------------- 272 parentprofile=scha950.Profile
273 -class Profile(parentprofile):
274 serialsname=Phone.serialsname 275 WALLPAPER_WIDTH=176 276 WALLPAPER_HEIGHT=220 277 # 128x96: outside LCD 278 autodetect_delay=3 279 usbids=( ( 0x04e8, 0x6640, 2),) 280 deviceclasses=("serial",) 281 BP_Calendar_Version=3 282 # For phone detection 283 phone_manufacturer=Phone.my_manufacturer 284 phone_model=Phone.my_model 285 # arbitrary ringtone file size limit 286 RINGTONE_LIMITS= { 287 'MAXSIZE': 100000 288 } 289 WALLPAPER_FILENAME_CHARS="abcdefghijklmnopqrstuvwxyz0123456789 ._:" 290 RINGTONE_FILENAME_CHARS="abcdefghijklmnopqrstuvwxyz0123456789 ._:" 291 292 # fill in the list of ringtone/sound origins on your phone 293 ringtoneorigins=('ringers', 'sounds') 294 # ringtone origins that are not available for the contact assignment 295 excluded_ringtone_origins=('sounds',) 296 297 imageorigins={} 298 imageorigins.update(common.getkv(parentprofile.stockimageorigins, "images")) 299 imageorigins.update(common.getkv(parentprofile.stockimageorigins, "video")) 300 # wallpaper origins that are not available for the contact assignment 301 excluded_wallpaper_origins=('video',) 302 303 # our targets are the same for all origins 304 imagetargets={} 305 imagetargets.update(common.getkv(parentprofile.stockimagetargets, "wallpaper", 306 {'width': 220, 'height': 184, 'format': "JPEG"})) 307 imagetargets.update(common.getkv(parentprofile.stockimagetargets, "pictureid", 308 {'width': 128, 'height': 96, 'format': "JPEG"})) 309 imagetargets.update(common.getkv(parentprofile.stockimagetargets, "outsidelcd", 310 {'width': 128, 'height': 96, 'format': "JPEG"}))
311 - def GetTargetsForImageOrigin(self, origin):
312 return self.imagetargets
313
314 - def __init__(self):
315 parentprofile.__init__(self)
316 317 _supportedsyncs=( 318 ('phonebook', 'read', None), # all phonebook reading 319 ('phonebook', 'write', 'OVERWRITE'), # only overwriting phonebook 320 ('calendar', 'read', None), # all calendar reading 321 ('calendar', 'write', 'OVERWRITE'), # only overwriting calendar 322 ('ringtone', 'read', None), # all ringtone reading 323 ('ringtone', 'write', 'MERGE'), 324 ('wallpaper', 'read', None), # all wallpaper reading 325 ('wallpaper', 'write', 'MERGE'), 326 ('memo', 'read', None), # all memo list reading DJP 327 ('memo', 'write', 'OVERWRITE'), # all memo list writing DJP 328 ('call_history', 'read', None),# all call history list reading 329 ('sms', 'read', None), # all SMS list reading DJP 330 ) 331 332 field_color_data={ 333 'phonebook': { 334 'name': { 335 'first': 1, 'middle': 1, 'last': 1, 'full': 1, 336 'nickname': 0, 'details': 1 }, 337 'number': { 338 'type': 5, 'speeddial': 5, 'number': 5, 339 'details': 5, 340 'ringtone': False, 'wallpaper': False }, 341 'email': 2, 342 'email_details': { 343 'emailspeeddial': False, 'emailringtone': False, 344 'emailwallpaper': False }, 345 'address': { 346 'type': 0, 'company': 0, 'street': 0, 'street2': 0, 347 'city': 0, 'state': 0, 'postalcode': 0, 'country': 0, 348 'details': 0 }, 349 'url': 0, 350 'memo': 1, 351 'category': 1, 352 'wallpaper': 1, 353 'ringtone': 1, 354 'storage': 0, 355 }, 356 'calendar': { 357 'description': True, 'location': True, 'allday': False, 358 'start': True, 'end': True, 'priority': False, 359 'alarm': True, 'vibrate': True, 360 'repeat': True, 361 'memo': False, 362 'category': False, 363 'wallpaper': False, 364 'ringtone': True, 365 }, 366 'memo': { 367 'subject': False, 368 'date': False, 369 'secret': False, 370 'category': False, 371 'memo': True, 372 }, 373 'todo': { 374 'summary': False, 375 'status': False, 376 'due_date': False, 377 'percent_complete': False, 378 'completion_date': False, 379 'private': False, 380 'priority': False, 381 'category': False, 382 'memo': False, 383 }, 384 }
385