from flask import request, Blueprint from flask.wrappers import Response 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 import shutil from backstage.utils.routes import get_trans_title_url_name contents_app = Blueprint('contents', __name__) api = Api(contents_app) logger = logging.getLogger(__name__) DATA_FIELD = ['title:', 'url:','tags:','image:','description:'] def _get_data(file_dir): def load_data(): if 'meta_title:' in line: s = line.split('"') result['meta_title'] = s[1] elif 'collection_title:' in line: s = line.split('"') result['collection_title'] = s[1] elif 'title:' in line: #print(line) # debug use #data_field.remove('title: ') #i have to remove this because you wont get the correct results s = line.split('"') result['title'] = s[1] elif 'date: ' in line: # data_field.remove('date: ') s = line.replace('date: ', '').strip() result['date'] = s elif 'draft: ' in line: # data_field.remove('draft: ') s = line.replace('draft: ', '').strip() result['draft'] = s elif 'display: ' in line: # data_field.remove('draft: ') s = line.replace('display: ', '').strip() result['display'] = s elif 'url: ' in line: data_field.remove('url:') s = line.split('"') result['url'] = s[1] elif 'tags: ' in line: data_field.remove('tags:') s = line.replace('tags: ', '').strip() """ if s != "": s = s + "," s = s + "全部屋型,全部坪數,全部預算,全部格局" """ result['tags'] = s elif 'categories: ' in line: s = line.replace('categories: ', '').strip() result['categories'] = s elif 'blog_tag: ' in line: s = line.replace('blog_tag: ', '').strip() result['blog_tag'] = s elif 'image: ' in line: s = line.replace('image: ', '').strip() s = s.replace('"', '').strip() result['image'] = s elif 'collection_description: ' in line: s = line.replace('collection_description: ', '').strip() s = s.replace('"', '').strip() result['collection_description'] = s elif 'description: ' in line: s = line.replace('description: ', '').strip() s = s.replace('"', '').strip() result['description'] = s 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 if not 'tags' in result: result['tags'] = "全部類型,全部坪數,全部預算,全部格局" else: if result['tags'] != "": result['tags'] = result['tags'] + "," result['tags'] = result['tags'].replace('"', '') + "全部類型,全部坪數,全部預算,全部格局" 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_content_dir(type_, categories=None): target = categories or 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 categories: if 'categories' in line: return list(filter(None, re.split('"|\n|]', line)))[-1] else: if 'type:' in line: return list(filter(None, re.split('"|\n', line)))[-1] for file_dir in _gen_content_files(): if target == _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 #print(result['path']) yield result def _get_contents(self): for file_dir in _gen_content_files(): yield _get_data(file_dir) def get(self): if self.url: results = self._search_content() else: results = self._get_contents() x = list(results) print(type(x), type(results)) x.sort(key = lambda k: k["date"], reverse=True) return x def post(self): try: requrl = request.args.get('url', type=str) print(requrl) if "frequently_asked_questions" in requrl: file_dir = path.join(_search_dir(requrl), '_index.md') else: file_dir = path.join(_search_dir(requrl), '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) shutil.rmtree(file_dir[0:file_dir.replace('\\', '/').rfind('/')+1]) # print(file_dir[0:file_dir.replace('\\','/').rfind('/')+1]) logger.info('delete dir: {}'.format( file_dir[0:file_dir.replace('\\', '/').rfind('/')+1])) 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)) #print("file_dir 1 is " + file_dir) img_dir = path.join(file_dir, 'img/{}'.format(img_data.filename)) print("img_dir 1 is " + img_dir) img_data.save(img_dir) return {'filename': img_data.filename} @contents_app.route('/api/upload/img_to_dir', methods=['POST']) def upload_img_to_dir(): img_data = request.files['image'] file_dir = _search_dir(request.args.get('url', type=str)) #print("file_dir 2 is " + file_dir) img_dir = path.join(file_dir, 'img/{}'.format(request.args.get('filename', type=str))) print("img_dir 2 is " + img_dir) 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', 'title') print("static img directory is " + img_dir) #debug use if not path.exists(img_dir): # foolproofing, just in case mkdir(img_dir) img_file_dir = path.join(img_dir, request.args.get('filename', type=str)) print("static img file directory is " + img_file_dir) #debug use img_data.save(img_file_dir) return {'filename': request.args.get('filename', type=str)} @contents_app.route('/api/new_content', methods=['POST']) def gen_content(): print(request.json.get('type')) print(get_trans_title_url_name(request.json.get('type'))) front_matter = request.json.get('frontMatter', '---\n---') name = request.json.get('name', 'Undefind') if request.json.get('type') == "blog": dir_ = CONTENT_DIR + "/"+ "blog" + "/" + name if not path.exists(dir_): mkdir(dir_) if not path.exists(path.join(dir_, 'img')): mkdir(path.join(dir_, 'img')) with open(path.join(dir_, 'index.md'), 'w', encoding="utf-8") as md: md.write(front_matter) # print(front_matter) else: dir_ = path.join(CONTENT_DIR, request.json.get('type'), name) print(dir_) if dir_: if not path.exists(dir_): mkdir(dir_) else: return Response({}, status=201) if not path.exists(path.join(dir_, 'img')): mkdir(path.join(dir_, 'img')) with open(path.join(dir_, 'index.md'), 'w', encoding="utf-8") as md: md.write(front_matter) return {'new_content': name} @contents_app.route('/api/get_cats', methods=['POST', 'GET']) def get_cats(): """ front_matter = request.json.get('frontMatter', '---\n---') name = request.json.get('name', 'Undefind') dir_ = path.join(_search_content_dir( request.json.get('type'), request.json.get('categories')), name) """ #print(_search_content_dir('blog', 'home_inspection_knowledge')) return {} @contents_app.route('/api/new_cat', methods=['POST']) def gen_cat(): front_matter = request.json.get('frontMatter', '---\n---') name = request.json.get('name', 'Undefind') dir_ = path.join(_search_content_dir( request.json.get('type'), request.json.get('categories')), name) #print(request.json.get('type') + ',' + request.json.get('categories')) if dir_: if not path.exists(dir_): mkdir(dir_) else: return Response({}, status=201) if not path.exists(path.join(dir_, 'img')): mkdir(path.join(dir_, 'img')) with open(path.join(dir_, 'index.md'), 'w', encoding="utf-8") as md: md.write(front_matter) return {'new_content': name} api.add_resource(Content, '/api/contents')