Gittip is a weekly gift exchange, helping to create a culture of generosity. If you'd like to learn more, check out https://gittip.com/about. If you'd like to contribute to Gittip, the best first reference is https://gittip.com/for/contributors.
$ git clone git@github.com:gittip/www.gittip.com.git
$ cd www.gittip.com
$ sudo -u postgres createuser --superuser $USER
$ createdb gittip
$ make schema
$ make run
And/or:
$ make test
We also include a Vagrantfile.
- Installation
- Dependencies
- Building
- Launching
- Help!
- Configuration
- Modifying CSS
- Testing
- Setting up a Database
- API
- Implementations
- Glossary
- See Also
Thanks for hacking on Gittip! Be sure to review CONTRIBUTING as well if that's what you're planning to do.
Building www.gittip.com
requires Python
2.7, and a gcc/make toolchain.
All Python library dependencies are bundled in the repo (under vendor/
) and
if you do not want to install Postgres locally you can try to use a cloud instance
by issuing make cloud-db
(it is somewhat slow for regular development).
To configure local Postgres create default role and database:
$ sudo -u postgres createuser --superuser $USER
$ createdb gittip
On Debian or Ubuntu you will need the following packages:
libpq5-dev
/libpq-dev
, (includes headers needed to build the psycopg2
Python library)
and python-dev
(includes Python header files for psycopg2
).
If you are receiving issues from psycopg2
, please ensure that its needs are
met.
All Python dependencies (including virtualenv) are bundled with Gittip in the vendor/ directory. Gittip is designed so that you don't manage its virtualenv directly and you don't download its dependencies at build time.
The included Makefile
contains several targets. Configuration options
are stored in default_local.env file while overrides are in local.env.
To create virtualenv enviroment with all python dependencies installed in a sandbox:
$ make env
If you haven't run Gittip for a while, you can reinstall the dependencies:
$ make clean env
Add the necessary schemas and insert dummy data into postgres:
$ make schema
$ make data
Once you've installed Python and Postgres and set up a database, you can use make to build and launch Gittip:
$ make run
If you don't have make, look at the Makefile to see what steps you need to perform to build and launch Gittip. The Makefile is pretty simple and straightforward.
If Gittip launches successfully it will look like this:
$ make run
./env/bin/honcho -e default_local.env,local.env run ./env/bin/aspen \
--www_root=www/ \
--project_root=. \
--show_tracebacks=yes \
--changes_reload=yes \
--network_address=:8537
pid-27937 thread-47041048338176 (MainThread) Reading configuration from defaults, environment, and command line.
pid-27937 thread-47041048338176 (MainThread) changes_reload False default
pid-27937 thread-47041048338176 (MainThread) changes_reload True command line option --changes_reload=yes
pid-27937 thread-47041048338176 (MainThread) charset_dynamic UTF-8 default
pid-27937 thread-47041048338176 (MainThread) charset_static None default
pid-27937 thread-47041048338176 (MainThread) configuration_scripts [] default
pid-27937 thread-47041048338176 (MainThread) indices [u'index.html', u'index.json', u'index', u'index.html.spt', u'index.json.spt', u'index.spt'] default
pid-27937 thread-47041048338176 (MainThread) list_directories False default
pid-27937 thread-47041048338176 (MainThread) logging_threshold 0 default
pid-27937 thread-47041048338176 (MainThread) media_type_default text/plain default
pid-27937 thread-47041048338176 (MainThread) media_type_json application/json default
pid-27937 thread-47041048338176 (MainThread) network_address ((u'0.0.0.0', 8080), 2) default
pid-27937 thread-47041048338176 (MainThread) network_address ((u'0.0.0.0', 8537), 2) command line option --network_address=:8537
pid-27937 thread-47041048338176 (MainThread) network_engine cheroot default
pid-27937 thread-47041048338176 (MainThread) project_root None default
pid-27937 thread-47041048338176 (MainThread) project_root . command line option --project_root=.
pid-27937 thread-47041048338176 (MainThread) renderer_default stdlib_percent default
pid-27937 thread-47041048338176 (MainThread) show_tracebacks False default
pid-27937 thread-47041048338176 (MainThread) show_tracebacks True command line option --show_tracebacks=yes
pid-27937 thread-47041048338176 (MainThread) www_root None default
pid-27937 thread-47041048338176 (MainThread) www_root www/ command line option --www_root=www/
pid-27937 thread-47041048338176 (MainThread) project_root is relative to CWD: '.'.
pid-27937 thread-47041048338176 (MainThread) project_root set to /home/zbynek/www.gittip.com.
pid-27937 thread-47041048338176 (MainThread) Found plugin for renderer 'jinja2'
pid-27937 thread-47041048338176 (MainThread) Won't log to Sentry (SENTRY_DSN is empty).
pid-27937 thread-47041048338176 (MainThread) Loading configuration file '/home/zbynek/www.gittip.com/configure-aspen.py' (possibly changing settings)
pid-27937 thread-47041048338176 (MainThread) Renderers (*ed are unavailable, CAPS is default):
pid-27937 thread-47041048338176 (MainThread) stdlib_percent
pid-27937 thread-47041048338176 (MainThread) stdlib_format
pid-27937 thread-47041048338176 (MainThread) JINJA2
pid-27937 thread-47041048338176 (MainThread) stdlib_template
pid-27937 thread-47041048338176 (MainThread) Starting cheroot engine.
pid-27937 thread-47041048338176 (MainThread) Greetings, program! Welcome to port 8537.
pid-27937 thread-47041048338176 (MainThread) Aspen will restart when configuration scripts or Python modules change.
pid-27937 thread-47041048338176 (MainThread) Starting up Aspen website.
You should then find this in your browser at http://localhost:8537/:
Congratulations! Sign in using Twitter or GitHub and you're off and running. At some point, try running the test suite.
If you get stuck somewhere along the way, you can find help in the #gittip channel on Freenode or in the issue tracker here on GitHub. If all else fails ping @whit537 on Twitter or email chad@gittip.com.
Thanks for installing Gittip! 😃
When using make run
, Gittip's execution environment is defined in an
environment files [default_local.env]
(https://github.com/gittip/www.gittip.com/blob/master/default_local.env)
local.env
. The former contains all variables needed to run successfully.
The later allows for easy overrides since it is not included in the source
code repo.
The following text explains some of the content of that file:
The BALANCED_API_SECRET
is a test marketplace. To generate a new secret for
your own testing run this command:
curl -X POST https://api.balancedpayments.com/v1/api_keys | grep secret
Grab that secret and also create a new marketplace to test against:
curl -X POST https://api.balancedpayments.com/v1/marketplaces -u <your_secret>:
The site works without this, except for the credit card page. Visit the Balanced Documentation if you want to know more about creating marketplaces.
The GITHUB_* keys are for a gittip-dev application in the Gittip organization
on Github. It points back to localhost:8537, which is where Gittip will be
running if you start it locally with make run
. Similarly with the TWITTER_*
keys, but there they required us to spell it 127.0.0.1
.
You probably don't need it, but at one point I had to set this to get psycopg2 working on Mac OS with EnterpriseDB's Postgres 9.1 installer:
DYLD_LIBRARY_PATH=/Library/PostgreSQL/9.1/lib
If you wish to use different username or database name for the database, you
should change the DATABASE_URL
using the following format:
DATABASE_URL=postgres://<username>@localhost/<database name>
We use SCSS, with files stored in scss/
. All of the individual files are
combined in scss/gittip.scss
which itself is compiled by libsass
in
www/assets/%version/gittip.css.spt
on each request.
Please write unit tests for all new code and all code you change. Gittip's
test suite uses the py.test test runner, which will be installed into the
virtualenv you get by running make env
. As a rule of thumb, each test case
should perform one assertion.
The easiest way to run the test suite is:
$ make test
However, the test suite deletes data in all tables in the public schema of the database configured in your testing environment.
To invoke py.test directly you should use the honcho
utility that comes
with the install. First make tests/env
, activate the virtualenv and then:
[gittip] $ cd tests/
[gittip] $ honcho -e ../default_tests.env,env py.test
The tests will try to use gittip-test
database of the current $USER.
For the best development experience, you need a local
installation of Postgres. The best
version of Postgres to use is 9.3.2, because that's what we're using in
production at Heroku. You need at least 9.2, because we depend on being able to
specify a URI to psql
, and that was added in 9.2.
If you're on a Mac, maybe try out Heroku's
Postgres.app. If installing using a
package manager, you may need several packages. On Ubuntu and Debian, the
required packages are: postgresql
(base) and postgresql-contrib
(includes hstore).
To setup the instance for gittip's needs run:
$ sudo -u postgres createuser --superuser $USER
$ createdb gittip
$ createdb gittip-test
You can speed up the test suite when using a regular HDD by running:
$ psql -q gittip-test -c 'alter database "gittip-test" set synchronous_commit to off'
Once Postgres is set up, run:
$ make schema
That will populate the database named by DATABASE_URL with the Gittip schema, per ./schema.sql.
The schema for the Gittip.com database is defined in schema.sql. It should be considered append-only. The idea is that this is the log of DDL that we've run against the production database. You should never change commands that have already been run. New DDL will be (manually) run against the production database as part of deployment.
The gittip database created in the last step is empty. To populate it with some fake data, so that more of the site is functional, run this command:
$ make data
The Gittip API is comprised of these six endpoints:
/about/charts.json (source)—public—Returns an array of objects, one per week, showing aggregate numbers over time. The charts page uses this.
/about/paydays.json (source)—public—Returns an array of objects, one per week, showing aggregate numbers over time. The charts page used to use this.
/about/stats.json (source)—public—Returns an object giving a point-in-time snapshot of Gittip. The stats page displays the same info.
/%username
/charts.json
(example,
source)—public—Returns
an array of objects, one per week, showing aggregate numbers over time for the
given user.
/%username
/public.json
(example,
source)—public—Returns an object with these keys:
-
"receiving"—an estimate of the amount the given participant will receive this week
-
"my_tip"—logged-in user's tip to the Gittip participant in question; possible values are:
undefined
(key not present)—there is no logged-in user- "self"—logged-in user is the participant in question
null
—user has never tipped this participant- "0.00"—user used to tip this participant
- "3.00"—user tips this participant the given amount
-
"goal"—funding goal of the given participant; possible values are:
undefined
(key not present)—participant is a patron (or has 0 as the goal)null
—participant is grateful for gifts, but doesn't have a specific funding goal- "100.00"—participant's goal is to receive the given amount per week
-
"elsewhere"—participant's connected accounts elsewhere; returns an object with these keys:
- "bitbucket"—participant's Bitbucket account; possible values are:
undefined
(key not present)—no Bitbucket account connectedhttps://bitbucket.org/api/1.0/users/%bitbucket_username
- "github"—participant's GitHub account; possible values are:
undefined
(key not present)—no GitHub account connectedhttps://api.github.com/users/%github_username
- "twitter"—participant's Twitter account; possible values are:
undefined
(key not present)—no Twitter account connectedhttps://api.twitter.com/1.1/users/show.json?id=%twitter_immutable_id&include_entities=1
- "openstreetmap"—participant's OpenStreetMap account; possible values are:
undefined
(key not present)—no OpenStreetMap account connected%OPENSTREETMAP_API/user/%openstreetmap_username
- "bitbucket"—participant's Bitbucket account; possible values are:
/%username
/tips.json
(source)—private—Responds
to GET
with an array of objects representing your current tips. POST
the
same structure back in order to update tips in bulk (be sure to set
Content-Type
to application/json
instead of
application/x-www-form-urlencoded
). You can POST
a partial array to update
a subset of your tips. The response to a POST
will be only the subset you
updated. If the amount
is "error"
then there will also be an error
attribute with a one-word error code. If you include an also_prune
key in the
querystring (not the body!) with a value of yes
, true
, or 1
, then any
tips not in the array you POST
will be zeroed out.
NOTE: The amounts must be encoded as a string (rather than a number). Additionally, currently, the only supported platform is 'gittip'.
This endpoint requires authentication. Look for your API key on your profile page, and pass it as the basic auth username. E.g.:
curl https://www.gittip.com/foobar/tips.json \
-u API_KEY: \
-X POST \
-d'[{"username":"bazbuz", "platform":"gittip", "amount": "1.00"}]' \
-H"Content-Type: application/json"
Below are some projects that use the Gittip APIs, that can serve as inspiration for your project!
-
Drupal: Gittip—Includes a Gittip giving field type to let you implement the Khan academy model for users on your Drupal site.
-
Node.js: Node-Gittip (also see Khan Academy's setup)
-
Ruby: gratitude: A ruby gem that wraps the Gittip API (currently in development and not feature complete).
-
hubot-gittip: A Hubot script for interacting with a shared Gittip account.
-
gittip-collab: A Khan-style tool for managing a Gittip account as a team.
Account Elsewhere - An entity's registration on a platform other than Gittip (e.g., Twitter).
Entity - An entity.
Participant - An entity registered with Gittip.
User - A person using the Gittip website. Can be authenticated or anonymous. If authenticated, the user is guaranteed to also be a participant.
Here's a list of projects we're aware of in the crowd-funding space. Something missing? Ping @whit537 on Twitter or edit the file yourself (add your link at the end). 😀
Note: there are comprehensive directories that can complement this list, such as startingtrends.com's and crowdsourcing.org's
- Kickstarter - crowdfunding campaigns
- Flattr - micro-donations (flat monthly rate)
- TipTheWeb - micro-donations
- IndieGoGo - crowdfunding campaigns (partial funding allowed)
- PledgeMusic - crowdfunding for musicians
- Propster
- Kachingle
- Venmo - transactions among friends (US only)
- Snoball - link events or actions as triggers for micro-donations
- Pledgie - crowdfunding campaigns
- HumbleBundle
- CrowdTilt - crowdfunding campaigns
- NetworkForGood
- AnyFu - hire an expert for one-on-one, screen-share work sessions
- OpenOfficeHours
- [discontinued] TipJoy
- HopeMob
- AwesomeFoundation
- CrowdRise
- [discontinued] ChipIn
- Fundable - fund start-up companies
- ModestNeeds - crowdfunding campaigns in support of the “working poor”
- FreedomSponsors - Crowdfunding Free Software, one issue at a time
- GumRoad
- MacHeist
- Prosper - peer-to-peer lending
- [discontinued] Togather
- PaySwarm - open payment protocol
- [discontinued] Gitbo - another implementation of the bounty model
- Affero - old skool attempt “to bring a culture of patronage to the Internet”
- ShareAGift - one-off, crowd-sourced cash gifts
- GoFundMe - derpy-looking platform that reaches normal people (my dad emailed this link to me)
- DonorsChoose.org - crowd-funded school supplies; Alexis Ohanian likes it.
- Catincan - FOSS bounty site
- Bountysource - FOSS bounty site
- IssueHunter - FOSS bounty site
- TinyPass - Soft paywall, used by e.g. Daily Dish
- Patreon - Patronage model for content creators(!)
- [discontinued] WhyNotMe - "Give as a group to any non-profit in America"
- LoveMachine - "the cool new employee recognition system" (supposedly came out of Linden Lab)
- See.Me - sustainable crowdfunding for artists
- NoiseTrade - band mailing lists + tips
- YouTube Nonprofit Program - puts donate buttons on your vids
- Generous - Pay-what-you-want platform
- FundAnything - Kickstarter knock-off, I guess?
- ShareTribe - Create your own community marketplace
- Subbable - What John and Hank Green wanted (cf. #737)
- Pitch In - Widget-centric project-based funding campaigns
- Binpress - Binpress is the marketplace for commercial open-source projects.
- TubeStart - a crowdfunding platform dedicated exclusively to YouTube creators
- Fundit - An Ireland-wide initiative
- Snowdrift.coop - a new sustainable patronage system
- PieTrust - an "open company" developing a secure reputation system for sharing credit.
- BountyOSS - Where crowdfunding means business
- Suprmasv - Empowering the Hacker Class.
- Tip4Commit - Donate bitcoins to open source projects or make commits and get tips for it.
- BitHub - An experiment in funding privacy OSS.
- Fundly - Crowdfund Anything
- I Love Open Source - Simple recognition for open source developers
- Razoo - Create online fundraisers for anything and everything that matters to you.
- CoinGiving - Personified Bitcoin Donations
- Bittip - Bitcoin Microdonations - Like Flattr, but with Btc
- MedStartr - Fund the medical breakthroughs and innovations you care about
- Upstart - Raise money from your future self