• Stars
    star
    173
  • Rank 218,827 (Top 5 %)
  • Language
    Python
  • License
    BSD 3-Clause "New...
  • Created over 15 years ago
  • Updated over 10 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Toolkit to simplify static media development and deployment.

django-mediasync

One of the more significant development roadblocks we have relates to local vs. deployed media. Ideally all media (graphics, css, scripts) development would occur locally and not use production media. Then, when ready to deploy, the media should be pushed to production. That way there can be significant changes to media without disturbing the production web site.

The goal of mediasync is to develop locally and then flip a switch in production that makes all the media URLs point to remote media URLs instead of the local media directory.

All code is under a BSD-style license, see LICENSE for details.

Source: http://github.com/sunlightlabs/django-mediasync/

Requirements

  • django >= 1.0
  • boto >= 1.8d
  • slimmer == 0.1.30 (optional)
  • python-cloudfiles == 1.7.5 (optional, for Rackspace Cloud Files backend)

Upgrading from mediasync 1.x

  1. Update your mediasync settings as described in the next section.
  2. Run ./manage.py syncmedia --force to force updates of all files:
    • gzip instead of deflate compression
    • sync both compressed and original versions of files
  3. add "django.core.context_processors.request" to TEMPLATE_CONTEXT_PROCESSORS

An important note about Django 1.3

When DEBUG = True and the project is run with manage.py runserver, Django 1.3 automatically adds django.views.static.serve to urlpatterns. While this feature makes local development easier for most people, it screws everything up if you've added mediasync.urls to urlpatterns. As of now, the only way I can find to disable the automatic addition of django.views.static.serve is to use a full URL for STATIC_URL instead of just a path:

STATIC_URL = "http://localhost:8000/static/"

Configuration

settings.py

Add to INSTALLED_APPS:

'mediasync'

Add to TEMPLATE_CONTEXT_PROCESSORS:

'django.core.context_processors.request'

Make sure your STATIC_ROOT setting is the correct path to your media:

STATIC_ROOT = '/path/to/media'

When media is being served locally (instead of from S3 or Cloud Files), mediasync serves media through a Django view. Set your STATIC_URL to what you'd like that local media URL to be. This can be whatever you'd like, as long as you're using the {% media_url %} tag (more details on this later):

STATIC_URL = 'http://localhost:8000/devmedia/'

STATIC_URL is the URL that will be used in debug mode. Otherwise, the STATIC_URL will be loaded from the backend settings. Please see An important note about Django 1.3.

The following settings dict must also be added:

MEDIASYNC = {
    'BACKEND': 'path.to.backend',
}

If you want to use a different media URL than that specified in settings.STATIC_URL, you can add STATIC_URL to the MEDIASYNC settings dict:

MEDIASYNC = {
    ...
    'STATIC_URL': '/url/to/media/', # becomes http://yourhost.com/url/to/media/
    ...
}

Same goes for STATIC_ROOT:

MEDIASYNC = {
    ...
    'STATIC_ROOT': '/path/to/media/',
    ...
}

mediasync supports pluggable backends. Please see below for information on the provided backends as well as directions on implementing your own.

Media expiration

If the client supports media expiration, all files are set to expire 365 days after the file was synced. You may override this value by adding EXPIRATION_DAYS to the MEDIASYNC settings dict.

# Expire in 10 years.
MEDIASYNC['EXPIRATION_DAYS'] = 365 * 10

Serving media remote (S3/Cloud Files) or locally

The media URL is selected based on the SERVE_REMOTE attribute in the MEDIASYNC dict in settings.py. When False, media will be served locally instead of from S3.

# This would force mediasync to serve all media through the value
# specified in settings.STATIC_URL.
MEDIASYNC['SERVE_REMOTE'] = False

# This would serve all media through S3/Cloud Files.
MEDIASYNC['SERVE_REMOTE'] = True

# This would serve media locally while in DEBUG mode, and remotely when
# in production (DEBUG == False).
MEDIASYNC['SERVE_REMOTE'] = not DEBUG

