# Path: clam/common/util.py
# def globsymlinks(pattern, recursion=True):
#     for f in glob.glob(pattern):
#         if os.path.islink(f):
#             yield f, os.readlink(f)
#     if recursion:
#         for d in os.listdir(os.path.dirname(pattern)):
#             if os.path.isdir(d):
#                 for linkf,realf in globsymlinks(d + '/' + os.path.basename(pattern),recursion):
#                     yield linkf,realf
# 
# def setdebug(debug):
#     global DEBUG
#     DEBUG = debug
# 
# def setlog(log):
#     global LOG
#     LOG = log
# 
# def setlogfile(filename):
#     global LOG, DEBUGLOG
#     LOG = DEBUGLOG = io.open(filename,'w', encoding='utf-8')
# 
# def printlog(msg):
#     if LOG:
#         now = datetime.datetime.now()
#         LOG.write("[" + now.strftime("%d/%b/%Y %H:%M:%S") + "] " + msg + "\n")
# 
# def printdebug(msg):
#     if DEBUG:
#         now = datetime.datetime.now()
#         DEBUGLOG.write("[" + now.strftime("%d/%b/%Y %H:%M:%S") + " DEBUG] " + msg + "\n")
# 
# def xmlescape(s):
#     begin = -1
#     s2 = ""
#     for i,c in enumerate(s):
#         if c == '&':
#             begin = i
#         elif c == ';':
#             if begin > -1:
#                 s2 += s[begin:i+1]
#                 begin = -1
#             else:
#                 s2 += c
#         elif c == ' ':
#             if begin != -1:
#                 s2 += "&amp;" + s[begin+1:i+1]
#                 begin = -1
#             else:
#                 s2 += c
#         elif c == '<':
#             s2 += "&lt;"
#         elif c == '>':
#             s2 += "&gt;"
#         elif c == '"':
#             s2 += "&quot;"
#         elif begin == -1:
#             s2 += c
#     if begin != -1:
#         s2 += "&amp;" + s[begin+1:]
#     s = s2
#     return s
# 
# def withheaders(response, contenttype="text/xml; charset=UTF-8", headers=None):
#     if headers is None: headers = { }
#     response.headers['Referrer-Policy'] = 'strict-origin-when-cross-origin'
#     response.headers['Content-Type'] = contenttype
#     try:
#         for key, value in headers.items():
#             if key == 'allow_origin':
#                 response.headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, DELETE'
#                 response.headers['Access-Control-Allow-Headers'] = 'Authorization'
#                 key = 'Access-Control-Allow-Origin'
#             response.headers[key] = value
#     except AttributeError: #no dictionary? could be generator/list of tuples
#         for key, value in headers:
#             if key == 'allow_origin':
#                 response.headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, DELETE'
#                 response.headers['Access-Control-Allow-Headers'] = 'Authorization'
#                 key = 'Access-Control-Allow-Origin'
#             response.headers[key] = value
#     return response
# 
# def computediskusage(path):
#     total_size = 0
#     total_files = 0
#     for dirpath, dirnames, filenames in os.walk(path): #pylint: disable=unused-variable
#         for f in filenames:
#             fp = os.path.join(dirpath, f)
#             try:
#                 total_size += os.path.getsize(fp)
#                 total_files += 1
#             except:
#                 #may happen in case of dangling symlinks
#                 pass
#     return total_size / 1024 / 1024, total_files #MB


import shutil
import os
import io
import stat
import subprocess
import importlib
import glob
import sys
import datetime
import random
import re
import hashlib
import argparse
import time
import socket
import json
import mimetypes
import flask
import werkzeug
import requests
import base64
import copy
import clam.common.status
import clam.common.parameters
import clam.common.formats
import clam.common.auth
import clam.common.oauth
import clam.common.data
import clam.common.viewers
import clam.config.defaults as settings #will be overridden by real settings later
    import MySQLdb
    import foliatools
    import uwsgi
from clam.common.util import globsymlinks, setdebug, setlog, setlogfile, printlog, printdebug, xmlescape, withheaders, computediskusage
from urllib.parse import urlencode, unquote
    from requests_oauthlib import OAuth2Session
        from werkzeug.debug import DebuggedApplication

    @staticmethod
    def downloader(targetuser, project, type, filename, credentials=None):
        user, oauth_access_token = parsecredentials(credentials) #pylint: disable=unused-variable
        if not settings.ADMINS or not user in settings.ADMINS:
            return flask.make_response('You shall not pass!!! You are not an administrator!',403)

        if type == 'input':
            try:
                outputfile = clam.common.data.CLAMInputFile(Project.path(project, targetuser), filename)
            except:
                raise flask.abort(404)
        elif type == 'output':
            try:
                outputfile = clam.common.data.CLAMOutputFile(Project.path(project, targetuser), filename) #pylint: disable=redefined-variable-type
            except:
                raise flask.abort(404)
        else:
            return withheaders(flask.make_response('Invalid type',403),"text/plain",headers={'allow_origin': settings.ALLOW_ORIGIN})

        if outputfile.metadata:
            headers = dict(list(outputfile.metadata.httpheaders()))
            mimetype = outputfile.metadata.mimetype
        else:
            headers = {}
            mimetype = 'application/octet-stream'
        headers['allow_origin'] = settings.ALLOW_ORIGIN
        try:
            return withheaders(flask.Response( (line for line in outputfile) ), mimetype, headers )
        except UnicodeError:

