content: # -*- coding: utf-8 -*-
  
  """
      cli
      ~~~
  
      Implements CLI mode
  
      :author:    Feei <feei@feei.cn>
      :homepage:  https://github.com/WhaleShark-Team/cobra
      :license:   MIT, see LICENSE for more details.
      :copyright: Copyright (c) 2018 Feei. All rights reserved
  """
  import re
  import os
  
  from .detection import Detection
  from .engine import scan, Running
  from .exceptions import PickupException
  from .export import write_to_file
  from .log import logger
  from .pickup import Directory
  from .send_mail import send_mail
  from .utils import ParseArgs
  from .utils import md5, random_generator, clean_dir
  from .push_to_api import PushToThird
  
  
  def get_sid(target, is_a_sid=False):
      target = target
      if isinstance(target, list):
          target = ';'.join(target)
      sid = md5(target)[:5]
      if is_a_sid:
          pre = 'a'
      else:
          pre = 's'
      sid = '{p}{sid}{r}'.format(p=pre, sid=sid, r=random_generator())
      return sid.lower()
  
  
  def start(target, formatter, output, special_rules, a_sid=None, is_del=False):
      """
      Start CLI
      :param target: File, FOLDER, GIT
      :param formatter:
      :param output:
      :param special_rules:
      :param a_sid: all scan id
      :param is_del: del target directory
      :return:
      """
      # generate single scan id
      s_sid = get_sid(target)
      r = Running(a_sid)
      data = (s_sid, target)
      r.init_list(data=target)
      r.list(data)
  
      report = '?sid={a_sid}'.format(a_sid=a_sid)
      d = r.status()
      d['report'] = report
      r.status(d)
      logger.info('[REPORT] Report URL: {u}'.format(u=report))
  
      # parse target mode and output mode
      pa = ParseArgs(target, formatter, output, special_rules, a_sid=None)
      target_mode = pa.target_mode
      output_mode = pa.output_mode
  
      # target directory
      try:
          target_directory = pa.target_directory(target_mode)
          target_directory = target_directory.rstrip("/")
          logger.info('[CLI] Target directory: {d}'.format(d=target_directory))
  
          # static analyse files info
          files, file_count, time_consume = Directory(target_directory).collect_files()
  
          # detection main language and framework
          dt = Detection(target_directory, files)
          main_language = dt.language
          main_framework = dt.framework
  
          logger.info('[CLI] [STATISTIC] Language: {l} Framework: {f}'.format(l=main_language, f=main_framework))
          logger.info('[CLI] [STATISTIC] Files: {fc}, Extensions:{ec}, Consume: {tc}'.format(fc=file_count,
                                                                                             ec=len(files),
                                                                                             tc=time_consume))
  
          if pa.special_rules is not None:
              logger.info('[CLI] [SPECIAL-RULE] only scan used by {r}'.format(r=','.join(pa.special_rules)))
          # scan
          scan(target_directory=target_directory, a_sid=a_sid, s_sid=s_sid, special_rules=pa.special_rules,
               language=main_language, framework=main_framework, file_count=file_count, extension_count=len(files))
  
          if target_mode == 'git' and '/tmp/cobra/git/' in target_directory and is_del is True:
              res = clean_dir(target_directory)
              if res is True:
                  logger.info('[CLI] Target directory remove success')
              else:
                  logger.info('[CLI] Target directory remove fail')
  
      except PickupException:
          result = {
              'code': 1002,
              'msg': 'Repository not exist!'
          }
          Running(s_sid).data(result)
          logger.critical('Repository or branch not exist!')
          exit()
      except Exception:
          result = {
              'code': 1002,
              'msg': 'Exception'
          }
          Running(s_sid).data(result)
          raise
  
      # 匹配邮箱地址
      if re.match(r'^[A-Za-z\d]+([-_.][A-Za-z\d]+)*@([A-Za-z\d]+[-.])+[A-Za-z\d]{2,4}$', output):
          # 生成邮件附件
          attachment_name = s_sid + '.' + formatter
          write_to_file(target=target, sid=s_sid, output_format=formatter, filename=attachment_name)
          # 发送邮件
          send_mail(target=target, filename=attachment_name, receiver=output)
      elif output.startswith('http'):
          # HTTP API URL
          pusher = PushToThird(url=output)
          pusher.add_data(target=target, sid=s_sid)
          pusher.push()
      else:
          write_to_file(target=target, sid=s_sid, output_format=formatter, filename=output)
  