|
@@ -1,153 +1,181 @@
|
|
|
-from flask import Flask, request, redirect, url_for
|
|
|
-from flask_restful import Resource, Api
|
|
|
-from flask_cors import CORS
|
|
|
-from os import path, remove, listdir, walk
|
|
|
-import logging
|
|
|
-import re
|
|
|
-from config import CONTENT_DIR
|
|
|
-
|
|
|
-app = Flask(__name__)
|
|
|
-api = Api(app)
|
|
|
-CORS(app, resources={r"/api/*": {"origins": "*"}})
|
|
|
-CURRENT_PATH = '/Users/weichen/choozmo/bhouse/bhouse'
|
|
|
-logger = logging.getLogger(__name__)
|
|
|
-DATA_FIELD = ['title:', 'url:']
|
|
|
-
|
|
|
-
|
|
|
-def _get_data(file_dir):
|
|
|
- def load_data():
|
|
|
- if 'title:' in line:
|
|
|
- data_field.remove('title:')
|
|
|
- s = line.split('"')
|
|
|
- result['title'] = s[1]
|
|
|
- elif 'url:' in line:
|
|
|
- data_field.remove('url:')
|
|
|
- s = line.split('"')
|
|
|
- result['url'] = s[1]
|
|
|
-
|
|
|
- data_field = list(DATA_FIELD)
|
|
|
- result = {}
|
|
|
- with open(file_dir, 'r', encoding="utf-8") as md:
|
|
|
- result['content'] = md.read()
|
|
|
- md.seek(0)
|
|
|
- md_line_data = md.readlines()
|
|
|
- for line in md_line_data:
|
|
|
- load_data()
|
|
|
- if not data_field:
|
|
|
- return result
|
|
|
- return result
|
|
|
-
|
|
|
-
|
|
|
-def _gen_content_files():
|
|
|
- for root, dirs, files in walk(CONTENT_DIR):
|
|
|
- for f in files:
|
|
|
- if '.md' not in f:
|
|
|
- continue
|
|
|
- yield path.join(root, f)
|
|
|
-
|
|
|
-
|
|
|
-def _search_dir(url):
|
|
|
- def _get_file_front_matter_url():
|
|
|
- with open(file_dir, 'r', encoding="utf-8") as md:
|
|
|
- md_line_data = md.readlines()
|
|
|
- for line in md_line_data:
|
|
|
- if 'url:' in line:
|
|
|
- return list(filter(None, re.split('"|\n', line)))[-1]
|
|
|
-
|
|
|
- for file_dir in _gen_content_files():
|
|
|
- if url == _get_file_front_matter_url():
|
|
|
- return path.dirname(file_dir)
|
|
|
-
|
|
|
-
|
|
|
-class Content(Resource):
|
|
|
- DATA_FIELD = ['title:', 'url:']
|
|
|
-
|
|
|
- @property
|
|
|
- def url(self):
|
|
|
- return request.args.get('url', type=str)
|
|
|
-
|
|
|
- def _search_content(self):
|
|
|
- result = {}
|
|
|
- for file_dir in _gen_content_files():
|
|
|
- data = _get_data(file_dir)
|
|
|
- if self.url in data.get('url', ''):
|
|
|
- result = data
|
|
|
- result['path'] = file_dir
|
|
|
- yield result
|
|
|
-
|
|
|
- def _get_contents(self):
|
|
|
- for file_dir in _gen_content_files():
|
|
|
- yield _get_data(file_dir)
|
|
|
-
|
|
|
- def get(self):
|
|
|
- if self.url:
|
|
|
- return list(self._search_content())
|
|
|
- else:
|
|
|
- return list(self._get_contents())
|
|
|
-
|
|
|
- def post(self):
|
|
|
- try:
|
|
|
- file_dir = path.join(
|
|
|
- _search_dir(request.args.get('url', type=str)), 'index.md')
|
|
|
- md_content = request.json.get('content')
|
|
|
- with open(file_dir, 'w', encoding="utf-8") as md:
|
|
|
- md.write(md_content)
|
|
|
- return md_content
|
|
|
- except TypeError as err:
|
|
|
- logger.error('Content post failed with file_dir param contain None. error: {}'.format(err))
|
|
|
- except OSError as err:
|
|
|
- logger.error('Content post failed with: {} is not exist{}'.format(file_dir, err))
|
|
|
- except AttributeError as err:
|
|
|
- logger.error('Content post failed with AttributeError: {}'.format(err))
|
|
|
- except Exception as err:
|
|
|
- logger.error('Content post failed with: {}'.format(err))
|
|
|
-
|
|
|
- def delete(self):
|
|
|
- content_data = list(self._search_content())
|
|
|
- file_dir = content_data[0].get('path')
|
|
|
- if path.exists(file_dir):
|
|
|
- remove(file_dir)
|
|
|
- logger.info('delete file: {}'.format(file_dir))
|
|
|
- else:
|
|
|
- logger.warning('delete fail with {} not exist'.format(file_dir))
|
|
|
-
|
|
|
-
|
|
|
-@app.route('/api/upload/img', methods=['POST'])
|
|
|
-def upload_img():
|
|
|
- img_data = request.files['image']
|
|
|
- file_dir = _search_dir(request.args.get('url', type=str))
|
|
|
- img_dir = path.join(file_dir, 'img/{}'.format(img_data.filename))
|
|
|
- img_data.save(img_dir)
|
|
|
- return {'filename': img_data.filename}
|
|
|
-
|
|
|
-
|
|
|
-@app.route('/api/delete/img', methods=['DELETE'])
|
|
|
-def delete_img():
|
|
|
- try:
|
|
|
- file_dir = _search_dir(request.args.get('url', type=str))
|
|
|
- img_dir = path.join(file_dir, 'img/{}'.format(request.args.get('filename', type=str)))
|
|
|
- remove(img_dir)
|
|
|
- logger.info('delete img: {}'.format(img_dir))
|
|
|
- return {'filename': request.args.get('filename', type=str)}
|
|
|
- except TypeError as err:
|
|
|
- logger.error('delete img: {} failed with file_dir is None. error: {}'.format(
|
|
|
- request.args.get('filename', type=str), err))
|
|
|
- return {'filename': request.args.get('filename', type=str)}
|
|
|
- except OSError as err:
|
|
|
- logger.error('delete img: {} failed with img_dir is not exist. error: {}'.format(
|
|
|
- request.args.get('filename', type=str), err))
|
|
|
- return {'filename': request.args.get('filename', type=str)}
|
|
|
- except Exception as err:
|
|
|
- logger.error('delete img: {} failed with {}'.format(
|
|
|
- request.args.get('filename', type=str), err))
|
|
|
- return {'filename': request.args.get('filename', type=str)}
|
|
|
-
|
|
|
-
|
|
|
-api.add_resource(Content, '/api/contents')
|
|
|
-
|
|
|
-
|
|
|
-if __name__ == '__main__':
|
|
|
- logging.basicConfig(
|
|
|
- level=logging.INFO,
|
|
|
- format='%(asctime)s %(levelname)s %(message)s')
|
|
|
- app.run(debug=True)
|
|
|
+from flask import request, Blueprint
|
|
|
+from flask_restful import Resource, Api
|
|
|
+from os import path, remove, walk, mkdir
|
|
|
+import logging
|
|
|
+import re
|
|
|
+from models.config import CONTENT_DIR, STATIC_DIR
|
|
|
+
|
|
|
+
|
|
|
+contents_app = Blueprint('contents', __name__)
|
|
|
+api = Api(contents_app)
|
|
|
+logger = logging.getLogger(__name__)
|
|
|
+DATA_FIELD = ['title:', 'url:']
|
|
|
+
|
|
|
+
|
|
|
+def _get_data(file_dir):
|
|
|
+ def load_data():
|
|
|
+ if 'title:' in line:
|
|
|
+ data_field.remove('title:')
|
|
|
+ s = line.split('"')
|
|
|
+ result['title'] = s[1]
|
|
|
+ elif 'url:' in line:
|
|
|
+ data_field.remove('url:')
|
|
|
+ s = line.split('"')
|
|
|
+ result['url'] = s[1]
|
|
|
+
|
|
|
+ data_field = list(DATA_FIELD)
|
|
|
+ result = {}
|
|
|
+ with open(file_dir, 'r', encoding="utf-8") as md:
|
|
|
+ result['content'] = md.read()
|
|
|
+ md.seek(0)
|
|
|
+ md_line_data = md.readlines()
|
|
|
+ for line in md_line_data:
|
|
|
+ load_data()
|
|
|
+ if not data_field:
|
|
|
+ return result
|
|
|
+ return result
|
|
|
+
|
|
|
+
|
|
|
+def _gen_content_files():
|
|
|
+ for root, dirs, files in walk(CONTENT_DIR):
|
|
|
+ for f in files:
|
|
|
+ if '.md' not in f:
|
|
|
+ continue
|
|
|
+ yield path.join(root, f)
|
|
|
+
|
|
|
+
|
|
|
+def _search_dir(url):
|
|
|
+ def _get_file_front_matter_url():
|
|
|
+ with open(file_dir, 'r', encoding="utf-8") as md:
|
|
|
+ md_line_data = md.readlines()
|
|
|
+ for line in md_line_data:
|
|
|
+ if 'url:' in line:
|
|
|
+ return list(filter(None, re.split('"|\n', line)))[-1]
|
|
|
+
|
|
|
+ for file_dir in _gen_content_files():
|
|
|
+ if url == _get_file_front_matter_url():
|
|
|
+ return path.dirname(file_dir)
|
|
|
+
|
|
|
+
|
|
|
+def _search_type_dir(type_):
|
|
|
+ def _get_file_front_matter_type():
|
|
|
+ with open(file_dir, 'r', encoding="utf-8") as md:
|
|
|
+ md_line_data = md.readlines()
|
|
|
+ for line in md_line_data:
|
|
|
+ if 'type:' in line:
|
|
|
+ return list(filter(None, re.split('"|\n', line)))[-1]
|
|
|
+ for file_dir in _gen_content_files():
|
|
|
+ if type_ == _get_file_front_matter_type():
|
|
|
+ return path.dirname(file_dir)
|
|
|
+
|
|
|
+
|
|
|
+class Content(Resource):
|
|
|
+ DATA_FIELD = ['title:', 'url:']
|
|
|
+
|
|
|
+ @property
|
|
|
+ def url(self):
|
|
|
+ return request.args.get('url', type=str)
|
|
|
+
|
|
|
+ def _search_content(self):
|
|
|
+ result = {}
|
|
|
+ for file_dir in _gen_content_files():
|
|
|
+ data = _get_data(file_dir)
|
|
|
+ if self.url in data.get('url', ''):
|
|
|
+ result = data
|
|
|
+ result['path'] = file_dir
|
|
|
+ yield result
|
|
|
+
|
|
|
+ def _get_contents(self):
|
|
|
+ for file_dir in _gen_content_files():
|
|
|
+ yield _get_data(file_dir)
|
|
|
+
|
|
|
+ def get(self):
|
|
|
+ if self.url:
|
|
|
+ return list(self._search_content())
|
|
|
+ else:
|
|
|
+ return list(self._get_contents())
|
|
|
+
|
|
|
+ def post(self):
|
|
|
+ try:
|
|
|
+ file_dir = path.join(
|
|
|
+ _search_dir(request.args.get('url', type=str)), 'index.md')
|
|
|
+ md_content = request.json.get('content')
|
|
|
+ with open(file_dir, 'w', encoding="utf-8") as md:
|
|
|
+ md.write(md_content)
|
|
|
+ return md_content
|
|
|
+ except TypeError as err:
|
|
|
+ logger.error(
|
|
|
+ 'Content post failed with file_dir param contain None. error: {}'.format(err))
|
|
|
+ except OSError as err:
|
|
|
+ logger.error(
|
|
|
+ 'Content post failed with: {} is not exist{}'.format(file_dir, err))
|
|
|
+ except AttributeError as err:
|
|
|
+ logger.error('Content post failed with AttributeError: {}'.format(err))
|
|
|
+ except Exception as err:
|
|
|
+ logger.error('Content post failed with: {}'.format(err))
|
|
|
+
|
|
|
+ def delete(self):
|
|
|
+ content_data = list(self._search_content())
|
|
|
+ file_dir = content_data[0].get('path')
|
|
|
+ if path.exists(file_dir):
|
|
|
+ remove(file_dir)
|
|
|
+ logger.info('delete file: {}'.format(file_dir))
|
|
|
+ else:
|
|
|
+ logger.warning('delete fail with {} not exist'.format(file_dir))
|
|
|
+
|
|
|
+
|
|
|
+@contents_app.route('/api/upload/img', methods=['POST'])
|
|
|
+def upload_img():
|
|
|
+ img_data = request.files['image']
|
|
|
+ file_dir = _search_dir(request.args.get('url', type=str))
|
|
|
+ img_dir = path.join(file_dir, 'img/{}'.format(img_data.filename))
|
|
|
+ img_data.save(img_dir)
|
|
|
+ return {'filename': img_data.filename}
|
|
|
+
|
|
|
+
|
|
|
+@contents_app.route('/api/delete/img', methods=['DELETE'])
|
|
|
+def delete_img():
|
|
|
+ try:
|
|
|
+ file_dir = _search_dir(request.args.get('url', type=str))
|
|
|
+ img_dir = path.join(file_dir, 'img/{}'.format(request.args.get('filename', type=str)))
|
|
|
+ remove(img_dir)
|
|
|
+ logger.info('delete img: {}'.format(img_dir))
|
|
|
+ return {'filename': request.args.get('filename', type=str)}
|
|
|
+ except TypeError as err:
|
|
|
+ logger.error('delete img: {} failed with file_dir is None. error: {}'.format(
|
|
|
+ request.args.get('filename', type=str), err))
|
|
|
+ return {'filename': request.args.get('filename', type=str)}
|
|
|
+ except OSError as err:
|
|
|
+ logger.error('delete img: {} failed with img_dir is not exist. error: {}'.format(
|
|
|
+ request.args.get('filename', type=str), err))
|
|
|
+ return {'filename': request.args.get('filename', type=str)}
|
|
|
+ except Exception as err:
|
|
|
+ logger.error('delete img: {} failed with {}'.format(
|
|
|
+ request.args.get('filename', type=str), err))
|
|
|
+ return {'filename': request.args.get('filename', type=str)}
|
|
|
+
|
|
|
+
|
|
|
+@contents_app.route('/api/upload/static/img', methods=['POST'])
|
|
|
+def upload_static_img():
|
|
|
+ img_data = request.files['image']
|
|
|
+ img_dir = path.join(STATIC_DIR, 'img',
|
|
|
+ request.args.get('type', type=str),
|
|
|
+ request.args.get('filename', type=str))
|
|
|
+ img_data.save(img_dir)
|
|
|
+ return {'filename': request.args.get('filename', type=str)}
|
|
|
+
|
|
|
+
|
|
|
+@contents_app.route('/api/new_content', methods=['POST'])
|
|
|
+def gen_content():
|
|
|
+ front_matter = request.json.get('frontMatter', '---\n---')
|
|
|
+ name = request.json.get('name', 'Undefind')
|
|
|
+ dir_ = path.join(_search_type_dir(request.json.get('type')), name)
|
|
|
+ if dir_:
|
|
|
+ mkdir(dir_)
|
|
|
+ mkdir(path.join(dir_, 'img'))
|
|
|
+ with open(path.join(dir_, 'index.md'), 'w') as md:
|
|
|
+ md.write(front_matter)
|
|
|
+ return {'new_content': name}
|
|
|
+
|
|
|
+
|
|
|
+api.add_resource(Content, '/api/contents')
|