Skip to content

Commit

Permalink
Add replication for new inquiries and listings.
Browse files Browse the repository at this point in the history
  • Loading branch information
fatlotus committed Mar 8, 2016
1 parent eb4586e commit ec30340
Show file tree
Hide file tree
Showing 9 changed files with 163 additions and 7 deletions.
25 changes: 24 additions & 1 deletion caravel/model/inquiry.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,38 @@
from caravel.model.principal import PrincipalMixin
from caravel.model.side_effects import SideEffectsMixin
from caravel.model.rate_limits import RateLimitMixin
from caravel.model.replication import ReplicationMixin


from flask import render_template


class _Inquiry(TimeOrderMixin, PrincipalMixin, ModeratedMixin,
ndb.Model):
ReplicationMixin, ndb.Model):

REPLICATION_URL = "https://go-marketplace.appspot.com/inquiries"

message = ndb.StringProperty()
listing = ndb.KeyProperty(kind=listing.Listing)

def encode_for_replication(self):
"""Flattens this Listing into a JSON dict."""

data = self.to_dict()
data["listing"] = self.listing.id()
data["sender"] = {
"email": self.principal.email,
"validated": (self.principal.auth_method == "GOOGLE_APPS")
}
data["moderated"] = (bool(self.principal.validated_by) or
(self.principal.auth_method == "GOOGLE_APPS"))
del data["principal"]
del data["posted_at"]
if "run_trigger" in data:
del data["run_trigger"]

return data


class Inquiry(SideEffectsMixin, _Inquiry):

Expand Down
30 changes: 29 additions & 1 deletion caravel/model/listing.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from caravel.model.full_text import FullTextMixin
from caravel.model.rate_limits import RateLimitMixin
from caravel.model.sellable import SellableMixin
from caravel.model.replication import ReplicationMixin

from caravel import utils

Expand All @@ -21,10 +22,11 @@

class _Listing(CategoriesMixin, PhotosMixin, PrincipalMixin, TimeOrderMixin,
SchemaMixin, PriceMixin, RateLimitMixin, ModeratedMixin,
SellableMixin, FullTextMixin, ndb.Model):
SellableMixin, FullTextMixin, ReplicationMixin, ndb.Model):

SCHEMA_VERSION = 12
MARK_AS_OLD_AFTER = datetime.timedelta(days=30)
REPLICATION_URL = "https://go-marketplace.appspot.com/listings"

title = ndb.StringProperty()
body = ndb.TextProperty()
Expand All @@ -33,6 +35,32 @@ class _Listing(CategoriesMixin, PhotosMixin, PrincipalMixin, TimeOrderMixin,
def can_bump(self):
return self.age >= datetime.timedelta(days=7)

def encode_for_replication(self):
"""Flattens this Listing into a JSON dict."""

data = self.to_dict()
data["posted_at"] = data["posted_at"].isoformat()
data["photos"] = [{"small": photo.public_url("small"),
"large": photo.public_url("large")}
for photo in data["photos"]]
data["price"] = float(data["price"])
if "run_trigger" in data:
del data["run_trigger"]
del data["version"]
del data["burst_count"]
del data["daily_count"]
del data["keywords"]
del data["principal"]

data["seller"] = {
"email": self.principal.email,
"validated": (self.principal.auth_method == "GOOGLE_APPS")
}
data["moderated"] = (bool(self.principal.validated_by) or
(self.principal.auth_method == "GOOGLE_APPS"))

return data


class Listing(SideEffectsMixin, _Listing):

Expand Down
31 changes: 31 additions & 0 deletions caravel/model/replication.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from google.appengine.ext import ndb, db
import urllib2
import json
from caravel.storage import config


class ReplicationMixin(ndb.Model):

"""
The ReplicatedMixin triggers a background urlfetch call to update this
listing.
"""

REPLICATION_URL = None

def encode_for_replication(self):
return self.to_dict()

def _post_put_hook(self, future):
"""
Write this entity to the third-party site URL.
"""

if self.REPLICATION_URL:
data = self.encode_for_replication()
data["key"] = self.key.id()
data["replication_key"] = config.replication_key

urllib2.urlopen(self.REPLICATION_URL, json.dumps(data))

return super(ReplicationMixin, self)._post_put_hook(future)
1 change: 1 addition & 0 deletions caravel/storage/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,6 @@ def get_tor_addresses():
"recaptcha_private_key",
"6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe")
app.config["RECAPTCHA_DATA_ATTRS"] = {"size": "compact"}
replication_key = lookup("replication_key", "~key~")

