Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Initial commit.
  • Loading branch information
xtao committed Feb 13, 2014
0 parents commit 0c846e4
Show file tree
Hide file tree
Showing 224 changed files with 57,586 additions and 0 deletions.
14 changes: 14 additions & 0 deletions .gitignore
@@ -0,0 +1,14 @@
*.pyc
/venv
/permdir
/tmpdir
/code/permdir
/code/tmpdir
*.ropeproject
node_modules
/dist
.tmp
.sass-cache
*.swp
*.swo
local_config.py
25 changes: 25 additions & 0 deletions LICENSE
@@ -0,0 +1,25 @@
Copyright (c) 2013, Douban Inc.
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the Douban Inc. nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL DOUBAN INC. BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
12 changes: 12 additions & 0 deletions Makefile
@@ -0,0 +1,12 @@
nothing:
@echo "Better make nothing be default"

ctags:
@ctags -R --exclude=dist --exclude=venv --exclude=permdir --exclude=tmpdir --exclude=node_modules

clean_pyc:
@find . -type f -name '*.pyc' -delete;

pylint:
@pylint --errors-only --reports=n --include-ids=y --output-format=parseable --ignore=tracplugs active_stubs/ libs/ models/ static/ stubs/ tasks/ tests/ tools/ views/

36 changes: 36 additions & 0 deletions README.md
@@ -0,0 +1,36 @@
Douban CODE
===========

* Website: <http://douban-code.github.io>

Prepare
-------
- mysql # default port

# import code/databases/schema.sql to database `valentine`
$ mysql -uroot -e 'create database valentine;'
$ mysql -uroot -D valentine < code/databases/schema.sql

- memcached # default port


Getting started
---------------
- `virtualenv venv`
- `. venv/bin/activate`
- `pip install cython` # should install first
- `pip install -U setuptools` # python-libmemcached require updated setuptools
- `pip install -r requirements.txt`
- `gunicorn -b 127.0.0.1:8000 app:app` # web & git http daemon


FAQ
----

1. single http daemon
- `gunicorn -b 127.0.0.1:8001 smart_httpd:app` # git http daemon


License
-------
See the LICENSE file for the full license text.
22 changes: 22 additions & 0 deletions app.py
@@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-

import re

from web import app as web
from smart_httpd import app as git_http


ROUTE_MAP = [(re.compile(r'/[^/]*\.git.*'), git_http),
(re.compile(r'/[^/]*/([^/]*)\.git.*'), git_http),
(re.compile(r'/.*'), web)]


class Application(object):

def __call__(self, environ, start_response):
for rule, func in ROUTE_MAP:
if rule.match(environ['PATH_INFO']):
return func(environ, start_response)
return web(environ, start_response)

app = Application()
Empty file added code/__init__.py
Empty file.
61 changes: 61 additions & 0 deletions code/config.py
@@ -0,0 +1,61 @@
# coding: utf-8

import os
from os.path import dirname, abspath

DEVELOP_MODE = False


DAE_ENV = os.environ.get('DAE_ENV')
CSS_JS_DEVELOP_MODE = DAE_ENV == 'SDK'


CODE_DIR = dirname(abspath(__file__))
HOOKS_DIR = os.path.join(CODE_DIR, 'hooks')
REPO_DIR = os.path.join(CODE_DIR, 'permdir')


MEMCACHED = {
'servers': ["127.0.0.1:11311", ],
'new_servers': [],
'backup_servers': [],
'disabled': False,
'local_cache': True,
'log_every_actions': False,
'slave_servers': [],
}

DOUBANDB = {
'servers': ["127.0.0.1:11311", ],
'proxies': []
}

REDIS = {'host': '127.0.0.1', 'port': 6379}
REDIS_STORE = {
'shire': {
'host': '127.0.0.1', 'port': 6379,
'dbs': {1: 'DEFAULT', 2: 'bloomfilters'},
},
'counter': {
'host': '127.0.0.1', 'port': 6379,
'dbs': {63: 'test-counter'},
},
}

MYSQL_STORE = {
"farms": {
"code_farm": {
"master": "localhost:3306:valentine:root:",
"tables": ["*"],
}
}
}

DOMAIN = "http://127.0.0.1/"

MAKO_FS_CHECK = True

try:
from local_config import *
except ImportError:
pass
117 changes: 117 additions & 0 deletions code/databases/schema.sql
@@ -0,0 +1,117 @@
-- MySQL dump 10.13 Distrib 5.1.70, for apple-darwin12 (x86_64)
--
-- Host: localhost Database: valentine
-- ------------------------------------------------------
-- Server version 5.1.70-log

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;

