@@ -26,57 +26,68 @@ debug = true
[server:main]
##nr of threads to spawn
threadpool_workers = 5
##max request before
threadpool_max_requests = 6
##option to use threads of process
use_threadpool = false
use = egg:Paste#http
host = 127.0.0.1
port = 5000
[app:main]
use = egg:rhodecode
full_stack = true
static_files = true
lang=en
cache_dir = %(here)s/data
####################################
### BEAKER CACHE ####
beaker.cache.data_dir=/%(here)s/data/cache/data
beaker.cache.lock_dir=/%(here)s/data/cache/lock
beaker.cache.regions=super_short_term,short_term,long_term
beaker.cache.long_term.type=memory
beaker.cache.long_term.expire=36000
beaker.cache.short_term.type=memory
beaker.cache.short_term.expire=60
beaker.cache.super_short_term.type=memory
beaker.cache.super_short_term.expire=10
beaker.cache.regions=super_short_term,short_term,long_term,sql_cache_short,sql_cache_med,sql_cache_long
beaker.cache.sql_cache_short.type=memory
beaker.cache.sql_cache_short.expire=5
beaker.cache.sql_cache_med.type=memory
beaker.cache.sql_cache_med.expire=360
beaker.cache.sql_cache_long.type=file
beaker.cache.sql_cache_long.expire=3600
### BEAKER SESSION ####
## Type of storage used for the session, current types are
## "dbm", "file", "memcached", "database", and "memory".
## The storage uses the Container API
##that is also used by the cache system.
beaker.session.type = file
beaker.session.key = rhodecode
beaker.session.secret = g654dcno0-9873jhgfreyu
beaker.session.timeout = 36000
##auto save the session to not to use .save()
beaker.session.auto = False
##true exire at browser close
#beaker.session.cookie_expires = 3600
################################################################################
## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
.. _changelog:
Changelog
=========
1.0.0rc4 (**2010-10-12**)
1.0.0rc3 (**tip**)
- fixed python2.5 missing simplejson imports (thanks to Jens Bäckman)
- removed cache_manager settings from sqlalchemy meta
- added sqlalchemy cache settings to ini files
1.0.0rc3 (**2010-10-11**)
- fixed i18n during installation.
1.0.0rc2 (**tip**)
1.0.0rc2 (**2010-10-11**)
- Disabled dirsize in file browser, it's causing nasty bug when dir renames
occure. After vcs is fixed it'll be put back again.
- templating/css rewrites, optimized css.
@@ -5,128 +5,125 @@ Setup
Setting up the application
--------------------------
::
paster make-config RhodeCode production.ini
- This will create `production.ini` config inside the directory
this config contain various settings for rhodecode, e.g port, email settings
static files, cache and logging.
paster setup-app production.ini`
- This command will create all needed tables and an admin account.
When asked for a path You can either use a new location of one with already
existing ones. RhodeCode will simply add all new found repositories to
it's database. Also make sure You specify correct path to repositories.
- Remember that the given path for mercurial_ repositories must be write
accessible for the application. It's very important since RhodeCode web interface
will work even without such an access but, when trying to do a push it'll
eventually faile with permission denied errors.
eventually fail with permission denied errors.
- Run
paster serve production.ini
- This command runs the rhodecode server the app should be available at the
127.0.0.1:5000. This ip and port is configurable via the production.ini
file created in previos step
file created in previous step
- Use admin account you created to login.
- Default permissions on each repository is read, and owner is admin. So
remember to update these.
- All needed configs are inside rhodecode sources ie. celeryconfig.py,
development.ini, production.ini You can configure the email, ports, loggers,
workers from there.
remember to update these if needed.
Setting up Whoosh
-----------------
- For full text search You can either put crontab entry for
python /var/www/rhodecode/rhodecode/lib/indexers/daemon.py incremental <put_here_path_to_repos>
python /var/www/rhodecode/<rhodecode_installation_path>/lib/indexers/daemon.py incremental <put_here_path_to_repos>
When using incremental mode whoosh will check last modification date of each file
and add it to reindex if newer file is available. Also indexing daemon checks
for removed files and removes them from index. Sometime You might want to rebuild
index from scrach, in admin pannel You can check `build from scratch` flag
and in standalone daemon You can pass `full` instead on incremental to build
remove previos index and build new one.
Nginx virtual host example
Sample config for nginx::
server {
listen 80;
server_name hg.myserver.com;
access_log /var/log/nginx/rhodecode.access.log;
error_log /var/log/nginx/rhodecode.error.log;
location / {
root /var/www/rhodecode/rhodecode/public/;
if (!-f $request_filename){
proxy_pass http://127.0.0.1:5000;
}
#this is important for https !!!
proxy_set_header X-Url-Scheme $scheme;
include /etc/nginx/proxy.conf;
Here's the proxy.conf. It's tunned so it'll not timeout on long
Here's the proxy.conf. It's tuned so it'll not timeout on long
pushes and also on large pushes::
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Proxy-host $proxy_host;
client_max_body_size 400m;
client_body_buffer_size 128k;
proxy_buffering off;
proxy_connect_timeout 3600;
proxy_send_timeout 3600;
proxy_read_timeout 3600;
proxy_buffer_size 8k;
proxy_buffers 8 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
Also when using root path with nginx You might set the static files to false
in production.ini file::
static_files = false
To not have the statics served by the application.
To not have the statics served by the application. And improve speed.
Other configuration files
-------------------------
Some extra configuration files and examples can be found here:
http://hg.python-works.com/rhodecode/files/tip/init.d
and also an celeryconfig file can be use from here:
http://hg.python-works.com/rhodecode/files/tip/celeryconfig.py
.. _virtualenv: http://pypi.python.org/pypi/virtualenv
.. _python: http://www.python.org/
.. _mercurial: http://mercurial.selenic.com/
.. _celery: http://celeryproject.org/
.. _rabbitmq: http://www.rabbitmq.com/
\ No newline at end of file
@@ -26,63 +26,74 @@ debug = true
##max request before thread respawn
threadpool_max_requests = 2
use_threadpool = true
port = 8001
## dbm, file, memcached, database, and memory.
## execute malicious code after an exception is raised. ##
set debug = false
##################################
### LOGVIEW CONFIG ###
@@ -3,33 +3,33 @@
# RhodeCode, a web based repository management based on pylons
# Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; version 2
# of the License or (at your opinion) any later version of the license.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.
"""
Created on April 9, 2010
RhodeCode, a web based repository management based on pylons
versioning implementation: http://semver.org/
@author: marcink
VERSION = (1, 0, 0, 'rc3')
VERSION = (1, 0, 0, 'rc4')
__version__ = '.'.join((str(each) for each in VERSION[:4]))
def get_version():
Returns shorter version (digit parts only) as string.
return '.'.join((str(each) for each in VERSION[:3]))
@@ -27,63 +27,74 @@ debug = true
app_instance_uuid = ${app_instance_uuid}
beaker.session.secret = ${app_instance_secret}
#!/usr/bin/env python
# encoding: utf-8
# changelog controller for pylons
Created on April 21, 2010
changelog controller for pylons
from json import dumps
from mercurial.graphmod import colored, CHANGESET, revisions as graph_rev
from pylons import request, session, tmpl_context as c
from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
from rhodecode.lib.base import BaseController, render
from rhodecode.model.hg_model import HgModel
from webhelpers.paginate import Page
import logging
log = logging.getLogger(__name__)
try:
import json
except ImportError:
#python 2.5 compatibility
import simplejson as json
class ChangelogController(BaseController):
@LoginRequired()
@HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
'repository.admin')
def __before__(self):
super(ChangelogController, self).__before__()
def index(self):
limit = 100
default = 20
if request.params.get('size'):
int_size = int(request.params.get('size'))
except ValueError:
int_size = default
int_size = int_size if int_size <= limit else limit
c.size = int_size
session['changelog_size'] = c.size
session.save()
else:
c.size = int(session.get('changelog_size', default))
changesets = HgModel().get_repo(c.repo_name)
p = int(request.params.get('page', 1))
c.total_cs = len(changesets)
c.pagination = Page(changesets, page=p, item_count=c.total_cs,
items_per_page=c.size)
self._graph(changesets, c.size, p)
return render('changelog/changelog.html')
def _graph(self, repo, size, p):
revcount = size
if not repo.revisions:return dumps([]), 0
if not repo.revisions:return json.dumps([]), 0
max_rev = repo.revisions[-1]
offset = 1 if p == 1 else ((p - 1) * revcount + 1)
rev_start = repo.revisions[(-1 * offset)]
revcount = min(max_rev, revcount)
rev_end = max(0, rev_start - revcount)
dag = graph_rev(repo.repo, rev_start, rev_end)
c.dag = tree = list(colored(dag))
data = []
for (id, type, ctx, vtx, edges) in tree:
if type != CHANGESET:
continue
data.append(('', vtx, edges))
c.jsdata = dumps(data)
c.jsdata = json.dumps(data)
@@ -14,49 +14,53 @@
Created on April 18, 2010
summary controller for pylons
from pylons import tmpl_context as c, request, url
from rhodecode.lib.utils import OrderedDict
from rhodecode.model.db import Statistics
from rhodecode.lib.celerylib import run_task
from rhodecode.lib.celerylib.tasks import get_commits_stats
from datetime import datetime, timedelta
from time import mktime
import calendar
class SummaryController(BaseController):
super(SummaryController, self).__before__()
hg_model = HgModel()
c.repo_info = hg_model.get_repo(c.repo_name)
c.repo_changesets = Page(list(c.repo_info[:10]), page=1, items_per_page=20)
e = request.environ
uri = u'%(protocol)s://%(user)s@%(host)s%(prefix)s/%(repo_name)s' % {
'protocol': e.get('wsgi.url_scheme'),
'user':str(c.rhodecode_user.username),
'host':e.get('HTTP_HOST'),
'prefix':e.get('SCRIPT_NAME'),
'repo_name':c.repo_name, }
c.clone_repo_url = uri
c.repo_tags = OrderedDict()
"""SQLAlchemy Metadata and Session object"""
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import scoped_session, sessionmaker
from rhodecode.model import caching_query
from beaker import cache
import os
from os.path import join as jn, dirname as dn, abspath
import time
# Beaker CacheManager. A home base for cache configurations.
cache_manager = cache.CacheManager()
__all__ = ['Base', 'Session']
# SQLAlchemy session manager. Updated by model.init_model()
Session = scoped_session(
sessionmaker(
query_cls=caching_query.query_callable(cache_manager)
)
# The declarative Base
Base = declarative_base()
#For another db...
#Base2 = declarative_base()
#===============================================================================
# CACHE OPTIONS
cache_base = jn(dn(dn(dn(abspath(__file__)))), 'data')
cache_dir = jn(cache_base, 'cache')
if not os.path.isdir(cache_base):
os.mkdir(cache_base)
if not os.path.isdir(cache_dir):
os.mkdir(cache_dir)
# set start_time to current time
# to re-cache everything
# upon application startup
start_time = time.time()
# configure the "sqlalchemy" cache region.
cache_manager.regions['sql_cache_short'] = {
'type':'memory',
'data_dir':cache_dir,
'expire':10,
'start_time':start_time
cache_manager.regions['sql_cache_med'] = {
'expire':360,
cache_manager.regions['sql_cache_long'] = {
'type':'file',
'expire':3600,
#to use cache use this in query
#.options(FromCache("sqlalchemy_cache_type", "cachekey"))
[egg_info]
tag_build = rc3
tag_build = rc4
tag_svn_revision = true
[easy_install]
find_links = http://www.pylonshq.com/download/
[nosetests]
verbose=True
verbosity=2
with-pylons=test.ini
detailed-errors=1
# Babel configuration
[compile_catalog]
domain = rhodecode
directory = rhodecode/i18n
statistics = true
[extract_messages]
add_comments = TRANSLATORS:
output_file = rhodecode/i18n/rhodecode.pot
width = 80
[init_catalog]
input_file = rhodecode/i18n/rhodecode.pot
output_dir = rhodecode/i18n
[update_catalog]
previous = true
[build_sphinx]
source-dir = docs/
build-dir = docs/_build
all_files = 1
[upload_sphinx]
upload-dir = docs/_build/html
Status change: