1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-06-29 16:37:56 +00:00
seahub/api/views.py
2012-07-24 22:13:07 +08:00

349 lines
11 KiB
Python

# Create your views here.
import re
import sys
import os
import stat
import simplejson as json
from django.http import HttpResponse, HttpResponseServerError
from auth.decorators import login_required, api_login_required
from seaserv import ccnet_rpc, ccnet_threaded_rpc, get_groups, get_users, get_repos, \
get_repo, get_commits, get_branches, \
seafserv_threaded_rpc, seafserv_rpc, get_binding_peerids, get_ccnetuser, \
get_group_repoids, check_group_staff
from seahub.utils import list_to_string, \
get_httpserver_root, gen_token, \
check_filename_with_rename, get_accessible_repos, EMPTY_SHA1
from seahub.views import access_to_repo, validate_owner
from pysearpc import SearpcError
from djangorestframework.renderers import JSONRenderer
from djangorestframework.compat import View
from djangorestframework.mixins import ResponseMixin
from djangorestframework.response import Response
from django.core.urlresolvers import reverse
from auth.forms import AuthenticationForm
from auth import login as auth_login
from django.views.decorators.csrf import csrf_exempt
json_content_type = 'application/json; charset=utf-8'
def calculate_repo_info(repo_list, username):
"""
Get some info for repo.
"""
for repo in repo_list:
try:
commit = get_commits(repo.id, 0, 1)[0]
repo.latest_modify = commit.ctime
repo.commit = commit.id
repo.size = seafserv_threaded_rpc.server_repo_size(repo.id),
password_need = False
if repo.props.encrypted:
try:
ret = seafserv_rpc.is_passwd_set(repo.id, username)
if ret != 1:
password_need = True
except SearpcErroe, e:
pass
repo.password_need = password_need
except:
repo.latest_modify = None
repo.commit = None
repo.size = -1
repo.password_need = None
def api_error(request, code='404', msg=None):
err_resp = {'error_msg':msg}
return HttpResponse(json.dumps(err_resp), status=code,
content_type=json_content_type)
def can_access_repo(request, repo_id):
repo_ap = seafserv_threaded_rpc.repo_query_access_property(repo_id)
if not repo_ap:
repo_ap = 'own'
# check whether user can view repo
return access_to_repo(request, repo_id, repo_ap)
def get_dir_entrys_by_path(reqquest, commit, path):
dentrys = []
if path[-1] != '/':
path = path + '/'
if not commit.root_id == EMPTY_SHA1:
try:
dirs = seafserv_threaded_rpc.list_dir_by_path(commit.id,
path.encode('utf-8'))
except SearpcError, e:
return api_error(request, "404", e.msg)
for dirent in dirs:
dtype = "file"
entry={}
if stat.S_ISDIR(dirent.props.mode):
dtype = "dir"
else:
try:
entry["size"] = seafserv_threaded_rpc.get_file_size(dirent.obj_id)
except:
entry["size"]=0
entry["type"]=dtype
entry["name"]=dirent.obj_name
entry["id"]=dirent.obj_id
dentrys.append(entry)
return HttpResponse(json.dumps(dentrys), status=200,
content_type=json_content_type)
def get_dir_entrys_by_id(reqquest, dir_id):
dentrys = []
try:
dirs = seafserv_threaded_rpc.list_dir(dir_id)
except SearpcError, e:
return api_error(request, "404", e.msg)
for dirent in dirs:
dtype = "file"
entry={}
if stat.S_ISDIR(dirent.props.mode):
dtype = "dir"
else:
try:
entry["size"] = seafserv_threaded_rpc.get_file_size(dirent.obj_id)
except Exception, e:
entry["size"]=0
entry["type"]=dtype
entry["name"]=dirent.obj_name
entry["id"]=dirent.obj_id
dentrys.append(entry)
return HttpResponse(json.dumps(dentrys), status=200,
content_type=json_content_type)
@csrf_exempt
def api_login(request):
if request.method == "POST" :
form = AuthenticationForm(data=request.POST)
else:
return api_error(request, 400, "method not supported")
if form.is_valid():
auth_login(request, form.get_user())
return HttpResponse(json.dumps(request.session.session_key), status=200,
content_type=json_content_type)
else:
return HttpResponse(json.dumps("failed"), status=401,
content_type=json_content_type)
class Ping(ResponseMixin, View):
renderers = (JSONRenderer,)
@api_login_required
def get(self, request):
response = Response(200, "pong")
return self.render(response)
class ReposView(ResponseMixin, View):
renderers = (JSONRenderer,)
@api_login_required
def get(self, request):
email = request.user.username
owned_repos = seafserv_threaded_rpc.list_owned_repos(email)
calculate_repo_info (owned_repos, email)
owned_repos.sort(lambda x, y: cmp(y.latest_modify, x.latest_modify))
n_repos = seafserv_threaded_rpc.list_share_repos(email,
'to_email', -1, -1)
calculate_repo_info (n_repos, email)
owned_repos.sort(lambda x, y: cmp(y.latest_modify, x.latest_modify))
repos_json = []
for r in owned_repos:
repo = {
"type":"repo",
"id":r.props.id,
"owner":email,
"name":r.props.name,
"desc":r.props.desc,
"mtime":r.lastest_modify,
"commit":r.commit,
"size":r.size,
"password_need":r.password_need,
}
repos_json.append(repo)
for r in n_repos:
repo = {
"type":"repo",
"id":r.props.id,
"owner":r.props.shared_email,
"name":r.props.name,
"desc":r.props.desc,
"mtime":r.lastest_modify,
"commit":r.commit,
"size":r.size,
"password_need":r.password_need,
}
repos_json.append(repo)
response = Response(200, repos_json)
return self.render(response)
class RepoView(ResponseMixin, View):
renderers = (JSONRenderer,)
@api_login_required
def get_repo_info(request, repo_id):
# check whether user can view repo
if not can_access_repo(request, repo_id):
return api_error(request, '403', "can not access repo")
# check whether use is repo owner
if validate_owner(request, repo_id):
owner = "self"
else:
owner = "share"
repo = get_repo(repo_id)
if not repo:
return api_error(request, '404', "repo not found")
try:
repo.latest_modify = get_commits(repo.id, 0, 1)[0].ctime
except:
repo.latest_modify = None
# query whether set password if repo is encrypted
password_need = False
if repo.props.encrypted:
try:
ret = seafserv_rpc.is_passwd_set(repo_id, request.user.username)
if ret != 1:
password_need = True
except SearpcError, e:
return api_error(request, '403', e.msg)
# query repo infomation
repo_size = seafserv_threaded_rpc.server_repo_size(repo_id)
current_commit = get_commits(repo_id, 0, 1)[0]
repo_json = {
"type":"repo",
"id":repo.props.id,
"owner":owner,
"name":repo.props.name,
"desc":repo.props.desc,
"mtime":repo.lastest_modify,
"password_need":password_need,
"size":repo_size,
"commit":current_commit.id,
}
response = Response(200, repo_json)
return self.render(response)
class RepoDirPathView(ResponseMixin, View):
renderers = (JSONRenderer,)
@api_login_required
def get(self, request, repo_id):
if not can_access_repo(request, repo_id):
return api_error(request, '403', "can not access repo")
current_commit = get_commits(repo_id, 0, 1)[0]
repo = get_repo(repo_id)
if not repo:
return api_error(request, '404', "repo not found")
password_set = False
if repo.props.encrypted:
try:
ret = seafserv_rpc.is_passwd_set(repo_id, request.user.username)
if ret == 1:
password_set = True
except SearpcError, e:
return api_error(request, '403', e.msg)
if repo.props.encrypted and not password_set:
return api_error(request, '403', "password needed")
path = request.GET.get('p', '/')
return get_dir_entrys_by_path(request, current_commit, path)
class RepoDirIdView(ResponseMixin, View):
renderers = (JSONRenderer,)
@api_login_required
def get(self, request, repo_id, dir_id):
if not can_access_repo(request, repo_id):
return api_error(request, '403', "can not access repo")
repo = get_repo(repo_id)
if not repo:
return api_error(request, '404', "repo not found")
password_set = False
if repo.props.encrypted:
try:
ret = seafserv_rpc.is_passwd_set(repo_id, request.user.username)
if ret == 1:
password_set = True
except SearpcError, e:
return api_error(request, '403', e.msg)
if repo.props.encrypted and not password_set:
return api_error(request, '403', "password needed")
return get_dir_entrys_by_id(request, dir_id)
class RepoFileView(ResponseMixin, View):
renderers = (JSONRenderer,)
@api_login_required
def get(self, request, repo_id, file_id):
if not can_access_repo(request, repo_id):
return api_error(request, '403', "can not access repo")
repo = get_repo(repo_id)
if not repo:
return api_error(request, '404', "repo not found")
password_set = False
if repo.props.encrypted:
try:
ret = seafserv_rpc.is_passwd_set(repo_id, request.user.username)
if ret == 1:
password_set = True
except SearpcError, e:
return api_error(request, '403', e.msg)
if repo.props.encrypted and not password_set:
return api_error(request, '403', "password needed")
file_name = request.GET.get('file_name', file_id)
token = gen_token()
# put token into memory in seaf-server
seafserv_rpc.web_save_access_token(token, file_id)
http_server_root = get_httpserver_root()
op='download'
redirect_url = '%s/access?repo_id=%s&id=%s&filename=%s&op=%s&t=%s&u=%s' % (http_server_root,
repo_id, file_id,
file_name, op,
token,
request.user.username)
response = Response(200, redirect_url)
return self.render(response)