def delete(self, delete_images=True):
        """
        Deletes the contract json from the OpenBazaar directory as well as the listing
        metadata from the db and all the related images in the file system.
        """
        # build the file_name from the contract
        file_name = str(self.contract["vendor_offer"]["listing"]["item"]["title"][:100])
        file_name = re.sub(r"[^\w\s]", '', file_name)
        file_name = re.sub(r"\s+", '_', file_name)
        file_path = DATA_FOLDER + "store/listings/contracts/" + file_name + ".json"

        h = HashMap()

        # maybe delete the images from disk
        if "image_hashes" in self.contract["vendor_offer"]["listing"]["item"] and delete_images:
            for image_hash in self.contract["vendor_offer"]["listing"]["item"]["image_hashes"]:
                # delete from disk
                image_path = h.get_file(unhexlify(image_hash))
                if os.path.exists(image_path):
                    os.remove(image_path)
                # remove pointer to the image from the HashMap
                h.delete(unhexlify(image_hash))

        # delete the contract from disk
        if os.path.exists(file_path):
            os.remove(file_path)
        # delete the listing metadata from the db
        contract_hash = digest(json.dumps(self.contract, indent=4))
        ListingsStore().delete_listing(contract_hash)
        # remove the pointer to the contract from the HashMap
        h.delete(contract_hash)
    def delete(self, delete_images=True):
        """
        Deletes the contract json from the OpenBazaar directory as well as the listing
        metadata from the db and all the related images in the file system.
        """
        # build the file_name from the contract
        file_name = str(
            self.contract["vendor_offer"]["listing"]["item"]["title"][:100])
        file_name = re.sub(r"[^\w\s]", '', file_name)
        file_name = re.sub(r"\s+", '_', file_name)
        file_path = DATA_FOLDER + "store/listings/contracts/" + file_name + ".json"

        h = HashMap()

        # maybe delete the images from disk
        if "image_hashes" in self.contract["vendor_offer"]["listing"][
                "item"] and delete_images:
            for image_hash in self.contract["vendor_offer"]["listing"]["item"][
                    "image_hashes"]:
                # delete from disk
                image_path = h.get_file(unhexlify(image_hash))
                if os.path.exists(image_path):
                    os.remove(image_path)
                # remove pointer to the image from the HashMap
                h.delete(unhexlify(image_hash))

        # delete the contract from disk
        if os.path.exists(file_path):
            os.remove(file_path)
        # delete the listing metadata from the db
        contract_hash = digest(json.dumps(self.contract, indent=4))
        ListingsStore().delete_listing(contract_hash)
        # remove the pointer to the contract from the HashMap
        h.delete(contract_hash)
    def update(self,
               expiration_date=None,
               metadata_category=None,
               title=None,
               description=None,
               currency_code=None,
               price=None,
               process_time=None,
               nsfw=None,
               est_delivery_domestic=None,
               est_delivery_international=None,
               shipping_origin=None,
               shipping_regions=None,
               keywords=None,
               category=None,
               condition=None,
               sku=None,
               image_hashes=None,  # if intending to delete an image, pass in
                                   # the hashes that are staying.
               images=None,  # to add new images pass in a list of image files.
               free_shipping=None,
               shipping_currency_code=None,
               shipping_domestic=None,
               shipping_international=None):

        self.delete(False)
        vendor_listing = self.contract["vendor_offer"]["listing"]
        if expiration_date is not None:
            vendor_listing["item"]["expiry"] = expiration_date
        if metadata_category is not None:
            vendor_listing["metadata"]["category"] = metadata_category
        if metadata_category != "physical good" and vendor_listing["metadata"][
                "category"] == "physical good":
            del vendor_listing["shipping"]
        elif metadata_category == "physical good" and vendor_listing["metadata"][
                "category"] != "physical good":
            vendor_listing["shipping"] = {}
            vendor_listing["shipping"]["est_delivery"] = {}
            vendor_listing["shipping"]["free"] = False
        if title is not None:
            vendor_listing["item"]["title"] = title
        if description is not None:
            vendor_listing["item"]["description"] = description
        if currency_code is not None:
            if currency_code.upper() != "BTC" and "bitcoin" \
                    in vendor_listing["item"]["price_per_unit"]:
                p = vendor_listing["item"]["price_per_unit"]["bitcoin"]
                del vendor_listing["item"]["price_per_unit"]["bitcoin"]
                vendor_listing["item"]["price_per_unit"]["fiat"] = {}
                vendor_listing["item"]["price_per_unit"]["fiat"][
                    "currency_code"] = currency_code
                vendor_listing["item"]["price_per_unit"]["fiat"]["price"] = p
            elif currency_code.upper() == "BTC" and "fiat" in \
                    vendor_listing["item"]["price_per_unit"]:
                p = vendor_listing["item"]["price_per_unit"]["fiat"]["price"]
                del vendor_listing["item"]["price_per_unit"]["fiat"]
                vendor_listing["item"]["price_per_unit"]["bitcoin"] = p
        if price is not None:
            if "bitcoin" in vendor_listing["item"]["price_per_unit"]:
                vendor_listing["item"]["price_per_unit"]["bitcoin"] = price
            else:
                vendor_listing["item"]["price_per_unit"]["fiat"]["price"] = price
        if process_time is not None:
            vendor_listing["item"]["process_time"] = process_time
        if nsfw is not None:
            vendor_listing["item"]["nsfw"] = nsfw
        if keywords is not None:
            vendor_listing["item"]["keywords"] = []
            vendor_listing["item"]["keywords"].extend(keywords)
        if category is not None:
            vendor_listing["item"]["category"] = category
        if image_hashes is not None:
            to_delete = list(set(vendor_listing["item"]["image_hashes"]) - set(image_hashes))
            for image_hash in to_delete:
                # delete from disk
                h = HashMap()
                image_path = h.get_file(unhexlify(image_hash))
                if os.path.exists(image_path):
                    os.remove(image_path)
                # remove pointer to the image from the HashMap
                h.delete(unhexlify(image_hash))
            vendor_listing["item"]["image_hashes"] = []
            vendor_listing["item"]["image_hashes"].extend(image_hashes)
        if images is not None:
            if "image_hashes" not in vendor_listing["item"]:
                vendor_listing["item"]["image_hashes"] = []
            for image in images:
                hash_value = digest(image).encode("hex")
                vendor_listing["item"]["image_hashes"].append(hash_value)
                with open(DATA_FOLDER + "store/media/" + hash_value, 'w') as outfile:
                    outfile.write(image)
                HashMap().insert(digest(image), DATA_FOLDER + "store/media/" + hash_value)
        if vendor_listing["metadata"]["category"] == "physical good" and condition is not None:
            vendor_listing["item"]["condition"] = condition
        if sku is not None:
            vendor_listing["item"]["sku"] = sku
        if vendor_listing["metadata"]["category"] == "physical good":
            if shipping_origin is not None:
                vendor_listing["shipping"]["shipping_origin"] = shipping_origin
            if free_shipping is not None:
                if free_shipping is True and vendor_listing["shipping"]["free"] is False:
                    vendor_listing["shipping"]["free"] = True
                    del vendor_listing["shipping"]["flat_fee"]
                elif free_shipping is False and vendor_listing["shipping"]["free"] is True:
                    vendor_listing["shipping"]["flat_fee"] = {}
                    vendor_listing["shipping"]["flat_fee"]["bitcoin"] = {}
                    vendor_listing["shipping"]["free"] = False
            if shipping_currency_code is not None and vendor_listing["shipping"]["free"] is False:
                if shipping_currency_code == "BTC" and "bitcoin" not in \
                        vendor_listing["shipping"]["flat_fee"]:
                    vendor_listing["shipping"]["flat_fee"]["bitcoin"] = {}
                    d = vendor_listing["shipping"]["flat_fee"]["fiat"]["price"]["domestic"]
                    i = vendor_listing["shipping"]["flat_fee"]["fiat"]["price"][
                        "international"]
                    vendor_listing["shipping"]["flat_fee"]["bitcoin"]["domestic"] = d
                    vendor_listing["shipping"]["flat_fee"]["bitcoin"]["international"] = i
                    del vendor_listing["shipping"]["flat_fee"]["fiat"]
                elif shipping_currency_code != "BTC" and "bitcoin" in \
                        vendor_listing["shipping"]["flat_fee"]:
                    d = vendor_listing["shipping"]["flat_fee"]["bitcoin"]["domestic"]
                    i = vendor_listing["shipping"]["flat_fee"]["bitcoin"]["international"]
                    vendor_listing["shipping"]["flat_fee"]["fiat"] = {}
                    vendor_listing["shipping"]["flat_fee"]["fiat"]["price"] = {}
                    vendor_listing["shipping"]["flat_fee"]["fiat"]["price"]["domestic"] = d
                    vendor_listing["shipping"]["flat_fee"]["fiat"]["price"][
                        "international"] = i
                    vendor_listing["shipping"]["flat_fee"]["fiat"][
                        "currency_code"] = shipping_currency_code
                    del vendor_listing["shipping"]["flat_fee"]["bitcoin"]
            if shipping_domestic is not None and "bitcoin" not in \
                    vendor_listing["shipping"]["flat_fee"]:
                vendor_listing["shipping"]["flat_fee"]["fiat"]["price"][
                    "domestic"] = shipping_domestic
            if shipping_international is not None and "bitcoin" not in \
                    vendor_listing["shipping"]["flat_fee"]:
                vendor_listing["shipping"]["flat_fee"]["fiat"]["price"][
                    "international"] = shipping_international
            if shipping_domestic is not None and "bitcoin" in \
                    vendor_listing["shipping"]["flat_fee"]:
                vendor_listing["shipping"]["flat_fee"]["bitcoin"][
                    "domestic"] = shipping_domestic
            if shipping_international is not None and "bitcoin" in \
                    vendor_listing["shipping"]["flat_fee"]:
                vendor_listing["shipping"]["flat_fee"]["bitcoin"][
                    "international"] = shipping_international
            if shipping_regions is not None:
                vendor_listing["shipping"]["shipping_regions"] = shipping_regions
            if est_delivery_domestic is not None:
                vendor_listing["shipping"]["est_delivery"]["domestic"] = est_delivery_domestic
            if est_delivery_international is not None:
                vendor_listing["shipping"]["est_delivery"][
                    "international"] = est_delivery_international

        self.save()
    def update(
            self,
            expiration_date=None,
            metadata_category=None,
            title=None,
            description=None,
            currency_code=None,
            price=None,
            process_time=None,
            nsfw=None,
            est_delivery_domestic=None,
            est_delivery_international=None,
            shipping_origin=None,
            shipping_regions=None,
            keywords=None,
            category=None,
            condition=None,
            sku=None,
            image_hashes=None,  # if intending to delete an image, pass in
            # the hashes that are staying.
        images=None,  # to add new images pass in a list of image files.
            free_shipping=None,
            shipping_currency_code=None,
            shipping_domestic=None,
            shipping_international=None):

        self.delete(False)
        vendor_listing = self.contract["vendor_offer"]["listing"]
        if expiration_date is not None:
            vendor_listing["item"]["expiry"] = expiration_date
        if metadata_category is not None:
            vendor_listing["metadata"]["category"] = metadata_category
        if metadata_category != "physical good" and vendor_listing["metadata"][
                "category"] == "physical good":
            del vendor_listing["shipping"]
        elif metadata_category == "physical good" and vendor_listing[
                "metadata"]["category"] != "physical good":
            vendor_listing["shipping"] = {}
            vendor_listing["shipping"]["est_delivery"] = {}
            vendor_listing["shipping"]["free"] = False
        if title is not None:
            vendor_listing["item"]["title"] = title
        if description is not None:
            vendor_listing["item"]["description"] = description
        if currency_code is not None:
            if currency_code.upper() != "BTC" and "bitcoin" \
                    in vendor_listing["item"]["price_per_unit"]:
                p = vendor_listing["item"]["price_per_unit"]["bitcoin"]
                del vendor_listing["item"]["price_per_unit"]["bitcoin"]
                vendor_listing["item"]["price_per_unit"]["fiat"] = {}
                vendor_listing["item"]["price_per_unit"]["fiat"][
                    "currency_code"] = currency_code
                vendor_listing["item"]["price_per_unit"]["fiat"]["price"] = p
            elif currency_code.upper() == "BTC" and "fiat" in \
                    vendor_listing["item"]["price_per_unit"]:
                p = vendor_listing["item"]["price_per_unit"]["fiat"]["price"]
                del vendor_listing["item"]["price_per_unit"]["fiat"]
                vendor_listing["item"]["price_per_unit"]["bitcoin"] = p
        if price is not None:
            if "bitcoin" in vendor_listing["item"]["price_per_unit"]:
                vendor_listing["item"]["price_per_unit"]["bitcoin"] = price
            else:
                vendor_listing["item"]["price_per_unit"]["fiat"][
                    "price"] = price
        if process_time is not None:
            vendor_listing["item"]["process_time"] = process_time
        if nsfw is not None:
            vendor_listing["item"]["nsfw"] = nsfw
        if keywords is not None:
            vendor_listing["item"]["keywords"] = []
            vendor_listing["item"]["keywords"].extend(keywords)
        if category is not None:
            vendor_listing["item"]["category"] = category
        if image_hashes is not None:
            to_delete = list(
                set(vendor_listing["item"]["image_hashes"]) -
                set(image_hashes))
            for image_hash in to_delete:
                # delete from disk
                h = HashMap()
                image_path = h.get_file(unhexlify(image_hash))
                if os.path.exists(image_path):
                    os.remove(image_path)
                # remove pointer to the image from the HashMap
                h.delete(unhexlify(image_hash))
            vendor_listing["item"]["image_hashes"] = []
            vendor_listing["item"]["image_hashes"].extend(image_hashes)
        if images is not None:
            if "image_hashes" not in vendor_listing["item"]:
                vendor_listing["item"]["image_hashes"] = []
            for image in images:
                hash_value = digest(image).encode("hex")
                vendor_listing["item"]["image_hashes"].append(hash_value)
                with open(DATA_FOLDER + "store/media/" + hash_value,
                          'w') as outfile:
                    outfile.write(image)
                HashMap().insert(digest(image),
                                 DATA_FOLDER + "store/media/" + hash_value)
        if vendor_listing["metadata"][
                "category"] == "physical good" and condition is not None:
            vendor_listing["item"]["condition"] = condition
        if sku is not None:
            vendor_listing["item"]["sku"] = sku
        if vendor_listing["metadata"]["category"] == "physical good":
            if shipping_origin is not None:
                vendor_listing["shipping"]["shipping_origin"] = shipping_origin
            if free_shipping is not None:
                if free_shipping is True and vendor_listing["shipping"][
                        "free"] is False:
                    vendor_listing["shipping"]["free"] = True
                    del vendor_listing["shipping"]["flat_fee"]
                elif free_shipping is False and vendor_listing["shipping"][
                        "free"] is True:
                    vendor_listing["shipping"]["flat_fee"] = {}
                    vendor_listing["shipping"]["flat_fee"]["bitcoin"] = {}
                    vendor_listing["shipping"]["free"] = False
            if shipping_currency_code is not None and vendor_listing[
                    "shipping"]["free"] is False:
                if shipping_currency_code == "BTC" and "bitcoin" not in \
                        vendor_listing["shipping"]["flat_fee"]:
                    vendor_listing["shipping"]["flat_fee"]["bitcoin"] = {}
                    d = vendor_listing["shipping"]["flat_fee"]["fiat"][
                        "price"]["domestic"]
                    i = vendor_listing["shipping"]["flat_fee"]["fiat"][
                        "price"]["international"]
                    vendor_listing["shipping"]["flat_fee"]["bitcoin"][
                        "domestic"] = d
                    vendor_listing["shipping"]["flat_fee"]["bitcoin"][
                        "international"] = i
                    del vendor_listing["shipping"]["flat_fee"]["fiat"]
                elif shipping_currency_code != "BTC" and "bitcoin" in \
                        vendor_listing["shipping"]["flat_fee"]:
                    d = vendor_listing["shipping"]["flat_fee"]["bitcoin"][
                        "domestic"]
                    i = vendor_listing["shipping"]["flat_fee"]["bitcoin"][
                        "international"]
                    vendor_listing["shipping"]["flat_fee"]["fiat"] = {}
                    vendor_listing["shipping"]["flat_fee"]["fiat"][
                        "price"] = {}
                    vendor_listing["shipping"]["flat_fee"]["fiat"]["price"][
                        "domestic"] = d
                    vendor_listing["shipping"]["flat_fee"]["fiat"]["price"][
                        "international"] = i
                    vendor_listing["shipping"]["flat_fee"]["fiat"][
                        "currency_code"] = shipping_currency_code
                    del vendor_listing["shipping"]["flat_fee"]["bitcoin"]
            if shipping_domestic is not None and "bitcoin" not in \
                    vendor_listing["shipping"]["flat_fee"]:
                vendor_listing["shipping"]["flat_fee"]["fiat"]["price"][
                    "domestic"] = shipping_domestic
            if shipping_international is not None and "bitcoin" not in \
                    vendor_listing["shipping"]["flat_fee"]:
                vendor_listing["shipping"]["flat_fee"]["fiat"]["price"][
                    "international"] = shipping_international
            if shipping_domestic is not None and "bitcoin" in \
                    vendor_listing["shipping"]["flat_fee"]:
                vendor_listing["shipping"]["flat_fee"]["bitcoin"][
                    "domestic"] = shipping_domestic
            if shipping_international is not None and "bitcoin" in \
                    vendor_listing["shipping"]["flat_fee"]:
                vendor_listing["shipping"]["flat_fee"]["bitcoin"][
                    "international"] = shipping_international
            if shipping_regions is not None:
                vendor_listing["shipping"][
                    "shipping_regions"] = shipping_regions
            if est_delivery_domestic is not None:
                vendor_listing["shipping"]["est_delivery"][
                    "domestic"] = est_delivery_domestic
            if est_delivery_international is not None:
                vendor_listing["shipping"]["est_delivery"][
                    "international"] = est_delivery_international

        self.save()