When serving files locally, you can emulate the CSS/JS combo/minifying behavior we get from using media processors by specifying the following.

MEDIASYNC['SERVE_REMOTE'] = False
MEDIASYNC['EMULATE_COMBO'] = True

Note that this will only work if your STATIC_URL is pointing at your Django dev server. Also keep in mind that some processors may take a while, and is best used to check things over before rolling out to production.

DOCTYPE

link and script tags are written using XHTML syntax. The rendering can be overridden by using the DOCTYPE setting. Allowed values are 'html4', 'html5', or 'xhtml'. The default in mediasync 2.0 is html5, just as the DOCTYPE on your site should be.

MEDIASYNC['DOCTYPE'] = 'html5'

For each doctype, the following tags are rendered:

html4
<link rel="stylesheet" href="..." type="text/css" media="...">
<script type="text/javascript" charset="utf-8" src="..."></script>
html5
<link rel="stylesheet" href="..." media="...">
<script src="..."></script>
xhtml
<link rel="stylesheet" href="..." type="text/css" media="..." />
<script type="text/javascript" charset="utf-8" src="..."></script>

SSL

mediasync will attempt to intelligently determine if your media should be served using HTTPS. In order to use automatic SSL detection, django.core.context_processors.request must be added to TEMPLATE_CONTEXT_PROCESSORS in settings.py:

TEMPLATE_CONTEXT_PROCESSORS = (
    ...
    'django.core.context_processors.request',
    ...
)

The USE_SSL mediasync setting can be used to override the SSL URL detection.

# Force HTTPS.
MEDIASYNC['USE_SSL'] = True

or

# Force HTTP.
MEDIASYNC['USE_SSL'] = False

Some backends will be unable to use SSL. In these cases USE_SSL and SSL detection will be ignored.

urls.py

To serve local media through mediasync, add a reference to mediasync.urls in your main urls.py file.

