Skip to content

Instantly share code, notes, and snippets.

View jeffdeville's full-sized avatar

Jeff Deville jeffdeville

View GitHub Profile
@jeffdeville
jeffdeville / coercers.rb
Created May 29, 2015 17:34
Splitting the mapping and the normalizing process for testability
module SherlockHomes
module PropertyCoercer
def self.coerce(input)
case
when property.respond_to?(:zillow_thing)
ZillowCoercer.coerce(input)
when property.respond_to?(:redfin_thing)
RedfinCoercer.coerce(input)
when property.respond_to?(:trulia_thing)
TruliaCoercer.coerce(input)
@jeffdeville
jeffdeville / sample_json.js
Created May 6, 2015 17:28
Thoughts on Scraping real estate data
// Each parent w/ a sub-hash is a class in Ruby Class naming
// so geo -> Geo, property_details -> PropertyDetails
// Property
{
"property":
{
sources: [
{
"source": ["zillow","trulia","redfine","realtor"],
#!/usr/bin/env ruby
begin
gem 'geocoder'
rescue
p "you must install the geocoder gem: `gem install geocoder`, or `sudo gem install geocoder`"
raise
end
require 'pry'
require 'geocoder'
require 'rubygems'
require 'bundler/setup'
Rubillow.configure do |configuration|
configuration.zwsid = ENV["API_KEY"]
end
address = "701 Lorraine St" #request.params[:address]
citystatezip = "Ardmore, PA 19003" # request.params[:citystatezip]
This was just a branch off of master. We're not using the Federated path,
but we are using SSO (it'd be nice if we could make this a separate setting)
"""Logs a user in using a token from Keystone's POST."""
referer = request.META.get('HTTP_REFERER')
auth_url = re.sub(r'/auth.*', '', referer)
- request.federated_login = True
+ request.federated_login = False
request.user = auth.authenticate(request=request, auth_url=auth_url)
@dependency.requires('assignment_api', 'identity_api')
class InferredDomain(Domain):
def _authenticate(self, remote_user, context):
# OIDC sets the remote user as:
# remote_user = [email protected]@sso.sungardas.lab/service
# so if we use the email's domain as the remote_domain, it'd be as simple as this:
context['environment']['REMOTE_DOMAIN'] = remote_user.split("@")[1]
return super(InferredDomain, self)._authenticate(remote_user, context)
@jeffdeville
jeffdeville / keystone.conf
Created February 24, 2015 17:30
SSO Debug
<VirtualHost *:5000>
WSGIDaemonProcess keystone-public processes=5 threads=1 user=vagrant display-name=%{GROUP}
WSGIProcessGroup keystone-public
WSGIScriptAlias / /var/www/keystone/main
WSGIApplicationGroup %{GLOBAL}
<IfVersion >= 2.4>
ErrorLogFormat "%{cu}t %M"
</IfVersion>
ErrorLog /var/log/apache2/keystone.log
CustomLog /var/log/apache2/keystone_access.log combined
@jeffdeville
jeffdeville / cache_poc.rb
Created January 12, 2015 16:24
caching method calls
cache :read,
invalidate_on: [:update, :update_cloud_director_contact, :update_cloud_service, :update_cc_payment_info],
key: :account_id
# Module overrides read to look like this:
module Cacheable
def cache(methods_to_cache, methods_to_invalidate, key)
methods_to_cache.each do |method|
define_method method do |*args|
@jeffdeville
jeffdeville / BusibeeAndNikola.md
Last active August 29, 2015 14:10
Info on BusiBee's Design, and how to port it to the Nikola architecture

BusiBee Design Challenges

Challenge 1: BSIL's API methods are confusing

The BSIL API is remote procedure call style (RPC), rather than RESTful. However, it's data model IS RESTful. So even though each call that operates on an Account requires a fully populated Account object, it will only do something with a small subset of the data you pass in. Unfortunately, it's not clear which portion. In order to fully create an Account, we make 6 calls to BSIL. What's more, the data returned is inconsistently populated. So we'll often have to re-load a value after updating it to get the complete new state of the object.

If BusiBee just mapped the various BSIL calls straight through, then all of this complexity would wind up littered throughout UCP. We wanted to be able to just update the values on an account, and tell BusiBee to update it, and trust that whatever needed to happen, would indeed happen.

Basically: Make the methods simple and consistent

{
"caret_extra_width": 2,
"color_scheme": "Packages/Tomorrow Color Schemes/Tomorrow-Night-Eighties.tmTheme",
"detect_indentation": false,
"detect_slow_plugins": true,
"ensure_newline_at_eof_on_save": true,
"file_exclude_patterns":
[
"*.pyc",
"*.pyo",