Ejemplo n.º 1
0
def test_lookups():
    a = entities.Listing(title="lista", body="ba", key_name="foo")
    a.put()
    assert helpers.lookup_listing("foo").title == "lista"

    a.title = "listb"
    a.put()
    assert helpers.lookup_listing("foo").title == "lista"

    helpers.invalidate_listing(a)
    assert helpers.lookup_listing("foo").title == "listb"
Ejemplo n.º 2
0
def test_lookups():
    a = entities.Listing(title="lista", body="ba", key_name="foo")
    a.put()
    assert helpers.lookup_listing("foo").title == "lista"

    a.title = "listb"
    a.put()
    assert helpers.lookup_listing("foo").title == "lista"

    helpers.invalidate_listing(a)
    assert helpers.lookup_listing("foo").title == "listb"
Ejemplo n.º 3
0
def claim_listing(permalink):
    """Allow a seller to claim a listing whose email they have lost."""

    # Look up the existing listing used for this person.
    listing = helpers.lookup_listing(permalink)
    if not listing:
        abort(404)

    # Prevent button spamming.
    seller = listing.seller
    title = listing.title
    if (dos.rate_limit(listing.seller, 4, 60) or
            dos.rate_limit(listing.key().name, 2, 60)):
        seller = "*****@*****.**"
        title = "SPAM REQUEST: " + listing.title

    # Send the user an email to let them edit the listing.
    email.send_mail(
        to=seller,
        subject="Marketplace Listing \"{}\"".format(title),
        html=render_template("email/welcome.html", listing=listing),
        text=render_template("email/welcome.txt", listing=listing)
    )

    flash("We've emailed you a link to edit this listing.")

    return redirect(url_for("show_listing", permalink=listing.permalink))
Ejemplo n.º 4
0
def edit_listing(permalink):
    """Allow a seller to update or unpublish a listing."""

    # Retrieve the listing by key.
    listing = helpers.lookup_listing(permalink)
    if not listing:
        abort(404)

    form = forms.EditListingForm()

    # Prevent non-creators from editing a listing.
    if session.get("email") != listing.seller or not session["email"]:
        abort(403)

    # Allow the author of a listing to unpublish it.
    if request.form.get("unpublish"):
        listing.posting_time = 0.0
        listing.put()
        helpers.invalidate_listing(listing)

        return redirect("/")

    # Upload photos after validate_on_submit(), even if other fields in the form
    # are invalid.
    is_valid = form.validate_on_submit()
    if request.method == "POST":
        photos = []
        for photo in form.photos:
            if not photo.data:
                continue
            image = photo.data["image"]
            if not image or (hasattr(image, "filename") and not image.filename):
                continue
            photos.append(image)
        listing.photos = photos

    # Allow authors to edit listings.
    if is_valid:
        listing.title = form.title.data
        listing.body = form.description.data
        listing.categories = form.categories.data
        listing.price = int(form.price.data * 100)
        listing.put()

        helpers.invalidate_listing(listing)

        return redirect(url_for("show_listing", permalink=listing.permalink))

    # Display an edit form.
    form.title.data = listing.title
    form.description.data = listing.body
    form.categories.data = listing.categories
    form.price.data = listing.price / 100.0
    for index, entry in enumerate(form.photos.entries):
        if index < len(listing.photos):
            entry["image"].data = listing.photos[index]
        else:
            entry["image"].data = None

    return render_template("listing_form.html", type="Edit", form=form)
Ejemplo n.º 5
0
def claim_listing(permalink):
    """Allow a seller to claim a listing whose email they have lost."""

    # Look up the existing listing used for this person.
    listing = helpers.lookup_listing(permalink)
    if not listing:
        abort(404)

    # Prevent button spamming.
    seller = listing.seller
    title = listing.title
    if dos.rate_limit(listing.seller, 4, 60) or dos.rate_limit(listing.key().name, 2, 60):
        seller = "*****@*****.**"
        title = "SPAM REQUEST: " + listing.title

    # Send the user an email to let them edit the listing.
    message = sendgrid.Mail()
    message.set_from("Marketplace Team <*****@*****.**>")
    message.add_to(seller)
    message.set_subject('Marketplace Listing "{}"'.format(title))
    message.set_html(render_template("email/welcome.html", listing=listing))
    message.set_text(render_template("email/welcome.txt", listing=listing))
    config.send_grid_client.send(message)

    flash("We've emailed you a link to edit this listing.")

    return redirect(url_for("show_listing", permalink=listing.permalink))
Ejemplo n.º 6
0
def run_integration_test():
    """Ensures that this version of Marketplace mostly works."""

    def opener(url):
        """Stub to map network activity to a local directory."""
        path = "{}/fixtures{}".format(os.path.dirname(__file__),
                                      urlparse.urlparse(url).path)
        return open(path)

    # Migrate a listing from the old site.
    replication.pull_from_old_marketplace("listing-a", _urlopen=opener)

    # Verify that the listing was created.
    data = helpers.lookup_listing("listing-a")
    if (data.key().name() != "listing-a" or
        data.title != "my fancy sublet" or
        data.body != "description here" or
        data.price != 123456 or
        len(data.photos) != 2 or
        data.posting_time != 1441609780.0 or
        data.seller != "*****@*****.**"):

        raise ValueError("migration failed")

    return "ok"
