app.py 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. import os
  2. import hashlib
  3. import sys
  4. import json
  5. import re
  6. import logging
  7. from uuid import uuid4
  8. from email.mime.text import MIMEText
  9. from subprocess import Popen, PIPE
  10. from flask import Flask, request, render_template, abort, url_for, make_response
  11. app = Flask(__name__)
  12. if 'MESSAGGERIA_SETTING' in os.environ:
  13. app.config.from_envvar('MESSAGGERIA_SETTING')
  14. UPLOAD_DIR = os.getenv("UPLOAD_DIR", "./uploads/")
  15. logging.basicConfig(level=logging.DEBUG)
  16. def sendmail(sender, to, subject, body):
  17. #msg = MIMEText(body)
  18. #msg["From"] = sender
  19. #msg["To"] = to
  20. #msg["Subject"] = subject
  21. #p = Popen(["/usr/sbin/sendmail", "-t", "-oi"], stdin=PIPE)
  22. args = ["/usr/bin/mail", "-s", subject, '--'] + to
  23. p = Popen(args, stdin=PIPE)
  24. # p.communicate(msg.as_bytes())
  25. p.communicate(body.encode('utf8'))
  26. def read_config():
  27. try:
  28. cfgname = os.getenv("CONFIG_FILE", "./config.json")
  29. with open(cfgname) as buf:
  30. cfg = json.load(buf)
  31. except:
  32. app.logger.exception("Error reading conf")
  33. cfg = {}
  34. cfg.setdefault("sites", {})
  35. return cfg
  36. @app.route("/")
  37. def home():
  38. # TODO: redirect to /default, meglio che render
  39. return render_template("index.htm", site="default")
  40. @app.route("/<site>")
  41. def site(site):
  42. return render_template("index.htm", site=site)
  43. @app.route("/upload/<site>", methods=["POST"])
  44. def upload(site):
  45. temp_fname = '_%s.ogg' % uuid4().hex
  46. temp_fpath = os.path.join(UPLOAD_DIR, temp_fname)
  47. # prima scrivi su un file temporaneo, poi fai rename
  48. h = hashlib.new('sha1')
  49. with open(temp_fpath, "wb") as buf:
  50. while True:
  51. some_data = request.stream.read(1024)
  52. if not some_data:
  53. break
  54. buf.write(some_data)
  55. h.update(some_data)
  56. # rinomina con l'hash
  57. app.logger.info('hash = %s', h.hexdigest())
  58. fname = '%s.ogg' % h.hexdigest()
  59. os.rename(temp_fpath, os.path.join(UPLOAD_DIR, fname))
  60. if site in read_config()["sites"]:
  61. to = read_config()["sites"][site].get("email", [])
  62. if to:
  63. sender = os.getenv('MAIL_FROM', '')
  64. if not sender:
  65. app.logger.info('Not sending email (unconfigured FROM)')
  66. else:
  67. app.logger.debug('Sending email for `%s` to `%s`',
  68. site, ';'.join(to))
  69. url = url_for("dl", fname=fname, _external=True, _scheme='https')
  70. sendmail(sender, to,
  71. subject='Nuovo messaggio (%s)' % site,
  72. body="Ascoltalo su\n%s" % url)
  73. return fname
  74. @app.route("/listen/<fname>")
  75. def play(fname):
  76. # prevent path traversal or any other trick
  77. if "/" in fname or not re.match(r"^[a-z0-9]*.(ogg|wav)", fname):
  78. abort(400)
  79. fpath = os.path.join(UPLOAD_DIR, fname)
  80. if not os.path.exists(fpath):
  81. abort(404)
  82. return render_template('player.html', fname=fname)
  83. @app.route("/download/<fname>")
  84. def dl(fname):
  85. # prevent path traversal or any other trick
  86. if "/" in fname or not re.match(r"^[a-z0-9]*.(ogg|wav)", fname):
  87. abort(400)
  88. fpath = os.path.join(UPLOAD_DIR, fname)
  89. if not os.path.exists(fpath):
  90. abort(404)
  91. with open(fpath, "rb") as buf:
  92. content = buf.read()
  93. r = make_response(content)
  94. r.headers['Content-Type'] = 'audio/ogg' # TODO: better detect
  95. return r