Source code for kabbes_icloud.ICloudContacts

from parent_class import ParentPluralDict
from kabbes_menu import Menu
from kabbes_icloud import ICloudContact, Connection
import pandas as pd
import py_starter as ps


[docs]class ICloudContacts( ParentPluralDict, Menu ): _OVERRIDE_OPTIONS = {1: ['Open iCloud Contact', 'run_Child_user']} TABLE_NAME = 'ICloudContacts' DATA_COL = 'data' COLS = [ICloudContact.ID_COL, DATA_COL] def __init__( self, conn = None, df = pd.DataFrame(), json_string = None, dictionary = {} ): ParentPluralDict.__init__( self, 'Contacts' ) Menu.__init__( self ) self.conn = conn if not df.empty: self._import_from_df( df ) elif json_string != None: self._import_from_json( json_string ) elif dictionary != {}: self._import_from_dict( dictionary ) elif self.conn != None: self._get_Contacts_from_iCloud() def _get_Contacts_from_iCloud( self ): list_of_dictionaries = self.conn.conn.contacts.all() for dictionary in list_of_dictionaries: self.add_ICloudContact( ICloudContact( dictionary ) ) def _import_from_dict( self, dictionary ): '''Given a dictionary, populate the Contacts''' for contactId in dictionary: new_Contact = ICloudContact( dictionary[contactId] ) self.add_ICloudContact( new_Contact ) def _import_from_json( self, json_string ): '''Given a json string, populate the Contacts ''' dictionary = ps.json_to_dict( json_string ) self._import_from_dict( dictionary ) def _import_from_df( self, df ): '''Given a DataFrame, populate the Contacts ''' json_strings = df[ self.DATA_COL ] for i in range(len( json_strings )): new_Contact = ICloudContact( json_string = json_strings[i] ) self.add_ICloudContact( new_Contact )
[docs] def export_to_dict( self ): '''export all contacts to a dictionary''' dictionary = {} for Contact in self: dictionary.update({ Contact.ID_COL : Contact.export_to_dict() }) return dictionary
[docs] def export_to_json( self ): '''export all contacts to a json format''' dictionary = self.export_to_dict() return ps.dict_to_json( dictionary )
[docs] def export_to_df( self ): '''export all contacts to a pandas DataFrame''' df = pd.DataFrame( columns = self.COLS ) for Contact in self: new_df = pd.DataFrame( columns = self.COLS ) for col in self.COLS: if col == self.DATA_COL: value = Contact.export_to_json() else: value = Contact.get_attr( col ) new_df[ col ] = [ value ] df = df.append( new_df, ignore_index = True ) return df
[docs] def merge_ICloudContacts( self, Contacts_inst, how = 'left', overwrite = False ): if how == 'right': left = Contacts_inst right = self else: #left, there are only two merge options left = self right = Contacts_inst ### Perform the merge merged_Contacts = ICloudContacts() left_ids = [ Contact.get_id() for Contact in list(left) ] right_ids = [ Contact.get_id() for Contact in list(right) ] for j in range(len(right)): id = right_ids[j] # if this contact is also present in the left, update the Contact with the info from the left if id in left_ids: right.Contacts[ id ].update( dictionary = left.Contacts[id].export_to_dict() ) merged_Contacts.add_ICloudContact( right.Contacts[ id ] ) # add all contacts which are present in the left but not in the right for i in range(len(left)): id = left_ids[i] if id not in right_ids: merged_Contacts.add_ICloudContact( left.Contacts[ id ] ) if overwrite: self = merged_Contacts return merged_Contacts
[docs] def add_ICloudContact( self, Contact_inst ): '''Add a singular iCloud_Contact to the Contacts dictionary''' self._add( Contact_inst.contactId, Contact_inst )
[docs] def remove_ICloudContact( self, Contact_inst ): '''Remove a singular iCloud_Contact from the Contacts dictionary''' self._remove( Contact_inst.contactId )
[docs] def select_Contacts_where( self, dictionary = {} ): '''Returns an iCloud_Contacts instance where all Contacts have keys=values in the dictionary dictionary = {'firstName': 'James', 'lastName': 'Kabbes'} returns an instance with all Contacts that contain James Kabbes''' # use recursion to select Contacts where keys=values Valid_Contacts = ICloudContacts() Valid_Contacts.Contacts = self.Contacts.copy() for att in dictionary: boolean_dict = Valid_Contacts.lambda_on_Contacts( lambda Contact: Contact.get_attr( att ) == dictionary[att] ) for contactId in boolean_dict: if not boolean_dict[ contactId ]: Valid_Contacts.remove_iCloud_Contact( Valid_Contacts.Contacts[contactId] ) # returns an iCloud_Contacts class instance return Valid_Contacts
[docs] def update_Contacts( self, dictionary = {}, json_string = None ): ''' { contactId1: Dictionary1, contactId2: Dictionary2 } ''' if json_string != None: dictionary = ps.json_to_dict( json_string ) ids = [ Contact.get_attr(Contact.ID_COL) for Contact in list(self) ] for id in dictionary: if id in ids: self.update( dictionary[id] )
[docs] def lambda_on_Contacts( self, lambda_func ): '''given a lambda function (lambda Contact: Contact.get_attr("firstName")), put each return statement in a dict''' results = {} for contactId in self.Contacts: results[contactId] = lambda_func( self.Contacts[contactId] ) return results
[docs] def show_attribute_breakdown( self ): values_and_counts = {} for contactId in self.Contacts: Contact_inst = self.Contacts[contactId] for key in vars(Contact_inst): if key not in values_and_counts: values_and_counts[key] = 1 else: values_and_counts[key] += 1 df_breakdown = pd.DataFrame( {'Key': list(values_and_counts.keys()), 'Frequency': list(values_and_counts.values()) } ) df_breakdown['Proportion'] = df_breakdown['Frequency'] / len(self.Contacts) df_breakdown.sort_values( 'Frequency', inplace = True, ascending = False ) self.df_breakdown = df_breakdown return df_breakdown