Bootstrap(app)
5 changes: 5 additions & 0 deletions caravel/templates/listings/map.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<div class="col-xs-12 col-sm-6 float-to-inline-block listing thumbnail-width">
<div class="thumbnail">
<iframe style="width:100%;height:350px" frameborder="0" style="border:0" src="https://www.google.com/maps/embed/v1/view?zoom=14&center=41.7943%2C-87.5907&key=AIzaSyDzo7LIWcwdUI1_cUBML8HSphyuFBDTs6M" allowfullscreen></iframe>
</div>
</div>
11 changes: 6 additions & 5 deletions caravel/tests/helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import uuid
import time
import sys
import urllib2
import os
from contextlib import contextmanager

Expand Down Expand Up @@ -94,10 +95,10 @@ def setUp(self):
sendgrid = config.send_grid_client
self._send, sendgrid.send = sendgrid.send, self.emails.append

# Capture outgoing Slack messages.
# self.chats = []
# self._send_chat = slack.send_chat
# slack.send_chat = lambda **kw: self.chats.append(kw)
# Capture outgoing webhooks.
self.webhooks = []
self._urlopen = urllib2.urlopen
urllib2.urlopen = lambda url, body: self.webhooks.append((url, body))

# Ensure that UUIDs are deterministic.
self._uuid4 = uuid.uuid4
Expand Down Expand Up @@ -156,7 +157,7 @@ def tearDown(self):
# Un-stub mocks.
uuid.uuid4 = self._uuid4
config.send_grid_client.send = self._send
# slack.send_chat = self._send_chat
urllib2.urlopen = self._urlopen

super(CaravelTestCase, self).tearDown()

Expand Down
67 changes: 67 additions & 0 deletions caravel/tests/test_replication.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
from caravel.tests import helper
from caravel import model
import json


class TestListings(helper.CaravelTestCase):

def test_creation(self):
# Submit an inquiry.
with self.google_apps_user("visitor@uchicago.edu"):
self.post("/listing_b", data={
"principal": "buyer@foo.com",
"message": u"message\u2606 goes here",
"csrf_token": self.csrf_token("/listing_b"),
})

self.assertEquals(
[(u, json.loads(d)) for u, d in self.webhooks],
[
("https://go-marketplace.appspot.com/listings",
{u"replication_key": u"~key~",
u"key": u"listing_a",
u"title": u"Listing \u2606A",
u"sold": False,
u"body": u"Body of \u2606A",
u"categories": [u"cars"],
u"photos": [
{u"large": u"/_ah/gcs/test.appspot.com/listing-a-large",
u"small": u"/_ah/gcs/test.appspot.com/listing-a-small"},
{u"large": u"/_ah/gcs/test.appspot.com/listing-a2-large",
u"small": u"/_ah/gcs/test.appspot.com/listing-a2-small"}
],
u"posted_at": self.listing_a.posted_at.isoformat(),
u"price": 3.1,
u"seller": {
u"email": u"seller-a@uchicago.edu",
u"validated": True},
u"moderated": True}),
("https://go-marketplace.appspot.com/listings",
{u"replication_key": u"~key~",
u"key": u"listing_b",
u"title": u"Listing \u2606B",
u"sold": False,
u"body": u"Body of \u2606B",
u"categories": [u"apartments"],
u"photos": [
{u"large": u"/_ah/gcs/test.appspot.com/listing-b-large",
u"small": u"/_ah/gcs/test.appspot.com/listing-b-small"},
{u"large": u"/_ah/gcs/test.appspot.com/listing-b2-large",
u"small": u"/_ah/gcs/test.appspot.com/listing-b2-small"}
],
u"posted_at": self.listing_b.posted_at.isoformat(),
u"price": 71.1,
u"seller": {
u"email": u"seller-b@uchicago.edu",
u"validated": False},
u"moderated": True}),
("https://go-marketplace.appspot.com/inquiries",
{u"key": 11,
u"listing": "listing_b",
u"message": u"message\u2606 goes here",
u"moderated": True,
u"replication_key": u"~key~",
u"sender": {
u"email": u"visitor@uchicago.edu", u"validated": True}
})
])
Empty file.
Empty file.

0 comments on commit ec30340

Please sign in to comment.