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

399 lines
13 KiB
Python
Raw Normal View History

2012-07-14 02:47:59 +00:00
# Create your views here.
import re
import sys
import os
import stat
import simplejson as json
2012-07-24 14:10:26 +00:00
from django.http import HttpResponse, HttpResponseServerError
2012-07-14 02:47:59 +00:00
2012-07-14 12:26:41 +00:00
from auth.decorators import login_required, api_login_required
2012-07-14 02:47:59 +00:00
2012-07-27 03:39:55 +00:00
from seaserv import ccnet_rpc, ccnet_threaded_rpc, get_repos, \
2012-07-14 02:47:59 +00:00
get_repo, get_commits, get_branches, \
seafserv_threaded_rpc, seafserv_rpc, get_binding_peerids, \
2012-07-14 02:47:59 +00:00
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, \
gen_file_get_url
2012-07-14 02:47:59 +00:00
from seahub.views import access_to_repo, validate_owner
2012-07-14 12:26:41 +00:00
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
2012-07-21 17:16:43 +00:00
from auth.forms import AuthenticationForm
from auth import login as auth_login
from django.views.decorators.csrf import csrf_exempt
2012-07-14 12:26:41 +00:00
2012-07-25 02:40:14 +00:00
from mime import MIME_MAP
2012-07-14 02:47:59 +00:00
json_content_type = 'application/json; charset=utf-8'
2012-07-25 02:40:14 +00:00
def get_file_mime(name):
sufix = os.path.splitext(name)[1][1:]
if sufix:
return MIME_MAP[sufix]
return None
2012-07-25 02:40:14 +00:00
2012-07-24 14:10:26 +00:00
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.root = commit.root_id
2012-07-25 18:17:32 +00:00
repo.size = seafserv_threaded_rpc.server_repo_size(repo.id)
if not repo.size :
repo.size = 0;
2012-07-24 14:10:26 +00:00
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
2012-07-14 02:47:59 +00:00
def api_error(request, code='404', msg=None):
err_resp = {'error_msg':msg}
return HttpResponse(json.dumps(err_resp), status=code,
2012-07-14 12:26:41 +00:00
content_type=json_content_type)
2012-07-14 02:47:59 +00:00
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)
2012-07-25 18:17:32 +00:00
def get_file_size (id):
size = seafserv_threaded_rpc.get_file_size(dirent.obj_id)
if size:
return size
else:
return 0
def get_dir_entrys_by_id(request, dir_id):
2012-07-14 02:47:59 +00:00
dentrys = []
try:
2012-07-14 12:26:41 +00:00
dirs = seafserv_threaded_rpc.list_dir(dir_id)
2012-07-14 02:47:59 +00:00
except SearpcError, e:
return api_error(request, "404", e.msg)
for dirent in dirs:
2012-07-24 14:10:26 +00:00
dtype = "file"
2012-07-14 02:47:59 +00:00
entry={}
if stat.S_ISDIR(dirent.props.mode):
2012-07-24 14:10:26 +00:00
dtype = "dir"
2012-07-14 02:47:59 +00:00
else:
2012-07-25 02:40:14 +00:00
mime = get_file_mime (dirent.obj_name)
if mime:
entry["mime"] = mime
2012-07-14 02:47:59 +00:00
try:
2012-07-25 18:17:32 +00:00
entry["size"] = get_file_size(dirent.obj_id)
2012-07-24 14:10:26 +00:00
except Exception, e:
2012-07-14 02:47:59 +00:00
entry["size"]=0
2012-07-24 14:10:26 +00:00
entry["type"]=dtype
2012-07-14 02:47:59 +00:00
entry["name"]=dirent.obj_name
entry["id"]=dirent.obj_id
dentrys.append(entry)
response = HttpResponse(json.dumps(dentrys), status=200,
content_type=json_content_type)
response["oid"] = dir_id
return response
def get_dir_entrys_by_path(request, commit, path):
dentrys = []
if path[-1] != '/':
path = path + '/'
dir_id = None
try:
dir_id = seafserv_threaded_rpc.get_dirid_by_path(commit.id,
path.encode('utf-8'))
except SearpcError, e:
return api_error(request, "404", e.msg)
return get_dir_entrys_by_id(request, dir_id)
2012-07-14 02:47:59 +00:00
2012-07-21 17:16:43 +00:00
@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):
def get(self, request):
response = HttpResponse(json.dumps("pong"), status=200, content_type=json_content_type)
if request.user.is_authenticated():
response["logined"] = True
else:
response["logined"] = False
return response
2012-07-21 17:16:43 +00:00
2012-07-14 12:26:41 +00:00
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)
2012-07-24 14:10:26 +00:00
calculate_repo_info (owned_repos, email)
2012-07-14 12:26:41 +00:00
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)
2012-07-24 14:10:26 +00:00
calculate_repo_info (n_repos, email)
2012-07-14 12:26:41 +00:00
owned_repos.sort(lambda x, y: cmp(y.latest_modify, x.latest_modify))
repos_json = []
for r in owned_repos:
repo = {
2012-07-24 14:10:26 +00:00
"type":"repo",
2012-07-14 12:26:41 +00:00
"id":r.props.id,
2012-07-24 14:10:26 +00:00
"owner":email,
2012-07-14 12:26:41 +00:00
"name":r.props.name,
"desc":r.props.desc,
"mtime":r.lastest_modify,
"root":r.root,
2012-07-24 14:10:26 +00:00
"size":r.size,
"password_need":r.password_need,
2012-07-14 12:26:41 +00:00
}
repos_json.append(repo)
for r in n_repos:
repo = {
2012-07-24 14:10:26 +00:00
"type":"repo",
2012-07-14 12:26:41 +00:00
"id":r.props.id,
"owner":r.props.shared_email,
"name":r.props.name,
"desc":r.props.desc,
"mtime":r.lastest_modify,
"root":r.root,
2012-07-24 14:10:26 +00:00
"size":r.size,
"password_need":r.password_need,
2012-07-14 12:26:41 +00:00
}
repos_json.append(repo)
response = Response(200, repos_json)
return self.render(response)
2012-07-21 17:16:43 +00:00
2012-07-14 12:26:41 +00:00
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"
2012-07-14 02:47:59 +00:00
2012-07-14 12:26:41 +00:00
repo = get_repo(repo_id)
if not repo:
return api_error(request, '404', "repo not found")
2012-07-14 02:47:59 +00:00
try:
2012-07-14 12:26:41 +00:00
repo.latest_modify = get_commits(repo.id, 0, 1)[0].ctime
except:
repo.latest_modify = None
2012-07-14 02:47:59 +00:00
2012-07-14 12:26:41 +00:00
# query whether set password if repo is encrypted
2012-07-24 14:10:26 +00:00
password_need = False
2012-07-14 12:26:41 +00:00
if repo.props.encrypted:
try:
ret = seafserv_rpc.is_passwd_set(repo_id, request.user.username)
2012-07-24 14:10:26 +00:00
if ret != 1:
password_need = True
2012-07-14 12:26:41 +00:00
except SearpcError, e:
2012-07-21 17:16:43 +00:00
return api_error(request, '403', e.msg)
2012-07-14 12:26:41 +00:00
# query repo infomation
repo_size = seafserv_threaded_rpc.server_repo_size(repo_id)
current_commit = get_commits(repo_id, 0, 1)[0]
repo_json = {
2012-07-24 14:10:26 +00:00
"type":"repo",
2012-07-14 02:47:59 +00:00
"id":repo.props.id,
"owner":owner,
"name":repo.props.name,
"desc":repo.props.desc,
"mtime":repo.lastest_modify,
2012-07-24 14:10:26 +00:00
"password_need":password_need,
2012-07-14 02:47:59 +00:00
"size":repo_size,
"root":current_commit.root_id,
2012-07-14 02:47:59 +00:00
}
2012-07-14 12:26:41 +00:00
response = Response(200, repo_json)
return self.render(response)
2012-07-14 02:47:59 +00:00
2012-07-14 12:26:41 +00:00
class RepoDirPathView(ResponseMixin, View):
renderers = (JSONRenderer,)
2012-07-14 02:47:59 +00:00
2012-07-14 12:26:41 +00:00
@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]
2012-07-14 02:47:59 +00:00
2012-07-14 12:26:41 +00:00
repo = get_repo(repo_id)
if not repo:
return api_error(request, '404', "repo not found")
2012-07-14 02:47:59 +00:00
2012-07-14 12:26:41 +00:00
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)
2012-07-14 02:47:59 +00:00
2012-07-14 12:26:41 +00:00
if repo.props.encrypted and not password_set:
return api_error(request, '403', "password needed")
2012-07-14 02:47:59 +00:00
2012-07-14 12:26:41 +00:00
path = request.GET.get('p', '/')
return get_dir_entrys_by_path(request, current_commit, path)
2012-07-14 02:47:59 +00:00
2012-07-14 12:26:41 +00:00
class RepoDirIdView(ResponseMixin, View):
renderers = (JSONRenderer,)
2012-07-14 02:47:59 +00:00
2012-07-14 12:26:41 +00:00
@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")
2012-07-14 02:47:59 +00:00
2012-07-14 12:26:41 +00:00
repo = get_repo(repo_id)
if not repo:
return api_error(request, '404', "repo not found")
2012-07-14 02:47:59 +00:00
2012-07-14 12:26:41 +00:00
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)
def get_repo_file(request, repo_id, file_id, file_name):
token = gen_token()
op='download'
seafserv_rpc.web_save_access_token(token, repo_id, file_id,
op, request.user.username)
redirect_url = gen_file_get_url(token, file_name)
response = HttpResponse(json.dumps(redirect_url), status=200,
content_type=json_content_type)
response["oid"] = file_id
return response
class RepoFileIdView(ResponseMixin, View):
2012-07-14 12:26:41 +00:00
renderers = (JSONRenderer,)
@api_login_required
def get(self, request, repo_id, file_id):
repo = get_repo(repo_id)
if not repo:
return api_error(request, '404', "repo not found")
2012-07-14 12:26:41 +00:00
if not can_access_repo(request, repo_id):
return api_error(request, '403', "can not access repo")
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)
return get_repo_file (request, repo_id, file_id, file_name)
class RepoFilePathView(ResponseMixin, View):
@api_login_required
def get(self, request, repo_id):
path = request.GET.get('p', '/')
if not path:
return api_error(request, '404', "Path invalid")
2012-07-14 12:26:41 +00:00
repo = get_repo(repo_id)
if not repo:
return api_error(request, '404', "repo not found")
if not can_access_repo(request, repo_id):
return api_error(request, '403', "can not access repo")
2012-07-14 12:26:41 +00:00
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_id = None
try:
file_id = seafserv_threaded_rpc.get_file_by_path(commit.id,
path.encode('utf-8'))
except SearpcError, e:
return api_error(request, '403', e.msg)
if not file_id:
return api_error(request, '400', "Path invalid")
file_name = request.GET.get('file_name', file_id)
return get_repo_file(request, repo_id, file_id)
2012-07-14 12:26:41 +00:00