def savephonebook(self, fundamentals): self.log('Writing phonebook contacts') self._get_wallpaper_range(fundamentals) _pb_dict=fundamentals.get('phonebook', {}) _rec_cnt=0 _entry_cnt=1 _total_cnt=0 _pbentry_list=[None] fundamentals['numberlist']=[] fundamentals['emaillist']=[] fundamentals['wplist']=[] fundamentals['sdlist']=[] _pb_list=[(nameparser.getfullname(_entry['names'][0]), _key) \ for _key,_entry in _pb_dict.items()] _pb_list.sort() _journal_file=self.protocolclass.JournalFile() for _name,_key in _pb_list: _entry=_pb_dict[_key] _pbentry=PBEntry(self, _entry, fundamentals) _pbentry_list.append(_pbentry) _entry_cnt+=1 _total_cnt+=1 self._update_journal_file(_journal_file, _pbentry, _total_cnt, fundamentals) if _entry_cnt>7: self._write_pb_rec(_pbentry_list, _rec_cnt, fundamentals) _pbentry_list=[] _rec_cnt+=1 _entry_cnt=0 if _entry_cnt: self._write_pb_rec(_pbentry_list, _rec_cnt, fundamentals) self._write_journal_file(_journal_file) fundamentals['rebootphone']=True self._del_private_dicts(fundamentals) return fundamentals
def _build_sim_entry(self, entry, groups): _req=self.protocolclass.write_sim_phonebook_req() _req.group=self._lookup_group(entry, groups) _req.name=nameparser.getfullname(entry['names'][0]) _number=entry.get('numbers', [{'number': ''}])[0]['number'] if _number: _req.number=_number _req.number_type=129 return _req
def _build_sim_entry(self, entry, groups): _req = self.protocolclass.write_sim_phonebook_req() _req.group = self._lookup_group(entry, groups) _req.name = nameparser.getfullname(entry['names'][0]) _number = entry.get('numbers', [{'number': ''}])[0]['number'] if _number: _req.number = _number _req.number_type = 129 return _req
def _write_pb_entry(self, entry, fundamentals): """Write an phonebook entry to the phone""" _req=self.protocolclass.write_pb_req() _req.name=nameparser.getfullname(entry['names'][0]) _req.group=self._get_group_code(entry, fundamentals) fundamentals['primary']=False self._write_pb_entry_numbers(entry, _req, fundamentals) self._write_pb_entry_emails(entry, _req, fundamentals) del fundamentals['primary']
def _build(self, entry): self.pb.name=nameparser.getfullname(entry['names'][0]) _ringtone=entry.get('ringtones', [{}])[0].get('ringtone', None) _primary=True # the first number is the primary one for _number in entry.get('numbers', []): self._build_number(_number, _ringtone, _primary) _primary=False self._build_email(entry.get('emails', [])) self._build_group(entry.get('categories', [{}])[0].get('category', None)) self._build_wallpaper(entry.get('wallpapers', [{}])[0].get('wallpaper', None))
def _build(self, entry): self.pb.info=self.phone.protocolclass.PB_FLG_NONE self.pb.name=nameparser.getfullname(entry['names'][0]) _ringtone=entry.get('ringtones', [{}])[0].get('ringtone', None) _primary=True # the first number is the primary one for _number in entry.get('numbers', []): self._build_number(_number, _ringtone, _primary) _primary=False self._build_email(entry.get('emails', [])) self.pb.datetime=self.phone._time_now() self._build_group(entry.get('categories', [{}])[0].get('category', None)) self._build_wallpaper(entry.get('wallpapers', [{}])[0].get('wallpaper', None))
def _save_sim_phonebook(self, entries, groups): """ got the the phonebook dict and write them out to the phone""" # build the full names & SIM keys _pb_list=[(nameparser.getfullname(e['names'][0]), k) \ for k,e in entries.items() if self._in_sim(e)] # sort alphabetical order _pb_list.sort() # switch to the main phone storage _req = self.protocolclass.select_storage_req() _req.storage = self.protocolclass.PB_MEMORY_SIM self.sendATcommand(_req, None) _del_entry = self.protocolclass.del_phonebook_req() # send each entry to the phone _index = self.protocolclass.PB_SIM_MIN_INDEX for l in _pb_list: _del_entry.index = _index _index += 1 self.sendATcommand(_del_entry, None) time.sleep(0.2) _req = self._build_sim_entry(entries[l[1]], groups) self.progress(_index, self.protocolclass.PB_SIM_MAX_INDEX, 'Writing SIM entry %d: %s' % (_index, _req.name)) try: self.sendATcommand(_req, None) _retry = False except: _retry = True if _retry: try: self.sendATcommand(_req, None) except: self.log('Failed to write SIM entry %d: %s' % (_index, _req.name)) time.sleep(0.2) # clear out the rest of the phonebook for i in range(_index, self.protocolclass.PB_SIM_MAX_INDEX + 1): self.progress(i, self.protocolclass.PB_SIM_MAX_INDEX, 'Deleting SIM entry %d' % i) try: _del_entry.index = i self.sendATcommand(_del_entry, None) continue except: self.log('Trying to delete entry %d' % i) try: self.sendATcommand(_del_entry, None) except: self.log('Failed to delete entry %d' % i)
def _write_pb_entry(self, entry, fundamentals): """Write an phonebook entry to the phone""" _req=self.protocolclass.write_pb_req() _req.name=nameparser.getfullname(entry['names'][0]) _req.group=self._get_group_code(entry, fundamentals) fundamentals['primary']=False fundamentals['phonewallpaper']=entry.get('wallpapers', [{}])[0].get('wallpaper', None) fundamentals['phoneringtone']=entry.get('ringtones', [{}])[0].get('ringtone', None) # first, write out the numbers self._write_pb_entry_numbers(entry, _req, fundamentals) # then email self._write_pb_entry_emails(entry, _req, fundamentals) # and mail list # self._write_pb_entry_maillist(entry, _req, fundamentals) del fundamentals['primary'], fundamentals['phonewallpaper'], fundamentals['phoneringtone']
def _write_pb_entry(self, entry, fundamentals): """Write an phonebook entry to the phone""" _req = self.protocolclass.write_pb_req() _req.name = nameparser.getfullname(entry["names"][0]) _req.group = self._get_group_code(entry, fundamentals) fundamentals["primary"] = False fundamentals["phonewallpaper"] = entry.get("wallpapers", [{}])[0].get("wallpaper", None) fundamentals["phoneringtone"] = entry.get("ringtones", [{}])[0].get("ringtone", None) # first, write out the numbers self._write_pb_entry_numbers(entry, _req, fundamentals) # then email self._write_pb_entry_emails(entry, _req, fundamentals) # and mail list # self._write_pb_entry_maillist(entry, _req, fundamentals) del fundamentals["primary"], fundamentals["phonewallpaper"], fundamentals["phoneringtone"]
def _save_sim_phonebook(self, entries, groups): """ got the the phonebook dict and write them out to the phone""" # build the full names & SIM keys _pb_list=[(nameparser.getfullname(e['names'][0]), k) \ for k,e in entries.items() if self._in_sim(e)] # sort alphabetical order _pb_list.sort() # switch to the main phone storage _req=self.protocolclass.select_storage_req() _req.storage=self.protocolclass.PB_MEMORY_SIM self.sendATcommand(_req, None) _del_entry=self.protocolclass.del_phonebook_req() # send each entry to the phone _index=self.protocolclass.PB_SIM_MIN_INDEX for l in _pb_list: _del_entry.index=_index _index+=1 self.sendATcommand(_del_entry, None) time.sleep(0.2) _req=self._build_sim_entry(entries[l[1]], groups) self.progress(_index, self.protocolclass.PB_SIM_MAX_INDEX, 'Writing SIM entry %d: %s'%(_index, _req.name)) try: self.sendATcommand(_req, None) _retry=False except: _retry=True if _retry: try: self.sendATcommand(_req, None) except: self.log('Failed to write SIM entry %d: %s'%(_index, _req.name)) time.sleep(0.2) # clear out the rest of the phonebook for i in range(_index, self.protocolclass.PB_SIM_MAX_INDEX+1): self.progress(i, self.protocolclass.PB_SIM_MAX_INDEX, 'Deleting SIM entry %d'%i) try: _del_entry.index=i self.sendATcommand(_del_entry, None) continue except: self.log('Trying to delete entry %d'%i) try: self.sendATcommand(_del_entry, None) except: self.log('Failed to delete entry %d'%i)
def _write_pb_entries(self, fundamentals): """Write out the phonebook to the phone""" _pb_book = fundamentals.get("phonebook", {}) _total_entries = len(_pb_book) _cnt = 0 for _key, _entry in _pb_book.items(): try: _name = nameparser.getfullname(_entry["names"][0]) except: _name = "<Unknown>" _cnt += 1 self.progress(_cnt, _total_entries, "Writing contact %d: %s" % (_cnt, _name)) self._write_pb_entry(_entry, fundamentals) # delete all unused slots for _index, _entry in enumerate(fundamentals.get("sd-slots", [])): if not _entry: self.progress(_index, self.protocolclass.PB_TOTAL_ENTRIES, "Deleting contact slot %d" % _index) self._del_pb_entry(_index)
def _build_main_entry(self, entry, groups): _req=self.protocolclass.write_phonebook_req() _req.group=self._lookup_group(entry, groups) _req.name=nameparser.getfullname(entry['names'][0]) _req.email=entry.get('emails', [{'email': ''}])[0]['email'] _req.memo=entry.get('memos', [{'memo': ''}])[0]['memo'] for n in entry.get('numbers', []): _type=n['type'] _number=n['number'] if _type=='cell': _req.mobile=_number _req.mobile_type=129 elif _type=='home': _req.home=_number _req.home_type=129 elif _type=='office': _req.office=_number _req.office_type=129 return _req
def _build_main_entry(self, entry, groups): _req = self.protocolclass.write_phonebook_req() _req.group = self._lookup_group(entry, groups) _req.name = nameparser.getfullname(entry['names'][0]) _req.email = entry.get('emails', [{'email': ''}])[0]['email'] _req.memo = entry.get('memos', [{'memo': ''}])[0]['memo'] for n in entry.get('numbers', []): _type = n['type'] _number = n['number'] if _type == 'cell': _req.mobile = _number _req.mobile_type = 129 elif _type == 'home': _req.home = _number _req.home_type = 129 elif _type == 'office': _req.office = _number _req.office_type = 129 return _req
def _write_pb_entries(self, fundamentals): """Write out the phonebook to the phone""" _pb_book=fundamentals.get('phonebook', {}) _total_entries=len(_pb_book) _cnt=0 for _key,_entry in _pb_book.items(): try: _name=nameparser.getfullname(_entry['names'][0]) except: _name='<Unknown>' _cnt+=1 self.progress(_cnt, _total_entries, 'Writing contact %d: %s'%(_cnt, _name)) self._write_pb_entry(_entry, fundamentals) for _index,_entry in enumerate(fundamentals.get('sd-slots', [])): if not _entry: self.progress(_index, self.protocolclass.PB_TOTAL_ENTRIES, 'Deleting contact slot %d'%_index) self._del_pb_entry(_index)
def _save_main_phonebook(self, entries, groups): """ got the the phonebook dict and write them out to the phone""" _pb_list=[(nameparser.getfullname(e['names'][0]), k) \ for k,e in entries.items() if not self._in_sim(e)] _pb_list.sort() _req=self.protocolclass.select_storage_req() _req.storage=self.protocolclass.PB_MEMORY_MAIN self.sendATcommand(_req, None) _del_entry=self.protocolclass.del_phonebook_req() _index=self.protocolclass.PB_MAIN_MIN_INDEX for l in _pb_list: _del_entry.index=_index _index+=1 self.sendATcommand(_del_entry, None) time.sleep(0.2) _req=self._build_main_entry(entries[l[1]], groups) self.progress(_index, self.protocolclass.PB_MAIN_MAX_INDEX, 'Writing entry %d: %s'%(_index, _req.name)) try: self.sendATcommand(_req, None) _retry=False except: _retry=True if _retry: try: self.sendATcommand(_req, None) except: self.log('Failed to write entry %d: %s'%(_index, _req.name)) time.sleep(0.2) for i in range(_index, self.protocolclass.PB_MAIN_MAX_INDEX+1): self.progress(i, self.protocolclass.PB_MAIN_MAX_INDEX, 'Deleting entry %d'%i) try: _del_entry.index=i self.sendATcommand(_del_entry, None) continue except: self.log('Trying to delete entry %d'%i) try: self.sendATcommand(_del_entry, None) except: self.log('Failed to delete entry %d'%i)
def _write_pb_entries(self, fundamentals): """Write out the phonebook to the phone""" _pb_book=fundamentals.get('phonebook', {}) _total_entries=len(_pb_book) _cnt=0 for _key,_entry in _pb_book.items(): try: _name=nameparser.getfullname(_entry['names'][0]) except: _name='<Unknown>' _cnt+=1 self.progress(_cnt, _total_entries, 'Writing contact %d: %s'%(_cnt, _name)) self._write_pb_entry(_entry, fundamentals) # delete all unused slots for _index,_entry in enumerate(fundamentals.get('sd-slots', [])): if not _entry: self.progress(_index, self.protocolclass.PB_TOTAL_ENTRIES, 'Deleting contact slot %d'%_index) self._del_pb_entry(_index)
def savephonebook(self, fundamentals): self.log('Writing phonebook contacts') self._read_ringtone_range(fundamentals) _pb_dict=fundamentals.get('phonebook', {}) _pb_list=[(nameparser.getfullname(_entry['names'][0]), _key) \ for _key,_entry in _pb_dict.items()] _pb_list.sort() _req=self.protocolclass.ss_pb_clear_req() _rp=self.sendbrewcommand(_req, self.protocolclass.ss_pb_clear_resp) if _rp.flg: self.log('Failed to clear phonebook') self._del_private_dicts(fundamentals) return fundamentals _req=self.protocolclass.ss_pb_write_req() _total_cnt=len(_pb_list) _cnt=0 for _name,_key in _pb_list: try: _entry=_pb_dict[_key] _wp=_entry.get('wallpapers', [{}])[0].get('wallpaper', None) if _wp: self._add_wp_cache(_wp, fundamentals) _pbentry=PBEntry(self, _entry, fundamentals) _req.entry=_pbentry.pb _cnt+=1 self.progress(_cnt, _total_cnt, 'Writing entry" %s'%_req.entry.name) _resp=self.sendbrewcommand(_req, self.protocolclass.ss_pb_write_resp) except: self.log('Failed to write entry') if __debug__: raise fundamentals['rebootphone']=True self._del_private_dicts(fundamentals) return fundamentals
def __validate_entry(self, pb_entry, pb_groups, ringtone_index): try: name=nameparser.getfullname(pb_entry['names'][0]).replace('"', '') if len(name)>self.__pb_max_name_len: name=name[:self.__pb_max_name_len] pb_entry['names'][0].setdefault('full', name) url=pb_entry.get('urls', [{}])[0].get('url', None) if url is not None: url=re.sub('[,"]', '', url) if len(url)>self.__pb_max_alias_chars: url=url[:self.__pb_max_alias_chars] pb_entry['urls']=[ { 'url': url } ] has_number_or_email=False if pb_entry.has_key('numbers'): for n in pb_entry['numbers']: num=self.phonize(n['number']) if len(num)>self.__pb_max_number_len: num=num[:self.__pb_max_number_len] if num != n['number']: self.log('Updating number from '+n['number']+' to '+num) n['number']=num try: self._get_number_type(n['type']) except: self.log(n['number']+': setting type to home.') n['type']='home' has_number_or_email=True if pb_entry.has_key('emails'): if len(pb_entry['emails'])>self.__pb_max_emails: self.log(name+': Each entry can only have %s emails. The rest will be ignored.'%str(self.__pb_max_emails)) email=pb_entry['emails'][0]['email'].replace('"', '') if len(email)>self.__pb_max_email_chars: email=email[:self.__pb_max_email_chars] if email!=pb_entry['emails'][0]['email']: pb_entry['emails'][0]['email']=email has_number_or_email=True if not has_number_or_email: self.log(name+': Entry has no numbers or emails') return False found=False if pb_entry.has_key('categories') and len(pb_entry['categories']): pb_cat=pb_entry['categories'][0]['category'] for k in pb_groups: if pb_groups[k]['name']==pb_cat: found=True break if not found: self.log(name+': category set to '+pb_groups[0]['name']) pb_entry['categories']=[{'category': pb_groups[0]['name']}] found=False if pb_entry.has_key('ringtones') and len(pb_entry['ringtones']): pb_rt=pb_entry['ringtones'][0]['ringtone'] for k, rt in ringtone_index.items(): if pb_rt==rt['name']: found=True break if not found: rt=ringtone_index[0]['name'] self.log(name+': ringtone set to '+rt) pb_entry['ringtones']=[{'ringtone': rt, 'use': 'call' }] return True except: raise def _has_duplicate_speeddial(self, pb_book): b=[False]*(self.__pb_max_speeddials+1) for k in pb_book: try: for k1, kk in enumerate(pb_book[k]['numbers']): sd=kk['speeddial'] if sd and b[sd]: del pb_book[k]['numbers'][k1]['speeddial'] self.log('speeddial %d exists, deleted'%sd) else: b[sd]=True except: pass return False def _update_speeddial(self, pb_entry): try: s=self._my_serials(pb_entry) s1=int(s['serial2']) sd=self._get_speeddial(pb_entry) if not sd: self._set_speeddial(pb_entry, s1) elif sd!=s1: self._del_my_serials(pb_entry) except: pass def _get_speeddial(self, pb_entry): n=pb_entry.get('numbers', []) for k in n: try: if k['speeddial']: return k['speeddial'] except: pass return 0 def _set_speeddial(self, pb_entry, sd): if not pb_entry.has_key('numbers'): return for k in pb_entry['numbers']: if k.has_key('speeddial'): k['speeddial']=sd return pb_entry['numbers'][0]['speeddial']=sd def _del_phone_entry(self, pb_entry): try: return self.save_phone_entry(self._my_serials(pb_entry)['serial1']) except: return False def _same_serial1(self, s1, pb_entry): for k in pb_entry['serials']: if k['sourcetype']==self.serialsname and k.has_key('serial1'): return k['serial1']==s1 return False def _has_serial1(self, pb_entry): for k in pb_entry['serials']: if k['sourcetype']==self.serialsname and k.has_key('serial1'): return True return False def _bitpim_serials(self, pb_entry): for k in pb_entry['serials']: if k['sourcetype']=="bitpim": return k return {} def _del_my_serials(self, pb_entry): for k in range(len(pb_entry['serials'])): if pb_entry['serials'][k]['sourcetype']==self.serialsname: del pb_entry['serials'][k] return def _my_serials(self, pb_entry): for k in pb_entry['serials']: if k['sourcetype']==self.serialsname: return k return {} def _get_number_type(self, type): n=self.__pb_numbers for k in range(len(n)): if n[k].has_key(type): return k, n[k][type] raise common.IntegrityCheckFailed(self.desc, "Invalid Number Type") def _write_phone_entry(self, pb_entry, data): e=['0']*self.__pb_atpbokw_field_count serials=self._my_serials(pb_entry) e[self.__pb_entry]=serials['serial1'] e[self.__pb_mem_loc]=serials['serial2'] groups=data.get('groups', {}) e[self.__pb_group]='0' try: grp_name=pb_entry['categories'][0]['category'] for k, n in groups.items(): if n.get('name', None)==grp_name: e[self.__pb_group]=`k` break except: pass ringtone_index=data.get('ringtone-index', {}) e[self.__pb_ringtone]='0' try: rt=pb_entry['ringtones'][0]['ringtone'] for k, n in ringtone_index.items(): if rt==n.get('name', None): e[self.__pb_ringtone]=`k` break except: pass e[self.__pb_name]='"'+nameparser.getfullname(\ pb_entry['names'][0])+'"' url='' try: url=pb_entry['urls'][0]['url'] except: pass e[self.__pb_alias]=url if len(url): e[self.__pb_alias+1]='0' else: e[self.__pb_alias+1]='' for k in range(len(self.__pb_numbers)): for kk in self.__pb_numbers[k]: e[self.__pb_numbers[k][kk]]='' e[self.__pb_numbers[k][kk]+1]='' speed_dial='0' n=pb_entry.get('numbers', []) for k in range(len(n)): try: nk=n[k] kkk, kk=self._get_number_type(nk['type']) except: nk['type']='home' kkk, kk=0, self.__pb_home_num e[kk],e[kk+1]=self.phonize(nk['number']),'0' try: if nk['speeddial']: speed_dial=`kkk` except: pass e[self.__pb_speed_dial]=speed_dial email='' try: email=pb_entry['emails'][0]['email'] except: pass e[self.__pb_email]='"'+email+'"' e[self.__pb_image_assign]='5' e[self.__pb_image_id]='0' e[self.__pb_contact_image]='""' try: imgName = pb_entry['wallpapers'][0]['wallpaper'] image_index=data.get('wallpaper-index', {}) for k, n in image_index.items(): if imgName==n.get('name', None): if k>self.protocolclass.max_image_entries: e[self.__pb_image_assign]='3' e[self.__pb_contact_image]='"'+self.__wp_photo_dir+'/'+imgName.split('.')[0]+'"' e[self.__pb_image_id]='0' else: e[self.__pb_image_assign]='4' e[self.__pb_image_id]=`k` e[self.__pb_contact_image]='""' break except: pass for k in self.__pb_blanks: e[k]='' e[self.__pb_date_time_stamp]=self.get_time_stamp() ee=self.get_phone_entry(int(e[self.__pb_entry])) if len(ee)==self.__pb_atpbokw_field_count: ee[self.__pb_name]='"'+ee[self.__pb_name]+'"' ee[self.__pb_email]='"'+ee[self.__pb_email]+'"' ee[self.__pb_contact_image]='"'+ee[self.__pb_contact_image]+'"' k=self.__pb_atpbokw_field_count-1 if e[:k]==ee[:k]: return True return self.save_phone_entry('0,'+','.join(e)) def getringtones(self, result): self.setmode(self.MODEBREW) m=FileEntries(self, self.__ringtone_info) rt_info=RingtoneIndex(self).get_download_info() r=m.get_media(result, rt_info) self.setmode(self.MODEMODEM) return r def saveringtones(self, result, merge): self.setmode(self.MODEBREW) m=FileEntries(self, self.__ringtone_info) result['rebootphone']=1 r=m.save_media(result, RingtoneIndex(self).get_download_info()) self.setmode(self.MODEMODEM) return r def getwallpapers(self, result): self.setmode(self.MODEBREW) m=FileEntries(self, self.__wallpaper_info) img_info=ImageIndex(self).get_download_info() m.get_media(result, img_info) FileEntries(self, self.__video0_info).get_video(result, 'Video001.avi') r=FileEntries(self, self.__video1_info).get_video(result, 'Video002.avi') self.setmode(self.MODEMODEM) return r def savewallpapers(self, result, merge): self.setmode(self.MODEBREW) m=FileEntries(self, self.__wallpaper_info) r=m.save_media(result, ImageIndex(self).get_download_info()) result['rebootphone']=1 self.setmode(self.MODEMODEM) return r getmemo=parent_phone._getmemo savememo=parent_phone._savememo gettodo=parent_phone._gettodo savetodo=parent_phone._savetodo getsms=parent_phone._getsms savesms=parent_phone._savesms getphoneinfo=parent_phone._getphoneinfo getmedia=None detectphone=staticmethod(parent_phone._detectphone) "Talk to the Samsung SCH-A670 Cell Phone" class Profile (com_samsung.Profile) : serialsname='scha670' WALLPAPER_WIDTH=128 WALLPAPER_HEIGHT=128 MAX_WALLPAPER_BASENAME_LENGTH=19 WALLPAPER_FILENAME_CHARS="abcdefghijklmnopqrstuvwxyz0123456789_ ." WALLPAPER_CONVERT_FORMAT="jpg" MAX_RINGTONE_BASENAME_LENGTH=19 RINGTONE_FILENAME_CHARS="abcdefghijklmnopqrstuvwxyz0123456789_ ." RINGTONE_LIMITS= { 'MAXSIZE': 30000 } phone_manufacturer='SAMSUNG ELECTRONICS' phone_model='SCH-A670/164' def __init__(self): com_samsung.Profile.__init__(self) _supportedsyncs=( ('phonebook', 'read', None), ('phonebook', 'write', 'OVERWRITE'), ('calendar', 'read', None), ('calendar', 'write', 'OVERWRITE'), ('ringtone', 'read', None), ('ringtone', 'write', 'OVERWRITE'), ('wallpaper', 'read', None), ('wallpaper', 'write', 'OVERWRITE'), ('memo', 'read', None), ('memo', 'write', 'OVERWRITE'), ('todo', 'read', None), ('todo', 'write', 'OVERWRITE'), ('sms', 'read', None), ) if __debug__: _supportedsyncs+=(('sms', 'write', 'OVERWRITE'),) def convertphonebooktophone(self, helper, data): return data __audio_ext={ 'MIDI': 'mid', 'PMD': 'pmd', 'QCP': 'pmd' } def QueryAudio(self, origin, currentextension, afi): if afi.format in ("MIDI", "PMD", "QCP"): for k,n in self.RINGTONE_LIMITS.items(): setattr(afi, k, n) return currentextension, afi d=self.RINGTONE_LIMITS.copy() d['format']='QCP' return ('pmd', fileinfo.AudioFileInfo(afi, **d)) imageorigins={} imageorigins.update(common.getkv(com_samsung.Profile.stockimageorigins, "images")) imagetargets={} imagetargets.update(common.getkv(com_samsung.Profile.stockimagetargets, "wallpaper", {'width': 128, 'height': 128, 'format': "PNG"})) imagetargets.update(common.getkv(com_samsung.Profile.stockimagetargets, "fullscreen", {'width': 128, 'height': 160, 'format': "PNG"})) imagetargets.update(common.getkv(com_samsung.Profile.stockimagetargets, "pictureid", {'width': 96, 'height': 96, 'format': "JPEG"})) def GetImageOrigins(self): return self.imageorigins def GetTargetsForImageOrigin(self, origin): if origin=='images': return self.imagetargets if __debug__: _supportedsyncs+=(('sms', 'write', 'OVERWRITE'),) imageorigins.update(common.getkv(com_samsung.Profile.stockimageorigins, "images")) imagetargets.update(common.getkv(com_samsung.Profile.stockimagetargets, "wallpaper", {'width': 128, 'height': 128, 'format': "PNG"})) imagetargets.update(common.getkv(com_samsung.Profile.stockimagetargets, "fullscreen", {'width': 128, 'height': 160, 'format': "PNG"})) imagetargets.update(common.getkv(com_samsung.Profile.stockimagetargets, "pictureid", {'width': 96, 'height': 96, 'format': "JPEG"})) class FileEntries : def __init__(self, phone, info): self.__phone=phone self.__file_type, self.__index_type, self.__origin, self.__path, self.__max_file_len, self.__max_file_count=info def get_media(self, result, download_info=None): self.__phone.log('Getting media for type '+self.__file_type) if download_info is None: return self.__get_media_by_dir(result) else: return self.__get_media_by_index(result, download_info) def __get_media_by_dir(self, result): media=result.get(self.__file_type, {}) idx=result.get(self.__index_type, {}) file_cnt, idx_k=0, len(idx) path_len=len(self.__path)+1 try: file_list=self.__phone.listfiles(self.__path) for k in file_list: try: index=k[path_len:] media[index]=self.__phone.getfilecontents(k, True) idx[idx_k]={ 'name': index, 'origin': self.__origin } idx_k+=1 file_cnt += 1 except: self.__phone.log('Failed to read file '+k) except: self.__phone.log('Failed to read dir '+self.__path) result[self.__file_type]=media result[self.__index_type]=idx if file_cnt > self.__max_file_count: self.__phone.log('This phone only supports %d %s. %d %s read, weird things may happen.' % \ (self.__max_file_count, self.__file_type, file_cnt, self.__file_type)) return result def __get_media_by_index(self, result, rt_info): media=result.get(self.__file_type, {}) media_index=result.get(self.__index_type, {}) mms_img_path=self.__phone.protocolclass.mms_image_path mms_img_len=len(mms_img_path) for k, m in media_index.items(): file_key=m.get('name', None) file_name=rt_info.get(file_key, None) if file_key is not None and file_name is not None: try : contents=self.__phone.getfilecontents(file_name, True) img_origin=m.get('origin', None) if img_origin=='images': if file_name[:mms_img_len]==mms_img_path: contents=contents[52:] elif img_origin=='camera': m['date']=\ ( int(contents[47:51]), int(contents[51:53]), int(contents[53:55]), int(contents[55:57]), int(contents[57:59])) contents=contents[96:] if contents[-1]=='\xff': contents+='\x00' media[file_key]=contents except: self.__phone.log('Failed to read file '+file_name) if __debug__: raise result[self.__file_type]=media return result def get_video(self, result, video_file_name): if not conversions.helperavailable('bmp2avi'): self.__phone.log('Helper bmp2avi not found, cannot retrieve '+\ video_file_name) return result self.__phone.log('Getting video file '+video_file_name) media=result.get(self.__file_type, {}) idx=result.get(self.__index_type, {}) tmp_avi_name=common.gettempfilename("avi") try: file_list=self.__phone.listfiles(self.__path) except com_brew.BrewNoSuchDirectoryException: file_list={} except: file_list={} if __debug__: raise if not len(file_list): return result file_keys=file_list.keys() file_keys.sort(); for k in file_keys: try: conversions.convertjpgtoavi(self.__phone.getfilecontents(k, True)[96:], tmp_avi_name) except: self.__phone.log('Failed to read video files') if __debug__: raise if len(idx): idx_k=max(idx.keys())+1 else: idx_k=0 media[video_file_name]=open(tmp_avi_name, 'rb').read() idx[idx_k]={ 'name': video_file_name, 'origin': 'video' } result[self.__file_type]=media result[self.__index_type]=idx try: os.remove(tmp_avi_name) except: pass return result __mms_max_file_name_len=35 def __mms_header(self, img_name, img_type, img_data_len): if len(img_name)>=self.__mms_max_file_name_len: name=img_name[:self.__mms_max_file_name_len-1] else: name=img_name return str('\x06'+str(name)+\ '\x00'*(self.__mms_max_file_name_len-len(name))+\ common.LSBstr32(img_data_len)+chr(img_type)+\ '\x00'*11) def __mms_file_name(self): now = time.localtime(time.time()) return '%02d%02d%02d%02d%02d%02d'%((now[0]%2000,)+now[1:6]) def _to_mms_JPEG(self, img_name, img_data_len): return (self.__mms_file_name(), self.__mms_header(img_name, 0, img_data_len)) def _to_mms_BMP(self, img_name, img_data_len): return (self.__mms_file_name(), self.__mms_header(img_name, 1, img_data_len)) def _to_mms_PNG(self, img_name, img_data_len): return (self.__mms_file_name(), self.__mms_header(img_name, 2, img_data_len)) def _to_mms_GIF(self, img_name, img_data_len): return (self.__mms_file_name(), self.__mms_header(img_name, 3, img_data_len)) def save_media(self, result, dl_info): self.__phone.log('Saving media for type '+self.__file_type) media, idx=result[self.__file_type], result[self.__index_type] media_names=[media[k]['name'] for k in media] dl_info_keys=dl_info.keys() deleted_keys=[k for k in dl_info_keys if k not in media_names] new_keys=[k for k in media if media[k]['name'] not in dl_info_keys] campix_file_path=self.__phone.protocolclass.cam_pix_file_path campix_file_len=len(campix_file_path) for k in deleted_keys: file_name=dl_info[k] if file_name[:campix_file_len]==campix_file_path: continue self.__phone.log('Deleting file: '+file_name) try: self.__phone.rmfile(file_name) except: self.__phone.log('Failed to delete file: '+file_name) if len(new_keys): try: self.__phone.mkdirs(self.__path) self.__phone.mkdirs('brew/shared') except: pass file_count=0 for k in new_keys: n=media[k] origin=n.get('origin', None) if origin is not None and origin != self.__origin: continue if len(n['name']) > self.__max_file_len: self.__phone.log('%s %s name is too long and not sent to phone'% \ (self.__file_type, n['name'])) continue file_count+=1 if file_count>self.__max_file_count: self.__phone.log('This phone only supports %d %s. Save operation stopped.'%\ (self.__max_file_count, self.__file_type)) break if self.__origin=='images': file_info=fileinfo.identify_imagestring(n['data']) if file_info.format in ('JPEG', 'GIF', 'BMP'): (mms_file_name, file_hdr)=\ getattr(self, '_to_mms_'+file_info.format)( n['name'], len(n['data'])) file_name=self.__path+'/'+mms_file_name file_contents=file_hdr+n['data'] elif file_info.format=='PNG': file_name='brew/shared/'+n['name'] file_contents=conversions.convertto8bitpng_joe(n['data']) else: continue else: file_name=self.__path+'/'+n['name'] file_contents=n['data'] self.__phone.log('Writing file: '+file_name) try: self.__phone.writefile(file_name, file_contents) except: self.__phone.log('Failed to write file: '+file_name) media[k]['origin']=self.__origin return result class RingtoneIndex : __builtin_ringtones=( 'Inactive', 'Bell 1', 'Bell 2', 'Bell 3', 'Bell 4', 'Bell 5', 'Melody 1', 'Melody 2', 'Melody 3', 'Melody 4', 'Melody 5', 'Melody 6', 'Melody 7', 'Melody 8', 'Melody 9', 'Melody 10') def __init__(self, phone): self.__phone=phone def get_builtin_index(self): r={} for k, n in enumerate(self.__builtin_ringtones): r[k]={ 'name': n, 'origin': 'builtin' } return r def get_download_index(self): r={} try: rt_idx=self.__phone.protocolclass.ringtones() buf=prototypes.buffer(self.__phone.getfilecontents( \ self.__phone.protocolclass.ringtone_index_file_name)) rt_idx.readfrombuffer(buf) idx=len(self.__builtin_ringtones) l=len(self.__phone.protocolclass.ringtone_file_path)+1 for i in range(self.__phone.protocolclass.max_ringtone_entries): e=rt_idx.entry[i] if e.name_len: r[idx+i]={ 'name': e.file_name[l:e.file_name_len], 'origin': 'ringtone' } except: pass return r def get(self): r=self.get_builtin_index() r.update(self.get_download_index()) return r def get_download_info(self): r={} try: rt_idx=self.__phone.protocolclass.ringtones() buf=prototypes.buffer(self.__phone.getfilecontents( \ self.__phone.protocolclass.ringtone_index_file_name)) rt_idx.readfrombuffer(buf) l=len(self.__phone.protocolclass.ringtone_file_path)+1 for i in range(self.__phone.protocolclass.max_ringtone_entries): e=rt_idx.entry[i] if e.name_len: r[e.file_name[l:e.file_name_len]]=e.file_name[:e.file_name_len] except: pass return r class ImageIndex : def __init__(self, phone): self.__phone=phone def get_download_index(self): r={} try: img_idx=self.__phone.protocolclass.images() buf=prototypes.buffer(self.__phone.getfilecontents( \ self.__phone.protocolclass.image_index_file_name)) img_idx.readfrombuffer(buf) l=len(self.__phone.protocolclass.image_file_path)+1 mms_img_path=self.__phone.protocolclass.mms_image_path mms_img_len=len(mms_img_path) for i in range(self.__phone.protocolclass.max_image_entries): e=img_idx.entry[i] if e.name_len and e.file_name_len: if e.file_name[:mms_img_len]==mms_img_path: idx_name=e.name[:e.name_len] else: idx_name=e.file_name[l:e.file_name_len] r[i]={ 'name': idx_name, 'origin': 'images' } idx=self.__phone.protocolclass.max_image_entries+1 try: dir_l=self.__phone.listfiles(\ self.__phone.protocolclass.cam_pix_file_path) except com_brew.BrewNoSuchDirectoryException: dir_l={} l=len(self.__phone.protocolclass.cam_pix_file_path)+1 for f in dir_l: r[idx]={ 'name': f[l:]+'.jpg', 'origin': 'camera' } idx += 1 except: raise return r def get(self): return self.get_download_index() def get_download_info(self): r={} try: img_idx=self.__phone.protocolclass.images() buf=prototypes.buffer(self.__phone.getfilecontents( \ self.__phone.protocolclass.image_index_file_name)) img_idx.readfrombuffer(buf) l=len(self.__phone.protocolclass.image_file_path)+1 mms_img_path=self.__phone.protocolclass.mms_image_path mms_img_len=len(mms_img_path) for i in range(self.__phone.protocolclass.max_image_entries): e=img_idx.entry[i] if e.name_len and e.file_name_len: if e.file_name[:mms_img_len]==mms_img_path: idx_name=e.name[:e.name_len] else: idx_name=e.file_name[l:e.file_name_len] r[idx_name]=e.file_name[:e.file_name_len] try: dir_l=self.__phone.listfiles(\ self.__phone.protocolclass.cam_pix_file_path) except com_brew.BrewNoSuchDirectoryException: dir_l={} l=len(self.__phone.protocolclass.cam_pix_file_path)+1 for f in dir_l: r[f[l:]+'.jpg']=f except: pass return r
def __validate_entry(self, pb_entry, pb_groups, ringtone_index): try: # validate name name=nameparser.getfullname(pb_entry['names'][0]).replace('"', '') if len(name)>self.__pb_max_name_len: name=name[:self.__pb_max_name_len] pb_entry['names'][0].setdefault('full', name) # validate url/alias url=pb_entry.get('urls', [{}])[0].get('url', None) if url is not None: url=re.sub('[,"]', '', url) if len(url)>self.__pb_max_alias_chars: url=url[:self.__pb_max_alias_chars] pb_entry['urls']=[ { 'url': url } ] # validate numbers has_number_or_email=False if pb_entry.has_key('numbers'): for n in pb_entry['numbers']: num=self.phonize(n['number']) if len(num)>self.__pb_max_number_len: num=num[:self.__pb_max_number_len] if num != n['number']: self.log('Updating number from '+n['number']+' to '+num) n['number']=num try: self._get_number_type(n['type']) except: self.log(n['number']+': setting type to home.') n['type']='home' has_number_or_email=True # validate emails if pb_entry.has_key('emails'): if len(pb_entry['emails'])>self.__pb_max_emails: self.log(name+': Each entry can only have %s emails. The rest will be ignored.'%str(self.__pb_max_emails)) email=pb_entry['emails'][0]['email'].replace('"', '') if len(email)>self.__pb_max_email_chars: email=email[:self.__pb_max_email_chars] if email!=pb_entry['emails'][0]['email']: pb_entry['emails'][0]['email']=email has_number_or_email=True if not has_number_or_email: self.log(name+': Entry has no numbers or emails') # return False so this entry can be deleted from the dict return False # validate groups found=False if pb_entry.has_key('categories') and len(pb_entry['categories']): pb_cat=pb_entry['categories'][0]['category'] for k in pb_groups: if pb_groups[k]['name']==pb_cat: found=True break if not found: self.log(name+': category set to '+pb_groups[0]['name']) pb_entry['categories']=[{'category': pb_groups[0]['name']}] # validate ringtones found=False if pb_entry.has_key('ringtones') and len(pb_entry['ringtones']): pb_rt=pb_entry['ringtones'][0]['ringtone'] for k, rt in ringtone_index.items(): if pb_rt==rt['name']: found=True break if not found: rt=ringtone_index[0]['name'] self.log(name+': ringtone set to '+rt) pb_entry['ringtones']=[{'ringtone': rt, 'use': 'call' }] # to to: validate wallpaper # everything's cool return True except: raise
def _write_phone_entry(self, pb_entry, groups, ringtone_index, phone_book): # setting up a list to send to the phone, all fields preset to '0' e = ['0'] * self.__pb_max_entries # setting the entry # and memory location # serials = self._my_serials(pb_entry) e[self.__pb_entry] = serials['serial1'] e[self.__pb_mem_loc] = serials['serial2'] # groups/categories grp = 0 try: grp_name = pb_entry['categories'][0]['category'] for k in range(len(groups)): if groups[k]['name'] == grp_name: grp = k break except: # invalid group or no group specified, default to group 0 grp, pb_entry['categories'] = 0, [{'category': groups[0]['name']}] e[self.__pb_group] = ` grp ` # ringtones e[self.__pb_ringtone] = '0' # default to Inactive try: rt = pb_entry['ringtones'][0]['ringtone'] for k, n in ringtone_index.items(): if rt == n['name']: e[self.__pb_ringtone] = ` k ` break except: pass # name & alias e[self.__pb_name] = '"' + nameparser.getfullname( pb_entry['names'][0]) + '"' nick_name = '' try: nick_name = pb_entry['names'][0]['nickname'] except: pass e[self.__pb_alias] = nick_name if len(nick_name): e[self.__pb_alias + 1] = '0' else: e[self.__pb_alias + 1] = '' # numbers & speed dial # preset to empty for k in range(len(self.__pb_numbers)): for kk in self.__pb_numbers[k]: e[self.__pb_numbers[k][kk]] = '' e[self.__pb_numbers[k][kk] + 1] = '' speed_dial = '0' n = pb_entry.get('numbers', []) for k in range(len(n)): try: nk = n[k] kkk, kk = self._get_number_type(nk['type']) except: # invalid type, default to 'home' nk['type'] = 'home' kkk, kk = 0, self.__pb_home_num e[kk], e[kk + 1] = self.phonize(nk['number']), '0' try: if nk['speeddial']: speed_dial = ` kkk ` except: pass e[self.__pb_speed_dial] = speed_dial # email email = '' try: email = pb_entry['emails'][0]['email'] except: pass e[self.__pb_email] = '"' + email + '"' e[self.__pb_four] = '4' for k in self.__pb_blanks: e[k] = '' e[self.__pb_date_time_stamp] = self.get_time_stamp() # final check to determine if this entry has changed. # if it has not then do nothing and just return ee = self.get_phone_entry(int(e[self.__pb_entry]), self.__pb_alias, self.__pb_max_entries) if len(ee) == self.__pb_max_entries: # DSV took the " out, need to put them back in for comparison ee[self.__pb_name] = '"' + ee[self.__pb_name] + '"' ee[self.__pb_email] = '"' + ee[self.__pb_email] + '"' # set the correct ringtone index ee[self.__pb_ringtone]=str(phone_book.get_ringtone(\ int(e[self.__pb_mem_loc]))) k = self.__pb_max_entries - 2 if e[0:k] == ee[0:k]: return True return self.save_phone_entry('0,' + ','.join(e))
def __validate_entry(self, pb_entry, pb_groups, ringtone_index): try: # validate name & alias name = nameparser.getfullname(pb_entry['names'][0]).replace( '"', '') if len(name) > self.__pb_max_name_len: name = name[:self.__pb_max_name_len] pb_entry['names'][0].setdefault('full', name) if pb_entry['names'][0].has_key('nickname'): name = re.sub('[,"]', '', pb_entry['names'][0]['nickname']) if len(name) > self.__pb_max_name_len: name = name[:self.__pb_max_name_len] if pb_entry['names'][0]['nickname'] != name: pb_entry['names'][0]['nickname'] = name # validate numbers has_number_or_email = False if pb_entry.has_key('numbers'): for n in pb_entry['numbers']: num = self.phonize(n['number']) if len(num) > self.__pb_max_number_len: num = num[:self.__pb_max_number_len] if num != n['number']: self.log('Updating number from ' + n['number'] + ' to ' + num) n['number'] = num try: self._get_number_type(n['type']) except: self.log(n['number'] + ': setting type to home.') n['type'] = 'home' has_number_or_email = True # validate emails if pb_entry.has_key('emails'): if len(pb_entry['emails']) > self.__pb_max_emails: self.log( name + ': Each entry can only have %s emails. The rest will be ignored.' % str(self.__pb_max_emails)) email = pb_entry['emails'][0]['email'].replace('"', '') if len(email) > self.__pb_max_number_len: email = email[:self.__pb_max_number_len] if email != pb_entry['emails'][0]['email']: pb_entry['emails'][0]['email'] = email has_number_or_email = True if not has_number_or_email: self.log(name + ': Entry has no numbers or emails') # return False so this entry can be deleted from the dict return False # validate groups found = False if pb_entry.has_key('categories') and len(pb_entry['categories']): pb_cat = pb_entry['categories'][0]['category'] for k in pb_groups: if pb_groups[k]['name'] == pb_cat: found = True break if not found: self.log(name + ': category set to ' + pb_groups[0]['name']) pb_entry['categories'] = [{'category': pb_groups[0]['name']}] # validate ringtones found = False if pb_entry.has_key('ringtones') and len(pb_entry['ringtones']): pb_rt = pb_entry['ringtones'][0]['ringtone'] # can only set to builtin-ringtone for k, rt in ringtone_index.items(): if pb_rt == rt['name']: found = True break if not found: rt = ringtone_index[0]['name'] self.log(name + ': ringtone set to ' + rt) pb_entry['ringtones'] = [{'ringtone': rt, 'use': 'call'}] # everything's cool return True except: raise
def savephonebook(self, data): "Saves out the phonebook" pb_book = data['phonebook'] pb_groups = data['groups'] ringtone_index = data.get('ringtone-index', {}) self.log('Validating phonebook entries.') del_entries = [] for k in pb_book: if not self.__validate_entry(pb_book[k], pb_groups, ringtone_index): self.log('Invalid entry, entry will be not be sent.') del_entries.append(k) for k in del_entries: self.log('Deleting entry '+\ nameparser.getfullname(pb_book[k]['names'][0])) del pb_book[k] self._has_duplicate_speeddial(pb_book) self.log('All entries validated') pb_locs = [False] * (len(self.__phone_entries_range) + 1) pb_mem = [False] * len(pb_locs) # get existing phonebook from the phone self.log("Getting current phonebook from the phone") self.setmode(self.MODEBREW) phone_book = PhoneBook(self) phone_book.read() current_pb = phone_book.get_dict(data) self.setmode(self.MODEMODEM) # check and adjust for speeddial changes self.log("Processing speeddial data") for k in pb_book: self._update_speeddial(pb_book[k]) # check for deleted entries and delete them self.setmode(self.MODEPHONEBOOK) self.log("Processing deleted entries") for k1 in current_pb: s1 = current_pb[k1]['serials'][0]['serial1'] found = False for k2 in pb_book: if self._same_serial1(s1, pb_book[k2]): found = True break if found: pb_locs[int(current_pb[k1]['serials'][0]['serial1'])] = True pb_mem[int(current_pb[k1]['serials'][0]['serial2'])] = True else: self.log("Deleted item: "+\ nameparser.getfullname(current_pb[k1]['names'][0])) # delete the entries from data and the phone self.progress(0, 10, "Deleting "+\ nameparser.getfullname(\ current_pb[k1]['names'][0])) self._del_phone_entry(current_pb[k1]) mem_idx, loc_idx = self.__pb_max_speeddials, 1 # check for new entries & update serials self.log("Processing new & updated entries") serials_update = [] progresscur, progressmax = 1, len(pb_book) for k in pb_book: if progresscur > len(self.__phone_entries_range): self.log('Max phone entries exceeded: ' + str(progresscur)) break e = pb_book[k] if not self._has_serial1(e): while pb_locs[loc_idx]: loc_idx += 1 pb_locs[loc_idx] = True sd = self._get_speeddial(e) if sd: mem_index = sd pb_mem[sd] = True else: while pb_mem[mem_idx]: mem_idx -= 1 pb_mem[mem_idx] = True mem_index = mem_idx self._set_speeddial(e, mem_idx) s1 = { 'sourcetype': self.serialsname, 'sourceuniqueid': data['uniqueserial'], 'serial1': ` loc_idx `, 'serial2': ` mem_index ` } e['serials'].append(s1) self.log("New entries: Name: "+\ nameparser.getfullname(e['names'][0])+\ ", s1: "+`loc_idx`+", s2: "+`mem_index`) serials_update.append((self._bitpim_serials(e), s1)) self.progress(progresscur, progressmax, "Updating "+\ nameparser.getfullname(e['names'][0])) if not self._write_phone_entry(e, pb_groups, ringtone_index, phone_book): self.log("Failed to save entry: "+\ nameparser.getfullname(e['names'][0])) progresscur += 1 data["serialupdates"] = serials_update self.log("Done") self.setmode(self.MODEMODEM) return data
def _write_phone_entry(self, pb_entry, data): e=['0']*self.__pb_atpbokw_field_count serials=self._my_serials(pb_entry) e[self.__pb_entry]=serials['serial1'] e[self.__pb_mem_loc]=serials['serial2'] groups=data.get('groups', {}) e[self.__pb_group]='0' try: grp_name=pb_entry['categories'][0]['category'] for k, n in groups.items(): if n.get('name', None)==grp_name: e[self.__pb_group]=`k` break except: pass ringtone_index=data.get('ringtone-index', {}) e[self.__pb_ringtone]='0' try: rt=pb_entry['ringtones'][0]['ringtone'] for k, n in ringtone_index.items(): if rt==n.get('name', None): e[self.__pb_ringtone]=`k` break except: pass e[self.__pb_name]='"'+nameparser.getfullname(\ pb_entry['names'][0])+'"' url='' try: url=pb_entry['urls'][0]['url'] except: pass e[self.__pb_alias]=url if len(url): e[self.__pb_alias+1]='0' else: e[self.__pb_alias+1]='' for k in range(len(self.__pb_numbers)): for kk in self.__pb_numbers[k]: e[self.__pb_numbers[k][kk]]='' e[self.__pb_numbers[k][kk]+1]='' speed_dial='0' n=pb_entry.get('numbers', []) for k in range(len(n)): try: nk=n[k] kkk, kk=self._get_number_type(nk['type']) except: nk['type']='home' kkk, kk=0, self.__pb_home_num e[kk],e[kk+1]=self.phonize(nk['number']),'0' try: if nk['speeddial']: speed_dial=`kkk` except: pass e[self.__pb_speed_dial]=speed_dial email='' try: email=pb_entry['emails'][0]['email'] except: pass e[self.__pb_email]='"'+email+'"' e[self.__pb_image_assign]='5' e[self.__pb_image_id]='0' e[self.__pb_contact_image]='""' try: imgName = pb_entry['wallpapers'][0]['wallpaper'] image_index=data.get('wallpaper-index', {}) for k, n in image_index.items(): if imgName==n.get('name', None): if k>self.protocolclass.max_image_entries: e[self.__pb_image_assign]='3' e[self.__pb_contact_image]='"'+self.__wp_photo_dir+'/'+imgName.split('.')[0]+'"' e[self.__pb_image_id]='0' else: e[self.__pb_image_assign]='4' e[self.__pb_image_id]=`k` e[self.__pb_contact_image]='""' break except: pass for k in self.__pb_blanks: e[k]='' e[self.__pb_date_time_stamp]=self.get_time_stamp() ee=self.get_phone_entry(int(e[self.__pb_entry])) if len(ee)==self.__pb_atpbokw_field_count: ee[self.__pb_name]='"'+ee[self.__pb_name]+'"' ee[self.__pb_email]='"'+ee[self.__pb_email]+'"' ee[self.__pb_contact_image]='"'+ee[self.__pb_contact_image]+'"' k=self.__pb_atpbokw_field_count-1 if e[:k]==ee[:k]: return True return self.save_phone_entry('0,'+','.join(e))
def _write_phone_entry(self, pb_entry, data): # setting up a list to send to the phone, all fields preset to '0' e=['0']*self.__pb_atpbokw_field_count # setting the entry # and memory location # serials=self._my_serials(pb_entry) e[self.__pb_entry]=serials['serial1'] e[self.__pb_mem_loc]=serials['serial2'] # groups/categories groups=data.get('groups', {}) e[self.__pb_group]='0' try: grp_name=pb_entry['categories'][0]['category'] for k, n in groups.items(): if n.get('name', None)==grp_name: e[self.__pb_group]=`k` break except: pass # ringtones ringtone_index=data.get('ringtone-index', {}) e[self.__pb_ringtone]='0' try: rt=pb_entry['ringtones'][0]['ringtone'] for k, n in ringtone_index.items(): if rt==n.get('name', None): e[self.__pb_ringtone]=`k` break except: pass # name & alias/url e[self.__pb_name]='"'+nameparser.getfullname(\ pb_entry['names'][0])+'"' url='' try: url=pb_entry['urls'][0]['url'] except: pass e[self.__pb_alias]=url if len(url): e[self.__pb_alias+1]='0' else: e[self.__pb_alias+1]='' # numbers & speed dial # preset to empty for k in range(len(self.__pb_numbers)): for kk in self.__pb_numbers[k]: e[self.__pb_numbers[k][kk]]='' e[self.__pb_numbers[k][kk]+1]='' speed_dial='0' n=pb_entry.get('numbers', []) for k in range(len(n)): try: nk=n[k] kkk, kk=self._get_number_type(nk['type']) except: # invalid type, default to 'home' nk['type']='home' kkk, kk=0, self.__pb_home_num e[kk],e[kk+1]=self.phonize(nk['number']),'0' try: if nk['speeddial']: speed_dial=`kkk` except: pass e[self.__pb_speed_dial]=speed_dial # email email='' try: email=pb_entry['emails'][0]['email'] except: pass e[self.__pb_email]='"'+email+'"' # wallpaper: phonebook entry "caller id" image # Default: No image assigned e[self.__pb_image_assign]='5' e[self.__pb_image_id]='0' e[self.__pb_contact_image]='""' try: imgName = pb_entry['wallpapers'][0]['wallpaper'] image_index=data.get('wallpaper-index', {}) for k, n in image_index.items(): if imgName==n.get('name', None): if k>self.protocolclass.max_image_entries: # this is a 'Gallery' entry e[self.__pb_image_assign]='3' e[self.__pb_contact_image]='"'+self.__wp_photo_dir+'/'+imgName.split('.')[0]+'"' e[self.__pb_image_id]='0' else: # 'My Image' entry e[self.__pb_image_assign]='4' e[self.__pb_image_id]=`k` e[self.__pb_contact_image]='""' break except: pass for k in self.__pb_blanks: e[k]='' e[self.__pb_date_time_stamp]=self.get_time_stamp() # final check to determine if this entry has changed. # if it has not then do nothing an just return ee=self.get_phone_entry(int(e[self.__pb_entry])) if len(ee)==self.__pb_atpbokw_field_count: # DSV took the " out, need to put them back in for comparison ee[self.__pb_name]='"'+ee[self.__pb_name]+'"' ee[self.__pb_email]='"'+ee[self.__pb_email]+'"' ee[self.__pb_contact_image]='"'+ee[self.__pb_contact_image]+'"' # exclude the timestamp field k=self.__pb_atpbokw_field_count-1 if e[:k]==ee[:k]: return True return self.save_phone_entry('0,'+','.join(e))
def _write_phone_entry(self, pb_entry, groups, ringtone_index, phone_book): # setting up a list to send to the phone, all fields preset to '0' e=['0']*self.__pb_max_entries # setting the entry # and memory location # serials=self._my_serials(pb_entry) e[self.__pb_entry]=serials['serial1'] e[self.__pb_mem_loc]=serials['serial2'] # groups/categories grp=0 try: grp_name=pb_entry['categories'][0]['category'] for k in range(len(groups)): if groups[k]['name']==grp_name: grp=k break except: # invalid group or no group specified, default to group 0 grp, pb_entry['categories']=0, [{'category': groups[0]['name']}] e[self.__pb_group]=`grp` # ringtones e[self.__pb_ringtone]='0' # default to Inactive try: rt=pb_entry['ringtones'][0]['ringtone'] for k, n in ringtone_index.items(): if rt==n['name']: e[self.__pb_ringtone]=`k` break except: pass # name & alias e[self.__pb_name]='"'+nameparser.getfullname(pb_entry['names'][0])+'"' nick_name='' try: nick_name=pb_entry['names'][0]['nickname'] except: pass e[self.__pb_alias]=nick_name if len(nick_name): e[self.__pb_alias+1]='0' else: e[self.__pb_alias+1]='' # numbers & speed dial # preset to empty for k in range(len(self.__pb_numbers)): for kk in self.__pb_numbers[k]: e[self.__pb_numbers[k][kk]]='' e[self.__pb_numbers[k][kk]+1]='' speed_dial='0' n=pb_entry.get('numbers', []) for k in range(len(n)): try: nk=n[k] kkk, kk=self._get_number_type(nk['type']) except: # invalid type, default to 'home' nk['type']='home' kkk, kk=0, self.__pb_home_num e[kk],e[kk+1]=self.phonize(nk['number']),'0' try: if nk['speeddial']: speed_dial=`kkk` except: pass e[self.__pb_speed_dial]=speed_dial # email email='' try: email=pb_entry['emails'][0]['email'] except: pass e[self.__pb_email]='"'+email+'"' e[self.__pb_four]='4' for k in self.__pb_blanks: e[k]='' e[self.__pb_date_time_stamp]=self.get_time_stamp() # final check to determine if this entry has changed. # if it has not then do nothing and just return ee=self.get_phone_entry(int(e[self.__pb_entry]), self.__pb_alias, self.__pb_max_entries) if len(ee)==self.__pb_max_entries: # DSV took the " out, need to put them back in for comparison ee[self.__pb_name]='"'+ee[self.__pb_name]+'"' ee[self.__pb_email]='"'+ee[self.__pb_email]+'"' # set the correct ringtone index ee[self.__pb_ringtone]=str(phone_book.get_ringtone(\ int(e[self.__pb_mem_loc]))) k=self.__pb_max_entries-2 if e[0:k]==ee[0:k]: return True return self.save_phone_entry('0,'+','.join(e))
def _write_phone_entry(self, pb_entry, data): # setting up a list to send to the phone, all fields preset to '0' e = ['0'] * self.__pb_atpbokw_field_count # setting the entry # and memory location # serials = self._my_serials(pb_entry) e[self.__pb_entry] = serials['serial1'] e[self.__pb_mem_loc] = serials['serial2'] # groups/categories groups = data.get('groups', {}) e[self.__pb_group] = '0' try: grp_name = pb_entry['categories'][0]['category'] for k, n in groups.items(): if n.get('name', None) == grp_name: e[self.__pb_group] = ` k ` break except: pass # ringtones ringtone_index = data.get('ringtone-index', {}) e[self.__pb_ringtone] = '0' try: rt = pb_entry['ringtones'][0]['ringtone'] for k, n in ringtone_index.items(): if rt == n.get('name', None): e[self.__pb_ringtone] = ` k ` break except: pass # name & alias/url e[self.__pb_name]='"'+nameparser.getfullname(\ pb_entry['names'][0])+'"' url = '' try: url = pb_entry['urls'][0]['url'] except: pass e[self.__pb_alias] = url if len(url): e[self.__pb_alias + 1] = '0' else: e[self.__pb_alias + 1] = '' # numbers & speed dial # preset to empty for k in range(len(self.__pb_numbers)): for kk in self.__pb_numbers[k]: e[self.__pb_numbers[k][kk]] = '' e[self.__pb_numbers[k][kk] + 1] = '' speed_dial = '0' n = pb_entry.get('numbers', []) for k in range(len(n)): try: nk = n[k] kkk, kk = self._get_number_type(nk['type']) except: # invalid type, default to 'home' nk['type'] = 'home' kkk, kk = 0, self.__pb_home_num e[kk], e[kk + 1] = self.phonize(nk['number']), '0' try: if nk['speeddial']: speed_dial = ` kkk ` except: pass e[self.__pb_speed_dial] = speed_dial # email email = '' try: email = pb_entry['emails'][0]['email'] except: pass e[self.__pb_email] = '"' + email + '"' # wallpaper: phonebook entry "caller id" image # Default: No image assigned e[self.__pb_image_assign] = '5' e[self.__pb_image_id] = '0' e[self.__pb_contact_image] = '""' try: imgName = pb_entry['wallpapers'][0]['wallpaper'] image_index = data.get('wallpaper-index', {}) for k, n in image_index.items(): if imgName == n.get('name', None): if k > self.protocolclass.max_image_entries: # this is a 'Gallery' entry e[self.__pb_image_assign] = '3' e[self. __pb_contact_image] = '"' + self.__wp_photo_dir + '/' + imgName.split( '.')[0] + '"' e[self.__pb_image_id] = '0' else: # 'My Image' entry e[self.__pb_image_assign] = '4' e[self.__pb_image_id] = ` k ` e[self.__pb_contact_image] = '""' break except: pass for k in self.__pb_blanks: e[k] = '' e[self.__pb_date_time_stamp] = self.get_time_stamp() # final check to determine if this entry has changed. # if it has not then do nothing an just return ee = self.get_phone_entry(int(e[self.__pb_entry])) if len(ee) == self.__pb_atpbokw_field_count: # DSV took the " out, need to put them back in for comparison ee[self.__pb_name] = '"' + ee[self.__pb_name] + '"' ee[self.__pb_email] = '"' + ee[self.__pb_email] + '"' ee[self. __pb_contact_image] = '"' + ee[self.__pb_contact_image] + '"' # exclude the timestamp field k = self.__pb_atpbokw_field_count - 1 if e[:k] == ee[:k]: return True return self.save_phone_entry('0,' + ','.join(e))
def _write_phone_entry(self, pb_entry, groups, ringtone_index, phone_book): e=['0']*self.__pb_max_entries serials=self._my_serials(pb_entry) e[self.__pb_entry]=serials['serial1'] e[self.__pb_mem_loc]=serials['serial2'] grp=0 try: grp_name=pb_entry['categories'][0]['category'] for k in range(len(groups)): if groups[k]['name']==grp_name: grp=k break except: grp, pb_entry['categories']=0, [{'category': groups[0]['name']}] e[self.__pb_group]=`grp` e[self.__pb_ringtone]='0' try: rt=pb_entry['ringtones'][0]['ringtone'] for k, n in ringtone_index.items(): if rt==n['name']: e[self.__pb_ringtone]=`k` break except: pass e[self.__pb_name]='"'+nameparser.getfullname(pb_entry['names'][0])+'"' nick_name='' try: nick_name=pb_entry['names'][0]['nickname'] except: pass e[self.__pb_alias]=nick_name if len(nick_name): e[self.__pb_alias+1]='0' else: e[self.__pb_alias+1]='' for k in range(len(self.__pb_numbers)): for kk in self.__pb_numbers[k]: e[self.__pb_numbers[k][kk]]='' e[self.__pb_numbers[k][kk]+1]='' speed_dial='0' n=pb_entry.get('numbers', []) for k in range(len(n)): try: nk=n[k] kkk, kk=self._get_number_type(nk['type']) except: nk['type']='home' kkk, kk=0, self.__pb_home_num e[kk],e[kk+1]=self.phonize(nk['number']),'0' try: if nk['speeddial']: speed_dial=`kkk` except: pass e[self.__pb_speed_dial]=speed_dial email='' try: email=pb_entry['emails'][0]['email'] except: pass e[self.__pb_email]='"'+email+'"' e[self.__pb_four]='4' for k in self.__pb_blanks: e[k]='' e[self.__pb_date_time_stamp]=self.get_time_stamp() ee=self.get_phone_entry(int(e[self.__pb_entry]), self.__pb_alias, self.__pb_max_entries) if len(ee)==self.__pb_max_entries: ee[self.__pb_name]='"'+ee[self.__pb_name]+'"' ee[self.__pb_email]='"'+ee[self.__pb_email]+'"' ee[self.__pb_ringtone]=str(phone_book.get_ringtone(\ int(e[self.__pb_mem_loc]))) k=self.__pb_max_entries-2 if e[0:k]==ee[0:k]: return True return self.save_phone_entry('0,'+','.join(e)) def getringtones(self, result): self.setmode(self.MODEBREW) m=FileEntries(self, self.__ringtone_info) rt_info=RingtoneIndex(self).get_download_info() r=m.get_media(result, rt_info) self.setmode(self.MODEMODEM) return r def saveringtones(self, result, merge): self.setmode(self.MODEBREW) m=FileEntries(self, self.__ringtone_info) result['rebootphone']=1 r=m.save_media(result, RingtoneIndex(self).get_download_info()) self.setmode(self.MODEMODEM) return r def getwallpapers(self, result): self.setmode(self.MODEBREW) m=FileEntries(self, self.__wallpaper_info) img_info=ImageIndex(self).get_download_info() r=m.get_media(result, img_info) self.setmode(self.MODEMODEM) return r def savewallpapers(self, result, merge): self.setmode(self.MODEBREW) m=FileEntries(self, self.__wallpaper_info) r=m.save_media(result, ImageIndex(self).get_download_info()) result['rebootphone']=1 self.setmode(self.MODEMODEM) return r getmemo=parent_phone._getmemo savememo=parent_phone._savememo gettodo=parent_phone._gettodo savetodo=parent_phone._savetodo getsms=parent_phone._getsms savesms=parent_phone._savesms getphoneinfo=parent_phone._getphoneinfo getmedia=None detectphone=staticmethod(parent_phone._detectphone) "Talk to the Samsung SCH-A650 Cell Phone" class Profile (com_samsung.Profile) : serialsname='scha650' WALLPAPER_WIDTH=128 WALLPAPER_HEIGHT=160 MAX_WALLPAPER_BASENAME_LENGTH=17 WALLPAPER_FILENAME_CHARS="abcdefghijklmnopqrstuvwxyz0123456789_*[]=<>;|?:% ." WALLPAPER_CONVERT_FORMAT="png" MAX_RINGTONE_BASENAME_LENGTH=17 RINGTONE_FILENAME_CHARS="abcdefghijklmnopqrstuvwxyz0123456789_*[]=<>;|?:% ." RINGTONE_LIMITS= { 'MAXSIZE': 30000 } phone_manufacturer='SAMSUNG ELECTRONICS' phone_model='SCH-A650/163' def __init__(self): com_samsung.Profile.__init__(self) _supportedsyncs=( ('phonebook', 'read', None), ('phonebook', 'write', 'OVERWRITE'), ('calendar', 'read', None), ('calendar', 'write', 'OVERWRITE'), ('ringtone', 'read', None), ('ringtone', 'write', 'OVERWRITE'), ('wallpaper', 'read', None), ('wallpaper', 'write', 'OVERWRITE'), ('memo', 'read', None), ('memo', 'write', 'OVERWRITE'), ('todo', 'read', None), ('todo', 'write', 'OVERWRITE'), ('sms', 'read', None), ) if __debug__: _supportedsyncs+=(('sms', 'write', 'OVERWRITE'),) def convertphonebooktophone(self, helper, data): return data __audio_ext={ 'MIDI': 'mid', 'QCP': 'qcp', 'PMD': 'pmd' } def QueryAudio(self, origin, currentextension, afi): if afi.format in ("MIDI", "QCP", "PMD"): for k,n in self.RINGTONE_LIMITS.items(): setattr(afi, k, n) return currentextension, afi d=self.RINGTONE_LIMITS.copy() d['format']='QCP' return ('qcp', fileinfo.AudioFileInfo(afi, **d)) imageorigins={} imageorigins.update(common.getkv(com_samsung.Profile.stockimageorigins, "images")) imagetargets={} imagetargets.update(common.getkv(com_samsung.Profile.stockimagetargets, "wallpaper", {'width': 128, 'height': 128, 'format': "PNG"})) imagetargets.update(common.getkv(com_samsung.Profile.stockimagetargets, "fullscreen", {'width': 128, 'height': 160, 'format': "PNG"})) def GetImageOrigins(self): return self.imageorigins def GetTargetsForImageOrigin(self, origin): if origin=='images': return self.imagetargets if __debug__: _supportedsyncs+=(('sms', 'write', 'OVERWRITE'),) imageorigins.update(common.getkv(com_samsung.Profile.stockimageorigins, "images")) imagetargets.update(common.getkv(com_samsung.Profile.stockimagetargets, "wallpaper", {'width': 128, 'height': 128, 'format': "PNG"})) imagetargets.update(common.getkv(com_samsung.Profile.stockimagetargets, "fullscreen", {'width': 128, 'height': 160, 'format': "PNG"}))
def _save_sim_phonebook(self, entries, groups): """ got the the phonebook dict and write them out to the phone""" _pb_list=[(nameparser.getfullname(e['names'][0]), k) \ for k,e in entries.items() if self._in_sim(e)] _pb_list.sort() _req=self.protocolclass.select_storage_req() _req.storage=self.protocolclass.PB_MEMORY_SIM self.sendATcommand(_req, None) _del_entry=self.protocolclass.del_phonebook_req() _index=self.protocolclass.PB_SIM_MIN_INDEX for l in _pb_list: _del_entry.index=_index _index+=1 self.sendATcommand(_del_entry, None) time.sleep(0.2) _req=self._build_sim_entry(entries[l[1]], groups) self.progress(_index, self.protocolclass.PB_SIM_MAX_INDEX, 'Writing SIM entry %d: %s'%(_index, _req.name)) try: self.sendATcommand(_req, None) _retry=False except: _retry=True if _retry: try: self.sendATcommand(_req, None) except: self.log('Failed to write SIM entry %d: %s'%(_index, _req.name)) time.sleep(0.2) for i in range(_index, self.protocolclass.PB_SIM_MAX_INDEX+1): self.progress(i, self.protocolclass.PB_SIM_MAX_INDEX, 'Deleting SIM entry %d'%i) try: _del_entry.index=i self.sendATcommand(_del_entry, None) continue except: self.log('Trying to delete entry %d'%i) try: self.sendATcommand(_del_entry, None) except: self.log('Failed to delete entry %d'%i) def savephonebook(self, data): "Saves out the phonebook" self.log('Writing phonebook') self.setmode(self.MODEMODEM) self.charset_ascii() pb_book=data.get('phonebook', {}) pb_groups=data.get('groups', {}) self._save_main_phonebook(pb_book, pb_groups) self._save_sim_phonebook(pb_book, pb_groups) return data def _del_media_files(self, names): self.charset_ascii() _req=self.protocolclass.del_media_req() for n in names: self.log('Deleting media %s'%n) _req.file_name=n try: self.sendATcommand(_req, None) except: self.log('Failed to delete media %s'%n) def _add_media_file(self, file_name, media_name, media_code, data): """ Add one media ringtone """ if not file_name or not media_name or not data: return False self.log('Writing media %s'%file_name) _media_name='' for s in media_name: _media_name+=s+'\x00' _cmd='AT+DDLW=0,"%s","%s",%d,%d,0,0,0,0\r' % \ (file_name, base64.encodestring(_media_name), len(data), media_code) _data64=base64.encodestring(data) self.comm.write(str(_cmd)) if self.comm.read(4)!='\r\n> ': return False for l in _data64.split('\n'): if l: self.comm.write(l+'\n') time.sleep(0.01) self.comm.write(str('\x1A')) return self.comm.read(6)=='\r\nOK\r\n' def _add_ringtones(self, names, name_dict, media): self.charset_base64() for n in names: _media_key=name_dict[n] if not self._add_media_file(n, common.stripext(n), 20, media[_media_key].get('data', '')): self.log('Failed to send ringtone %s'%n) self.charset_ascii() def saveringtones(self, result, merge): self.log('Saving ringtones') self.setmode(self.MODEMODEM) self.charset_ascii() self._ringtone_mode() media=result.get('ringtone', {}) media_index=result.get('ringtone-index', {}) media_names=[x['name'] for x in media.values()] index_names=[x['name'] for x in media_index.values()] del_names=[x for x in index_names if x not in media_names] new_names=[x for x in media_names if x not in index_names] self._del_media_files(del_names) names_to_keys={} for k,e in media.items(): names_to_keys[e['name']]=k self._add_ringtones(new_names, names_to_keys, media) return result def getringtones(self, result): self.log('Reading ringtones index') self.setmode(self.MODEMODEM) self.charset_ascii() self._ringtone_mode() media={} media_index=self._get_ringtone_index() for e in media_index.values(): media[e['name']]='dummy data' result['ringtone']=media result['ringtone-index']=media_index return result def getwallpapers(self, result): self.log('Reading wallpaper index') self.setmode(self.MODEMODEM) self.charset_ascii() self._wallpaper_mode() media={} media_index=self._get_wallpaper_index() _dummy_data=file(guihelper.getresourcefile('wallpaper.png'),'rb').read() for e in media_index.values(): media[e['name']]=_dummy_data result['wallpapers']=media result['wallpaper-index']=media_index return result def _add_wallpapers(self, names, name_dict, media): self.charset_base64() for n in names: _media_key=name_dict[n] if not self._add_media_file(n, common.stripext(n), 12, media[_media_key].get('data', '')): self.log('Failed to send wallpaper %s'%n) self.charset_ascii() def savewallpapers(self, result, merge): self.log('Saving wallpapers') self.setmode(self.MODEMODEM) self.charset_ascii() self._wallpaper_mode() media=result.get('wallpapers', {}) media_index=result.get('wallpaper-index', {}) media_names=[x['name'] for x in media.values()] index_names=[x['name'] for x in media_index.values()] del_names=[x for x in index_names if x not in media_names] new_names=[x for x in media_names if x not in index_names] self._del_media_files(del_names) names_to_keys={} for k,e in media.items(): names_to_keys[e['name']]=k self._add_wallpapers(new_names, names_to_keys, media) return result def getmemo(self, result): self.log('Reading Memo') self.setmode(self.MODEMODEM) self.charset_ascii() _req=self.protocolclass.memo_read_req() _res=self.sendATcommand(_req, self.protocolclass.memo_read_resp) res={} for e in _res: _memo=memo.MemoEntry() _memo.text=e.text res[_memo.id]=_memo result['memo']=res return res def savememo(self, result, merge): self.log('Writing Memo') self.setmode(self.MODEMODEM) self.charset_ascii() _req=self.protocolclass.memo_del_req() for i in range(self.protocolclass.MEMO_MIN_INDEX, self.protocolclass.MEMO_MAX_INDEX+1): _req.index=i try: self.sendATcommand(_req, None) except: pass _memo_dict=result.get('memo', {}) _keys=_memo_dict.keys() _keys.sort() _req=self.protocolclass.memo_write_req() for k in _keys: _req.text=_memo_dict[k].text try: self.sendATcommand(_req, None) except: self.log('Failed to write memo %s'%_req.text) return _memo_dict def _process_sms(self, _resp, res): for i in range(0, len(_resp), 2): try: _entry=self.protocolclass.sms_msg_list_header() _buf=prototypes.buffer(_resp[i]) _entry.readfrombuffer(_buf) _sms=sms.SMSEntry() if _entry.msg_type==self.protocolclass.SMS_MSG_REC_UNREAD or \ _entry.msg_type==self.protocolclass.SMS_MSG_REC_READ: _sms._from=_entry.address _sms.folder=sms.SMSEntry.Folder_Inbox _sms.read=_entry.msg_type==self.protocolclass.SMS_MSG_REC_READ elif _entry.msg_type==self.protocolclass.SMS_MSG_STO_SENT: _sms.add_recipient(_entry.address) _sms.folder=sms.SMSEntry.Folder_Sent elif _entry.msg_type==self.protocolclass.SMS_MSG_STO_UNSENT: _sms.folder=sms.SMSEntry.Folder_Saved _sms.add_recipient(_entry.address) else: self.log('Unknown message type: %s'%_entry.msg_type) _sms=None if _sms: if _entry.timestamp: _sms.datetime=_entry.timestamp _sms.text=_resp[i+1] res[_sms.id]=_sms except: if __debug__: raise return res def getsms(self, result): self.log('Getting SMS Messages') self.setmode(self.MODEMODEM) self.charset_ascii() res={} _req=self.protocolclass.sms_format_req() self.sendATcommand(_req, None) self.log('Getting SMS messages from the phone memory') _sms_mem=self.protocolclass.sms_memory_select_req() _sms_mem.list_memory=self.protocolclass.SMS_MEMORY_PHONE self.sendATcommand(_sms_mem, None) _list_sms=self.protocolclass.sms_msg_list_req() _resp=self.sendATcommand(_list_sms, None) self._process_sms(_resp, res) self.log('Getting SMS message from the SIM card') _sms_mem.list_memory=self.protocolclass.SMS_MEMORY_SIM self.sendATcommand(_sms_mem, None) _resp=self.sendATcommand(_list_sms, None) self._process_sms(_resp, res) try: self.sendATcommand(_sms_mem, None) except commport.ATError: pass result['sms']=res return result def _get_history_calls(self, log_str, call_type, min_idx, max_idx): self.log(log_str) _sel_mem=self.protocolclass.select_storage_req() _sel_mem.storage=call_type self.sendATcommand(_sel_mem, None) _list_pb=self.protocolclass.read_phonebook_req() _list_pb.start_index=min_idx _list_pb.end_index=max_idx self.sendATcommand(_list_pb, None) def getcallhistory(self, result): self.log('Getting Call History') self.setmode(self.MODEMODEM) self.charset_ascii() res={} for l in self.protocolclass.PB_CALL_HISTORY_INFO: self._get_history_calls(*l) result['call_history']=res return result """ Talk to the LG G4015 Phone""" parent_profile=com_gsm.Profile class Profile (parent_profile) : serialsname=Phone.serialsname WALLPAPER_WIDTH=128 WALLPAPER_HEIGHT=128 MAX_WALLPAPER_BASENAME_LENGTH=19 WALLPAPER_FILENAME_CHARS="abcdefghijklmnopqrstuvwxyz0123456789_ ." WALLPAPER_CONVERT_FORMAT="jpg" MAX_RINGTONE_BASENAME_LENGTH=19 RINGTONE_FILENAME_CHARS="abcdefghijklmnopqrstuvwxyz0123456789_ ." RINGTONE_LIMITS= { 'MAXSIZE': 20480 } phone_manufacturer='LGE' phone_model='G4015' usbids=( ( 0x10AB, 0x10C5, 1), ) deviceclasses=("serial",) imageorigins={} imageorigins.update(common.getkv(parent_profile.stockimageorigins, "images")) imagetargets={} imagetargets.update(common.getkv(parent_profile.stockimagetargets, "wallpaper", {'width': 128, 'height': 128, 'format': "JPEG"})) def GetImageOrigins(self): return self.imageorigins def GetTargetsForImageOrigin(self, origin): if origin=='images': return self.imagetargets def __init__(self): parent_profile.__init__(self) _supportedsyncs=( ('phonebook', 'read', None), ('phonebook', 'write', 'OVERWRITE'), ('calendar', 'read', None), ('calendar', 'write', 'OVERWRITE'), ('ringtone', 'read', None), ('ringtone', 'write', 'OVERWRITE'), ('wallpaper', 'read', None), ('wallpaper', 'write', 'OVERWRITE'), ('memo', 'read', None), ('memo', 'write', 'OVERWRITE'), ('sms', 'read', None), ('call_history', 'read', None), ) def convertphonebooktophone(self, helper, data): return data imageorigins.update(common.getkv(parent_profile.stockimageorigins, "images")) imagetargets.update(common.getkv(parent_profile.stockimagetargets, "wallpaper", {'width': 128, 'height': 128, 'format': "JPEG"}))
def _write_phone_entry(self, pb_entry, groups, ringtone_index, phone_book): e=['0']*self.__pb_max_entries serials=self._my_serials(pb_entry) e[self.__pb_entry]=serials['serial1'] e[self.__pb_mem_loc]=serials['serial2'] grp=0 try: grp_name=pb_entry['categories'][0]['category'] for k in range(len(groups)): if groups[k]['name']==grp_name: grp=k break except: grp, pb_entry['categories']=0, [{'category': groups[0]['name']}] e[self.__pb_group]=`grp` e[self.__pb_ringtone]='0' # default to Inactive try: rt=pb_entry['ringtones'][0]['ringtone'] for k, n in ringtone_index.items(): if rt==n['name']: e[self.__pb_ringtone]=`k` break except: pass e[self.__pb_name]='"'+nameparser.getfullname(pb_entry['names'][0])+'"' nick_name='' try: nick_name=pb_entry['names'][0]['nickname'] except: pass e[self.__pb_alias]=nick_name if len(nick_name): e[self.__pb_alias+1]='0' else: e[self.__pb_alias+1]='' for k in range(len(self.__pb_numbers)): for kk in self.__pb_numbers[k]: e[self.__pb_numbers[k][kk]]='' e[self.__pb_numbers[k][kk]+1]='' speed_dial='0' n=pb_entry.get('numbers', []) for k in range(len(n)): try: nk=n[k] kkk, kk=self._get_number_type(nk['type']) except: nk['type']='home' kkk, kk=0, self.__pb_home_num e[kk],e[kk+1]=self.phonize(nk['number']),'0' try: if nk['speeddial']: speed_dial=`kkk` except: pass e[self.__pb_speed_dial]=speed_dial email='' try: email=pb_entry['emails'][0]['email'] except: pass e[self.__pb_email]='"'+email+'"' e[self.__pb_four]='4' for k in self.__pb_blanks: e[k]='' e[self.__pb_date_time_stamp]=self.get_time_stamp() ee=self.get_phone_entry(int(e[self.__pb_entry]), self.__pb_alias, self.__pb_max_entries) if len(ee)==self.__pb_max_entries: ee[self.__pb_name]='"'+ee[self.__pb_name]+'"' ee[self.__pb_email]='"'+ee[self.__pb_email]+'"' ee[self.__pb_ringtone]=str(phone_book.get_ringtone(\ int(e[self.__pb_mem_loc]))) k=self.__pb_max_entries-2 if e[0:k]==ee[0:k]: return True return self.save_phone_entry('0,'+','.join(e))
def __validate_entry(self, pb_entry, pb_groups, ringtone_index): try: name=nameparser.getfullname(pb_entry['names'][0]).replace('"', '') if len(name)>self.__pb_max_name_len: name=name[:self.__pb_max_name_len] pb_entry['names'][0].setdefault('full', name) if pb_entry['names'][0].has_key('nickname'): name=re.sub('[,"]', '', pb_entry['names'][0]['nickname']) if len(name)>self.__pb_max_name_len: name=name[:self.__pb_max_name_len] if pb_entry['names'][0]['nickname']!=name: pb_entry['names'][0]['nickname']=name has_number_or_email=False if pb_entry.has_key('numbers'): for n in pb_entry['numbers']: num=self.phonize(n['number']) if len(num)>self.__pb_max_number_len: num=num[:self.__pb_max_number_len] if num != n['number']: self.log('Updating number from '+n['number']+' to '+num) n['number']=num try: self._get_number_type(n['type']) except: self.log(n['number']+': setting type to home.') n['type']='home' has_number_or_email=True if pb_entry.has_key('emails'): if len(pb_entry['emails'])>self.__pb_max_emails: self.log(name+': Each entry can only have %s emails. The rest will be ignored.'%str(self.__pb_max_emails)) email=pb_entry['emails'][0]['email'].replace('"', '') if len(email)>self.__pb_max_number_len: email=email[:self.__pb_max_number_len] if email!=pb_entry['emails'][0]['email']: pb_entry['emails'][0]['email']=email has_number_or_email=True if not has_number_or_email: self.log(name+': Entry has no numbers or emails') return False found=False if pb_entry.has_key('categories') and len(pb_entry['categories']): pb_cat=pb_entry['categories'][0]['category'] for k in pb_groups: if pb_groups[k]['name']==pb_cat: found=True break if not found: self.log(name+': category set to '+pb_groups[0]['name']) pb_entry['categories']=[{'category': pb_groups[0]['name']}] found=False if pb_entry.has_key('ringtones') and len(pb_entry['ringtones']): pb_rt=pb_entry['ringtones'][0]['ringtone'] for k, rt in ringtone_index.items(): if pb_rt==rt['name']: found=True break if not found: rt=ringtone_index[0]['name'] self.log(name+': ringtone set to '+rt) pb_entry['ringtones']=[{'ringtone': rt, 'use': 'call' }] return True except: raise
def _write_phone_entry(self, pb_entry, data): e=['0']*self.__pb_atpbokw_field_count serials=self._my_serials(pb_entry) e[self.__pb_entry]=serials['serial1'] e[self.__pb_mem_loc]=serials['serial2'] groups=data.get('groups', {}) e[self.__pb_group]='0' try: grp_name=pb_entry['categories'][0]['category'] for k, n in groups.items(): if n.get('name', None)==grp_name: e[self.__pb_group]=`k` break except: pass ringtone_index=data.get('ringtone-index', {}) e[self.__pb_ringtone]='0' try: rt=pb_entry['ringtones'][0]['ringtone'] for k, n in ringtone_index.items(): if rt==n.get('name', None): e[self.__pb_ringtone]=`k` break except: pass e[self.__pb_name]='"'+nameparser.getfullname(\ pb_entry['names'][0])+'"' url='' try: url=pb_entry['urls'][0]['url'] except: pass e[self.__pb_alias]=url if len(url): e[self.__pb_alias+1]='0' else: e[self.__pb_alias+1]='' for k in range(len(self.__pb_numbers)): for kk in self.__pb_numbers[k]: e[self.__pb_numbers[k][kk]]='' e[self.__pb_numbers[k][kk]+1]='' speed_dial='0' n=pb_entry.get('numbers', []) for k in range(len(n)): try: nk=n[k] kkk, kk=self._get_number_type(nk['type']) except: nk['type']='home' kkk, kk=0, self.__pb_home_num e[kk],e[kk+1]=self.phonize(nk['number']),'0' try: if nk['speeddial']: speed_dial=`kkk` except: pass e[self.__pb_speed_dial]=speed_dial email='' try: email=pb_entry['emails'][0]['email'] except: pass e[self.__pb_email]='"'+email+'"' e[self.__pb_image_assign]='5' e[self.__pb_image_id]='0' e[self.__pb_contact_image]='""' try: imgName = pb_entry['wallpapers'][0]['wallpaper'] image_index=data.get('wallpaper-index', {}) for k, n in image_index.items(): if imgName==n.get('name', None): if k>self.protocolclass.max_image_entries: e[self.__pb_image_assign]='3' e[self.__pb_contact_image]='"'+self.__wp_photo_dir+'/'+imgName.split('.')[0]+'"' e[self.__pb_image_id]='0' else: e[self.__pb_image_assign]='4' e[self.__pb_image_id]=`k` e[self.__pb_contact_image]='""' break except: pass for k in self.__pb_blanks: e[k]='' e[self.__pb_date_time_stamp]=self.get_time_stamp() ee=self.get_phone_entry(int(e[self.__pb_entry])) if len(ee)==self.__pb_atpbokw_field_count: ee[self.__pb_name]='"'+ee[self.__pb_name]+'"' ee[self.__pb_email]='"'+ee[self.__pb_email]+'"' ee[self.__pb_contact_image]='"'+ee[self.__pb_contact_image]+'"' k=self.__pb_atpbokw_field_count-1 if e[:k]==ee[:k]: return True return self.save_phone_entry('0,'+','.join(e)) def getringtones(self, result): self.setmode(self.MODEBREW) m=FileEntries(self, self.__ringtone_info) rt_info=RingtoneIndex(self).get_download_info() r=m.get_media(result, rt_info) self.setmode(self.MODEMODEM) return r def saveringtones(self, result, merge): self.setmode(self.MODEBREW) m=FileEntries(self, self.__ringtone_info) result['rebootphone']=1 r=m.save_media(result, RingtoneIndex(self).get_download_info()) self.setmode(self.MODEMODEM) return r def getwallpapers(self, result): self.setmode(self.MODEBREW) m=FileEntries(self, self.__wallpaper_info) img_info=ImageIndex(self).get_download_info() m.get_media(result, img_info) FileEntries(self, self.__video0_info).get_video(result, 'Video001.avi') r=FileEntries(self, self.__video1_info).get_video(result, 'Video002.avi') self.setmode(self.MODEMODEM) return r def savewallpapers(self, result, merge): self.setmode(self.MODEBREW) m=FileEntries(self, self.__wallpaper_info) r=m.save_media(result, ImageIndex(self).get_download_info()) result['rebootphone']=1 self.setmode(self.MODEMODEM) return r getmemo=parent_phone._getmemo savememo=parent_phone._savememo gettodo=parent_phone._gettodo savetodo=parent_phone._savetodo getsms=parent_phone._getsms savesms=parent_phone._savesms getphoneinfo=parent_phone._getphoneinfo getmedia=None detectphone=staticmethod(parent_phone._detectphone) "Talk to the Samsung SCH-A670 Cell Phone" class Profile (com_samsung.Profile) : serialsname='scha670' WALLPAPER_WIDTH=128 WALLPAPER_HEIGHT=128 MAX_WALLPAPER_BASENAME_LENGTH=19 WALLPAPER_FILENAME_CHARS="abcdefghijklmnopqrstuvwxyz0123456789_ ." WALLPAPER_CONVERT_FORMAT="jpg" MAX_RINGTONE_BASENAME_LENGTH=19 RINGTONE_FILENAME_CHARS="abcdefghijklmnopqrstuvwxyz0123456789_ ." RINGTONE_LIMITS= { 'MAXSIZE': 30000 } phone_manufacturer='SAMSUNG ELECTRONICS' phone_model='SCH-A670/164' def __init__(self): com_samsung.Profile.__init__(self) _supportedsyncs=( ('phonebook', 'read', None), ('phonebook', 'write', 'OVERWRITE'), ('calendar', 'read', None), ('calendar', 'write', 'OVERWRITE'), ('ringtone', 'read', None), ('ringtone', 'write', 'OVERWRITE'), ('wallpaper', 'read', None), ('wallpaper', 'write', 'OVERWRITE'), ('memo', 'read', None), ('memo', 'write', 'OVERWRITE'), ('todo', 'read', None), ('todo', 'write', 'OVERWRITE'), ('sms', 'read', None), ) if __debug__: _supportedsyncs+=(('sms', 'write', 'OVERWRITE'),) def convertphonebooktophone(self, helper, data): return data __audio_ext={ 'MIDI': 'mid', 'PMD': 'pmd', 'QCP': 'pmd' } def QueryAudio(self, origin, currentextension, afi): if afi.format in ("MIDI", "PMD", "QCP"): for k,n in self.RINGTONE_LIMITS.items(): setattr(afi, k, n) return currentextension, afi d=self.RINGTONE_LIMITS.copy() d['format']='QCP' return ('pmd', fileinfo.AudioFileInfo(afi, **d)) imageorigins={} imageorigins.update(common.getkv(com_samsung.Profile.stockimageorigins, "images")) imagetargets={} imagetargets.update(common.getkv(com_samsung.Profile.stockimagetargets, "wallpaper", {'width': 128, 'height': 128, 'format': "PNG"})) imagetargets.update(common.getkv(com_samsung.Profile.stockimagetargets, "fullscreen", {'width': 128, 'height': 160, 'format': "PNG"})) imagetargets.update(common.getkv(com_samsung.Profile.stockimagetargets, "pictureid", {'width': 96, 'height': 96, 'format': "JPEG"})) def GetImageOrigins(self): return self.imageorigins def GetTargetsForImageOrigin(self, origin): if origin=='images': return self.imagetargets if __debug__: _supportedsyncs+=(('sms', 'write', 'OVERWRITE'),) imageorigins.update(common.getkv(com_samsung.Profile.stockimageorigins, "images")) imagetargets.update(common.getkv(com_samsung.Profile.stockimagetargets, "wallpaper", {'width': 128, 'height': 128, 'format': "PNG"})) imagetargets.update(common.getkv(com_samsung.Profile.stockimagetargets, "fullscreen", {'width': 128, 'height': 160, 'format': "PNG"})) imagetargets.update(common.getkv(com_samsung.Profile.stockimagetargets, "pictureid", {'width': 96, 'height': 96, 'format': "JPEG"}))
def savephonebook(self, data): "Saves out the phonebook" pb_book=data['phonebook'] pb_groups=data['groups'] ringtone_index=data.get('ringtone-index', {}) self.log('Validating phonebook entries.') del_entries=[] for k in pb_book: if not self.__validate_entry(pb_book[k], pb_groups, ringtone_index): self.log('Invalid entry, entry will be not be sent.') del_entries.append(k) for k in del_entries: self.log('Deleting entry '+\ nameparser.getfullname(pb_book[k]['names'][0])) del pb_book[k] self._has_duplicate_speeddial(pb_book) self.log('All entries validated') pb_locs=[False]*(len(self.__phone_entries_range)+1) pb_mem=[False]*len(pb_locs) self.log("Getting current phonebook from the phone") self.setmode(self.MODEBREW) phone_book=PhoneBook(self) phone_book.read() current_pb=phone_book.get_dict(data) self.setmode(self.MODEMODEM) self.log("Processing speeddial data") for k in pb_book: self._update_speeddial(pb_book[k]) self.setmode(self.MODEPHONEBOOK) self.log("Processing deleted entries") for k1 in current_pb: s1=current_pb[k1]['serials'][0]['serial1'] found=False for k2 in pb_book: if self._same_serial1(s1, pb_book[k2]): found=True break if found: pb_locs[int(current_pb[k1]['serials'][0]['serial1'])]=True pb_mem[int(current_pb[k1]['serials'][0]['serial2'])]=True else: self.log("Deleted item: "+\ nameparser.getfullname(current_pb[k1]['names'][0])) self.progress(0, 10, "Deleting "+\ nameparser.getfullname(\ current_pb[k1]['names'][0])) self._del_phone_entry(current_pb[k1]) mem_idx, loc_idx = self.__pb_max_speeddials, 1 self.log("Processing new & updated entries") serials_update=[] progresscur, progressmax=1,len(pb_book) for k in pb_book: if progresscur>len(self.__phone_entries_range): self.log('Max phone entries exceeded: '+str(progresscur)) break e=pb_book[k] if not self._has_serial1(e): while pb_locs[loc_idx]: loc_idx += 1 pb_locs[loc_idx]=True sd=self._get_speeddial(e) if sd: mem_index=sd pb_mem[sd]=True else: while pb_mem[mem_idx]: mem_idx -= 1 pb_mem[mem_idx]=True mem_index=mem_idx self._set_speeddial(e, mem_idx) s1={ 'sourcetype': self.serialsname, 'sourceuniqueid': data['uniqueserial'], 'serial1': `loc_idx`, 'serial2': `mem_index` } e['serials'].append(s1) self.log("New entries: Name: "+\ nameparser.getfullname(e['names'][0])+\ ", s1: "+`loc_idx`+", s2: "+`mem_index`) serials_update.append((self._bitpim_serials(e), s1)) self.progress(progresscur, progressmax, "Updating "+\ nameparser.getfullname(e['names'][0])) if not self._write_phone_entry(e, pb_groups, ringtone_index, phone_book): self.log("Failed to save entry: "+\ nameparser.getfullname(e['names'][0])) progresscur += 1 data["serialupdates"]=serials_update self.log("Done") self.setmode(self.MODEMODEM) return data
def __validate_entry(self, pb_entry, pb_groups, ringtone_index): try: name=nameparser.getfullname(pb_entry['names'][0]).replace('"', '') if len(name)>self.__pb_max_name_len: name=name[:self.__pb_max_name_len] pb_entry['names'][0].setdefault('full', name) if pb_entry['names'][0].has_key('nickname'): name=re.sub('[,"]', '', pb_entry['names'][0]['nickname']) if len(name)>self.__pb_max_name_len: name=name[:self.__pb_max_name_len] if pb_entry['names'][0]['nickname']!=name: pb_entry['names'][0]['nickname']=name has_number_or_email=False if pb_entry.has_key('numbers'): for n in pb_entry['numbers']: num=self.phonize(n['number']) if len(num)>self.__pb_max_number_len: num=num[:self.__pb_max_number_len] if num != n['number']: self.log('Updating number from '+n['number']+' to '+num) n['number']=num try: self._get_number_type(n['type']) except: self.log(n['number']+': setting type to home.') n['type']='home' has_number_or_email=True if pb_entry.has_key('emails'): if len(pb_entry['emails'])>self.__pb_max_emails: self.log(name+': Each entry can only have %s emails. The rest will be ignored.'%str(self.__pb_max_emails)) email=pb_entry['emails'][0]['email'].replace('"', '') if len(email)>self.__pb_max_number_len: email=email[:self.__pb_max_number_len] if email!=pb_entry['emails'][0]['email']: pb_entry['emails'][0]['email']=email has_number_or_email=True if not has_number_or_email: self.log(name+': Entry has no numbers or emails') return False found=False if pb_entry.has_key('categories') and len(pb_entry['categories']): pb_cat=pb_entry['categories'][0]['category'] for k in pb_groups: if pb_groups[k]['name']==pb_cat: found=True break if not found: self.log(name+': category set to '+pb_groups[0]['name']) pb_entry['categories']=[{'category': pb_groups[0]['name']}] found=False if pb_entry.has_key('ringtones') and len(pb_entry['ringtones']): pb_rt=pb_entry['ringtones'][0]['ringtone'] for k, rt in ringtone_index.items(): if pb_rt==rt['name']: found=True break if not found: rt=ringtone_index[0]['name'] self.log(name+': ringtone set to '+rt) pb_entry['ringtones']=[{'ringtone': rt, 'use': 'call' }] return True except: raise def _has_duplicate_speeddial(self, pb_book): b=[False]*(self.__pb_max_speeddials+1) for k in pb_book: try: for k1, kk in enumerate(pb_book[k]['numbers']): sd=kk['speeddial'] if sd and b[sd]: del pb_book[k]['numbers'][k1]['speeddial'] self.log('speeddial %d exists, deleted'%sd) else: b[sd]=True except: pass return False def _update_speeddial(self, pb_entry): try: s=self._my_serials(pb_entry) s1=int(s['serial2']) sd=self._get_speeddial(pb_entry) if not sd: self._set_speeddial(pb_entry, s1) elif sd!=s1: self._del_my_serials(pb_entry) except: pass def _get_speeddial(self, pb_entry): n=pb_entry.get('numbers', []) for k in n: try: if k['speeddial']: return k['speeddial'] except: pass return 0 def _set_speeddial(self, pb_entry, sd): if not pb_entry.has_key('numbers'): return for k in pb_entry['numbers']: if k.has_key('speeddial'): k['speeddial']=sd return pb_entry['numbers'][0]['speeddial']=sd def _del_phone_entry(self, pb_entry): try: return self.save_phone_entry(self._my_serials(pb_entry)['serial1']) except: return False def _same_serial1(self, s1, pb_entry): for k in pb_entry['serials']: if k['sourcetype']==self.serialsname and k.has_key('serial1'): return k['serial1']==s1 return False def _has_serial1(self, pb_entry): for k in pb_entry['serials']: if k['sourcetype']==self.serialsname and k.has_key('serial1'): return True return False def _bitpim_serials(self, pb_entry): for k in pb_entry['serials']: if k['sourcetype']=="bitpim": return k return {} def _del_my_serials(self, pb_entry): for k in range(len(pb_entry['serials'])): if pb_entry['serials'][k]['sourcetype']==self.serialsname: del pb_entry['serials'][k] return def _my_serials(self, pb_entry): for k in pb_entry['serials']: if k['sourcetype']==self.serialsname: return k return {} def _get_number_type(self, type): n=self.__pb_numbers for k in range(len(n)): if n[k].has_key(type): return k, n[k][type] raise common.IntegrityCheckFailed(self.desc, "Invalid Number Type") def _write_phone_entry(self, pb_entry, groups, ringtone_index, phone_book): e=['0']*self.__pb_max_entries serials=self._my_serials(pb_entry) e[self.__pb_entry]=serials['serial1'] e[self.__pb_mem_loc]=serials['serial2'] grp=0 try: grp_name=pb_entry['categories'][0]['category'] for k in range(len(groups)): if groups[k]['name']==grp_name: grp=k break except: grp, pb_entry['categories']=0, [{'category': groups[0]['name']}] e[self.__pb_group]=`grp` e[self.__pb_ringtone]='0' try: rt=pb_entry['ringtones'][0]['ringtone'] for k, n in ringtone_index.items(): if rt==n['name']: e[self.__pb_ringtone]=`k` break except: pass e[self.__pb_name]='"'+nameparser.getfullname(pb_entry['names'][0])+'"' nick_name='' try: nick_name=pb_entry['names'][0]['nickname'] except: pass e[self.__pb_alias]=nick_name if len(nick_name): e[self.__pb_alias+1]='0' else: e[self.__pb_alias+1]='' for k in range(len(self.__pb_numbers)): for kk in self.__pb_numbers[k]: e[self.__pb_numbers[k][kk]]='' e[self.__pb_numbers[k][kk]+1]='' speed_dial='0' n=pb_entry.get('numbers', []) for k in range(len(n)): try: nk=n[k] kkk, kk=self._get_number_type(nk['type']) except: nk['type']='home' kkk, kk=0, self.__pb_home_num e[kk],e[kk+1]=self.phonize(nk['number']),'0' try: if nk['speeddial']: speed_dial=`kkk` except: pass e[self.__pb_speed_dial]=speed_dial email='' try: email=pb_entry['emails'][0]['email'] except: pass e[self.__pb_email]='"'+email+'"' e[self.__pb_four]='4' for k in self.__pb_blanks: e[k]='' e[self.__pb_date_time_stamp]=self.get_time_stamp() ee=self.get_phone_entry(int(e[self.__pb_entry]), self.__pb_alias, self.__pb_max_entries) if len(ee)==self.__pb_max_entries: ee[self.__pb_name]='"'+ee[self.__pb_name]+'"' ee[self.__pb_email]='"'+ee[self.__pb_email]+'"' ee[self.__pb_ringtone]=str(phone_book.get_ringtone(\ int(e[self.__pb_mem_loc]))) k=self.__pb_max_entries-2 if e[0:k]==ee[0:k]: return True return self.save_phone_entry('0,'+','.join(e)) def getringtones(self, result): self.setmode(self.MODEBREW) m=FileEntries(self, self.__ringtone_info) rt_info=RingtoneIndex(self).get_download_info() r=m.get_media(result, rt_info) self.setmode(self.MODEMODEM) return r def saveringtones(self, result, merge): self.setmode(self.MODEBREW) m=FileEntries(self, self.__ringtone_info) result['rebootphone']=1 r=m.save_media(result, RingtoneIndex(self).get_download_info()) self.setmode(self.MODEMODEM) return r def getwallpapers(self, result): self.setmode(self.MODEBREW) m=FileEntries(self, self.__wallpaper_info) img_info=ImageIndex(self).get_download_info() r=m.get_media(result, img_info) self.setmode(self.MODEMODEM) return r def savewallpapers(self, result, merge): self.setmode(self.MODEBREW) m=FileEntries(self, self.__wallpaper_info) r=m.save_media(result, ImageIndex(self).get_download_info()) result['rebootphone']=1 self.setmode(self.MODEMODEM) return r getmemo=parent_phone._getmemo savememo=parent_phone._savememo gettodo=parent_phone._gettodo savetodo=parent_phone._savetodo getsms=parent_phone._getsms savesms=parent_phone._savesms getphoneinfo=parent_phone._getphoneinfo getmedia=None detectphone=staticmethod(parent_phone._detectphone) "Talk to the Samsung SCH-A650 Cell Phone" class Profile (com_samsung.Profile) : serialsname='scha650' WALLPAPER_WIDTH=128 WALLPAPER_HEIGHT=160 MAX_WALLPAPER_BASENAME_LENGTH=17 WALLPAPER_FILENAME_CHARS="abcdefghijklmnopqrstuvwxyz0123456789_*[]=<>;|?:% ." WALLPAPER_CONVERT_FORMAT="png" MAX_RINGTONE_BASENAME_LENGTH=17 RINGTONE_FILENAME_CHARS="abcdefghijklmnopqrstuvwxyz0123456789_*[]=<>;|?:% ." RINGTONE_LIMITS= { 'MAXSIZE': 30000 } phone_manufacturer='SAMSUNG ELECTRONICS' phone_model='SCH-A650/163' def __init__(self): com_samsung.Profile.__init__(self) _supportedsyncs=( ('phonebook', 'read', None), ('phonebook', 'write', 'OVERWRITE'), ('calendar', 'read', None), ('calendar', 'write', 'OVERWRITE'), ('ringtone', 'read', None), ('ringtone', 'write', 'OVERWRITE'), ('wallpaper', 'read', None), ('wallpaper', 'write', 'OVERWRITE'), ('memo', 'read', None), ('memo', 'write', 'OVERWRITE'), ('todo', 'read', None), ('todo', 'write', 'OVERWRITE'), ('sms', 'read', None), ) if __debug__: _supportedsyncs+=(('sms', 'write', 'OVERWRITE'),) def convertphonebooktophone(self, helper, data): return data __audio_ext={ 'MIDI': 'mid', 'QCP': 'qcp', 'PMD': 'pmd' } def QueryAudio(self, origin, currentextension, afi): if afi.format in ("MIDI", "QCP", "PMD"): for k,n in self.RINGTONE_LIMITS.items(): setattr(afi, k, n) return currentextension, afi d=self.RINGTONE_LIMITS.copy() d['format']='QCP' return ('qcp', fileinfo.AudioFileInfo(afi, **d)) imageorigins={} imageorigins.update(common.getkv(com_samsung.Profile.stockimageorigins, "images")) imagetargets={} imagetargets.update(common.getkv(com_samsung.Profile.stockimagetargets, "wallpaper", {'width': 128, 'height': 128, 'format': "PNG"})) imagetargets.update(common.getkv(com_samsung.Profile.stockimagetargets, "fullscreen", {'width': 128, 'height': 160, 'format': "PNG"})) def GetImageOrigins(self): return self.imageorigins def GetTargetsForImageOrigin(self, origin): if origin=='images': return self.imagetargets if __debug__: _supportedsyncs+=(('sms', 'write', 'OVERWRITE'),) imageorigins.update(common.getkv(com_samsung.Profile.stockimageorigins, "images")) imagetargets.update(common.getkv(com_samsung.Profile.stockimagetargets, "wallpaper", {'width': 128, 'height': 128, 'format': "PNG"})) imagetargets.update(common.getkv(com_samsung.Profile.stockimagetargets, "fullscreen", {'width': 128, 'height': 160, 'format': "PNG"})) class FileEntries : def __init__(self, phone, info): self.__phone=phone self.__file_type, self.__index_type, self.__origin, self.__path, self.__max_file_len, self.__max_file_count=info def get_media(self, result, download_info=None): self.__phone.log('Getting media for type '+self.__file_type) if download_info is None: return self.__get_media_by_dir(result) else: return self.__get_media_by_index(result, download_info) def __get_media_by_dir(self, result): media=result.get(self.__file_type, {}) idx=result.get(self.__index_type, {}) file_cnt, idx_k=0, len(idx) path_len=len(self.__path)+1 try: file_list=self.__phone.getfilesystem(self.__path, 0) for k in file_list: try: index=k[path_len:] media[index]=self.__phone.getfilecontents(k, True) idx[idx_k]={ 'name': index, 'origin': self.__origin } idx_k+=1 file_cnt += 1 except: self.__phone.log('Failed to read file '+k) except: self.__phone.log('Failed to read dir '+self.__path) result[self.__file_type]=media result[self.__index_type]=idx if file_cnt > self.__max_file_count: self.__phone.log('This phone only supports %d %s. %d %s read, weird things may happen.' % \ (self.__max_file_count, self.__file_type, file_cnt, self.__file_type)) return result def __get_media_by_index(self, result, rt_info): media=result.get(self.__file_type, {}) media_index=result.get(self.__index_type, {}) for k, m in media_index.items(): file_key=m.get('name', None) file_name=rt_info.get(file_key, None) if file_key is not None and file_name is not None: try : media[file_key]=self.__phone.getfilecontents(file_name, True) except: self.__phone.log('Failed to read file '+file_name) result[self.__file_type]=media return result def save_media(self, result, dl_info): self.__phone.log('Saving media for type '+self.__file_type) media, idx=result[self.__file_type], result[self.__index_type] media_names=[media[k]['name'] for k in media] dl_info_keys=dl_info.keys() deleted_keys=[k for k in dl_info_keys if k not in media_names] new_keys=[k for k in media if media[k]['name'] not in dl_info_keys] for k in deleted_keys: file_name=dl_info[k] self.__phone.log('Deleting file: '+file_name) try: self.__phone.rmfile(file_name) except: self.__phone.log('Failed to delete file: '+file_name) if len(new_keys): try: self.__phone.mkdirs(self.__path) except: pass file_count=0 for k in new_keys: n=media[k] origin=n.get('origin', None) if origin is not None and origin != self.__origin: continue if len(n['name']) > self.__max_file_len: self.__phone.log('%s %s name is too long and not sent to phone'% \ (self.__file_type, n['name'])) continue file_count+=1 if file_count>self.__max_file_count: self.__phone.log('This phone only supports %d %s. Save operation stopped.'%\ (self.__max_file_count, self.__file_type)) break file_name=self.__path+'/'+n['name'] if self.__origin=='images': file_contents=conversions.convertto8bitpng_joe(n['data']) else: file_contents=n['data'] self.__phone.log('Writing file: '+file_name) try: self.__phone.writefile(file_name, file_contents) except: self.__phone.log('Failed to write file: '+file_name) media[k]['origin']=self.__origin return result class RingtoneIndex : __builtin_ringtones=( 'Inactive', 'Bell 1', 'Bell 2', 'Bell 3', 'Bell 4', 'Bell 5', 'Melody 1', 'Melody 2', 'Melody 3', 'Melody 4', 'Melody 5', 'Melody 6', 'Melody 7', 'Melody 8', 'Melody 9', 'Melody 10') def __init__(self, phone): self.__phone=phone def get_builtin_index(self): r={} for k, n in enumerate(self.__builtin_ringtones): r[k]={ 'name': n, 'origin': 'builtin' } return r def get_download_index(self): r={} try: rt_idx=self.__phone.protocolclass.ringtones() buf=prototypes.buffer(self.__phone.getfilecontents( \ self.__phone.protocolclass.ringtone_index_file_name)) rt_idx.readfrombuffer(buf) idx=len(self.__builtin_ringtones) l=len(self.__phone.protocolclass.ringtone_file_path)+1 for i in range(self.__phone.protocolclass.max_ringtone_entries): e=rt_idx.entry[i] if e.name_len: r[idx+i]={ 'name': e.file_name[l:e.file_name_len], 'origin': 'ringtone' } except: pass return r def get(self): r=self.get_builtin_index() r.update(self.get_download_index()) return r def get_download_info(self): r={} try: rt_idx=self.__phone.protocolclass.ringtones() buf=prototypes.buffer(self.__phone.getfilecontents( \ self.__phone.protocolclass.ringtone_index_file_name)) rt_idx.readfrombuffer(buf) l=len(self.__phone.protocolclass.ringtone_file_path)+1 for i in range(self.__phone.protocolclass.max_ringtone_entries): e=rt_idx.entry[i] if e.name_len: r[e.file_name[l:e.file_name_len]]=e.file_name[:e.file_name_len] except: pass return r class ImageIndex : __builtin_images=( 'Clock1', 'Dual Clock', 'Calendar', 'Aquarium', 'Landscape', 'Water Drop' ) def __init__(self, phone): self.__phone=phone def get_builtin_index(self): r={} for k, n in enumerate(self.__builtin_images): r[k]={ 'name': n, 'origin': 'builtin' } return r def get_download_index(self): r={} try: img_idx=self.__phone.protocolclass.images() buf=prototypes.buffer(self.__phone.getfilecontents( \ self.__phone.protocolclass.image_index_file_name)) img_idx.readfrombuffer(buf) idx=len(self.__builtin_images) l=len(self.__phone.protocolclass.image_file_path)+1 for i in range(self.__phone.protocolclass.max_image_entries): e=img_idx.entry[i] if e.name_len: r[idx+i]={ 'name': e.file_name[l:e.file_name_len], 'origin': 'images' } except: raise return r def get(self): r=self.get_builtin_index() r.update(self.get_download_index()) return r def get_download_info(self): r={} try: img_idx=self.__phone.protocolclass.images() buf=prototypes.buffer(self.__phone.getfilecontents( \ self.__phone.protocolclass.image_index_file_name)) img_idx.readfrombuffer(buf) l=len(self.__phone.protocolclass.image_file_path)+1 for i in range(self.__phone.protocolclass.max_image_entries): e=img_idx.entry[i] if e.name_len: r[e.file_name[l:e.file_name_len]]=e.file_name[:e.file_name_len] except: pass return r class PhoneNumbers : def __init__(self, phone): self.__phone=phone self.__numbers=None def read(self): try: buf=prototypes.buffer(self.__phone.getfilecontents(\ self.__phone.protocolclass.number_file_name)) self.__numbers=self.__phone.protocolclass.numbers() self.__numbers.readfrombuffer(buf) except: self.__phone.log('Failed to read numbers file') self.__numbers=[] def get(self, index, default=None): if index>=self.__phone.protocolclass.max_number_entries: return default e=self.__numbers.entry[index] if e.valid: return e.name[:e.length] return default class PhoneBook : __pb_numbers= ({'home': 'home_num_index' }, {'office': 'office_num_index' }, {'cell': 'mobile_num_index' }, {'pager': 'pager_num_index' }, {'fax': 'fax_num_index' }) def __init__(self, phone): self.__phone=phone self.__pb=None self.__numbers=None self.__groups=None self.__rt_index=None self.__id=None self.__slots=None def read(self): try: buf=prototypes.buffer(self.__phone.getfilecontents(\ self.__phone.protocolclass.pb_file_name)) self.__pb=self.__phone.protocolclass.pbbook() self.__pb.readfrombuffer(buf) except: self.__pb=[] self.__phone.log('Failed to read phonebook') def get_ringtone(self, index): """ Return the ringtone index of this entry. """ if self.__pb is None: self.read() rt=self.__pb.entry[index].ringer_type if rt: rt-=71 return rt def __extract_entry(self, e, pb_cnt, mem_index): res={} res['serials']=[ {'sourcetype': self.__phone.serialsname, 'sourceuniqueid': self.__id, 'serial1': `pb_cnt`, 'serial2': `mem_index` }] res['names']=[ {'full': unicode(e.name, errors='ignore') } ] if e.alias_num_index: res['names'][0]['nickname']=self.__numbers.get(e.alias_num_index, '') res['categories']=[ {'category': self.__groups[e.group_num]['name'] } ] if e.email_index: res['emails']=[ { 'email': self.__numbers.get(e.email_index, '') } ] rt=e.ringer_type if rt: rt-=71 res['ringtones']=[ { 'ringtone': self.__rt_index[rt]['name'], 'use': 'call' } ] speed_dial=e.speed_dial_index res['numbers']=[] for k, a in enumerate(self.__pb_numbers): for key, attr in a.items(): idx=getattr(e, attr, 0) if idx: num=self.__numbers.get(idx, '') if idx==speed_dial: res['numbers'].append({ 'number': num, 'type': key, 'speeddial': mem_index } ) else: res['numbers'].append({ 'number': num, 'type': key }) return res def get_dict(self, result): if self.__pb is None: self.read() if self.__numbers is None: self.__numbers=PhoneNumbers(self.__phone) self.__numbers.read() if self.__slots is None: self.__slots=PBSlot(self.__phone) self.__slots.read() self.__groups=result.get('groups', {}) self.__rt_index=result.get('ringtone-index', {}) self.__id=result.get('uniqueserial', '') r={} for pb_cnt, i in enumerate(self.__slots): if i==0: continue e=self.__pb.entry[i] if e.mem_index: if i != e.mem_index: self.__phone.log('i: %d, mem_index: %d'%(i, e.mem_index)) r[pb_cnt]=self.__extract_entry(e, pb_cnt, i) return r class PBSlot : """ Class to handle Phonebook entry slot -> memory slot """ def __init__(self, phone): self.__phone=phone self.__slots=None def read(self): try: buf=prototypes.buffer(self.__phone.getfilecontents(\ self.__phone.protocolclass.slot_file_name)) self.__slots=self.__phone.protocolclass.pbslots() self.__slots.readfrombuffer(buf) except: self.__slots=[] self.__phone.log('Failed to read slot file') def __getitem__(self, key): if type(key) is not int: raise KeyError if key<0 or key>=self.__phone.protocolclass.max_pb_slots: raise IndexError if self.__slots is None: self.read() return self.__slots.slot[key].pbbook_index """ Class to handle Phonebook entry slot -> memory slot """