mirror of
https://github.com/haiwen/seahub.git
synced 2025-07-19 01:29:05 +00:00
225 lines
7.9 KiB
Python
225 lines
7.9 KiB
Python
# Copyright (c) 2012-2016 Seafile Ltd.
|
|
import logging
|
|
from datetime import datetime
|
|
|
|
from rest_framework.authentication import SessionAuthentication
|
|
from rest_framework.permissions import IsAuthenticated
|
|
from rest_framework.response import Response
|
|
from rest_framework.views import APIView
|
|
from rest_framework import status
|
|
|
|
from seaserv import seafile_api
|
|
|
|
from seahub.api2.throttling import UserRateThrottle
|
|
from seahub.api2.authentication import TokenAuthentication
|
|
from seahub.api2.utils import api_error
|
|
from seahub.utils import get_file_history
|
|
from seahub.utils.timeutils import utc_datetime_to_isoformat_timestr, timestamp_to_isoformat_timestr
|
|
from seahub.utils.file_revisions import get_file_revisions_within_limit
|
|
from seahub.views import check_folder_permission
|
|
from seahub.avatar.templatetags.avatar_tags import api_avatar_url
|
|
from seahub.base.templatetags.seahub_tags import email2nickname, \
|
|
email2contact_email
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
def get_new_file_history_info(ent, avatar_size):
|
|
|
|
info = {}
|
|
|
|
creator_name = ent.op_user
|
|
url, is_default, date_uploaded = api_avatar_url(creator_name, avatar_size)
|
|
|
|
info['creator_avatar_url'] = url
|
|
info['creator_email'] = creator_name
|
|
info['creator_name'] = email2nickname(creator_name)
|
|
info['creator_contact_email'] = email2contact_email(creator_name)
|
|
info['op_type'] = ent.op_type
|
|
info['ctime'] = utc_datetime_to_isoformat_timestr(ent.timestamp)
|
|
info['commit_id'] = ent.commit_id
|
|
info['size'] = ent.size
|
|
info['rev_file_id'] = ent.file_id
|
|
info['old_path'] = ent.old_path if hasattr(ent, 'old_path') else ''
|
|
info['path'] = ent.path
|
|
|
|
return info
|
|
|
|
def get_file_history_info(commit, avatar_size):
|
|
|
|
info = {}
|
|
|
|
creator_name = commit.creator_name
|
|
url, is_default, date_uploaded = api_avatar_url(creator_name, avatar_size)
|
|
|
|
info['creator_avatar_url'] = url
|
|
info['creator_email'] = creator_name
|
|
info['creator_name'] = email2nickname(creator_name)
|
|
info['creator_contact_email'] = email2contact_email(creator_name)
|
|
info['ctime'] = timestamp_to_isoformat_timestr(commit.ctime)
|
|
info['description'] = commit.desc
|
|
info['commit_id'] = commit.id
|
|
info['size'] = commit.rev_file_size
|
|
info['rev_file_id'] = commit.rev_file_id
|
|
info['rev_renamed_old_path'] = commit.rev_renamed_old_path
|
|
|
|
return info
|
|
|
|
|
|
class FileHistoryView(APIView):
|
|
authentication_classes = (TokenAuthentication, SessionAuthentication)
|
|
permission_classes = (IsAuthenticated,)
|
|
throttle_classes = (UserRateThrottle,)
|
|
|
|
def get(self, request, repo_id):
|
|
""" Get file history within certain commits.
|
|
Controlled by path(rev_renamed_old_path), commit_id and next_start_commit.
|
|
"""
|
|
# argument check
|
|
path = request.GET.get('path', '')
|
|
if not path:
|
|
error_msg = 'path invalid.'
|
|
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
|
|
|
|
# resource check
|
|
repo = seafile_api.get_repo(repo_id)
|
|
if not repo:
|
|
error_msg = 'Library %s not found.' % repo_id
|
|
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
|
|
|
|
commit_id = request.GET.get('commit_id', '')
|
|
if not commit_id:
|
|
commit_id = repo.head_cmmt_id
|
|
|
|
try:
|
|
avatar_size = int(request.GET.get('avatar_size', 32))
|
|
except ValueError:
|
|
avatar_size = 32
|
|
|
|
# Don't use seafile_api.get_file_id_by_path()
|
|
# if path parameter is `rev_renamed_old_path`.
|
|
# seafile_api.get_file_id_by_path() will return None.
|
|
file_id = seafile_api.get_file_id_by_commit_and_path(repo_id,
|
|
commit_id, path)
|
|
if not file_id:
|
|
error_msg = 'File %s not found.' % path
|
|
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
|
|
|
|
# permission check
|
|
if not check_folder_permission(request, repo_id, '/'):
|
|
error_msg = 'Permission denied.'
|
|
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
|
|
|
|
# get repo history limit
|
|
try:
|
|
keep_days = seafile_api.get_repo_history_limit(repo_id)
|
|
except Exception as e:
|
|
logger.error(e)
|
|
error_msg = 'Internal Server Error'
|
|
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
|
|
|
|
# get file history
|
|
limit = request.GET.get('limit', 50)
|
|
try:
|
|
limit = 50 if int(limit) < 1 else int(limit)
|
|
except ValueError:
|
|
limit = 50
|
|
|
|
try:
|
|
file_revisions, next_start_commit = get_file_revisions_within_limit(
|
|
repo_id, path, commit_id, limit)
|
|
except Exception as e:
|
|
logger.error(e)
|
|
error_msg = 'Internal Server Error'
|
|
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
|
|
|
|
result = []
|
|
present_time = datetime.utcnow()
|
|
for commit in file_revisions:
|
|
history_time = datetime.utcfromtimestamp(commit.ctime)
|
|
if (keep_days != -1) and ((present_time - history_time).days > keep_days):
|
|
next_start_commit = False
|
|
break
|
|
info = get_file_history_info(commit, avatar_size)
|
|
info['path'] = path
|
|
result.append(info)
|
|
|
|
return Response({
|
|
"data": result,
|
|
"next_start_commit": next_start_commit or False
|
|
})
|
|
|
|
|
|
class NewFileHistoryView(APIView):
|
|
authentication_classes = (TokenAuthentication, SessionAuthentication)
|
|
permission_classes = (IsAuthenticated,)
|
|
throttle_classes = (UserRateThrottle,)
|
|
|
|
def get(self, request, repo_id):
|
|
""" Get file history within certain commits.
|
|
|
|
Controlled by path(rev_renamed_old_path), commit_id and next_start_commit.
|
|
"""
|
|
# argument check
|
|
path = request.GET.get('path', '')
|
|
if not path:
|
|
error_msg = 'path invalid.'
|
|
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
|
|
|
|
# resource check
|
|
repo = seafile_api.get_repo(repo_id)
|
|
if not repo:
|
|
error_msg = 'Library %s not found.' % repo_id
|
|
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
|
|
|
|
commit_id = repo.head_cmmt_id
|
|
|
|
try:
|
|
avatar_size = int(request.GET.get('avatar_size', 32))
|
|
page = int(request.GET.get('page', '1'))
|
|
per_page = int(request.GET.get('per_page', '25'))
|
|
except ValueError:
|
|
avatar_size = 32
|
|
page = 1
|
|
per_page = 25
|
|
|
|
# Don't use seafile_api.get_file_id_by_path()
|
|
# if path parameter is `rev_renamed_old_path`.
|
|
# seafile_api.get_file_id_by_path() will return None.
|
|
file_id = seafile_api.get_file_id_by_commit_and_path(repo_id,
|
|
commit_id, path)
|
|
if not file_id:
|
|
error_msg = 'File %s not found.' % path
|
|
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
|
|
|
|
# permission check
|
|
if not check_folder_permission(request, repo_id, '/'):
|
|
error_msg = 'Permission denied.'
|
|
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
|
|
|
|
# get repo history limit
|
|
try:
|
|
history_limit = seafile_api.get_repo_history_limit(repo_id)
|
|
except Exception as e:
|
|
logger.error(e)
|
|
error_msg = 'Internal Server Error'
|
|
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
|
|
|
|
start = (page - 1) * per_page
|
|
count = per_page
|
|
|
|
try:
|
|
file_revisions, total_count = get_file_history(repo_id, path, start, count, history_limit)
|
|
except Exception as e:
|
|
logger.error(e)
|
|
error_msg = 'Internal Server Error'
|
|
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
|
|
|
|
data = [get_new_file_history_info(ent, avatar_size) for ent in file_revisions]
|
|
result = {
|
|
"data": data,
|
|
"page": page,
|
|
"total_count": total_count
|
|
}
|
|
|
|
return Response(result)
|