text: # -*- coding: utf-8 -*-
  import os
  import logging
  
  from rest_framework.authentication import SessionAuthentication
  from rest_framework.permissions import IsAdminUser
  from rest_framework.response import Response
  from rest_framework.views import APIView
  from rest_framework import status
  from django.utils.translation import ugettext as _
  
  from seaserv import seafile_api
  
  from seahub.api2.authentication import TokenAuthentication
  from seahub.api2.throttling import UserRateThrottle
  from seahub.api2.permissions import IsProVersion
  from seahub.api2.utils import api_error, to_python_boolean
  from seahub.utils import get_virus_files, get_virus_file_by_vid, delete_virus_file, operate_virus_file
  
  logger = logging.getLogger(__name__)
  
  
  class AdminVirusFilesView(APIView):
  
      authentication_classes = (TokenAuthentication, SessionAuthentication)
      permission_classes = (IsAdminUser, IsProVersion)
      throttle_classes = (UserRateThrottle,)
  
      def get(self, request):
          """get virus files
          """
  
          if not request.user.admin_permissions.other_permission():
              return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.')
  
          try:
              page = int(request.GET.get('page', ''))
          except ValueError:
              page = 1
  
          try:
              per_page = int(request.GET.get('per_page', ''))
          except ValueError:
              per_page = 25
  
          try:
              has_handled = to_python_boolean(request.GET.get('has_handled', ''))
          except ValueError:
              has_handled = None
  
          start = (page - 1) * per_page
          count = per_page + 1
  
          try:
              virus_files = get_virus_files(has_handled=has_handled, start=start, limit=count)
          except Exception as e:
              logger.error(e)
              error_msg = 'Internal Server Error'
              return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
  
          if len(virus_files) > per_page:
              virus_files = virus_files[:per_page]
              has_next_page = True
          else:
              has_next_page = False
  
          virus_file_list = list()
          for virus_file in virus_files:
              try:
                  repo = seafile_api.get_repo(virus_file.repo_id)
                  repo_owner = seafile_api.get_repo_owner(virus_file.repo_id)
              except Exception as e:
                  logger.error(e)
                  continue
  
              if not repo:
                  continue
              else:
                  record = dict()
                  record["repo_name"] = repo.name
                  record["repo_owner"] = repo_owner
                  record["file_path"] = virus_file.file_path
                  record["has_deleted"] = virus_file.has_deleted
                  record["has_ignored"] = virus_file.has_ignored
                  record["virus_id"] = virus_file.vid
                  virus_file_list.append(record)
  
          return Response({"virus_file_list": virus_file_list, "has_next_page": has_next_page}, status=status.HTTP_200_OK)
  
  
  class AdminVirusFileView(APIView):
  
      authentication_classes = (TokenAuthentication, SessionAuthentication)
      permission_classes = (IsAdminUser, IsProVersion)
      throttle_classes = (UserRateThrottle,)
  
      def delete(self, request, virus_id):
          """delete virus file
          """
  
          if not request.user.admin_permissions.other_permission():
              return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.')
  
          virus_file = get_virus_file_by_vid(virus_id)
          if not virus_file:
              error_msg = 'Virus file %s not found.' % virus_id
              return api_error(status.HTTP_404_NOT_FOUND, error_msg)
  
          parent_dir = os.path.dirname(virus_file.file_path)
          filename = os.path.basename(virus_file.file_path)
          try:
              seafile_api.del_file(
                  virus_file.repo_id, parent_dir, filename, request.user.username
              )
              delete_virus_file(virus_id)
          except Exception as e:
              logger.error(e)
              error_msg = 'Internal Server Error'
              return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
  
          return Response({"success": True}, status=status.HTTP_200_OK)
  
      def put(self, request, virus_id):
          """ignore or un-ignore virus file
          """
  
          if not request.user.admin_permissions.other_permission():
              return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.')
  
          ignore = request.data.get('ignore')
          if ignore not in ('true', 'false'):
              error_msg = 'ignore invalid.'
              return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
          ignore = to_python_boolean(ignore)
  
          virus_file = get_virus_file_by_vid(virus_id)
          if not virus_file:
              error_msg = 'Virus file %s not found.' % virus_id
              return api_error(status.HTTP_404_NOT_FOUND, error_msg)
  
          try:
              operate_virus_file(virus_id, ignore)
          except Exception as e:
              logger.error(e)
              error_msg = 'Internal Server Error'
              return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
  
          virus_file = get_virus_file_by_vid(virus_id)
  
          repo = seafile_api.get_repo(virus_file.repo_id)
          repo_owner = seafile_api.get_repo_owner(virus_file.repo_id)
          res = dict(repo_name=repo.name)
          res["repo_owner"] = repo_owner
          res["file_path"] = virus_file.file_path
          res["has_deleted"] = virus_file.has_deleted
          res["has_ignored"] = virus_file.has_ignored
          res["virus_id"] = virus_file.vid
  
          return Response({"virus_file": res}, status=status.HTTP_200_OK)
  
  
  class AdminVirusFilesBatchView(APIView):
  
      authentication_classes = (TokenAuthentication, SessionAuthentication)
      permission_classes = (IsAdminUser, IsProVersion)
      throttle_classes = (UserRateThrottle,)
  
      def post(self, request):
          """ Delete virus files, ignore or cancel ignore virus files, in batch.
  
          Permission checking:
          1. admin user.
          """
  
          if not request.user.admin_permissions.other_permission():
              return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.')
  
          # argument check
          virus_ids = request.POST.getlist('virus_ids', None)
          if not virus_ids:
              error_msg = 'virus_ids invalid.'
              return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
  
          operation = request.POST.get('operation', None)
          if operation not in ('delete-virus', 'ignore-virus', 'cancel-ignore-virus'):
              error_msg = "operation can only be 'delete-virus', 'ignore-virus' or 'cancel-ignore-virus'."
              return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
  
          result = dict(failed=[])
          result['success'] = []
  
          virus_files = []
          for virus_id in virus_ids:
              virus_file = get_virus_file_by_vid(int(virus_id))
              if virus_file:
                  virus_files.append(virus_file)
              else:
                  result['failed'].append({
                      'virus_id': virus_id,
                      'error_msg': _('Virus file not found.')
                  })
                  continue
  
          if operation == 'delete-virus':
              for virus_file in virus_files:
                  parent_dir = os.path.dirname(virus_file.file_path)
                  filename = os.path.basename(virus_file.file_path)
                  virus_id = int(virus_file.vid)
                  try:
                      seafile_api.del_file(
                          virus_file.repo_id, parent_dir, filename, request.user.username
                      )
                      delete_virus_file(virus_id)
                  except Exception as e:
                      logger.error(e)
                      result['failed'].append({
                          'virus_id': virus_id,
                          'error_msg': _('Internal Server Error')
                      })
                      continue
  
                  result['success'].append({'virus_id': virus_id})
  
          if operation == 'ignore-virus':
              for virus_file in virus_files:
                  virus_id = int(virus_file.vid)
                  try:
                      operate_virus_file(virus_id, True)
                  except Exception as e:
                      logger.error(e)
                      result['failed'].append({
                          'virus_id': virus_id,
                          'error_msg': _('Internal Server Error')
                      })
                      continue
  
                  result['success'].append({'virus_id': virus_id})
  
          if operation == 'cancel-ignore-virus':
              for virus_file in virus_files:
                  virus_id = int(virus_file.vid)
                  try:
                      operate_virus_file(virus_id, False)
                  except Exception as e:
                      logger.error(e)
                      result['failed'].append({
                          'virus_id': virus_id,
                          'error_msg': _('Internal Server Error')
                      })
                      continue
  
                  result['success'].append({'virus_id': virus_id})
  
          return Response(result)
  