def parse_listings(listings): if listings is not None: response = {"listings": []} for l in listings.listing: listing_json = { "title": l.title, "contract_hash": l.contract_hash.encode("hex"), "thumbnail_hash": l.thumbnail_hash.encode("hex"), "category": l.category, "price": l.price, "currency_code": l.currency_code, "nsfw": l.nsfw, "origin": str(CountryCode.Name(l.origin)), "ships_to": [] } for country in l.ships_to: listing_json["ships_to"].append( str(CountryCode.Name(country))) response["listings"].append(listing_json) request.setHeader('content-type', "application/json") request.write(json.dumps(response, indent=4)) request.finish() else: request.write(json.dumps({})) request.finish()
def respond(l, node): if l is not None: listing_json = { "id": message_id, "listing": { "guid": node.id.encode("hex"), "title": l.title, "contract_hash": l.contract_hash.encode("hex"), "thumbnail_hash": l.thumbnail_hash.encode("hex"), "category": l.category, "price": l.price, "currency_code": l.currency_code, "nsfw": l.nsfw, "origin": str(CountryCode.Name(l.origin)), "ships_to": [], "avatar_hash": l.avatar_hash.encode("hex"), "handle": l.handle } } for country in l.ships_to: listing_json["listing"]["ships_to"].append( str(CountryCode.Name(country))) self.transport.write( str( bleach.clean(json.dumps(listing_json, indent=4), tags=ALLOWED_TAGS)))
def setUp(self): datastore.create_database(":memory:") self.test_hash = "87e0555568bf5c7e4debd6645fc3f41e88df6ca8" self.test_hash2 = "97e0555568bf5c7e4debd6645fc3f41e88df6ca8" self.test_file = "Contents of test.txt" self.test_file2 = "Contents of test2.txt" self.sp = Profile() self.sp.name = "Test User" self.sp.encryption_key = "Key" self.sp.location = CountryCode.Value('UNITED_STATES') self.serialized_listings = Listings() self.lm = self.serialized_listings.ListingMetadata() self.lm.contract_hash = self.test_hash self.lm.title = "TEST CONTRACT TITLE" self.lm.price = 0 self.lm.currency_code = "USD" self.lm.nsfw = False self.lm.origin = CountryCode.Value('ALL') self.hm = datastore.HashMap() self.hm.delete_all() self.ps = datastore.ProfileStore() self.ls = datastore.ListingsStore() self.ks = datastore.KeyStore()
def setUp(self): self.db = Database(filepath="test.db") self.test_hash = "87e0555568bf5c7e4debd6645fc3f41e88df6ca8" self.test_hash2 = "97e0555568bf5c7e4debd6645fc3f41e88df6ca8" self.test_file = "Contents of test.txt" self.test_file2 = "Contents of test2.txt" self.sp = Profile() self.key = Profile().PublicKey() self.key.public_key = "Key" self.key.signature = "Sig" self.sp.name = "Test User" self.sp.guid_key.MergeFrom(self.key) self.sp.location = CountryCode.Value('UNITED_STATES') self.serialized_listings = Listings() self.lm = self.serialized_listings.ListingMetadata() self.lm.contract_hash = self.test_hash self.lm.title = "TEST CONTRACT TITLE" self.lm.price = 0 self.lm.currency_code = "USD" self.lm.nsfw = False self.lm.origin = CountryCode.Value('ALL') self.u = Following.User() self.u.guid = '0000000000000000000000000000000000' self.u.pubkey = 'signed_pubkey' self.m = Metadata() self.m.name = 'Test User' self.m.handle = '@TestUser' self.m.avatar_hash = '' self.m.nsfw = False self.u.metadata.MergeFrom(self.m) self.f = Followers.Follower() self.f.guid = '0000000000000000000000000000000001' self.f.following = '' self.f.pubkey = '' self.f.metadata.MergeFrom(self.m) self.hm = self.db.filemap self.hm.delete_all() self.ps = self.db.profile self.ls = self.db.listings self.ks = self.db.keys self.fd = self.db.follow self.ms = self.db.messages self.ns = self.db.notifications self.vs = self.db.vendors self.bs = self.db.broadcasts self.moderators = self.db.moderators self.purchases = self.db.purchases self.sales = self.db.sales self.settings = self.db.settings
def handle_response(listings, node): count = 0 if listings is not None: for l in listings.listing: try: if l.contract_hash not in self.factory.outstanding_listings[message_id]: listing_json = { "id": message_id, "listing": { "guid": node.id.encode("hex"), "handle": listings.handle, "avatar_hash": listings.avatar_hash.encode("hex"), "title": l.title, "contract_hash": l.contract_hash.encode("hex"), "thumbnail_hash": l.thumbnail_hash.encode("hex"), "category": l.category, "price": l.price, "currency_code": l.currency_code, "nsfw": l.nsfw, "origin": str(CountryCode.Name(l.origin)), "ships_to": [] } } for country in l.ships_to: listing_json["listing"]["ships_to"].append(str(CountryCode.Name(country))) if not os.path.isfile(os.path.join( \ DATA_FOLDER, 'cache', l.thumbnail_hash.encode("hex"))): self.factory.mserver.get_image(node, l.thumbnail_hash) if not os.path.isfile(os.path.join( \ DATA_FOLDER, 'cache', listings.avatar_hash.encode("hex"))): self.factory.mserver.get_image(node, listings.avatar_hash) self.transport.write(str(bleach.clean( json.dumps(listing_json, indent=4), tags=ALLOWED_TAGS))) count += 1 self.factory.outstanding_listings[message_id].append(l.contract_hash) if count == 3: break except Exception: pass if node.id in vendors: del vendors[node.id] else: if node.id in vendors: del vendors[node.id] if node.id in self.factory.mserver.protocol.multiplexer.vendors: del self.factory.mserver.protocol.multiplexer.vendors[node.id] self.factory.db.vendors.delete_vendor(node.id.encode("hex")) if only_following: vendor_list = get_following_from_vendors(vendors) else: vendor_list = vendors.values() if len(vendor_list) > 0: shuffle(vendor_list) node_to_ask = vendor_list[0] if node_to_ask is not None: self.factory.mserver.get_listings(node_to_ask).addCallback(handle_response, node_to_ask)
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) file_name += digest(json.dumps(self.contract, indent=4)).encode("hex")[:8] # 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]) if "category" in vendor_item: 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 self.db.HashMap().insert(data.contract_hash, file_path) # save the `ListingMetadata` protobuf to the database as well self.db.ListingsStore().add_listing(data)
def handle_response(listings, node): count = 0 if listings is not None: for l in listings.listing: if l.contract_hash not in self.factory.outstanding[ message_id]: listing_json = { "id": message_id, "listing": { "guid": node.id.encode("hex"), "handle": listings.handle, "avatar_hash": listings.avatar_hash.encode("hex"), "title": l.title, "contract_hash": l.contract_hash.encode("hex"), "thumbnail_hash": l.thumbnail_hash.encode("hex"), "category": l.category, "price": l.price, "currency_code": l.currency_code, "nsfw": l.nsfw, "origin": str(CountryCode.Name(l.origin)), "ships_to": [] } } for country in l.ships_to: listing_json["listing"]["ships_to"].append( str(CountryCode.Name(country))) if not os.path.isfile(DATA_FOLDER + 'cache/' + l.thumbnail_hash.encode("hex")): self.factory.mserver.get_image( node, l.thumbnail_hash) if not os.path.isfile( DATA_FOLDER + 'cache/' + listings.avatar_hash.encode("hex")): self.factory.mserver.get_image( node, listings.avatar_hash) self.sendMessage(json.dumps(listing_json, indent=4), False) count += 1 self.factory.outstanding[message_id].append( l.contract_hash) if count == 3: return count vendors.remove(node) else: VendorStore().delete_vendor(node.id) vendors.remove(node) return count
def parse_profile(profile): if profile is not None: profile_json = { "profile": { "name": profile.name, "location": str(CountryCode.Name(profile.location)), "encryption_key": profile.encryption_key.public_key.encode("hex"), "nsfw": profile.nsfw, "vendor": profile.vendor, "moderator": profile.moderator, "handle": profile.handle, "about": profile.about, "website": profile.website, "email": profile.email, "primary_color": profile.primary_color, "secondary_color": profile.secondary_color, "background_color": profile.background_color, "text_color": profile.text_color, "pgp_key": profile.pgp_key.public_key, "avatar_hash": profile.avatar_hash.encode("hex"), "header_hash": profile.header_hash.encode("hex"), "social_accounts": {} } } if "guid" in request.args: profile_json["profile"]["guid"] = request.args["guid"][0] else: profile_json["profile"][ "guid"] = self.keychain.guid.encode("hex") for account in profile.social: profile_json["profile"]["social_accounts"][str( objects.Profile.SocialAccount.SocialType.Name( account.type)).lower()] = { "username": account.username, "proof_url": account.proof_url } request.setHeader('content-type', "application/json") request.write(json.dumps(profile_json, indent=4)) request.finish() else: request.write(json.dumps({})) request.finish()
def respond(l, node): if l is not None: listing_json = { "id": message_id, "listing": { "guid": node.id.encode("hex"), "title": l.title, "contract_hash": l.contract_hash.encode("hex"), "thumbnail_hash": l.thumbnail_hash.encode("hex"), "category": l.category, "price": l.price, "currency_code": l.currency_code, "nsfw": l.nsfw, "origin": str(CountryCode.Name(l.origin)), "ships_to": [] } } for country in l.ships_to: listing_json["listing"]["ships_to"].append( str(CountryCode.Name(country))) self.sendMessage(json.dumps(listing_json, indent=4), False)
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 migratev2(db): ser = db.listings.get_proto() if ser is not None: path = os.path.join(DATA_FOLDER, "listings.csv") with open(path, 'w') as csvfile: fieldnames = [ "contract_type", "pricing_currency", "language", "title", "description", "processing_time", "price", "nsfw", "image_urls", "categories", "condition", "quantity", "sku_number", "shipping_option1_name", "shipping_option1_countries", "shipping_option1_service1_name", "shipping_option1_service1_estimated_delivery", "shipping_option1_service1_estimated_price", "shipping_option2_name", "shipping_option2_countries", "shipping_option2_service1_name", "shipping_option2_service1_estimated_delivery", "shipping_option2_service1_estimated_price" ] writer = csv.DictWriter(csvfile, fieldnames=fieldnames) writer.writeheader() l = objects.Listings() l.ParseFromString(ser) for listing in l.listing: with open( db.filemap.get_file( listing.contract_hash.encode("hex")), "r") as filename: contract = json.loads(filename.read(), object_pairs_hook=OrderedDict) price = "" if listing.currency_code.lower() == "btc": price = contract["vendor_offer"]["listing"]["item"][ "price_per_unit"]["bitcoin"] price = int(price * 100000000) else: price = contract["vendor_offer"]["listing"]["item"][ "price_per_unit"]["fiat"]["price"] sku = "" if "sku" in contract["vendor_offer"]["listing"]["item"]: sku = contract["vendor_offer"]["listing"]["item"]["sku"] condition = "" if "condition" in contract["vendor_offer"]["listing"]["item"]: condition = contract["vendor_offer"]["listing"]["item"][ "condition"] category = "" if "category" in contract["vendor_offer"]["listing"]["item"]: category = contract["vendor_offer"]["listing"]["item"][ "category"] contract_type = "PHYSICAL_GOOD" if contract["vendor_offer"]["listing"]["metadata"][ "category"] == "digital good": contract_type = "DIGITAL_GOOD" row = { 'contract_type': contract_type, 'pricing_currency': listing.currency_code, 'language': 'english', 'title': listing.title, 'description': contract["vendor_offer"]["listing"]["item"]["description"], 'processing_time': contract["vendor_offer"]["listing"]["item"] ["process_time"], 'price': price, 'nsfw': str(listing.nsfw), 'image_urls': '', 'categories': category, 'condition': condition, 'quantity': '-1', 'sku_number': sku } img64 = [] for img_hash in contract["vendor_offer"]["listing"]["item"][ "image_hashes"]: image_path = db.filemap.get_file(img_hash) with open(image_path, "rb") as image_file: encoded_string = base64.b64encode(image_file.read()) img64.append(encoded_string) if len(img64) == 1: row["image_urls"] = img64[0] else: img_csv = '' r = 0 for img in img64: r += 1 img_csv += img if r != len(img64): img_csv += "," row["image_urls"] = img_csv if contract_type == "PHYSICAL_GOOD": if "free" in contract["vendor_offer"]["listing"][ "shipping"]: row["shipping_option1_name"] = "Free Shipping" countries = [] for country in listing.ships_to: countries.append(str(CountryCode.Name(country))) if len(countries) == 1: row["shipping_option1_countries"] = countries[0] else: country_csv = '' r = 0 for c in countries: r += 1 country_csv += c if r != len(countries): country_csv += "," row["shipping_option1_countries"] = country_csv row["shipping_option1_service1_name"] = "default service" ed = "standard shipping time" row["shipping_option1_service1_estimated_delivery"] = ed row["shipping_option1_service1_estimated_price"] = "0" elif "flat_fee" in contract["vendor_offer"]["listing"][ "shipping"]: cc = "bitcoin" if listing.currency_code.lower() != "btc": cc = "fiat" if "domestic" in contract["vendor_offer"]["listing"][ "shipping"]["flat_fee"][cc]["price"]: row["shipping_option1_name"] = "Domestic Shipping" row["shipping_option1_countries"] = contract[ "vendor_offer"]["listing"]["shipping"][ "shipping_origin"] row["shipping_option1_service1_name"] = "default service" ed = contract["vendor_offer"]["listing"][ "shipping"]["est_delivery"]["domestic"] if ed == "": ed = "standard shipping time" row["shipping_option1_service1_estimated_delivery"] = ed ship_price = contract["vendor_offer"]["listing"][ "shipping"]["flat_fee"][cc]["price"][ "domestic"] if cc == "bitcoin": ship_price = int(ship_price * 100000000) row["shipping_option1_service1_estimated_price"] = ship_price if "international" in contract["vendor_offer"][ "listing"]["shipping"]["flat_fee"][cc][ "price"]: row["shipping_option2_name"] = "International Shipping" countries = [] for country in listing.ships_to: countries.append(str( CountryCode.Name(country))) if len(countries) == 1: row["shipping_option2_countries"] = countries[ 0] else: country_csv = '' r = 0 for c in countries: r += 1 country_csv += c if r != len(countries): country_csv += "," row["shipping_option2_countries"] = country_csv row["shipping_option2_service1_name"] = "default service" ed = contract["vendor_offer"]["listing"][ "shipping"]["est_delivery"]["international"] if ed == "": ed = "standard shipping time" row["shipping_option2_service1_estimated_delivery"] = ed row["shipping_option2_service1_estimated_price"] = contract[ "vendor_offer"]["listing"]["shipping"][ "flat_fee"][cc]["price"]["domestic"] writer.writerow(row) return path else: raise Exception("failed to deserialize listings")
def update_profile(self, request): try: p = Profile(self.db) if not p.get().encryption_key \ and "name" not in request.args \ and "location" not in request.args: request.write( json.dumps( { "success": False, "reason": "name or location not included" }, indent=4)) request.finish() 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 "short_description" in request.args: u.short_description = request.args["short_description"][0] if "nsfw" in request.args: u.nsfw = bool(request.args["nsfw"][0]) if "vendor" in request.args: u.vendor = bool(request.args["vendor"][0]) if "moderator" in request.args: u.moderator = bool(request.args["moderator"][0]) if "website" in request.args: u.website = request.args["website"][0] if "email" in request.args: u.email = request.args["email"][0] if "primary_color" in request.args: u.primary_color = int(request.args["primary_color"][0]) if "secondary_color" in request.args: u.secondary_color = int(request.args["secondary_color"][0]) if "background_color" in request.args: u.background_color = int(request.args["background_color"][0]) if "text_color" in request.args: u.text_color = int(request.args["text_color"][0]) if "avatar" in request.args: u.avatar_hash = unhexlify(request.args["avatar"][0]) if "header" in request.args: u.header_hash = unhexlify(request.args["header"][0]) if "pgp_key" in request.args and "signature" in request.args: p.add_pgp_key(request.args["pgp_key"][0], request.args["signature"][0], self.keychain.guid.encode("hex")) enc = u.PublicKey() enc.public_key = self.keychain.encryption_pubkey enc.signature = self.keychain.signing_key.sign(enc.public_key)[:64] u.encryption_key.MergeFrom(enc) p.update(u) request.write(json.dumps({"success": True})) request.finish() return server.NOT_DONE_YET except Exception, e: request.write( json.dumps({ "success": False, "reason": e.message }, indent=4)) request.finish() return server.NOT_DONE_YET
def handle_response(listings, node): count = 0 if listings is not None: for l in listings.listing: try: if l.contract_hash not in self.factory.outstanding_listings[ message_id]: listing_json = { "id": message_id, "listing": { "guid": node.id.encode("hex"), "handle": listings.handle, "avatar_hash": listings.avatar_hash.encode("hex"), "title": l.title, "contract_hash": l.contract_hash.encode("hex"), "thumbnail_hash": l.thumbnail_hash.encode("hex"), "category": l.category, "price": l.price, "currency_code": l.currency_code, "nsfw": l.nsfw, "origin": str(CountryCode.Name(l.origin)), "ships_to": [] } } for country in l.ships_to: listing_json["listing"]["ships_to"].append( str(CountryCode.Name(country))) if not os.path.isfile( DATA_FOLDER + 'cache/' + l.thumbnail_hash.encode("hex")): self.factory.mserver.get_image( node, l.thumbnail_hash) if not os.path.isfile( DATA_FOLDER + 'cache/' + listings.avatar_hash.encode("hex")): self.factory.mserver.get_image( node, listings.avatar_hash) self.transport.write( str( bleach.clean(json.dumps(listing_json, indent=4), tags=ALLOWED_TAGS))) count += 1 self.factory.outstanding_listings[ message_id].append(l.contract_hash) if count == 3: break except Exception: pass vendors.remove(node) else: vendors.remove(node) if node.id in self.factory.mserver.protocol.multiplexer.vendors: del self.factory.mserver.protocol.multiplexer.vendors[ node.id]