text: # -*- coding: utf-8 -*-
  #
  # This file is part of Flask-Wiki
  # Copyright (C) 2020 RERO
  #
  # Flask-Wiki is free software; you can redistribute it and/or modify
  # it under the terms of the Revised BSD License; see LICENSE file for
  # more details.
  
  """Views to respond to HTTP requests."""
  
  import glob
  import os
  from datetime import datetime
  from functools import wraps
  
  from babel import Locale
  from flask import (Blueprint, abort, current_app, flash, jsonify, redirect,
                     render_template, request, url_for)
  from flask.wrappers import Response
  from flask_babelex import gettext as _
  from werkzeug.utils import secure_filename
  
  from .api import Processor, current_wiki, get_wiki
  from .forms import EditorForm
  
  blueprint = Blueprint(
      'wiki',
      __name__,
      template_folder='templates',
      static_folder='static'
  )
  
  
  # PERMISSIONS
  # ===========
  def can_read_permission(func):
      """Check Reading Permission."""
      @wraps(func)
      def decorated_view(*args, **kwargs):
          permission = current_app.config.get('WIKI_READ_VIEW_PERMISSION')()
          if isinstance(permission, bool):
              if not permission:
                  abort(403)
              return func(*args, **kwargs)
          return permission
      return decorated_view
  
  
  def can_edit_permission(func):
      """Check Edition Permission."""
      @wraps(func)
      def decorated_view(*args, **kwargs):
          permission = current_app.config.get('WIKI_EDIT_VIEW_PERMISSION')()
          if isinstance(permission, bool):
              if not permission:
                  abort(403)
              return func(*args, **kwargs)
          return permission
      return decorated_view
  
  
  # FILTERS
  # =======
  @blueprint.app_template_filter()
  def prune_url(path):
      return path.replace(
          current_app.config.get('WIKI_URL_PREFIX'),
          '').strip('/')
  
  
  @blueprint.app_template_filter()
  def translate_ln(ln):
      return Locale(current_wiki.current_language).languages.get(ln)
  
  
  @blueprint.app_template_filter()
  def edit_path_list(path):
      ln = path.split('_')[-1]
      base_path = path
      if ln in current_wiki.languages:
          base_path = path.rsplit('_', 1)[0]
      return list(
          filter(
              lambda v: v['path'] != path,
              [dict(ln=ln, path='_'.join((base_path, ln)))
               for ln in current_wiki.languages]))
  
  @blueprint.app_template_filter()
  def date_format(value, format=None):
      return value.strftime("%d-%m-%Y")
  
  # PROCESSORS
  # ==========
  @blueprint.context_processor
  def permission_processor():
      return dict(
          can_edit_wiki=current_app.config.get('WIKI_EDIT_UI_PERMISSION')(),
          can_read_wiki= current_app.config.get('WIKI_READ_UI_PERMISSION')()
      )
  
  
  # MISCS
  # =====
  @blueprint.before_request
  def setWiki():
      get_wiki()
  
  
  def allowed_file(filename):
      ALLOWED_EXTENSIONS = current_app.config.get('WIKI_ALLOWED_EXTENSIONS')
      return '.' in filename and \
             filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
  
  
  # ROUTES
  # ======
  @blueprint.route('/')
  @can_read_permission
  def index():
      return redirect(url_for('wiki.page', url=current_app.config.get('WIKI_HOME')))
  
  
  @blueprint.route('/<path:url>/')
  @can_read_permission
  def page(url):
      page = current_wiki.get_or_404(url)
      return render_template(
          current_app.config.get('WIKI_PAGE_TEMPLATE'),
          page=page)
  
  
  @blueprint.route('/edit/<path:url>/', methods=['GET', 'POST'])
  @can_edit_permission
  def edit(url):
      page = current_wiki.get(url)
      form = EditorForm(obj=page)
      if form.validate_on_submit():
          if not page:
              page = current_wiki.get_bare(url)
          form.populate_obj(page)
          page.save()
          flash(_('Saved'), category='success')
          return redirect(url_for('wiki.page', url=url))
      return render_template(
          current_app.config.get('WIKI_EDITOR_TEMPLATE'),
          form=form, page=page, path=url)
  
  
  @blueprint.route('/preview/', methods=['POST'])
  @can_edit_permission
  def preview():
      data = {}
      processor = Processor(request.form['body'])
      data['html'], data['body'], data['meta'], data['toc'] = processor.process()
      return data['html']
  
  @blueprint.route('/page/delete/<path:url>')
  @can_edit_permission
  def delete_page(url):
      if current_wiki.delete(url):
          flash(_('Page deleted'), category='success')
      else:
          flash(_('Could not delete page as it does not exist.'), category='error')
      return redirect(url_for('wiki.index'))
  
  @blueprint.route('/file/delete/<path:filename>')
  @can_edit_permission
  def delete_file(filename):
      path = os.path.join(current_app.config.get('WIKI_UPLOAD_FOLDER'), filename)
      try:
          os.remove(path)
          flash(_('File deleted'), category='success')
      except Exception as e:
          flash(_('Something went wrong. Could not delete file.'), category='error')
      return redirect(url_for('wiki.files'))
  
  @blueprint.route('/files', methods=['GET', 'POST'])
  @can_edit_permission
  def files():
      if request.method == 'POST' and current_app.config['WIKI_EDIT_UI_PERMISSION']():
          # check if the post request has the file part
          if 'file' not in request.files:
              flash(_('No file part'))
              return redirect(request.url)
          file = request.files['file']
          # if user does not select file, browser also
          # submit an empty part without filename
          if file.filename == '':
              flash(_('No selected file'))
              return redirect(request.url)
          if file and allowed_file(file.filename):
              filename = secure_filename(file.filename)
              output_filename = os.path.join(
                  current_app.config['WIKI_UPLOAD_FOLDER'], filename)
              if os.path.isfile(output_filename):
                  flash(_('File already exists'), category='danger')
              else:
                  file.save(output_filename)
      if request.method == 'POST' and not current_app.config['WIKI_EDIT_UI_PERMISSION']():
          flash(_('You do not have the permission to add files.'))
      files = [os.path.basename(f) for f in sorted(glob.glob(
          '/'.join([current_app.config.get('WIKI_UPLOAD_FOLDER'), '*'])), key=os.path.getmtime)]
      return render_template(
          current_app.config.get('WIKI_FILES_TEMPLATE'),
          files=files)
  
  
  @blueprint.route('/search', methods=['GET'])
  @can_edit_permission
  def search():
      query = request.args.get('q', '')
      results = current_wiki.search(query)
      return render_template(
          current_app.config.get('WIKI_SEARCH_TEMPLATE'),
          results=results, query=query)
  
  
  @blueprint.errorhandler(404)
  def not_found(error):
      return render_template(
          current_app.config.get('WIKI_NOT_FOUND_TEMPLATE')), 404
  
  
  @blueprint.errorhandler(403)
  def forbidden(error):
      return render_template(
          current_app.config.get('WIKI_FORBIDDEN_TEMPLATE')), 403
  