Skip to content
1337 edited this page May 16, 2012 · 9 revisions

Welcome to the Willet repo!

Here's a very brief, top-level explanation of our GAE application. This is basically the same as the README file.

Terminology

  • Model: data layers, object classes, or utilities that are meant to be singletons.
  • View: handles GETs
  • Controller: handles POSTs. Some controllers will have GETs that simply point to their POSTs to help debugging with just a URL.
  • App: installable Models (in Shopify's context, these are Models we define to be Shopify Apps)
  • User: anyone who loads our scripts
  • Client: any shop that installs our app
  • Merchant: the guy who owns the client
  • EmailCounter: merchants' emails. Merchants can have more than one email.
  • Instance: a personal version of the app that the user loads. For example: user watches movie on netflix. An "instance" of the movie is created for the user.
  • PartialInstance: if some action requires both starting and ending times, a partial instance is started, and converted to a full Instance when user completes action. For example: user orders movie on netflix. A partial instance aka trailer is shown. User completes payment, and a full instance of the movie is shown.
  • Willet code: rf.rs stands for "ReFeRS". rf.rs masks social-referral.appengine.com

Files

  • appengine_config.py: Used for gaesessions (and others?) to insert middleware.

  • urls.py: Crawls the repo looking for urls.py files (only looks in dirs specified within util/consts.py). As it crawls, it builds a list of { uri -> handler } and memcaches it so we don't need to build it frequently.

         If you ever need to refer to a uri within the code, you should 
         call url( 'HANDLER_NAME' ) and it'll return a relative uri.
    
         You can call URL within a template file too!
    

Dirs

  • apps/: Each subfolder in apps/ is something like a Django 'app', except it's not.

       We use MVC within each app folder. 
           M = models.py - db objects and fcns
           V = views.py - GETs and HTML views
           C = processes.py - PUTs, POSTs, and backend processing
    
       Any uri handlers need to be added to urls.py so that we can build all
       uris and memcache them! If you add a new app, you need to add it to 
       util/consts.py list of apps so that the uri builder knows to grab
       it's uris.
    
       Every subfolder under apps/ needs to have an __init__.py.
       Otherwise, things break!
    
       HTML files for views are stored within each app's dir under
       templates/. Some apps have additional files (ie. not just .html)
       within templates/. Essentially, any file that is dynamically
       served would go under templates.
    

Dirs under apps/

Egads! You've made it all the way into the depths of the apps/ folder?!

Here's a brief explanation of the apps in here. I make no promise that this README will be kept up-to-date after I leave!

  • action: We've built our own analytics code in-house. Good idea? Not entirely sure yet!

        All analytics are stored as 'action' datapoints. The top-level, parent
        class Actions are all located in models.py. 
    
  • admin: If you ever need to run a little script on the db to either: a) do a migration, or b) Crawl some data quickly, then you should make a little admin script for it.

       All scripts are in views.py.
    
       Other admin pages (like memcache viewer, uri routers etc) are in views.py
       too.
    
  • analytics_backend: Once we've stored all the action (read: analytic) datapoints, we need to crawl and aggregate them to see how Users are engaging with our apps. All the crawling / aggregation is in here.

                   Written by: MrMCH
    
  • app: Each 'app' we develop for merchants will have some commonalities. These are all managed in here.

     Right now, we have 'App' and 'AppShopify' as top-level, parent classes.
     All Apps inherit from 'App' and Shopify Apps inherit from 'AppShopify'.
     Therefore, Shopify Apps inherit from App and AppShopify.
    
  • buttons: A simple Shopify App to get us some initial customers.

  • client: A store is known as a 'Client'. We store all metadata about a store here.

  • email: This is a basic GAE email sending wrapper. If you want to create a new email message, add a static method to the Email class and add a new HTML template file to templates/.

  • gae_bingo: Colloquially referred to as "Gay Bingo", this is our AB test framework.

           Want to start a new AB test? Here's how:
             1. Create the options for your test and list 'em.
             2. Call ab_test on the options. It'll spit one of them out!
             3. Use that option.
         
           To score a successful bingo, just call bingo with the test name 
           when the user does the behaviour you want to see!
    
           So simple, eh?
    
  • homepage: We have a really spiffy website. It's all kept in here. Mostly just views and HTML.

  • link: These were used heavily in some other projects we've built and they were ported over here. If you ever need a short link, create a Link!

      Whenever a user clicks on the short link, the handleLinkClick fcn will
      take care of always cookieing the user!
    
  • order: We get paid when we deliver a new user to a store and they buy something. This means we need to keep track of when people place an order right?

       It's all stored in here.
    
  • product: Since products are so core to SIBT and Hot or Not, we just store all of our merchant's product metadata in our db.

  • referral: This is 100% deprecated. Leave it be until someone decides to delete it.

  • sibt: 'Should I Buy This' is our main app. There's all sorts of goodies in here!

  • user: People who visit a merchant's store are Users AND WE COOKIE THEM ALL AND TRACK ALL THEIR ACTIONS ON A WEBSITE!

      Users are the ones who interact with our apps and place purchases. We
      store as much information as we possibly can about them in this class.
    
      Caveats: If you come from a strong DB background, prepare to have your
      mind BLOWN. User is an Expando class.
      http://code.google.com/appengine/docs/python/datastore/expandoclass.html
    
      This means, every User object has different properties attached to it
      and we can create/assign new properties AT WHIM! Woooo!
    
      However, this means that anytime you want to fetch a value of property
      from a User object, you have to call user.get_attr('prop_name').
      THIS IS KEY!
    
  • gaesessions/: This isn't currently in use. If you want to have server-side sessions in GAE, you'll need to use it.

  • mapreduce/: This is GAE's mapreduce lib. Unfortunately, it needs to be kept in a top level folder. It is used to compute the analytics.

  • pipeline/: Future versions of mapreduce use the Pipeline lib.

  • static/: All static content is served from here. Right now, it's a bit messy.

  • util/: Random helpers and libs go in here.

  • w3c/: Privacy policy etc stored here. You'll never need to go in here ever!

Yamls

GAE is controlled using yaml files. The syntax is really straight-forward!

  • app.yaml: Controls the WHOLE APP! The most important part is 'application' - this field controls the deployment location of your app.

          Not much more will ever need to be changed here.
    
  • backends.yaml: Controls GAE's backends processes. Currently only used for analytics.

  • cron.yaml: Controls all cron jobs. Mostly everything is turned off right now.

  • handlers.yaml: Controls the uris available for our app. This file shouldn't ever need to edited unless you've added some special static files

  • index.yaml: Tells GAE which db indexes it needs to build and serve. Only edit if GAE complains about a missing index when you deploy.

  • mapreduce.yaml: Controls the mapreduce settings.

  • queue.yaml: Inits the task queues for running processes out-of-band.

Clone this wiki locally