web.py 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. from flask import Flask, render_template, make_response, request
  2. from bookworm import s3, constants
  3. import pg_simple
  4. import json
  5. import redis
  6. import os
  7. import re
  8. s3client = s3.client()
  9. app = Flask(__name__)
  10. pool = pg_simple.config_pool(dsn='dbname=david user=david')
  11. db = pg_simple.PgSimple(pool)
  12. r = redis.StrictRedis(host='localhost', port=6379, decode_responses=True)
  13. @app.route('/books/status', methods=['GET'])
  14. def status_books():
  15. keys = r.keys('book_*')
  16. ret = {}
  17. for key in keys:
  18. val = r.hgetall(key)
  19. ret[key] = val
  20. print(ret)
  21. return json.dumps(ret)
  22. def clean_book_name(book):
  23. cbr = re.compile(r'epub|azw3|mobi|\(v[0-9.]+\)')
  24. return cbr.sub('', book).rstrip('() .-')
  25. @app.route('/')
  26. def index():
  27. objects = s3client.list_objects_v2(Bucket=constants.PROCESSED_FILE_BUCKET)['Contents']
  28. objects = sorted(objects, key=lambda x: x['LastModified'], reverse=True)
  29. books = [(obj['Key'], clean_book_name(obj['Key'])) for obj in objects]
  30. return render_template('kindle-index.j2', books=books)
  31. @app.route('/book/<path:book>')
  32. def serve_books(book):
  33. obj = s3client.get_object(Bucket=constants.PROCESSED_FILE_BUCKET, Key=book)
  34. data = obj['Body'].read()
  35. response = make_response(data)
  36. response.headers.set('Content-Disposition', f'attachment; filename="{book}"')
  37. response.headers.set('Content-Length', len(data))
  38. _, ext = os.path.splitext(book)
  39. if ext == '.mobi':
  40. content_type = 'application/x-mobipocket-ebook'
  41. elif ext == '.azw3':
  42. content_type = 'application/x-mobi8-ebook'
  43. else:
  44. content_type = 'text/plain'
  45. response.headers.set('Content-Type', content_type)
  46. return response
  47. @app.route('/book/search', methods=['GET'])
  48. def search_books():
  49. terms = request.args.get('terms').split()
  50. terms = [f'%{term}%' for term in terms]
  51. books = db.fetchall('books',
  52. fields=['bot', 'book'],
  53. where=('lower(book) like all(%s)', [terms]),
  54. limit=100)
  55. return json.dumps([b._asdict() for b in books])
  56. @app.route('/book/fetch', methods=['POST'])
  57. def fetch_books():
  58. fetch = request.json
  59. data = {'bot': fetch['bot'],
  60. 'book': fetch['book'],
  61. 'meta': {
  62. 'unpack_file_queue': constants.REDIS_UNPACK_FILE,
  63. 'fetch_file_queue': constants.REDIS_FETCH_FILE,
  64. 'raw_file_bucket': constants.RAW_FILE_BUCKET,
  65. 'processed_file_bucket': constants.PROCESSED_FILE_BUCKET,
  66. }
  67. }
  68. r.rpush(constants.REDIS_BOOK_COMMANDS, json.dumps(data))
  69. return ''
  70. def main():
  71. app.run(host='0.0.0.0', debug=True)
  72. if __name__ == '__main__':
  73. main()