def get_image(self, request): @defer.inlineCallbacks def _showImage(resp=None): @defer.inlineCallbacks def _setContentDispositionAndSend(file_path, extension, content_type): request.setHeader('content-disposition', 'filename="%s.%s"' % (file_path, extension)) request.setHeader('content-type', content_type) f = open(file_path, "rb") yield FileSender().beginFileTransfer(f, request) f.close() defer.returnValue(0) if os.path.exists(image_path): yield _setContentDispositionAndSend(image_path, ".jpg", "image/jpeg") else: request.setResponseCode(http.NOT_FOUND) request.write("No such image '%s'" % request.path) request.finish() if "hash" in request.args: if HashMap().get_file(unhexlify( request.args["hash"][0])) is not None: image_path = HashMap().get_file( unhexlify(request.args["hash"][0])) else: image_path = DATA_FOLDER + "cache/" + request.args["hash"][0] if not os.path.exists(image_path) and "guid" in request.args: def get_node(node): if node is not None: self.mserver.get_image( node, unhexlify(request.args["hash"] [0])).addCallback(_showImage) else: _showImage() self.kserver.resolve(unhexlify( request.args["guid"][0])).addCallback(get_node) else: _showImage() else: request.write(NoResource().render(request)) request.finish() return server.NOT_DONE_YET
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 __init__(self, contract=None, hash_value=None): """ This class can be instantiated with either an `OrderedDict` or a hash of a contract. If a hash is used, we will load the contract from either the file system or cache. Alternatively, pass in no parameters if the intent is to create a new contract. Args: contract: an `OrderedDict` containing a filled out json contract hash: a hash (in raw bytes) of a contract """ if contract is not None: self.contract = contract elif hash_value is not None: try: file_path = HashMap().get_file(hash_value) if file_path is None: file_path = DATA_FOLDER + "cache/" + hexlify(hash_value) with open(file_path, 'r') as filename: self.contract = json.load(filename, object_pairs_hook=OrderedDict) except Exception: self.contract = {} else: self.contract = {}
def update_profile(self, request): p = Profile() if not p.get().encryption_key \ and "name" not in request.args \ and "location" not in request.args: return "False" u = objects.Profile() if "name" in request.args: u.name = request.args["name"][0] if "location" in request.args: # This needs to be formatted. Either here or from the UI. u.location = CountryCode.Value(request.args["location"][0].upper()) if "handle" in request.args: u.handle = request.args["handle"][0] if "about" in request.args: u.about = request.args["about"][0] if "nsfw" in request.args: u.nsfw = True if "vendor" in request.args: u.vendor = True if "moderator" in request.args: u.moderator = True if "website" in request.args: u.website = request.args["website"][0] if "email" in request.args: u.email = request.args["email"][0] if "avatar" in request.args: with open(DATA_FOLDER + "store/avatar", 'wb') as outfile: outfile.write(request.args["avatar"][0]) avatar_hash = digest(request.args["avatar"][0]) HashMap().insert(avatar_hash, DATA_FOLDER + "store/avatar") u.avatar_hash = avatar_hash if "header" in request.args: with open(DATA_FOLDER + "store/header", 'wb') as outfile: outfile.write(request.args["header"][0]) header_hash = digest(request.args["header"][0]) HashMap().insert(header_hash, DATA_FOLDER + "store/header") u.header_hash = header_hash if "pgp_key" in request.args and "signature" in request.args: p.add_pgp_key(request.args["pgp_key"][0], request.args["signature"][0], KeyChain().guid.encode("hex")) u.encryption_key = KeyChain().encryption_pubkey p.update(u)
def save(self): """ Saves the json contract into the OpenBazaar/store/listings/contracts/ directory. It uses the title as the file name so it's easy on human eyes. A mapping of the hash of the contract and file path is stored in the database so we can retrieve the contract with only its hash. Additionally, the contract metadata (sent in response to the GET_LISTINGS query) is saved in the db for fast access. """ # get the contract title to use as the file name and format it 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) # save the json contract to the file system file_path = DATA_FOLDER + "store/listings/contracts/" + file_name + ".json" with open(file_path, 'w') as outfile: outfile.write(json.dumps(self.contract, indent=4)) # Create a `ListingMetadata` protobuf object using data from the full contract listings = Listings() data = listings.ListingMetadata() data.contract_hash = digest(json.dumps(self.contract, indent=4)) vendor_item = self.contract["vendor_offer"]["listing"]["item"] data.title = vendor_item["title"] if "image_hashes" in vendor_item: data.thumbnail_hash = unhexlify(vendor_item["image_hashes"][0]) data.category = vendor_item["category"] if "bitcoin" not in vendor_item["price_per_unit"]: data.price = float(vendor_item["price_per_unit"]["fiat"]["price"]) data.currency_code = vendor_item["price_per_unit"]["fiat"][ "currency_code"] else: data.price = float(vendor_item["price_per_unit"]["bitcoin"]) data.currency_code = "BTC" data.nsfw = vendor_item["nsfw"] if "shipping" not in self.contract["vendor_offer"]["listing"]: data.origin = CountryCode.Value("NA") else: data.origin = CountryCode.Value( self.contract["vendor_offer"]["listing"]["shipping"] ["shipping_origin"].upper()) for region in self.contract["vendor_offer"]["listing"]["shipping"][ "shipping_regions"]: data.ships_to.append(CountryCode.Value(region.upper())) # save the mapping of the contract file path and contract hash in the database HashMap().insert(data.contract_hash, file_path) # save the `ListingMetadata` protobuf to the database as well ListingsStore().add_listing(data)
def setimage(): parser = argparse.ArgumentParser( description="Maps a image hash to a file path in the database", usage='''usage: networkcli.py setimage [-f FILEPATH]''') parser.add_argument('-f', '--filepath', help="a path to the image") args = parser.parse_args(sys.argv[2:]) with open(args.filepath, "r") as f: image = f.read() d = digest(image) h = HashMap() h.insert(d, args.filepath) print h.get_file(d)
def __init__(self, node_proto, router, signing_key): self.router = router RPCProtocol.__init__(self, node_proto, router) self.log = Logger(system=self) self.multiplexer = None self.hashmap = HashMap() self.signing_key = signing_key self.listeners = [] self.handled_commands = [ GET_CONTRACT, GET_IMAGE, GET_PROFILE, GET_LISTINGS, GET_USER_METADATA, GET_CONTRACT_METADATA, FOLLOW, UNFOLLOW, GET_FOLLOWERS, GET_FOLLOWING, NOTIFY, MESSAGE ]
def get_contract(self, request): def parse_contract(contract): if contract is not None: request.setHeader('content-type', "application/json") request.write(json.dumps(contract, indent=4)) request.finish() else: request.write(NoResource().render(request)) request.finish() if "id" in request.args: if "guid" in request.args: def get_node(node): if node is not None: self.mserver.get_contract(node, unhexlify(request.args["id"][0]))\ .addCallback(parse_contract) else: request.write(NoResource().render(request)) request.finish() try: with open(DATA_FOLDER + "cache/" + request.args["id"][0], "r") as filename: contract = json.loads(filename.read(), object_pairs_hook=OrderedDict) parse_contract(contract) except Exception: self.kserver.resolve(unhexlify( request.args["guid"][0])).addCallback(get_node) else: try: with open( HashMap().get_file(unhexlify( request.args["id"][0])), "r") as filename: contract = json.loads(filename.read(), object_pairs_hook=OrderedDict) parse_contract(contract) except Exception: parse_contract(None) else: request.write(NoResource().render(request)) request.finish() return server.NOT_DONE_YET
def setprofile(): parser = argparse.ArgumentParser( description="Sets a profile in the database.", usage='''usage: networkcli.py setprofile [options]''') parser.add_argument('-n', '--name', help="the name of the user/store") parser.add_argument('-o', '--onename', help="the onename id") parser.add_argument('-a', '--avatar', help="the file path to the avatar image") parser.add_argument('-hd', '--header', help="the file path to the header image") parser.add_argument( '-c', '--country', help= "a string consisting of country from protos.countries.CountryCode") # we could add all the fields here but this is good enough to test. args = parser.parse_args(sys.argv[2:]) p = Profile() u = objects.Profile() h = HashMap() if args.name is not None: u.name = args.name if args.country is not None: u.location = countries.CountryCode.Value(args.country.upper()) if args.onename is not None: u.handle = args.onename if args.avatar is not None: with open(args.avatar, "r") as filename: image = filename.read() hash_value = digest(image) u.avatar_hash = hash_value h.insert(hash_value, args.avatar) if args.header is not None: with open(args.header, "r") as filename: image = filename.read() hash_value = digest(image) u.header_hash = hash_value h.insert(hash_value, args.header) u.encryption_key = KeyChain().encryption_pubkey p.update(u)
def create(self, expiration_date, metadata_category, title, description, currency_code, price, process_time, nsfw, shipping_origin, shipping_regions, est_delivery_domestic=None, est_delivery_international=None, keywords=None, category=None, condition=None, sku=None, images=None, free_shipping=None, shipping_currency_code=None, shipping_domestic=None, shipping_international=None): """ All parameters are strings except: :param expiration_date: `string` (must be formatted UTC datetime) :param keywords: `list` :param nsfw: `boolean` :param images: a `list` of image files :param free_shipping: `boolean` :param shipping_origin: a 'string' formatted `CountryCode` :param shipping_regions: a 'list' of 'string' formatted `CountryCode`s """ # TODO: import keys into the contract, import moderator information from db, sign contract. profile = Profile().get() keychain = KeyChain() self.contract = OrderedDict({ "vendor_offer": { "listing": { "metadata": { "version": "0.1", "expiry": expiration_date + " UTC", "category": metadata_category, "category_sub": "fixed price" }, "id": { "guid": keychain.guid.encode("hex"), "pubkeys": { "guid": keychain.guid_signed_pubkey[64:].encode("hex"), "bitcoin": keychain.bitcoin_master_pubkey } }, "item": { "title": title, "description": description, "process_time": process_time, "price_per_unit": {}, "nsfw": nsfw } } } }) if metadata_category == "physical good" and condition is not None: self.contract["vendor_offer"]["listing"]["item"][ "condition"] = condition if currency_code.upper() == "BTC": item = self.contract["vendor_offer"]["listing"]["item"] item["price_per_unit"]["bitcoin"] = price else: item = self.contract["vendor_offer"]["listing"]["item"] item["price_per_unit"]["fiat"] = {} item["price_per_unit"]["fiat"]["price"] = price item["price_per_unit"]["fiat"]["currency_code"] = currency_code if keywords is not None: self.contract["vendor_offer"]["listing"]["item"]["keywords"] = [] self.contract["vendor_offer"]["listing"]["item"][ "keywords"].extend(keywords) if category is not None: self.contract["vendor_offer"]["listing"]["item"][ "category"] = category if sku is not None: self.contract["vendor_offer"]["listing"]["item"]["sku"] = sku if metadata_category == "physical good": self.contract["vendor_offer"]["listing"]["shipping"] = {} shipping = self.contract["vendor_offer"]["listing"]["shipping"] shipping["shipping_origin"] = shipping_origin if free_shipping is False: self.contract["vendor_offer"]["listing"]["shipping"][ "free"] = False self.contract["vendor_offer"]["listing"]["shipping"][ "flat_fee"] = {} if shipping_currency_code == "BTC": self.contract["vendor_offer"]["listing"]["shipping"][ "flat_fee"]["bitcoin"] = {} self.contract["vendor_offer"]["listing"]["shipping"][ "flat_fee"]["bitcoin"]["domestic"] = shipping_domestic self.contract["vendor_offer"]["listing"]["shipping"][ "flat_fee"]["bitcoin"][ "international"] = shipping_international else: shipping = self.contract["vendor_offer"]["listing"][ "shipping"] shipping["flat_fee"]["fiat"] = {} shipping["flat_fee"]["fiat"]["price"] = {} shipping["flat_fee"]["fiat"]["price"][ "domestic"] = shipping_domestic shipping["flat_fee"]["fiat"]["price"][ "international"] = shipping_international shipping["flat_fee"]["fiat"][ "currency_code"] = shipping_currency_code else: self.contract["vendor_offer"]["listing"]["shipping"][ "free"] = True self.contract["vendor_offer"]["listing"]["shipping"][ "shipping_regions"] = [] for region in shipping_regions: shipping = self.contract["vendor_offer"]["listing"]["shipping"] shipping["shipping_regions"].append(region) listing = self.contract["vendor_offer"]["listing"] listing["shipping"]["est_delivery"] = {} listing["shipping"]["est_delivery"][ "domestic"] = est_delivery_domestic listing["shipping"]["est_delivery"][ "international"] = est_delivery_international if profile.HasField("handle"): self.contract["vendor_offer"]["listing"]["id"][ "blockchain_id"] = profile.handle if images is not None: self.contract["vendor_offer"]["listing"]["item"][ "image_hashes"] = [] for image in images: hash_value = digest(image).encode("hex") self.contract["vendor_offer"]["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) listing = json.dumps(self.contract["vendor_offer"]["listing"], indent=4) self.contract["vendor_offer"]["signature"] = \ keychain.signing_key.sign(listing, encoder=nacl.encoding.HexEncoder)[:128] 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()