def test_update_two_playgrounds(self): utils.load_test_playgrounds() response = self.client.post(url_for('update_playground'), data={ 'id': 1, 'name': 'NEW NAME' }) self.assertEqual(response.status_code, 302) redirect_url = '%s/playground/%s.html' % (app_config.S3_BASE_URL, Playground.get(id=1).slug) self.assertEqual(response.headers['Location'].split('?')[0], redirect_url) response = self.client.post(url_for('update_playground'), data={ 'id': 2, 'name': 'ANOTHER NEW NAME' }) self.assertEqual(response.status_code, 302) redirect_url = '%s/playground/%s.html' % (app_config.S3_BASE_URL, Playground.get(id=2).slug) self.assertEqual(response.headers['Location'].split('?')[0], redirect_url) with open('data/changes.json') as f: updates = json.load(f) self.assertEqual(len(updates), 2) self.assertEqual(updates[0]['action'], 'update') self.assertEqual(updates[0]['playground']['id'], 1) self.assertEqual(updates[0]['playground']['name'], 'NEW NAME') self.assertEqual(updates[1]['action'], 'update') self.assertEqual(updates[1]['playground']['id'], 2) self.assertEqual(updates[1]['playground']['name'], 'ANOTHER NEW NAME')
def delete_playground_confirm(playground_slug=None): from flask import request # Only handle POST requests. if request.method == 'GET' and playground_slug: # Run the id through Playground and flag it as deactivated Playground.get(slug=playground_slug).deactivate() return json.dumps({"slug": playground_slug, "action": "delete", "success": True})
def test_playground_exists(self): utils.load_test_playgrounds() playground = Playground.get(id=1) response = self.client.get(url_for("_playground", playground_slug=playground.slug)) assert playground.display_name in response.data
def test_playground_exists(self): utils.load_test_playgrounds() playground = Playground.get(id=1) response = self.client.get( url_for('_playground', playground_slug=playground.slug)) assert playground.display_name in response.data
def process_update(record): """ Process a single update record from changes.json. """ playground_id = record['playground']['id'] playground = Playground.get(id=playground_id) old_data = copy.copy(playground.__dict__['_data']) new_data = {} for key, value in record['playground'].items(): if key not in ['id', 'features']: new_data[key] = value setattr(playground, key, value) playground.save() old_features = [] for feature in PlaygroundFeature.select().where(PlaygroundFeature.playground == playground_id): old_features.append(feature.slug) # Delete any features already attached to this playground. PlaygroundFeature.delete().where(PlaygroundFeature.playground == playground_id).execute() new_features = record['playground']['features'] for slug in new_features: PlaygroundFeature.create( slug=slug, playground=playground ) revisions = [] for key, value in new_data.items(): if old_data[key] != new_data[key]: revisions.append({ 'field': key, 'from': old_data[key], 'to': new_data[key] }) if set(old_features) != set(new_features): for feature in copytext.Copy(app_config.COPY_PATH)['feature_list']: slug = feature['key'] # Removed if slug in old_features and slug not in new_features: revisions.append({'field': slug, 'from': 1, 'to': 0}) # Added if slug in new_features and slug not in old_features: revisions.append({'field': slug, 'from': 0, 'to': 1}) return playground, revisions
def test_delete_playground_confirm(self): utils.load_test_playgrounds() app_config.configure_targets('staging') s3 = boto.connect_s3() bucket = s3.get_bucket(app_config.S3_BUCKETS[0]) k = Key(bucket) k.key = '%s/playground/%s.html' % (app_config.PROJECT_SLUG, Playground.get(id=1).slug) k.set_contents_from_string('foo') response = self.client.get(url_for('delete_playground_confirm', playground_slug=Playground.get(id=1).slug)) self.assertEqual(response.status_code, 200) self.assertFalse(Playground.get(id=1).active) self.assertIsNone(bucket.get_key(k.key)) app_config.configure_targets(None)
def process_update(record): """ Process a single update record from changes.json. """ playground_id = record['playground']['id'] playground = Playground.get(id=playground_id) old_data = copy.copy(playground.__dict__['_data']) new_data = {} for key, value in record['playground'].items(): if key not in ['id', 'features']: new_data[key] = value setattr(playground, key, value) playground.save() old_features = [] for feature in PlaygroundFeature.select().where( PlaygroundFeature.playground == playground_id): old_features.append(feature.slug) # Delete any features already attached to this playground. PlaygroundFeature.delete().where( PlaygroundFeature.playground == playground_id).execute() new_features = record['playground']['features'] for slug in new_features: PlaygroundFeature.create(slug=slug, playground=playground) revisions = [] for key, value in new_data.items(): if old_data[key] != new_data[key]: revisions.append({ 'field': key, 'from': old_data[key], 'to': new_data[key] }) if set(old_features) != set(new_features): for feature in copytext.Copy(app_config.COPY_PATH)['feature_list']: slug = feature['key'] # Removed if slug in old_features and slug not in new_features: revisions.append({'field': slug, 'from': 1, 'to': 0}) # Added if slug in new_features and slug not in old_features: revisions.append({'field': slug, 'from': 0, 'to': 1}) return playground, revisions
def delete_playground_confirm(playground_slug=None): """ Confirm deleting a playground. """ from flask import request if request.method != 'GET': abort(401) if not playground_slug: abort(400) Playground.get(slug=playground_slug).deactivate() return json.dumps({ 'slug': playground_slug, 'action': 'delete', 'success': True })
def process_delete(record): """ Create a revision from the delete requests. """ playground_slug = record['playground']['slug'] playground = Playground.get(slug=playground_slug) revisions = [{"field": "active", "from": True, "to": False}, {"field": "reason", "from": "", "to": record['playground']['text']}] return (playground, revisions)
def test_delete_playground_confirm(self): utils.load_test_playgrounds() app_config.configure_targets('staging') s3 = boto.connect_s3() bucket = s3.get_bucket(app_config.S3_BUCKETS[0]) k = Key(bucket) k.key = '%s/playground/%s.html' % (app_config.PROJECT_SLUG, Playground.get(id=1).slug) k.set_contents_from_string('foo') response = self.client.get( url_for('delete_playground_confirm', playground_slug=Playground.get(id=1).slug)) self.assertEqual(response.status_code, 200) self.assertFalse(Playground.get(id=1).active) self.assertIsNone(bucket.get_key(k.key)) app_config.configure_targets(None)
def process_delete(record): """ Create a revision from the delete requests. """ playground_slug = record['playground']['slug'] playground = Playground.get(slug=playground_slug) revisions = [ { 'field': 'active', 'from': True, 'to': False}, { 'field': 'reason', 'from': '', 'to': record['playground']['text'] } ] return (playground, revisions)
def test_process_updates_features(self): utils.load_test_playgrounds() PlaygroundFeature.create(slug='transfer-stations-to-play-components', playground=Playground.get(id=1)) # JSON adds one feature and removes the one just created updated_playgrounds, revision_group = data.process_changes( 'tests/data/test_updates_features.json') features = PlaygroundFeature.select().where( PlaygroundFeature.playground == 1) self.assertEqual(features.count(), 1) feature = features[0] self.assertEqual(feature.slug, 'smooth-surface-throughout')
def test_process_updates_features(self): utils.load_test_playgrounds() PlaygroundFeature.create( slug='transfer-stations-to-play-components', playground=Playground.get(id=1) ) # JSON adds one feature and removes the one just created updated_playgrounds, revision_group = data.process_changes('tests/data/test_updates_features.json') features = PlaygroundFeature.select().where(PlaygroundFeature.playground == 1) self.assertEqual(features.count(), 1) feature = features[0] self.assertEqual(feature.slug, 'smooth-surface-throughout')
def _playground(playground_slug): """ Playground detail page. """ from flask import request context = make_context() context['playground'] = Playground.get(slug=playground_slug) context['fields'] = context['playground'].update_form() context['features'] = context['playground'].update_features_form() context['revisions'] = Revision.select()\ .where(Revision.playground == context['playground'].id)\ .where((Revision.action == 'insert') | (Revision.action == 'update'))\ .order_by(Revision.timestamp.desc()) context['display_field_name'] = display_field_name context['path'] = request.path return render_template('playground.html', **context)
def update_playground(): """ Update a single playground. """ from flask import request if request.method != 'POST': abort(401) playground = Playground.get(id=request.form.get('id')) payload = create_change_payload('update', request) payload['playground']['id'] = int(request.form.get('id')) write_data(payload) return redirect('%s/playground/%s.html?action=editing_thanks' % (app_config.S3_BASE_URL, playground.slug))
def process_delete(record): """ Create a revision from the delete requests. """ playground_slug = record['playground']['slug'] playground = Playground.get(slug=playground_slug) revisions = [{ 'field': 'active', 'from': True, 'to': False }, { 'field': 'reason', 'from': '', 'to': record['playground']['text'] }] return (playground, revisions)
def process_delete(record): """ Create a revision from the delete requests. """ playground_slug = record['playground']['slug'] playground = Playground.get(slug=playground_slug) revisions = [{ "field": "active", "from": True, "to": False }, { "field": "reason", "from": "", "to": record['playground']['text'] }] return (playground, revisions)
def test_prepare_email(self): utils.load_test_playgrounds() playground = Playground.get(id=1) log = '''[{ "field": "name", "from": "%s", "to": "Test Playground" }]''' % playground.name Revision(action='update', timestamp=time.mktime( datetime.datetime.now(pytz.utc).timetuple()), playground=playground, log=log, headers='', cookies='', revision_group=1).save() body = app._prepare_email(1) self.assertTrue(body.find(playground.name) >= 0)
def test_prepare_email(self): utils.load_test_playgrounds() playground = Playground.get(id=1) log = '''[{ "field": "name", "from": "%s", "to": "Test Playground" }]''' % playground.name Revision( action='update', timestamp=time.mktime(datetime.datetime.now(pytz.utc).timetuple()), playground=playground, log=log, headers='', cookies='', revision_group=1 ).save() body = app._prepare_email(1) self.assertTrue(body.find(playground.name) >= 0)
def _prepare_email(revision_group): revisions = Revision.select().where( Revision.revision_group == int(revision_group)) context = {} context['base_url'] = '%s/playground/' % app_config.S3_BASE_URL context['total_revisions'] = revisions.count() context['deletes'] = {} context['deletes']['playgrounds'] = [] context['deletes']['total_revisions'] = 0 context['inserts'] = {} context['inserts']['playgrounds'] = [] context['inserts']['total_revisions'] = 0 context['updates'] = {} context['updates']['playgrounds'] = [] context['updates']['total_revisions'] = 0 inserts = revisions.where(Revision.action == 'insert') if inserts.count() > 0: context['inserts']['total_revisions'] = inserts.count() for revision in inserts: p = Playground.get(slug=revision.playground.slug) playground_dict = p.__dict__['_data'] playground_dict['display_name'] = p.display_name playground_dict['site_url'] = '%s/playground/%s.html' % ( app_config.S3_BASE_URL, revision.playground.slug) playground_dict['revision_group'] = int(revision_group) playground_dict['headers'] = revision.get_headers() playground_dict['feature_count'] = int(p.feature_count) nearby = p.nearby(3) playground_dict['nearby'] = [] for n in nearby: if n.distance < 0.5: playground_dict['nearby'].append(n) context['inserts']['playgrounds'].append(playground_dict) context['inserts']['playgrounds'] = sorted( context['inserts']['playgrounds'], key=lambda p: p['name']) deletes = revisions.where(Revision.action == 'delete-request') if deletes.count() > 0: context['deletes']['total_revisions'] = deletes.count() for revision in deletes: p = Playground.get(slug=revision.playground.slug) playground_dict = playground_dict = p.__dict__['_data'] playground_dict['display_name'] = p.display_name playground_dict['site_url'] = '%s/playground/%s.html' % ( app_config.S3_BASE_URL, revision.playground.slug) playground_dict['delete_url'] = '%s/delete-playground/%s/' % ( app_config.SERVER_BASE_URL, revision.playground.slug) playground_dict['revision_group'] = int(revision_group) for item in json.loads(revision.log): if item.get('field', None) == "reason": playground_dict['text'] = cgi.escape(item.get('to')) playground_dict['headers'] = revision.get_headers() context['deletes']['playgrounds'].append(playground_dict) context['deletes']['playgrounds'] = sorted( context['deletes']['playgrounds'], key=lambda p: p['name']) updates = revisions.where(Revision.action == 'update') if updates.count() > 0: context['updates']['total_revisions'] = updates.count() updated_playgrounds = Set([]) for revision in updates: updated_playgrounds.add(revision.playground.slug) for playground_slug in updated_playgrounds: p = Playground.get(slug=playground_slug) playground_dict = p.__dict__['_data'] playground_dict['display_name'] = p.display_name playground_dict['site_url'] = '%s/playground/%s.html' % ( app_config.S3_BASE_URL, playground_slug) playground_dict['revisions'] = [] for revision in updates: if revision.playground.id == p.id: revision_dict = {} revision_dict['revision_group'] = revision_group revision_dict['fields'] = revision.get_log() revision_dict['headers'] = revision.get_headers() playground_dict['revisions'].append(revision_dict) context['updates']['playgrounds'].append(playground_dict) context['updates']['playgrounds'] = sorted( context['updates']['playgrounds'], key=lambda p: p['name']) with open('templates/_email.html', 'rb') as read_template: payload = Template(read_template.read()) return payload.render(**context)
def update_playground(): from flask import request # Only handle POST requests. if request.method == 'POST': # How to know what fields are on this model? # Pick a single instance from the DB and serialize it. playground = Playground.get(id=request.form.get('id')) playground_fields = playground.__dict__['_data'].keys() # Prep the payload. payload = {} payload['action'] = 'update' payload['timestamp'] = time.mktime(datetime.datetime.now(pytz.utc).timetuple()) payload['playground'] = {} payload['request'] = {} payload['request']['ip_address'] = request.remote_addr payload['request']['cookies'] = request.cookies payload['request']['headers'] = {} # Write the request headers to the payload. # It's nicer when they use underscores instead of dashes. for key, value in request.headers: payload['request']['headers'][key.lower().replace('-', '_')] = value # Loop over all of the model fields looking to see if they're present in the POST. for field in playground_fields: # Transform integers into ints when possible. try: payload['playground'][field] = float(request.form.get(field, None)) if payload['playground'][field].is_integer(): payload['playground'][field] = int(payload['playground'][field]) except ValueError: payload['playground'][field] = request.form.get(field, None) except TypeError: pass # Special-case handling for zip_code, which is a string, not an int. try: payload['playground']['zip_code'] = str(payload['playground']['zip_code']) except KeyError: pass try: if payload['playground']['reverse_geocoded'] == "on": payload['playground']['reverse_geocoded'] = True except KeyError: pass # Set up a list for features. payload['playground']['features'] = [] # Loop over all of the possible features to see if they're present in the POST. for feature in copytext.COPY.feature_list: slug = feature['key'] if request.form.get(slug, None): payload['playground']['features'].append(slug) # If there weren't any features in this POST, remove the features list from payload. if len(payload['playground']['features']) == 0: del(payload['playground']['features']) # Write to the changes.json file. write_data(payload) # return json.dumps(payload) return redirect('%s/playground/%s.html?action=editing_thanks' % (app_config.S3_BASE_URL, playground.slug))
def process_update(record): """ Process a single update record from changes.json. """ playground_id = record['playground']['id'] # First, capture the old data from this playground. old_data = Playground.get(id=playground_id).__dict__['_data'] # This is an intermediate data store for this record. record_dict = {} # Loop through each of the key/value pairs in the playground record. for key, value in record['playground'].items(): # Ignore some keys because they aren't really what we want to update. if key not in ['id', 'features']: # Update the record_dict with our new key/value pair. record_dict[key] = value # Run the update query against this playground. # Pushes any updates in the record_dict to the model. playground = Playground.get(id=playground_id) if (record_dict): for k, v in record_dict.items(): setattr(playground, k, v) playground.save() # Set up the list of old features. # We're going to remove them all. # We'll re-add anything that stuck around. old_features = [] # Append the old features to the list. for feature in PlaygroundFeature.select().where(PlaygroundFeature.playground == playground_id): old_features.append(feature.slug) # Delete any features attached to this playground. PlaygroundFeature.delete().where(PlaygroundFeature.playground == playground_id).execute() # Check to see if we have any incoming features. try: features = record['playground']['features'] except KeyError: features = [] for slug in features: PlaygroundFeature.create( slug=slug, playground=playground ) # Now, let's set up some revisions. # Create a list of revisions to apply. revisions = [] # Our old data was captured up top. It's called old_ # This is the new It's just the record_dict from above. new_data = record_dict # Loop over the key/value pairs in the new data we have. for key, value in new_data.items(): # Now, if the old data and the new data don't match, let's make a revision. if old_data[key] != new_data[key]: # Set up an intermediate data structure for the revision. revision_dict = {} # Set up the data for this revision. revision_dict['field'] = key revision_dict['from'] = old_data[key] revision_dict['to'] = new_data[key] # Append it to the revisions list. revisions.append(revision_dict) # Let's get started on features. # First, let's figure out the new features coming from the Web. try: # If there are any new features, create a list for them. new_features = record['playground']['features'] except: # Otherwise, empty list. new_features = [] # First case: If the list of old and new features is identical, don't do anything. if old_features != new_features: # So there's a difference between the old and new feature lists. # Since the Web can both add new features and remove old features, # we have to prepare for each path. # First, let's loop over the list of features that are available. for feature in copytext.COPY.feature_list: slug = feature['key'] # If the slug is in the old feature set, let's check it against the new. if slug in old_features: # If it's not in the new feature set but IS in the old feature set, # let's append a revision taking it from 1 to 0. if slug not in new_features: revisions.append({"field": slug, "from": 1, "to": 0}) # Similarly, if the slug in the new feature set, let's check it agains the old. if slug in new_features: # If it's not in the old_feature set but IS in the new feature set, # let's append a revision taking it from 0 to 1. if slug not in old_features: revisions.append({"field": slug, "from": 0, "to": 1}) return playground, revisions
def _prepare_email(revision_group): revisions = Revision.select().where(Revision.revision_group == int(revision_group)) context = {} context['base_url'] = '%s/playground/' % app_config.S3_BASE_URL context['total_revisions'] = revisions.count() context['deletes'] = {} context['deletes']['playgrounds'] = [] context['deletes']['total_revisions'] = 0 context['inserts'] = {} context['inserts']['playgrounds'] = [] context['inserts']['total_revisions'] = 0 context['updates'] = {} context['updates']['playgrounds'] = [] context['updates']['total_revisions'] = 0 inserts = revisions.where(Revision.action == 'insert') if inserts.count() > 0: context['inserts']['total_revisions'] = inserts.count() for revision in inserts: p = Playground.get(slug=revision.playground.slug) playground_dict = p.__dict__['_data'] playground_dict['display_name'] = p.display_name playground_dict['site_url'] = '%s/playground/%s.html' % (app_config.S3_BASE_URL, revision.playground.slug) playground_dict['revision_group'] = int(revision_group) playground_dict['headers'] = revision.get_headers() playground_dict['feature_count'] = int(p.feature_count) nearby = p.nearby(3) playground_dict['nearby'] = [] for n in nearby: if n.distance < 0.5: playground_dict['nearby'].append(n) context['inserts']['playgrounds'].append(playground_dict) context['inserts']['playgrounds'] = sorted(context['inserts']['playgrounds'], key=lambda p: p['name']) deletes = revisions.where(Revision.action == 'delete-request') if deletes.count() > 0: context['deletes']['total_revisions'] = deletes.count() for revision in deletes: p = Playground.get(slug=revision.playground.slug) playground_dict = playground_dict = p.__dict__['_data'] playground_dict['display_name'] = p.display_name playground_dict['site_url'] = '%s/playground/%s.html' % (app_config.S3_BASE_URL, revision.playground.slug) playground_dict['delete_url'] = '%s/delete-playground/%s/' % (app_config.SERVER_BASE_URL, revision.playground.slug) playground_dict['revision_group'] = int(revision_group) for item in json.loads(revision.log): if item.get('field', None) == "reason": playground_dict['text'] = cgi.escape(item.get('to')) playground_dict['headers'] = revision.get_headers() context['deletes']['playgrounds'].append(playground_dict) context['deletes']['playgrounds'] = sorted(context['deletes']['playgrounds'], key=lambda p: p['name']) updates = revisions.where(Revision.action == 'update') if updates.count() > 0: context['updates']['total_revisions'] = updates.count() updated_playgrounds = Set([]) for revision in updates: updated_playgrounds.add(revision.playground.slug) for playground_slug in updated_playgrounds: p = Playground.get(slug=playground_slug) playground_dict = p.__dict__['_data'] playground_dict['display_name'] = p.display_name playground_dict['site_url'] = '%s/playground/%s.html' % (app_config.S3_BASE_URL, playground_slug) playground_dict['revisions'] = [] for revision in updates: if revision.playground.id == p.id: revision_dict = {} revision_dict['revision_group'] = revision_group revision_dict['fields'] = revision.get_log() revision_dict['headers'] = revision.get_headers() playground_dict['revisions'].append(revision_dict) context['updates']['playgrounds'].append(playground_dict) context['updates']['playgrounds'] = sorted(context['updates']['playgrounds'], key=lambda p: p['name']) with open('templates/_email.html', 'rb') as read_template: payload = Template(read_template.read()) return payload.render(**context)
def process_update(record): """ Process a single update record from changes.json. """ playground_id = record['playground']['id'] # First, capture the old data from this playground. old_data = Playground.get(id=playground_id).__dict__['_data'] # This is an intermediate data store for this record. record_dict = {} # Loop through each of the key/value pairs in the playground record. for key, value in record['playground'].items(): # Ignore some keys because they aren't really what we want to update. if key not in ['id', 'features']: # Update the record_dict with our new key/value pair. record_dict[key] = value # Run the update query against this playground. # Pushes any updates in the record_dict to the model. playground = Playground.get(id=playground_id) if (record_dict): for k, v in record_dict.items(): setattr(playground, k, v) playground.save() # Set up the list of old features. # We're going to remove them all. # We'll re-add anything that stuck around. old_features = [] # Append the old features to the list. for feature in PlaygroundFeature.select().where( PlaygroundFeature.playground == playground_id): old_features.append(feature.slug) # Delete any features attached to this playground. PlaygroundFeature.delete().where( PlaygroundFeature.playground == playground_id).execute() # Check to see if we have any incoming features. try: features = record['playground']['features'] except KeyError: features = [] for slug in features: PlaygroundFeature.create(slug=slug, playground=playground) # Now, let's set up some revisions. # Create a list of revisions to apply. revisions = [] # Our old data was captured up top. It's called old_ # This is the new It's just the record_dict from above. new_data = record_dict # Loop over the key/value pairs in the new data we have. for key, value in new_data.items(): # Now, if the old data and the new data don't match, let's make a revision. if old_data[key] != new_data[key]: # Set up an intermediate data structure for the revision. revision_dict = {} # Set up the data for this revision. revision_dict['field'] = key revision_dict['from'] = old_data[key] revision_dict['to'] = new_data[key] # Append it to the revisions list. revisions.append(revision_dict) # Let's get started on features. # First, let's figure out the new features coming from the Web. try: # If there are any new features, create a list for them. new_features = record['playground']['features'] except: # Otherwise, empty list. new_features = [] # First case: If the list of old and new features is identical, don't do anything. if old_features != new_features: # So there's a difference between the old and new feature lists. # Since the Web can both add new features and remove old features, # we have to prepare for each path. # First, let's loop over the list of features that are available. for feature in copytext.COPY.feature_list: slug = feature['key'] # If the slug is in the old feature set, let's check it against the new. if slug in old_features: # If it's not in the new feature set but IS in the old feature set, # let's append a revision taking it from 1 to 0. if slug not in new_features: revisions.append({"field": slug, "from": 1, "to": 0}) # Similarly, if the slug in the new feature set, let's check it agains the old. if slug in new_features: # If it's not in the old_feature set but IS in the new feature set, # let's append a revision taking it from 0 to 1. if slug not in old_features: revisions.append({"field": slug, "from": 0, "to": 1}) return playground, revisions