content.py 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. from flask import Flask, request, redirect, url_for
  2. from flask_restful import Resource, Api
  3. from flask_cors import CORS
  4. from os import path, remove, listdir, walk
  5. import logging
  6. import re
  7. from config import CONTENT_DIR
  8. app = Flask(__name__)
  9. api = Api(app)
  10. CORS(app, resources={r"/api/*": {"origins": "*"}})
  11. CURRENT_PATH = '/Users/weichen/choozmo/bhouse/bhouse'
  12. logger = logging.getLogger(__name__)
  13. DATA_FIELD = ['title:', 'url:']
  14. def _get_data(file_dir):
  15. def load_data():
  16. if 'title:' in line:
  17. data_field.remove('title:')
  18. s = line.split('"')
  19. result['title'] = s[1]
  20. elif 'url:' in line:
  21. data_field.remove('url:')
  22. s = line.split('"')
  23. result['url'] = s[1]
  24. data_field = list(DATA_FIELD)
  25. result = {}
  26. with open(file_dir, 'r', encoding="utf-8") as md:
  27. result['content'] = md.read()
  28. md.seek(0)
  29. md_line_data = md.readlines()
  30. for line in md_line_data:
  31. load_data()
  32. if not data_field:
  33. return result
  34. return result
  35. def _gen_content_files():
  36. for root, dirs, files in walk(CONTENT_DIR):
  37. for f in files:
  38. if '.md' not in f:
  39. continue
  40. yield path.join(root, f)
  41. def _search_dir(url):
  42. def _get_file_front_matter_url():
  43. with open(file_dir, 'r', encoding="utf-8") as md:
  44. md_line_data = md.readlines()
  45. for line in md_line_data:
  46. if 'url:' in line:
  47. return list(filter(None, re.split('"|\n', line)))[-1]
  48. for file_dir in _gen_content_files():
  49. if url == _get_file_front_matter_url():
  50. return path.dirname(file_dir)
  51. class Content(Resource):
  52. DATA_FIELD = ['title:', 'url:']
  53. @property
  54. def url(self):
  55. return request.args.get('url', type=str)
  56. def _search_content(self):
  57. result = {}
  58. for file_dir in _gen_content_files():
  59. data = _get_data(file_dir)
  60. if self.url in data.get('url', ''):
  61. result = data
  62. result['path'] = file_dir
  63. yield result
  64. def _get_contents(self):
  65. for file_dir in _gen_content_files():
  66. yield _get_data(file_dir)
  67. def get(self):
  68. if self.url:
  69. return list(self._search_content())
  70. else:
  71. return list(self._get_contents())
  72. def post(self):
  73. try:
  74. file_dir = path.join(
  75. _search_dir(request.args.get('url', type=str)), 'index.md')
  76. md_content = request.json.get('content')
  77. with open(file_dir, 'w', encoding="utf-8") as md:
  78. md.write(md_content)
  79. return md_content
  80. except TypeError as err:
  81. logger.error('Content post failed with file_dir param contain None. error: {}'.format(err))
  82. except OSError as err:
  83. logger.error('Content post failed with: {} is not exist{}'.format(file_dir, err))
  84. except AttributeError as err:
  85. logger.error('Content post failed with AttributeError: {}'.format(err))
  86. except Exception as err:
  87. logger.error('Content post failed with: {}'.format(err))
  88. def delete(self):
  89. content_data = list(self._search_content())
  90. file_dir = content_data[0].get('path')
  91. if path.exists(file_dir):
  92. remove(file_dir)
  93. logger.info('delete file: {}'.format(file_dir))
  94. else:
  95. logger.warning('delete fail with {} not exist'.format(file_dir))
  96. @app.route('/api/upload/img', methods=['POST'])
  97. def upload_img():
  98. img_data = request.files['image']
  99. file_dir = _search_dir(request.args.get('url', type=str))
  100. img_dir = path.join(file_dir, 'img/{}'.format(img_data.filename))
  101. img_data.save(img_dir)
  102. return {'filename': img_data.filename}
  103. @app.route('/api/delete/img', methods=['DELETE'])
  104. def delete_img():
  105. try:
  106. file_dir = _search_dir(request.args.get('url', type=str))
  107. img_dir = path.join(file_dir, 'img/{}'.format(request.args.get('filename', type=str)))
  108. remove(img_dir)
  109. logger.info('delete img: {}'.format(img_dir))
  110. return {'filename': request.args.get('filename', type=str)}
  111. except TypeError as err:
  112. logger.error('delete img: {} failed with file_dir is None. error: {}'.format(
  113. request.args.get('filename', type=str), err))
  114. return {'filename': request.args.get('filename', type=str)}
  115. except OSError as err:
  116. logger.error('delete img: {} failed with img_dir is not exist. error: {}'.format(
  117. request.args.get('filename', type=str), err))
  118. return {'filename': request.args.get('filename', type=str)}
  119. except Exception as err:
  120. logger.error('delete img: {} failed with {}'.format(
  121. request.args.get('filename', type=str), err))
  122. return {'filename': request.args.get('filename', type=str)}
  123. api.add_resource(Content, '/api/contents')
  124. if __name__ == '__main__':
  125. logging.basicConfig(
  126. level=logging.INFO,
  127. format='%(asctime)s %(levelname)s %(message)s')
  128. app.run(debug=True)