def remote_create( self, batch=None, failure=None, files=None, params=None, success=None, api_version=None, ): """Uploads filename and creates the AdImage object from it. It has same arguments as AbstractCrudObject.remote_create except it does not have the files argument but requires the 'filename' property to be defined. """ if not self[self.Field.filename]: raise FacebookBadObjectError( "AdImage required a filename to be defined.", ) filename = self[self.Field.filename] with open(filename, 'rb') as open_file: return_val = AbstractCrudObject.remote_create( self, files={filename: open_file}, batch=batch, failure=failure, params=params, success=success, api_version=api_version, ) return return_val
def _set_data(self, data): """ `data` may have a different structure depending if you're creating new AdImages or iterating over existing ones using something like AdAccount.get_ad_images(). While reading existing images, _set_data from AbstractCrudObject handles everything correctly, but we need to treat the remote_create case. remote_create sample response: { "images": { "8cf726a44ab7008c5cc6b4ebd2491234": { "hash":"8cf726a44ab7008c5cc6b4ebd2491234", "url":"https://fbcdn-photos-a.akamaihd.net/..." } } } Sample response when calling act_<ACT_ID>/adimages, used internally by AdAccount.get_ad_images(): { "data": [ { "hash": "181b88e3cdf6464af7ed52fe488fe559", "id": "1739564149602806:181b88e3cdf6464af7ed52fe488fe559" } ], "paging": { "cursors": { "before": "MTczOTU2NDE0OTYwMjgwNjoxODFiODh==", "after": "MTczOTU2NDE0OTYwMjgwNjoxODFiODhl==" } } } """ if 'images' in data: _, data = data['images'].popitem() for key in map(str, data): self._data[key] = data[key] # clear history due to the update self._changes.pop(key, None) self._data[self.Field.id] = '%s:%s' % ( self.get_parent_id_assured()[4:], self[self.Field.hash], ) return self else: return AbstractCrudObject._set_data(self, data)