urlpatterns = ('',
    ...
    url(r'^', include('mediasync.urls)),
    ...
)

Backends

mediasync now supports pluggable backends. A backend is a Python module that contains a Client class that implements a mediasync-provided BaseClient class.

S3

MEDIASYNC['BACKEND'] = 'mediasync.backends.s3'
Settings

The following settings are required in the mediasync settings dict:

MEDIASYNC = {
    'AWS_KEY': "s3_key",
    'AWS_SECRET': "s3_secret",
    'AWS_BUCKET': "bucket_name",
}

Optionally you may specify a path prefix:

MEDIASYNC['AWS_PREFIX'] = "key_prefix"

Assuming a correct DNS CNAME entry, setting AWS_BUCKET to assets.sunlightlabs.com and AWS_PREFIX to myproject/media would sync the media directory to http://assets.sunlightlabs.com/myproject/media/.

Amazon allows users to create DNS CNAME entries to map custom domain names to an AWS bucket. MEDIASYNC can be configured to use the bucket as the media URL by setting AWS_BUCKET_CNAME to True.

MEDIASYNC['AWS_BUCKET_CNAME'] = True

If you would prefer to not use gzip compression with the S3 client, it can be disabled:

MEDIASYNC['AWS_GZIP'] = False
Tips

Since files are given a far future expires header, one needs a way to do "cache busting" when you want the browser to fetch new files before the expire date arrives. One of the best and easiest ways to accomplish this is to alter the path to the media files with some sort of version string using the key prefix setting:

MEDIASYNC['AWS_PREFIX'] = "myproject/media/v20001201"

Given that and the above DNS CNAME example, the media directory URL would end up being http://assets.sunlightlabs.com/myproject/media/v20001201/. Whenever you need to update the media files, simply update the key prefix with a new versioned string.

A CACHE_BUSTER settings can be added to the main MEDIASYNC settings dict to add a query string parameter to all media URLs. The cache buster can either be a value or a callable which is passed the media URL as a parameter.

MEDIASYNC['CACHE_BUSTER'] = 1234567890

The above setting will generate a media path similar to:

http://yourhost.com/url/to/media/image.png?1234567890

An important thing to note is that if you're running your Django site in a multi-threaded or multi-node setup, you'll want to be careful about using a time-based cache buster value. Each worker/thread will probably have a slightly different value for datetime.now(), which means your users will find themselves having cache misses randomly from page to page.

Rackspace Cloud Files

MEDIASYNC['BACKEND'] = 'mediasync.backends.cloudfiles'
Settings

The following settings are required in the mediasync settings dict:

MEDIASYNC = {
    'CLOUDFILES_CONTAINER': 'container_name',
    'CLOUDFILES_USERNAME': 'cf_username',
    'CLOUDFILES_API_KEY': 'cf_apikey',
}
Tips

The Cloud Files backend lacks support for the following features:

  • setting HTTP Expires header
  • setting HTTP Cache-Control header
  • content compression (gzip)
  • SSL support
  • conditional sync based on file checksum

Custom backends

You can create a custom backend by creating a Python module containing a Client class. This class must inherit from mediasync.backends.BaseClient. Additionally, you must implement two methods:

def remote_media_url(self, with_ssl):
    ...

remote_media_url returns the full base URL for remote media. This can be either a static URL or one generated from mediasync settings:

def put(self, filedata, content_type, remote_path, force=False):
    ...

put is responsible for pushing a file to the backend storage.

  • filedata - the contents of the file
  • content_type - the mime type of the file
  • remote_path - the remote path (relative from remote_media_url) to which the file should be written
  • force - if True, write file to remote storage even if it already exists

If the client supports gzipped content, you will need to override supports_gzip to return True:

def supports_gzip(self):
        return True

File Processors

File processors allow you to modify the content of a file as it is being synced or served statically.

Mediasync ships with three processor modules:

  1. slim is a minifier written in Python and requires the slimmer Python package. The Python package can be found here: http://pypi.python.org/pypi/slimmer/
  2. yuicompressor is a minifier written in Java and can be downloaded from YUI's download page: http://developer.yahoo.com/yui/compressor/. This processor also requires an additional setting, as defined below. yuicompressor is new and should be considered experimental until the mediasync 2.1 release.
  3. closurecompiler is a javascript compiler provided by Google.

Custom processors can be specified using the PROCESSORS entry in the mediasync settings dict. PROCESSORS should be a list of processor entries. Each processor entry can be a callable or a string path to a callable. If the path is to a class definition, the class will be instantiated into an object. The processor callable should return a string of the processed file data, None if it chooses to not process the file, or raise mediasync.SyncException if something goes terribly wrong. The callable should take the following arguments:

def proc(filedata, content_type, remote_path, is_active):
        ...
filedata
the content of the file as a string
content_type
the mimetype of the file being processed
remote_path
the path to which the file is being synced (contains the file name)
is_active
True if the processor should... process

If the PROCESSORS setting is used, you will need to include the defaults if you plan on using them:

'PROCESSORS': (
    'mediasync.processors.slim.css_minifier',
    'mediasync.processors.slim.js_minifier',
        ...
),

mediasync will attempt to use slimmer by default if you have the package installed and do not use the PROCESSORS setting.

Google Closure Compiler

Google's JavaScript Closure Compiler provides an API that allows files to be compressed without installing anything locally. To use the service:

'PROCESSORS': ('mediasync.processors.closurecompiler.compile',)

YUI Compressor

To configure YUI Compressor you need to define a PROCESSORS and YUI_COMPRESSOR_PATH as follows, assuming you placed the ".jar" file in your ~/bin path:

'PROCESSORS': ('mediasync.processors.yuicompressor.css_minifier',
               'mediasync.processors.yuicompressor.js_minifier'),
'YUI_COMPRESSOR_PATH': '~/bin/yuicompressor.jar',

Features

Ignored Directories

Any directory in STATIC_ROOT that is hidden or starts with an underscore will be ignored during syncing.

Template Tags

When referring to media in HTML templates you can use custom template tags. These tags can by accessed by loading the media template tag collection.

{% load media %}

Any tag that has a path argument can use either a string or a variable:

{% media_url "images/avatar.png" }
{% media_url user.profile.avatar_path %}

Some backends (S3) support https URLs when the requesting page is secure. In order for the https to be detected, the request must be placed in the template context with the key 'request'. This can be done automatically by adding 'django.core.context_processors.request' to TEMPLATE_CONTEXT_PROCESSORS in settings.py

media_url

Renders the STATIC_URL from settings.py with trailing slashes removed.

<img src="{% media_url %}/images/stuff.png">

STATIC_URL takes an optional argument that is the media path. Using the argument allows mediasync to add the CACHE_BUSTER to the URL if one is specified.

<img src="{% media_url '/images/stuff.png' %}">

If CACHE_BUSTER is set to 12345, the above example will render as:

<img src="http://assets.example.com/path/to/media/images/stuff.png?12345">

NOTE: Don't use this tag to serve CSS or JS files. Use the js and css tags that were specifically designed for the purpose.

js

Renders a script tag with the correct include.

{% js "myfile.js" %}

css

Renders a <link> tag to include the stylesheet. It takes an optional second parameter for the media attribute; the default media is "screen, projector".

{% css "myfile.css" %}
{% css "myfile.css" "screen" %}

css_print

Shortcut to render as a print stylesheet.

{% css_print "myfile.css" %}

which is equivalent to

{% css "myfile.css" "print" %}

Writing Style Sheets

Users are encouraged to write stylesheets using relative URLS. The media directory is synced with S3 as is, so relative local paths will still work when pushed remotely.

background: url(../images/arrow_left.png);

Joined files

When serving media in production, it is beneficial to combine JavaScript and CSS into single files. This reduces the number of connections the browser needs to make to the web server. Fewer connections can dramatically decrease page load times and reduce the server-side load.

Joined files are specified in the MEDIASYNC dict using JOINED. This is a dict that maps individual media to an alias for the joined files.

'JOINED': {
    'styles/joined.css': ['styles/reset.css','styles/text.css'],
    'scripts/joined.js': ['scripts/jquery.js','scripts/processing.js'],
},

Files listed in JOINED will be combined and pushed to S3 with the name of the alias. The individual CSS files will also be pushed to S3. Aliases must end in either .css or .js in order for the content-type to be set appropriately.

The existing template tags may be used to refer to the joined media. Simply use the joined alias as the argument:

{% css_print "joined.css" %}

When served locally, template tags will render an HTML tag for each of the files that make up the joined file:

<link rel="stylesheet" href="/media/styles/reset.css" type="text/css" media="screen, projection" />
<link rel="stylesheet" href="/media/styles/text.css" type="text/css" media="screen, projection" />

When served remotely, one HTML tag will be rendered with the name of the joined file:

<link rel="stylesheet" href="http://bucket.s3.amazonaws.com/styles/joined.css" type="text/css" media="screen, projection" />

Smart GZIP for S3

In previous versions of mediasync's S3 client, certain content was always pushed in a compressed format. This can cause major issues with clients that do not support gzip. New in version 2.0, mediasync will push both a gzipped and an uncompressed version of the file to S3. The template tags look at the request and direct the user to the appropriate file based on the ACCEPT_ENCODING HTTP header. Assuming a file styles/layout.css, the following would be synced to S3:

styles/layout.css
styles/layout.css.gzt

Note the altered use of the .gz extension. Some versions of the Safari browser on OSX ignore the Content-Type header for files ending in .gz and treat them instead as files to download. This altered extension allows Safari to deflate and utilize the files correctly without affecting functionality in any other tested browsers.

Signals

mediasync provides two signals that allow you to hook into the syncing process. pre_sync is sent after the client is opened, but before the first file is synced. post_sync is sent after the last file is synced, but before the client is closed. This allows you to call commands on the client without having to worry about its state. The signals allow you to do common tasks such as calling Django 1.3's collectstatic command, process SASS stylesheets, or clean up files generated during a pre_sync process.

collectstatic receiver

A receiver for calling the collectstatic management command is provided:

from mediasync.signals import pre_sync, collectstatic_receiver

# run collectstatic before syncing media
pre_sync.connect(collectstatic_receiver)

SASS receiver

A receiver for compiling SASS into CSS is provided:

from mediasync.signals import pre_sync, sass_receiver

# compile SASS files before syncing media
pre_sync.connect(sass_receiver)

Any file in static root that has the sass or scss file extension will be compiled into CSS. The compiled CSS file will be placed in the same directory and the original extension will be replaced with css. If a file exists with the same css extension, it will be overwritten.

By default mediasync uses the sass command with no options. If you would like to specify your own command, specify SASS_COMMAND in settings:

MEDIASYNC = {
    ...
    'SASS_COMMAND': 'sass -scss -l',
    ...
}

Running MEDIASYNC

./manage.py syncmedia

Change Log

2.2.0

  • added pre_sync and post_sync signals
  • provide basic receiver for calling collectstatic before syncing
  • provide receiver for compiling SASS before syncing
  • show media directory listing when serving locally in debug mode
  • add processor for Google's Closure Compiler API for JavaScript
  • template tags can now take a variable as the path argument

2.1.0

  • default to using STATIC_URL and STATIC_ROOT (Django 1.3), falling back to MEDIA_URL and MEDIA_ROOT if the STATIC_* settings are not set
  • add AWS_GZIP setting to optionally disable gzip compression in S3 client

Thanks to Rob Hudson and Dolan Antenucci for their contributions to this release.

2.0.0

  • updated Rackspace Cloud Files backend
  • use gzip instead of deflate for compression (better browser support)
  • smart gzip client support detection
  • add pluggable backends
  • add pluggable file processors
  • experimental YUI Compressor
  • settings refactor
  • allow override of settings.MEDIA_URL
  • Improvements to the logic that decides which files to sync. Safely ignore a wider variety of hidden files/directories.
  • Make template tags aware of whether the current page is SSL-secured. If it is, ask the backend for an SSL media URL (if implemented by your backend).
  • made SERVE_REMOTE setting the sole factor in determining if media should be served locally or remotely
  • add many more tests
  • deprecate CSS_PATH and JS_PATH

Thanks to Greg Taylor, Peter Sanchez, Jonathan Drosdeck, Rich Leland, and Rob Hudson for their contributions to this release.

1.0.1

  • add application/javascript and application/x-javascript to JavaScript mimetypes
  • break out of CSS and JS mimetypes
  • add support for HTTPS URLs to S3
  • allow for storage of S3 keys in ~/.boto configuration file

Thanks to Rob Hudson and Peter Sanchez for their contributions.

1.0.0

Initial release.

More Repositories

1

us-laws

A ticket for every new law of the United States, as of March 12, 2014.
206
star
2

name-cleaver

Parser and standardizer for politician, individual and organization names.
Python
125
star
3

rack-honeypot

Middleware that functions as a spambot trap. Cast spambots off into the abyss.
Ruby
97
star
4

django-gatekeeper

Django object moderation
Python
88
star
5

python-sunlight

Unified Python bindings for Sunlight APIs
Python
65
star
6

ruby-sunlight

Ruby wrapper for the Sunlight Labs API
Ruby
64
star
7

clearmaps

An ActionScript mapping framework for data visualization.
ActionScript
62
star
8

scout

Government-wide search and notification website.
Ruby
50
star
9

opencongress

An open website for opening Congress.
HTML
48
star
10

congress-ios

iOS app for tracking and contacting your legislators, and learning about new bills and laws.
Objective-C
46
star
11

brisket

Influence Explorer: Following the political influence of people, politicians, and organizations
HTML
44
star
12

fcc-net-neutrality-comments

scraping, parsing and making sense of the flood of comments submitted to the FCC on net neutrality
Jupyter Notebook
39
star
13

sitegeist

Understand and uncover the identity of your location with a tap.
CSS
39
star
14

datacommons

The core of sunlightlabs' Data Commons project. Includes the Transparency Data site and the APIs that power TransparencyData.com and InfluenceExplorer.com
Python
37
star
15

photobooth

A Google Chrome/CSS3/WebSocket based photo booth for OS X
Python
32
star
16

echelon

library for analyzing it all
Clojure
31
star
17

django-locksmith

django utilities for shared api authentication & log aggregation
Python
27
star
18

lapidus

analytics dashboard
Python
27
star
19

chartoff

repository for development of visuals in accordance with the sunlight style guide
HTML
27
star
20

churnalism_us

Python
26
star
21

poligraft

Feed in a news article, blog post, or press release, and Poligraft will present you with an enhanced view of the people, organizations, and relationships described in the piece.
Ruby
26
star
22

publicmarkup

Display legislation and allow users to comment on individual sections, titles, or the entire legislation.
Python
25
star
23

django-shortcuts

Database driven "shortcuts". Basically redirects that can be configured via the admin. Exposes analytics for tracking.
Python
25
star
24

regulations-scraper

Scraper of public comments on regulations.gov
Python
23
star
25

python-transparencydata

Wrapper for TransparencyData.com API
Python
23
star
26

datajam

A real-time, data-driven platform for reporting on live events.
JavaScript
23
star
27

sotumachine

State of the Unions for the rest of us
Python
19
star
28

read_FEC

Turn raw electronic FEC filings into meaningful data
Python
19
star
29

crosslaws

Collection of code for parsing information related to the Code of Federal Regulations, the US Code, the US Statues at Large, etc.
Python
19
star
30

jquery-findyourrep

A basic jQuery plugin for finding out who represents you in federal and state legislatures
JavaScript
19
star
31

cluster-explorer

Tool for exploring clusters of similar documents in a text corpus.
Python
16
star
32

door-django

Django frontend for door access management/
JavaScript
13
star
33

django-simplesurvey

simple &amp;amp; versatile survey application for django
Python
13
star
34

ruby-unindentable

Write heredocs without worry of wonky indentation
Ruby
13
star
35

elenas_inbox

Presents the Kagan emails in a familiar interface.
Python
13
star
36

charty

SVG charting library in python
Python
12
star
37

wikipedia-dump-tools

Python tool for processing Wikipedia dump files.
Python
12
star
38

foia-data

Tracking FOIA data across government agencies and departments
HTML
12
star
39

django-feedinator

Python
11
star
40

databuoy

A spreadsheet-backed data catalog
JavaScript
11
star
41

photosynthesis

Official repo documenting the closure of Sunlight Labs
11
star
42

congrelate

Congressional data aggregator website and meta-API.
Ruby
11
star
43

tcorps

TransparencyCorps
Ruby
10
star
44

fara

Foreign influence database
Python
10
star
45

adhawk

Ad Hawk
Python
10
star
46

sitegeist-ios

Understand and uncover the identity of your location with a tap. Native iOS application.
Objective-C
10
star
47

vigo

Vigo the Carpathian watches his viewers.
Java
10
star
48

clearspending

source code for clearspending project
Python
9
star
49

python-superfastmatch

minimal python client for talking to a superfastmatch instance
Python
9
star
50

sunlight-academy-content

The content from Sunlight Academy as markdown.
9
star
51

sfapp

A template for Django and Flask mini Sunlight Foundation apps
CSS
8
star
52

door-android

Opens doors.
Java
8
star
53

openingparliament

HTML
8
star
54

roku-house

Roku app for the HouseLive.gov
Brightscript
8
star
55

drumbone

A RESTful JSON API over data about legislators, bills, and roll call votes.
Ruby
8
star
56

django-nonprofit

Django app for running a non-profit web site. Powers the next version of SunlightFoundation.com.
Python
8
star
57

calloncongress

Call on Congress is a free telephone service that helps you learn more about what Congress is doing.
Python
8
star
58

thezombies

Please don't bother trying to find her, she's not there.
Python
7
star
59

streamcongress

A real-time peek at Congress
Ruby
7
star
60

oxtail

Integration between Sunlight's Poligraft tool and Gmail
Python
7
star
61

django-simplepay

Create signed buttons for Amazon Simple Pay
Python
7
star
62

tour

Titanium/Django app for sightseeing
JavaScript
7
star
63

coleslaw

visualizing the US code
JavaScript
7
star
64

transparencycamp

DEPRECATED Transparency Camp by Sunlight Foundation XXX
HTML
6
star
65

earwig

Open Civic Data-based unified contact system
Python
6
star
66

django-wordpress-extras

A collection of useful, non-WordPress extensions for django-wordpress (the real one).
Python
6
star
67

Roku-Supreme-Court

Roku app for mp3 feeds of Supreme Court arguements
6
star
68

django-citizendialer3000

A tool to help US citizens call their representatives in Congress
Python
6
star
69

sitegeist-android

Android version of Sitegeist.
Java
6
star
70

know-thy-congressman

An entry in Sunlight Labs' Apps for America competition
JavaScript
6
star
71

widgets

Widgets about members of Congress, for embedding into news articles and blog posts
HTML
6
star
72

horseradish

Grate, add salt and white vinegar. Manages photographic assets.
HTML
6
star
73

parmenides

The Poor Man's Record Linkage Service
Clojure
6
star
74

capitol-defense

JavaScript
6
star
75

django-meetup

A very basic client for creating a local cache of Meetup.com/everywhere events.
Python
5
star
76

homebrew-sunlight

Sunlight Foundation homebrew formulas
Ruby
5
star
77

go-sunlight

Go bindings to the Sunlight APIs
Go
5
star
78

emailcongress

Lightweight Django web app and API to courier email messages to phantom-of-the-capitol using Postmark.
HTML
5
star
79

six-degrees

JavaScript
5
star
80

qr-android

Android app for Sunlight's QR code database.
Java
5
star
81

TexLege

TexLege iOS application source
Objective-C
5
star
82

sunlight-2d

qr codes ftw
Python
5
star
83

batman

serves up xml for boxee and roku apps
Python
5
star
84

django-doormat

A nice welcome mat to users from other sites.
Python
5
star
85

the-phantom-mask

Lightweight web app to courier email messages to phantom-of-the-capitol using postmark.
HTML
5
star
86

poindexter

Creates a datastore for information on 527s, political organizations which disclose donors and expenditures semiannually with the IRS and can raise and spend unlimited amounts of money without filing reports with the Federal Election Commission.
Python
5
star
87

openitup

A repository for projects that scrape data from government agencies
Python
5
star
88

wwc

WWC - WhatWorksCities Sunlight Foundation's Open Data Policy Initiative Subdomain
HTML
4
star
89

capitolhttpstester

a HTTPS validity tester for U.S. Capitol websites
Python
4
star
90

tcamp-guide

GCC Machine Description
4
star
91

sundrop

old experimental fabric script
Python
4
star
92

niceneighbor

Labs Olympics 2011
JavaScript
4
star
93

apollo

Open sourced OpenCongress design work
4
star
94

honoree-visualization

Widget for displaying information about honorarium payments for members of the legislative and executive branches.
Python
4
star
95

design

Collects and tracks Sunlight Foundation design tasks.
4
star
96

sf-icons

Icon font designed for Sunlight Foundation
HTML
4
star
97

roku-whitehouse

white house video roku app
4
star
98

branding-bar

Branding bar for Sunlight's tools and projects
JavaScript
4
star
99

Cordray-Jeopardy-Analysis

Scripts for processing j-archive.com HTML into stats
HTML
4
star
100

tcamp

TransparencyCamp site refresh for 2016
HTML
4
star