Ver Fonte

210701 editor.js/backend 修改

yukyo há 3 anos atrás
pai
commit
157046f84c

+ 5 - 0
backstage/__init__.py

@@ -1,10 +1,12 @@
 from flask import Flask
+#from flask_cors import CORS, cross_origin
 import os
 
 
 def create_app():
     SECRET_KEY = os.urandom(32)
     app = Flask(__name__)
+    #CORS(app)
     app.config['SECRET_KEY'] = SECRET_KEY
 
     from backstage.collections.routes import collections_app
@@ -13,12 +15,15 @@ def create_app():
     from backstage.room_planner.routes import room_planner_app
     from backstage.blogs.routes import blogs_app
     from backstage.store_locations.routes import store_locations_app
+    from backstage.upload.routes import upload_app
 
+    #CORS(upload_app)
     app.register_blueprint(collections_app)
     app.register_blueprint(editor_app)
     app.register_blueprint(home_app)
     app.register_blueprint(blogs_app)
     app.register_blueprint(room_planner_app)
     app.register_blueprint(store_locations_app)
+    app.register_blueprint(upload_app)
 
     return app

+ 3 - 2
backstage/static/js/blockHandler.js

@@ -1,9 +1,10 @@
 function loadDataToBlock(blockArray, blockCount, blockData) {
+  alert(JSON.stringify(blockData));
   blockData = blockData || {}
   var dataIndex = 0;
   const blockIndex = blockCount;
   const {blockDiv, h, titleInput, inputButton, descButton, imgButton} = getBlockElements(contentDiv);
-  if (_.get(blockData, 'title')) {
+  //if (_.get(blockData, 'title')) {
     loadTitleData(blockArray, blockIndex, h, _.get(blockData, 'title'));
     for (var data of _.get(blockData, 'data', [])) {
       if ('description' in data) {
@@ -17,7 +18,7 @@ function loadDataToBlock(blockArray, blockCount, blockData) {
         handleImgButton(blockDiv, blockArray, blockIndex, ownDataIndex, data);
       }
     }
-  }
+  //}
   inputButton.onclick = function() {
     loadTitleData(blockArray, blockIndex, h, titleInput.value);
   }

+ 243 - 31
backstage/static/js/editor.js

@@ -2,55 +2,267 @@ const contentDiv = document.getElementById('editor_block');
 const titleButton = document.getElementById('title_button');
 const submitButton = document.getElementById('submit_button');
 const contentApiUrl = `${PORTAL_SERVER}contents?url=${(JSON.parse(document.getElementById('url').textContent)).url}`
+
+aa = "";
+frontMatters = [];
+editorBlocks = [];
+//postData = { content: "", url: "" };
+var editor;
 axios.get(contentApiUrl).then(({ data }) => {
+  //alert(JSON.stringify(data[0]['content']));
+  aa = data[0]['content'];
   const content = _.get(data, '0.content', '');
-  var blockArray = [{title: '', data: []}];
+  var blockArray = [{ title: '', data: [] }];
   var blockCount = 0;
-  const {frontMatters, preBlockArray}  = parseMd(content);
-  for (var blockData of preBlockArray) {
-    blockCount = loadDataToBlock(blockArray, blockCount, blockData);
-  }
-  titleButton.onclick = function() {
-    blockCount = loadDataToBlock(blockArray, blockCount);
+  blocks = parseMd(content);
+  editor_block = document.getElementById('editor_block');
+  //alert(blocks[0]['text']);
+
+  ul = document.createElement('ul');
+  ul.id = "sortable";
+  for (i = 0; i < blocks.length; i++) {
+    li = document.createElement('li');
+    odiv = document.createElement('div');
+    odiv.style.border = 'inset 1px gray';
+    if (blocks[i]['type'] == "para") {
+      editorBlocks.push({ type: "paragraph", data: { text: blocks[i]['text'] } });
+      tmp = document.createElement('textarea');
+      tmp.style.border = 'outset 5px pink';
+      tmp.style.width = '100%';
+      tmp.value = blocks[i]['text'];
+      odiv.appendChild(tmp);
+    }
+    else if (blocks[i]['type'] == "br") {
+      editorBlocks.push({ type: "paragraph", data: { text: "" } });
+      tmp = document.createElement('br');
+      odiv.appendChild(tmp);
+    }
+    else if (blocks[i]['type'] == "img") {
+      ampimg = blocks[i]['text'];
+      //alert(ampimg.indexOf("width=\"",84));
+      //alert(ampimg.substr(ampimg.indexOf("alt=\"") + 5, ampimg.indexOf("\"", ampimg.indexOf("alt=\"") + 5) - ampimg.indexOf("alt=\"") - 5));
+      tmpsrc = BHOUSE_SERVER + JSON.parse(document.getElementById('url').textContent).url + '/' + ampimg.substr(ampimg.indexOf("src=\"") + 5, ampimg.indexOf(".webp") - ampimg.indexOf("src=\""));
+      //tmpsrc = ampimg.substr(ampimg.indexOf("src=\"") + 5, ampimg.indexOf(".webp") - ampimg.indexOf("src=\""));
+      editorBlocks.push({
+        type: "image", data: {
+          file: {
+            url: tmpsrc,
+            width: parseInt(ampimg.substr(ampimg.indexOf("width=\"") + 7, ampimg.indexOf("\"", ampimg.indexOf("width=\"") + 7) - ampimg.indexOf("width=\"") - 7)),
+            height: parseInt(ampimg.substr(ampimg.indexOf("height=\"") + 8, ampimg.indexOf("\"", ampimg.indexOf("height=\"") + 8) - ampimg.indexOf("height=\"") - 8)),
+          },
+          caption: ampimg.substr(ampimg.indexOf("alt=\"") + 5, ampimg.indexOf("\"", ampimg.indexOf("alt=\"") + 5) - ampimg.indexOf("alt=\"") - 5).toString(),
+          stretched: false,
+          withBorder: true,
+          withBackground: false,
+        }
+      });
+      //alert(ampimg.substr(ampimg.indexOf("height=\"") + 8, ampimg.indexOf("\"", ampimg.indexOf("height=\"") + 8) - ampimg.indexOf("height=\"") - 8));
+      img = document.createElement('img');
+      img.style.width = '100%';
+      img.src = tmpsrc;
+      odiv.appendChild(img);
+    }
+    else if (blocks[i]['type'] == "title") {
+      blocks[i]['text'] = blocks[i]['text'].replace("### **", "").replace("**", "")
+      editorBlocks.push({ type: "header", data: { text: blocks[i]['text'] } });
+      tmp = document.createElement('h3');
+      tmp.innerHTML = blocks[i]['text'];
+      odiv.appendChild(tmp);
+    }
+    else if (blocks[i]['type'] == "mt5") {
+      //alert('yo');
+      editorBlocks.push({ type: "delimiter", data: {} });
+    }
+    li.appendChild(odiv);
+    ul.appendChild(li);
+
   }
+  editor_block.appendChild(ul);
+  $("#sortable").sortable();
+  $("#sortable").disableSelection();
+
+  $("#editor_block").css({ "display": "none" });
+
+  editor = new EditorJS({
+    readOnly: false,
+    holder: 'editorjs',
+
+    tools: {
+      header: {
+        class: Header,
+        config: {
+          placeholder: 'Header'
+        }
+      },
+
+      image: {
+        class: ImageTool,
+        config: {
+          endpoints: {
+            byFile: '/backstage/upload', // Your backend file uploader endpoint
+            byUrl: '/backstage/getimage', // Your endpoint that provides uploading by Url
+          }
+        }
+      }
+      ,
+      delimiter: Delimiter
+    }
+    ,
+    data: { blocks: editorBlocks }
+    ,
+    /*
+    data: {
+      blocks: [
+        {
+          type: "header",
+          data: {
+            text: "Editor.js",
+            level: 2
+          }
+        },
+        {
+          type: "header",
+          data: {
+            text: "Key features",
+            level: 3
+          }
+        },
+        {
+          type: "header",
+          data: {
+            text: "What does it mean «block-styled editor»",
+            level: 3
+          }
+        },
+        {
+          type: 'paragraph',
+          data: {
+            text: `There are dozens of <a href="https://github.com/editor-js">ready-to-use Blocks</a> and the <a href="https://editorjs.io/creating-a-block-tool">simple API</a> for creation any Block you need. For example, you can implement Blocks for Tweets, Instagram posts, surveys and polls, CTA-buttons and even games.`
+          }
+        },
+        {
+          type: 'delimiter',
+          data: {}
+        },
+        {
+          type: 'image',
+          data: {
+            url: 'http://localhost:1313/img/logo2.png',
+            caption: '',
+            stretched: false,
+            withBorder: true,
+            withBackground: false,
+          }
+        },
+      ]
+    },*/
+
+    onReady: function () {
+      //saveButton.click();
+    },
+    onChange: function (api, block) {
+      console.log('something changed', block);
+    }
+  });
+
+  /*   for (var blockData of preBlockArray) {
+      blockCount = loadDataToBlock(blockArray, blockCount, blockData);
+    }
+    titleButton.onclick = function () {
+      blockCount = loadDataToBlock(blockArray, blockCount);
+    } */
+});
+
+submitButton.onclick = function () {
+
+  editor.save().then((outputData) => {
+    console.log('Article data: ', outputData);
 
-  submitButton.onclick = function() {
     var mdContent = '';
     for (var frontMatter of frontMatters) {
       mdContent += frontMatter + '\n';
     }
-    for (var idx=0; idx<blockArray.length; idx++) {
-      if (_.get(blockArray[idx], 'title', '').includes('敘述')) {
-        mdContent += `\n<!-- ### **${_.get(blockArray[idx], 'title', '')}**-->\n`
-      } else {
-        mdContent += `\n### **${_.get(blockArray[idx], 'title', '')}**\n`
+
+    for (i = 0; i < outputData.blocks.length; i++) {
+      //alert(block.type);
+      block = outputData.blocks[i];
+      if (block.type == "header") {
+        mdContent += '\n### **' + block.data.text + '**\n';
+      }
+      else if (block.type == "paragraph") {
+        mdContent += '\n' + block.data.text + '\n';
+      }
+      else if (block.type == "image") {
+        mdContent += '\n<amp-img\n  alt="' + block.data.caption
+          + '"\n  src="' + block.data.file.url.replace(BHOUSE_SERVER + JSON.parse(document.getElementById('url').textContent).url + '/', '')
+          + '"\n  height="' + block.data.file.height
+          + '"\n  width="' + block.data.file.width
+          + '"\n  layout="responsive">\n</amp-img>\n';
       }
-      for (var data of _.get(blockArray[idx], 'data', [])) {
-        if (_.get(_.keys(data), 0) === 'description') {
-          if (_.get(data, 'description.text', '').includes('\n')) {
-            for (const line of _.get(data, 'description.text', '').split('\n')) {
-              mdContent += `\n${line}    `;
-            }
-          } else {
-            mdContent += `\n${_.get(data, 'description.text', '')}`;
+      else if (block.type == "delimiter") {
+        mdContent += '\n{{% chuz-div class="mt-5" %}}\n';
+      }
+    }
+    //alert(mdContent);
+
+    postData = {
+      content: mdContent,
+      url: (JSON.parse(document.getElementById('url').textContent)).url
+    };
+    axios.post(contentApiUrl, json = postData);
+
+  }).catch((error) => {
+    console.log('Saving failed: ', error)
+  });
+
+  var mdContent = '';
+  for (var frontMatter of frontMatters) {
+    mdContent += frontMatter + '\n';
+  }
+
+  //alert(bb);
+  /*     for(var eBlock in outputData.blocks)
+      {
+        alert(eBlock.type);
+      } */
+
+  for (var idx = 0; idx < blockArray.length; idx++) {
+    if (_.get(blockArray[idx], 'title', '').includes('敘述')) {
+      mdContent += `\n<!-- ### **${_.get(blockArray[idx], 'title', '')}**-->\n`
+    } else {
+      mdContent += `\n### **${_.get(blockArray[idx], 'title', '')}**\n`
+    }
+    for (var data of _.get(blockArray[idx], 'data', [])) {
+      if (_.get(_.keys(data), 0) === 'description') {
+        if (_.get(data, 'description.text', '').includes('\n')) {
+          for (const line of _.get(data, 'description.text', '').split('\n')) {
+            mdContent += `\n${line}    `;
           }
-        } else if (_.get(_.keys(data), 0) === 'image') {
-          ampImgForm = `\n<amp-img\
+        } else {
+          mdContent += `\n${_.get(data, 'description.text', '')}`;
+        }
+      } else if (_.get(_.keys(data), 0) === 'image') {
+        ampImgForm = `\n<amp-img\
 \n  alt="${_.get(data, 'image.alt', '小寶優居')}"\
 \n  src="${_.get(data, 'image.src', '')}"\
 \n  height="${_.get(data, 'image.height', 300)}"\
 \n  width="${_.get(data, 'image.width', 400)}"\
 \n  layout="${_.get(data, 'image.layout', 'responsive')}">\
 \n</amp-img>\n`;
-          mdContent += ampImgForm;
-        }
+        mdContent += ampImgForm;
       }
     }
+  }
 
-    const postData = {
-      content: mdContent,
-      url: (JSON.parse(document.getElementById('url').textContent)).url
-    }
-    axios.post(contentApiUrl, json=postData);
+  /* const postData = {
+    content: mdContent,
+    url: (JSON.parse(document.getElementById('url').textContent)).url
+  }; */
+
+  if (aa != postData['content']) {
+    //alert(postData['content']);
+    alert(mdContent);
   }
-});
+  //axios.post(contentApiUrl, json = postData);
+
+}

+ 15 - 13
backstage/static/js/parsers.js

@@ -3,7 +3,7 @@ function parseMd(content) {
   var blockCount;
   var preDataIndex;
   var parseBlockDiv;
-  var preImgObject = {'image': {}};
+  var preImgObject = { 'image': {} };
   var isNotFrontMatterCount = 0;
   var isAmpImgRange = false;
   var result = [];
@@ -19,7 +19,7 @@ function parseMd(content) {
 
     if (isAmpImgRange === true && !(line.includes('</amp-img>'))) {
       imgParamObject = parseAmpImg(line);
-      preImgObject.image = {...preImgObject.image, ...imgParamObject};
+      preImgObject.image = { ...preImgObject.image, ...imgParamObject };
       continue;
     }
 
@@ -29,34 +29,36 @@ function parseMd(content) {
       blockCount = blockCount + 1 | 0;
       const preBlockindex = blockCount;
       const title = parseTitle(line);
-      result[preBlockindex]  = {title: title};
+      result[preBlockindex] = { title: title };
 
     } else if (line.includes('amp-img')) {
       const preBlockindex = blockCount;
       if (line.includes('</amp-img>')) {
         addDataToBlockArray(preImgObject, result, preBlockindex, preDataIndex);
         isAmpImgRange = false;
-        preImgObject = {'image': {}}
+        preImgObject = { 'image': {} }
         preDataIndex += 1;
         continue;
       }
       isAmpImgRange = true;
     } else {
-      if (parseBlockDiv === undefined){
+      if (parseBlockDiv === undefined) {
         // for skipping space before first title
         continue
       }
-      if (line === ''){
+      if (line === '') {
         // for skipping space
         continue
       }
       const preBlockindex = blockCount;
       const ownDataIndex = preDataIndex;
       preDataIndex += 1;
-      addDataToBlockArray({description: {text: line}}, result, preBlockindex, ownDataIndex);
+      //addDataToBlockArray({ description: { text: line } }, result, preBlockindex, ownDataIndex);
+      addDataToBlockArray({ text: line }, result, preBlockindex, ownDataIndex);
     }
   }
-  return {frontMatters: frontMatters, preBlockArray: result}
+  alert(JSON.stringify(result));
+  return { frontMatters: frontMatters, preBlockArray: result }
 }
 
 const parseTitle = line => {
@@ -73,17 +75,17 @@ const parseTitle = line => {
 const parseAmpImg = line => {
   if (line.includes('alt')) {
     const altParameter = line.replace(/ |alt=|"/g, '');
-    return {alt: altParameter};
+    return { alt: altParameter };
   } else if (line.includes('src')) {
     const srcParameter = line.replace(/ |src=|"/g, '');
-    return {src: srcParameter};
+    return { src: srcParameter };
   } else if (line.includes('height')) {
     const heightParameter = line.replace(/ |height=|"/g, '');
-    return {height: heightParameter};
+    return { height: heightParameter };
   } else if (line.includes('width')) {
     const widthParameter = line.replace(/ |width=|"/g, '');
-    return {width: widthParameter};
+    return { width: widthParameter };
   } else if (line.includes('layout')) {
-    const layoutParameter = line.replace(/ |layout=|"|>/g, '');                             
+    const layoutParameter = line.replace(/ |layout=|"|>/g, '');
   }
 }

+ 86 - 0
backstage/static/js/yo.js

@@ -0,0 +1,86 @@
+function parseMd(content) {
+    //var frontMatters = [];
+    var blockCount;
+    var preDataIndex;
+    var parseBlockDiv;
+    var preImgObject = { 'image': {} };
+    var isNotFrontMatterCount = 0;
+    var isAmpImgRange = false;
+    var result = [];
+
+    var blocks = new Array();
+    lineIdx = 1;
+    foundImg = false;
+    crossLine = "";
+
+    for (const line of content.split('\n')) {
+        lineIdx++;
+        if (isNotFrontMatterCount < 2) {
+            frontMatters.push(line)
+            if (line.includes('---')) {
+                isNotFrontMatterCount += 1;
+            }
+            continue;
+        }
+
+/*         if (line.toString().trim() == "") {
+            blocks.push({ 'type': 'br', 'text': line });
+            continue;
+        } */
+
+        if (line.includes('###')) {
+            blocks.push({ 'type': 'title', 'text': line });
+            continue;
+        }
+
+        if (line.includes('{{% chuz-div class=\"mt-5\" %}}')) {
+            blocks.push({ 'type': 'mt5', 'text': line });
+            continue;
+        }
+
+        if (line.includes('<amp-img') || foundImg) {
+            crossLine += line;
+            foundImg = true;
+            if (line.includes('</amp-img>'))
+            {
+                blocks.push({ 'type': 'img', 'text': crossLine });
+                foundImg = false;
+                crossLine = "";
+            }
+            continue;
+        }
+
+        blocks.push({ 'type': 'para', 'text': line });
+    }
+    
+    return blocks
+}
+
+const parseTitle = line => {
+    var title = '';
+    title = line.replace('### **', '');
+    title = title.replace('**', '');
+    if (title.includes('敘述')) {
+        title = title.replace('<!-- ', '');
+        title = title.replace('-->', '');
+    }
+    return title;
+};
+
+const parseAmpImg = line => {
+    if (line.includes('alt')) {
+        const altParameter = line.replace(/ |alt=|"/g, '');
+        return { alt: altParameter };
+    } else if (line.includes('src')) {
+        const srcParameter = line.replace(/ |src=|"/g, '');
+        return { src: srcParameter };
+    } else if (line.includes('height')) {
+        const heightParameter = line.replace(/ |height=|"/g, '');
+        return { height: heightParameter };
+    } else if (line.includes('width')) {
+        const widthParameter = line.replace(/ |width=|"/g, '');
+        return { width: widthParameter };
+    } else if (line.includes('layout')) {
+        const layoutParameter = line.replace(/ |layout=|"|>/g, '');
+    }
+}

+ 39 - 19
backstage/templates/editor.html

@@ -1,27 +1,47 @@
 {% extends "layout.html" %}
 {% block main %}
-  <div class="ui segment">
-    <div class="ui two column very relaxed grid">
-      <div class="column column__edit">
-        <h3 class="h3 column__h3"><i class="fas fa-user-edit mr-2"></i>編輯</h3>
-        <div class="mb-2">
-          <button class="btn__arTitle mb-2" id="title_button">標題修改</button>
-        </div>
-        <div id= "editor_block"></div>
-        <button id='submit_button' class="btn__submit">修改完成</button>
-        <script type="text/json" id="url">{"url": "{{ url }}"}</script>
-        <script type="text/javascript" src="{{url_for('static', filename='config.js')}}"></script>
-        <script type="text/javascript" src="{{url_for('static', filename='js/utils.js')}}"></script>
-        <script type="text/javascript" src="{{url_for('static', filename='js/blockElements.js')}}"></script>
-        <script type="text/javascript" src="{{url_for('static', filename='js/blockHandler.js')}}"></script>
-        <script type="text/javascript" src="{{url_for('static', filename='js/parsers.js')}}"></script>
-        <script type="text/javascript" src="{{url_for('static', filename='js/editor.js')}}"></script>
+<div class="ui segment">
+  <div class="ui two column very relaxed grid">
+    <div class="column column__edit">
+      <h3 class="h3 column__h3"><i class="fas fa-user-edit mr-2"></i>編輯</h3>
+      <div class="mb-2">
+        <button class="btn__arTitle mb-2" id="title_button">標題修改</button>
       </div>
-      <div class="column column__preview">
-        <h3 class="h3 column__h3"><i class="fas fa-eye mr-2"></i>預覽頁面</h3>
-        <iframe src='{{ bhouse_server }}{{ url }}/' width="100%" height="100%"></iframe>
+      <button id='submit_button' class="btn__submit">修改完成</button>
+      <div id="editorjs"></div>
+      <div id="editor_block"><span><button class="btn__arTitle mb-2"
+            id="add_title_button">+標題</button></span><span><button class="btn__arTitle mb-2"
+            id="add_img_button">+圖</button></span><span><button class="btn__arTitle mb-2"
+            id="add_para_button">+段落</button></span></span><span><button class="btn__arTitle mb-2"
+            id="add_hr_button">+換行</button></span><span><button class="btn__arTitle mb-2"
+            id="add_mt5_button">+mt5</button></span>
       </div>
+      
     </div>
+    <div class="column column__preview">
+      <h3 class="h3 column__h3"><i class="fas fa-eye mr-2"></i>預覽頁面</h3>
+      <iframe src='{{ bhouse_server }}{{ url }}/' width="100%" height="100%"></iframe>
     </div>
   </div>
+</div>
+<script type="text/json" id="url">{"url": "{{ url }}"}</script>
+<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
+<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
+<script type="text/javascript" src="{{url_for('static', filename='config.js')}}"></script>
+<!-- <script type="text/javascript" src="{{url_for('static', filename='js/utils.js')}}"></script>
+<script type="text/javascript" src="{{url_for('static', filename='js/blockElements.js')}}"></script>
+<script type="text/javascript" src="{{url_for('static', filename='js/blockHandler.js')}}"></script> -->
+
+<!-- Load Editor.js's Core -->
+<script src="https://cdn.jsdelivr.net/npm/@editorjs/editorjs@latest"></script>
+
+<script src="https://cdn.jsdelivr.net/npm/@editorjs/header@latest"></script><!-- Header -->
+<script src="https://cdn.jsdelivr.net/npm/@editorjs/image@latest"></script><!-- Image -->
+<script src="https://cdn.jsdelivr.net/npm/@editorjs/delimiter@latest"></script><!-- Delimiter -->
+<script src="https://cdn.jsdelivr.net/npm/@editorjs/simple-image@latest"></script>
+
+<script type="text/javascript" src="{{url_for('static', filename='js/yo.js')}}"></script>
+<script type="text/javascript" src="{{url_for('static', filename='js/editor.js')}}"></script>
+<script>//alert('yo');</script>
+</div>
 {% endblock main %}

+ 1 - 1
backstage/templates/layout.html

@@ -12,7 +12,7 @@
   <link rel="stylesheet"
     href="https://use.fontawesome.com/releases/v5.1.0/css/all.css" integrity="sha384-lKuwvrZot6UHsBSfcMvOkWwlCMgc0TaWr+30HWe3a4ltaBwTZhyTEggF5tJv8tbt"
     crossorigin="anonymous">
-  <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='styles/reset.css') }}">
+<!--   <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='styles/reset.css') }}"> -->
   <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='styles/main.css') }}">
   
   <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js"></script>

+ 74 - 0
backstage/upload/routes.py

@@ -0,0 +1,74 @@
+import os
+from flask import render_template, Blueprint, request, redirect, url_for
+from flask_cors import CORS, cross_origin
+from flask.helpers import make_response, send_file, send_from_directory
+from werkzeug.wrappers import Response
+import requests
+from PIL import Image
+from urllib.parse import urlparse
+import uuid
+
+#from backstage.utils.routes import update_manage_table
+from backstage.config import PORTAL_SERVER, BHOUSE_SERVER
+
+upload_app = Blueprint('upload', __name__)
+
+
+@upload_app.route('/backstage/upload', methods=['POST','GET'])
+def upload_post():
+    #bdata = request.stream.read()
+    #aa = request.get_data()
+    if request.method == 'POST':
+        print(request.method)
+        # check if the post request has the file part
+        #print(request.files)
+        """ if 'file' not in request.files:
+            #flash('No file part')
+            return redirect(request.url) """
+        file = request.files['image']
+        # If the user does not select a file, the browser submits an
+        # empty file without a filename.
+        """ if file.filename == '':
+            #flash('No selected file')
+            return redirect(request.url) """
+        if file:
+            #filename = secure_filename(file.filename)
+            #print(os.getcwd().)
+            file.save(os.getcwd()+ "/backstage/upload/img/"+ file.filename)
+            #return redirect(url_for('download_file', name=file.filename))    
+            aa = {"success" : 1,"file": { "url" : "/backstage/upload/"+ file.filename, } }
+            return aa
+    if request.method == 'GET':
+        print(request.method)
+        #print(request.files)
+        #print(request.form)
+    
+    #print(requests.post("/backstage/upload"))
+    aa = {"success" : 1,"file": { "url" : "https://www.tesla.com/tesla_theme/assets/img/_vehicle_redesign/roadster_and_semi/roadster/hero.jpg", } }
+    return aa
+
+@upload_app.route('/backstage/upload/<filename>', methods=['GET'])
+def upload_get(filename):
+    #print(filename)
+    #aa = {"success" : 1,"file": { "url" : "https://www.tesla.com/tesla_theme/assets/img/_vehicle_redesign/roadster_and_semi/roadster/hero.jpg", } }
+    #return redirect(url_for('upload.upload_get',filename=filename), code=301)
+    return send_from_directory(os.getcwd()+ "/backstage/upload/img" , filename)
+
+@upload_app.route('/backstage/getimage', methods=['POST','GET'])
+def get_image():
+
+    print(request.get_json()['url'])
+    fname = str(uuid.uuid4()) + str(request.get_json()['url'])[str(request.get_json()['url']).rfind("."):]
+    f = open(os.getcwd()+ "/backstage/upload/img/" + fname,'wb')
+    f.write(requests.get(request.get_json()['url']).content)
+    f.close()
+    
+    #image_object = Image.open(os.getcwd()+ "/backstage/upload/tmp")
+    #send_file() 
+    #aa = {"success" : 1,"file": { "url" : "http://localhost:9000/backstage/upload/avatar1.jpg", } }
+    #resp = make_response(open(os.getcwd()+ "/backstage/upload/" + fname, 'br').read(), 301)
+    #resp.content_type = "image/jpeg"
+    #resp.content_encoding = "Unicode"
+    #return redirect(request.get_json()['url'], code=301)
+    aa = {"success" : 1,"file": { "url" : "/backstage/upload/"+ fname , } }
+    return aa