--
-- Table structure for table `organizations`
--

DROP TABLE IF EXISTS `organizations`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `organizations` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(200) NOT NULL,
`description` varchar(512) NOT NULL,
`owner_id` int(11) NOT NULL,
`creator_id` int(11) NOT NULL,
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_name` (`name`),
KEY `idx_owner` (`owner_id`),
KEY `idx_creator` (`creator_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Table structure for table `project_forks`
--

DROP TABLE IF EXISTS `project_forks`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `project_forks` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`project_id` int(11) NOT NULL,
`forked_id` int(11) NOT NULL,
`family_id` int(11) NOT NULL,
`creator_id` int(11) NOT NULL,
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (`id`),
UNIQUE KEY `idx_project` (`project_id`),
KEY `idx_fork` (`forked_id`),
KEY `idx_family` (`family_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Table structure for table `projects`
--

DROP TABLE IF EXISTS `projects`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `projects` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(200) NOT NULL,
`description` varchar(512) NOT NULL,
`kind` tinyint(2) NOT NULL,
`owner_id` int(11) NOT NULL,
`creator_id` int(11) NOT NULL,
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_kind_owner_name` (`name`,`kind`,`owner_id`),
KEY `idx_name` (`name`),
KEY `idx_owner` (`owner_id`),
KEY `idx_kind_owner` (`kind`,`owner_id`),
KEY `idx_creator` (`creator_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Table structure for table `users`
--

DROP TABLE IF EXISTS `users`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(200) NOT NULL,
`password` varchar(200) NOT NULL,
`description` varchar(512) NOT NULL,
`email` varchar(200) DEFAULT NULL,
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_user` (`name`),
UNIQUE KEY `uk_email` (`email`),
KEY `idx_user_password` (`name`,`password`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;

-- Dump completed on 2013-12-25 2:00:50
46 changes: 46 additions & 0 deletions code/hooks/post-receive
@@ -0,0 +1,46 @@
#! /usr/bin/python
# -*- coding: utf-8 -*-
#
# This code is copyright (c) 2008 by Jack Moffitt jack@metajack.im
# and is available under the GPLv3.

import os
import sys
import urllib
import urllib2
import json


PROJECT_NAME = os.path.realpath('.').split('/permdir/')[1][:-4]
CODE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))
sys.path.insert(0, CODE_DIR)
#sys.path.append(CODE_DIR + "/venv/src/pygit2")
from config import DOMAIN


def http_post(url, data):
payload = json.dumps(data)
try:
u = urllib2.urlopen(url,
urllib.urlencode({'payload': payload}))
u.read()
u.close()
except urllib2.URLError, x:
print "%s => %s" % (url,x)


def main():
url = '%s/api/v1/post_receive/' % DOMAIN
refs = []
user = os.environ.get('CODE_REMOTE_USER')
for line in sys.stdin.readlines():
old, new, ref = line.strip().split(' ')
refs.append(dict(old_value=old,
new_value=new,
ref_name=ref,
user_name=user))
http_post(url, dict(refs=refs, project=PROJECT_NAME))


if __name__ == '__main__':
main()
Empty file added code/libs/__init__.py
Empty file.
56 changes: 56 additions & 0 deletions code/libs/auth/__init__.py
@@ -0,0 +1,56 @@
# -*- coding: utf-8 -*-
from base64 import b64decode
from quixote.errors import AccessError
from quixote import get_request
from code.models.user import User


class AuthCode(object):

def __init__(self, header):
self.login = None
self.passwd = None
self.user = None
try:
auth_type, auth_string = header.split()
login, passwd = b64decode(auth_string).split(':')
self.login = login
self.passwd = passwd
self.user = User.get_by_name(login)
except ValueError:
pass
except TypeError:
pass

def confirm(self):
username = self.login
passwd = self.passwd
if username == 'code' and passwd == 'code':
return True
# FIXME: user login
if username and passwd:
return True
raise UnauthorizedError


class UnauthorizedError(AccessError):
"""
The request requires user authentication.
This subclass of AccessError sends a 401 instead of a 403,
hinting that the client should try again with authentication.
(from http://www.quixote.ca/qx/HttpBasicAuthentication)
"""
status_code = 401
title = "Unauthorized"
description = "You are not authorized to access this resource."

def __init__(self, realm='Protected', public_msg=None, private_msg=None):
self.realm = realm
AccessError.__init__(self, public_msg, private_msg)

def format(self):
request = get_request()
request.response.set_header('WWW-Authenticate',
'Basic realm="%s"' % self.realm)
return AccessError.format(self)

0 comments on commit 0c846e4

Please sign in to comment.