Ejemplo n.º 7
0
def show_listing(permalink):
    """View a particular listing and provide links to place an inquiry."""

    # Retrieve the listing by key.
    listing = helpers.lookup_listing(permalink)
    if not listing:
        abort(404)

    # If the listing isn't yet published, check the URL key and update session.
    if request.args.get("key") == listing.admin_key and listing.admin_key:
        session["email"] = listing.seller
        if not listing.posting_time:
            listing.posting_time = time.time()
            listing.put()
            helpers.invalidate_listing(listing)

            flash("Your listing has been published.")
            return redirect(
                url_for("show_listing",
                        permalink=permalink,
                        q=request.args.get("q")))

    # Otherwise, hide the listing.
    elif not listing.posting_time:
        abort(404)

    # Display a form for buyers to place an offer.
    buyer_form = forms.BuyerForm()

    buyer = buyer_form.buyer.data
    message = buyer_form.message.data
    seller = listing.seller

    # Validate emails with the submission of the form.
    buyer_form.post_validate = (
        lambda: policy.place_inquiry(listing, buyer, message))

    # Handle submissions on the form.
    if buyer_form.validate_on_submit():

        # Track what requests are sent to which people.
        helpers.add_inqury(listing, buyer, message)

        # Provide a flash message.
        flash("Your inquiry has been sent.")

        return redirect(url_for("show_listing", permalink=permalink))

    # Have the form email default to the value from the session.
    if not buyer_form.buyer.data:
        buyer_form.buyer.data = session.get("email")

    # Display the resulting template.
    return render_template("listing_show.html",
                           listing=listing,
                           buyer_form=buyer_form)
Ejemplo n.º 8
0
def api_one_listing(permalink):
    """Display a single listing matching the given query."""

    # Parse filtering options from query.
    listing = helpers.lookup_listing(permalink)
    if not listing or not listing.posting_time:
        abort(404)

    # Return JSON if requested.
    return jsonify(_externalize(listing))
Ejemplo n.º 9
0
def api_one_listing(permalink):
    """Display a single listing matching the given query."""

    # Parse filtering options from query.
    listing = helpers.lookup_listing(permalink)
    if not listing or not listing.posting_time:
        abort(404)

    # Return JSON if requested.
    return jsonify(_externalize(listing))
Ejemplo n.º 10
0
def test_inquiries():
    ent = entities.Listing(title="car", key_name="entfortest")
    ent.put()

    helpers.add_inqury(ent, "e@mail", "foobar")
    helpers.add_inqury(ent, "e@mail", "foobar")
    helpers.add_inqury(ent, "e2@mail", "foobar")

    ent = helpers.lookup_listing("entfortest")
    assert set(ent.buyers) == set(["e@mail", "e2@mail"])
    assert len(ent.buyers) == 2
Ejemplo n.º 11
0
def test_inquiries():
    ent = entities.Listing(title="car", key_name="entfortest")
    ent.put()

    helpers.add_inqury(ent, "e@mail", "foobar")
    helpers.add_inqury(ent, "e@mail", "foobar")
    helpers.add_inqury(ent, "e2@mail", "foobar")

    ent = helpers.lookup_listing("entfortest")
    assert set(ent.buyers) == set(["e@mail", "e2@mail"])
    assert len(ent.buyers) == 2
Ejemplo n.º 12
0
def show_listing(permalink):
    """View a particular listing and provide links to place an inquiry."""

    # Retrieve the listing by key.
    listing = helpers.lookup_listing(permalink)
    if not listing:
        abort(404)

    # If the listing isn't yet published, check the URL key and update session.
    if request.args.get("key") == listing.admin_key and listing.admin_key:
        session["email"] = listing.seller
        if not listing.posting_time:
            listing.posting_time = time.time()
            listing.put()
            helpers.invalidate_listing(listing)

            flash("Your listing has been published.")
            return redirect(url_for("show_listing", permalink=permalink,
                                                    q=request.args.get("q")))

    # Otherwise, hide the listing.
    elif not listing.posting_time:
        abort(404)

    # Display a form for buyers to place an offer. 
    buyer_form = forms.BuyerForm()

    buyer = buyer_form.buyer.data
    message = buyer_form.message.data
    seller = listing.seller

    # Validate emails with the submission of the form.
    buyer_form.post_validate = (
        lambda: policy.place_inquiry(listing, buyer, message))

    # Handle submissions on the form.
    if buyer_form.validate_on_submit():

        # Track what requests are sent to which people.
        helpers.add_inqury(listing, buyer, message)

        # Provide a flash message.
        flash("Your inquiry has been sent.")

        return redirect(url_for("show_listing", permalink=permalink))

    # Have the form email default to the value from the session.
    if not buyer_form.buyer.data:
        buyer_form.buyer.data = session.get("email")

    # Display the resulting template.
    return render_template("listing_show.html", listing=listing,
                           buyer_form=buyer_form)