# Path: clam/common/util.py
# def globsymlinks(pattern, recursion=True):
#     for f in glob.glob(pattern):
#         if os.path.islink(f):
#             yield f, os.readlink(f)
#     if recursion:
#         for d in os.listdir(os.path.dirname(pattern)):
#             if os.path.isdir(d):
#                 for linkf,realf in globsymlinks(d + '/' + os.path.basename(pattern),recursion):
#                     yield linkf,realf
# 
# def setdebug(debug):
#     global DEBUG
#     DEBUG = debug
# 
# def setlog(log):
#     global LOG
#     LOG = log
# 
# def setlogfile(filename):
#     global LOG, DEBUGLOG
#     LOG = DEBUGLOG = io.open(filename,'w', encoding='utf-8')
# 
# def printlog(msg):
#     if LOG:
#         now = datetime.datetime.now()
#         LOG.write("[" + now.strftime("%d/%b/%Y %H:%M:%S") + "] " + msg + "\n")
# 
# def printdebug(msg):
#     if DEBUG:
#         now = datetime.datetime.now()
#         DEBUGLOG.write("[" + now.strftime("%d/%b/%Y %H:%M:%S") + " DEBUG] " + msg + "\n")
# 
# def xmlescape(s):
#     begin = -1
#     s2 = ""
#     for i,c in enumerate(s):
#         if c == '&':
#             begin = i
#         elif c == ';':
#             if begin > -1:
#                 s2 += s[begin:i+1]
#                 begin = -1
#             else:
#                 s2 += c
#         elif c == ' ':
#             if begin != -1:
#                 s2 += "&amp;" + s[begin+1:i+1]
#                 begin = -1
#             else:
#                 s2 += c
#         elif c == '<':
#             s2 += "&lt;"
#         elif c == '>':
#             s2 += "&gt;"
#         elif c == '"':
#             s2 += "&quot;"
#         elif begin == -1:
#             s2 += c
#     if begin != -1:
#         s2 += "&amp;" + s[begin+1:]
#     s = s2
#     return s
# 
# def withheaders(response, contenttype="text/xml; charset=UTF-8", headers=None):
#     if headers is None: headers = { }
#     response.headers['Referrer-Policy'] = 'strict-origin-when-cross-origin'
#     response.headers['Content-Type'] = contenttype
#     try:
#         for key, value in headers.items():
#             if key == 'allow_origin':
#                 response.headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, DELETE'
#                 response.headers['Access-Control-Allow-Headers'] = 'Authorization'
#                 key = 'Access-Control-Allow-Origin'
#             response.headers[key] = value
#     except AttributeError: #no dictionary? could be generator/list of tuples
#         for key, value in headers:
#             if key == 'allow_origin':
#                 response.headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, DELETE'
#                 response.headers['Access-Control-Allow-Headers'] = 'Authorization'
#                 key = 'Access-Control-Allow-Origin'
#             response.headers[key] = value
#     return response
# 
# def computediskusage(path):
#     total_size = 0
#     total_files = 0
#     for dirpath, dirnames, filenames in os.walk(path): #pylint: disable=unused-variable
#         for f in filenames:
#             fp = os.path.join(dirpath, f)
#             try:
#                 total_size += os.path.getsize(fp)
#                 total_files += 1
#             except:
#                 #may happen in case of dangling symlinks
#                 pass
#     return total_size / 1024 / 1024, total_files #MB


# Path: clam/clamservice.py
import shutil
import os
import io
import stat
import subprocess
import importlib
import glob
import sys
import datetime
import random
import re
import hashlib
import argparse
import time
import socket
import json
import mimetypes
import flask
import werkzeug
import requests
import base64
import copy
import clam.common.status
import clam.common.parameters
import clam.common.formats
import clam.common.auth
import clam.common.oauth
import clam.common.data
import clam.common.viewers
import clam.config.defaults as settings #will be overridden by real settings later
    import MySQLdb
    import foliatools
    import uwsgi
from clam.common.util import globsymlinks, setdebug, setlog, setlogfile, printlog, printdebug, xmlescape, withheaders, computediskusage
from urllib.parse import urlencode, unquote
    from requests_oauthlib import OAuth2Session
        from werkzeug.debug import DebuggedApplication


    @staticmethod
    def downloader(targetuser, project, type, filename, credentials=None):
        user, oauth_access_token = parsecredentials(credentials) #pylint: disable=unused-variable
        if not settings.ADMINS or not user in settings.ADMINS:
            return flask.make_response('You shall not pass!!! You are not an administrator!',403)

        if type == 'input':
            try:
                outputfile = clam.common.data.CLAMInputFile(Project.path(project, targetuser), filename)
            except:
                raise flask.abort(404)
        elif type == 'output':
            try:
                outputfile = clam.common.data.CLAMOutputFile(Project.path(project, targetuser), filename) #pylint: disable=redefined-variable-type
            except:
                raise flask.abort(404)
        else:
            return withheaders(flask.make_response('Invalid type',403),"text/plain",headers={'allow_origin': settings.ALLOW_ORIGIN})

        if outputfile.metadata:
            headers = dict(list(outputfile.metadata.httpheaders()))
            mimetype = outputfile.metadata.mimetype
        else:
            headers = {}
            mimetype = 'application/octet-stream'
        headers['allow_origin'] = settings.ALLOW_ORIGIN
        try:
            return withheaders(flask.Response( (line for line in outputfile) ), mimetype, headers )
        except UnicodeError:

            return withheaders(flask.make_response("Output file " + str(outputfile) + " is not in the expected encoding! Make sure encodings for output templates service configuration file are accurate.",500),"text/plain",headers={'allow_origin': settings.ALLOW_ORIGIN})