Ejemplo n.º 13
0
def claim_listing(permalink):
    """Allow a seller to claim a listing whose email they have lost."""

    # Look up the existing listing used for this person.
    listing = helpers.lookup_listing(permalink)
    if not listing:
        abort(404)

    # Follow policy when sending an email to the user.
    try:
        policy.claim_listing(listing)
    except ValidationError, e:
        flash(str(e), "danger")
Ejemplo n.º 14
0
def claim_listing(permalink):
    """Allow a seller to claim a listing whose email they have lost."""

    # Look up the existing listing used for this person.
    listing = helpers.lookup_listing(permalink)
    if not listing:
        abort(404)

    # Follow policy when sending an email to the user.
    try:
        policy.claim_listing(listing)
    except ValidationError, e:
        flash(str(e), "danger")
Ejemplo n.º 15
0
def show_listing(permalink):
    """View a particular listing and provide links to place an inquiry."""

    # Retrieve the listing by key.
    listing = helpers.lookup_listing(permalink)
    if not listing:
        abort(404)

    # If the listing isn't yet published, check the URL key and update session.
    if request.args.get("key") == listing.admin_key and listing.admin_key:
        session["email"] = listing.seller
        if not listing.posting_time:
            listing.posting_time = time.time()
            listing.put()
            helpers.invalidate_listing(listing)

            flash("Your listing has been published.")
            return redirect(url_for("show_listing", permalink=permalink,
                                    q=request.args.get("q")))

    # Otherwise, hide the listing.
    elif not listing.posting_time:
        abort(404)

    # Display a form for buyers to place an offer.
    buyer_form = forms.BuyerForm()

    # Handle submissions on the form.
    if buyer_form.validate_on_submit():
        buyer = buyer_form.buyer.data
        message = buyer_form.message.data
        seller = listing.seller

        # Track what requests are sent to which people.
        helpers.add_inqury(listing, buyer, message)

        # Block spam inquiries.
        if (buyer.strip() == "*****@*****.**" or
                buyer.strip() == "*****@*****.**" or
                dos.rate_limit(buyer.strip(), 4, 60) or
                dos.rate_limit(request.remote_addr, 4, 60) or
                dos.rate_limit(listing.seller, 20, 3600 * 24)):

            message = "MESSAGE BLOCKED!\n\n" + str(message)
            seller = "*****@*****.**"

        # Send a listing to the person.
        email.send_mail(
            to=seller,
            reply_to=buyer,
            subject="Re: Marketplace Listing \"{}\"".format(listing.title),
            html=render_template("email/inquiry.html", **locals()),
            text=render_template("email/inquiry.txt", **locals()),
        )

        return redirect(url_for("show_listing", permalink=permalink))

    # Have the form email default to the value from the session.
    if not buyer_form.buyer.data:
        buyer_form.buyer.data = session.get("email")

    # Display the resulting template.
    return render_template("listing_show.html", listing=listing,
                           buyer_form=buyer_form)
Ejemplo n.º 16
0
def edit_listing(permalink):
    """Allow a seller to update or unpublish a listing."""

    # Retrieve the listing by key.
    listing = helpers.lookup_listing(permalink)
    if not listing:
        abort(404)

    form = forms.EditListingForm()

    # Prevent non-creators from editing a listing.
    if session.get("email") != listing.seller or not session["email"]:
        abort(403)

    # Allow the author of a listing to unpublish it.
    if request.form.get("unpublish"):
        listing.posting_time = 0.0
        listing.put()
        helpers.invalidate_listing(listing)

        return redirect("/")

    # Upload photos after validate_on_submit(), even if other fields in the form
    # are invalid.
    is_valid = form.validate_on_submit()
    if request.method == "POST":
        photos = []
        for photo in form.photos:
            if not photo.data:
                continue
            image = photo.data["image"]
            if not image or (hasattr(image, "filename")
                             and not image.filename):
                continue
            photos.append(image)

        listing.photos = photos

    # Allow authors to edit listings.
    if is_valid:
        listing.title = form.title.data
        listing.body = form.description.data
        listing.categories = form.categories.data
        listing.price = int(form.price.data * 100)
        listing.put()

        helpers.invalidate_listing(listing)

        return redirect(url_for("show_listing", permalink=listing.permalink))

    # Display an edit form.
    form.title.data = listing.title
    form.description.data = listing.body
    form.categories.data = listing.categories
    form.price.data = listing.price / 100.0
    for index, entry in enumerate(form.photos.entries):
        if index < len(listing.photos):
            entry["image"].data = listing.photos[index]
        else:
            entry["image"].data = None

    return render_template("listing_form.html", type="Edit", form=form)