2019-02-05 04:59:03 +01:00
|
|
|
# Copyright: Ankitects Pty Ltd and contributors
|
2016-07-07 15:39:48 +02:00
|
|
|
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
2020-07-02 19:30:43 +02:00
|
|
|
|
|
|
|
from __future__ import annotations
|
|
|
|
|
Replaced the mediasrv.py SimpleHttp server by flask and waitress,
fixing HTML5 media support.
https://stackoverflow.com/questions/37044064/html-audio-cant-set-currenttime
https://stackoverflow.com/questions/21956683/enable-access-control-on-simple-http-server
https://stackoverflow.com/questions/5052635/what-is-relation-between-content-length-and-byte-ranges-in-http-1-1
https://stackoverflow.com/questions/16725907/google-app-engine-serving-mp3-for-audio-element-needs-content-range-header
I was trying to use HTML5 audio tag to display audios like:
```html
<audio id="elem_audio" src="myfile.mp3" controls></audio>
```
![image](https://user-images.githubusercontent.com/5332158/79063321-565b5500-7c77-11ea-9f8d-6e1df6f07892.png)
But the progress bar seek was not working. After researching, I found the problem was the HTML server not properly responding to the HTML5 header requests. The HTML server should respond to quite complicated things as 206 partial, properly handle keep-alive, provide media ranges and other HTTP headers: https://stackoverflow.com/questions/37044064/html-audio-cant-set-currenttime
To implement all these on the Simple HTTP server would be quite complicated. Then, instead, I imported the `flask` web server, which is quite simple and straight forward to use. Now, the back-end is using a secure complaint HTTP back-end:
1. https://palletsprojects.com/p/flask/
> Flask is a lightweight WSGI web application framework. It is designed to make getting started quick and easy, with the ability to scale up to complex applications. It began as a simple wrapper around Werkzeug and Jinja and has become one of the most popular Python web application frameworks.
>
> Flask offers suggestions, but doesn't enforce any dependencies or project layout. It is up to the developer to choose the tools and libraries they want to use. There are many extensions provided by the community that make adding new functionality easy.
1. https://docs.pylonsproject.org/projects/waitress/en/latest/
> Waitress is meant to be a production-quality pure-Python WSGI server with very acceptable performance. It has no dependencies except ones which live in the Python standard library. It runs on CPython on Unix and Windows under Python 2.7+ and Python 3.5+. It is also known to run on PyPy 1.6.0 on UNIX. It supports HTTP/1.0 and HTTP/1.1.
Right now, anki does not support fields passing file names directly to HTML audio tags, but this can be easily done with (https://github.com/ankitects/anki/pull 540 - Added arguments to the sound tag) plus the commit https://github.com/evandroforks/anki/commit/826a97df61b99814041c41c0f2c84268280ed8ad, the HTML5 audio tag can be used like this:
```html
// Audio = [sound:myfile.mp3|onlyfilename]
<audio id="elem_audio" src="{{Audio}}" controls controlsList="nodownload"></audio>
```
![image](https://user-images.githubusercontent.com/5332158/79063736-c539ad80-7c79-11ea-8420-40b72185f4e7.png)
# Conflicts:
# qt/aqt/mediasrv.py
2020-04-29 12:38:35 +02:00
|
|
|
import logging
|
2021-10-14 13:48:50 +02:00
|
|
|
import mimetypes
|
Replaced the mediasrv.py SimpleHttp server by flask and waitress,
fixing HTML5 media support.
https://stackoverflow.com/questions/37044064/html-audio-cant-set-currenttime
https://stackoverflow.com/questions/21956683/enable-access-control-on-simple-http-server
https://stackoverflow.com/questions/5052635/what-is-relation-between-content-length-and-byte-ranges-in-http-1-1
https://stackoverflow.com/questions/16725907/google-app-engine-serving-mp3-for-audio-element-needs-content-range-header
I was trying to use HTML5 audio tag to display audios like:
```html
<audio id="elem_audio" src="myfile.mp3" controls></audio>
```
![image](https://user-images.githubusercontent.com/5332158/79063321-565b5500-7c77-11ea-9f8d-6e1df6f07892.png)
But the progress bar seek was not working. After researching, I found the problem was the HTML server not properly responding to the HTML5 header requests. The HTML server should respond to quite complicated things as 206 partial, properly handle keep-alive, provide media ranges and other HTTP headers: https://stackoverflow.com/questions/37044064/html-audio-cant-set-currenttime
To implement all these on the Simple HTTP server would be quite complicated. Then, instead, I imported the `flask` web server, which is quite simple and straight forward to use. Now, the back-end is using a secure complaint HTTP back-end:
1. https://palletsprojects.com/p/flask/
> Flask is a lightweight WSGI web application framework. It is designed to make getting started quick and easy, with the ability to scale up to complex applications. It began as a simple wrapper around Werkzeug and Jinja and has become one of the most popular Python web application frameworks.
>
> Flask offers suggestions, but doesn't enforce any dependencies or project layout. It is up to the developer to choose the tools and libraries they want to use. There are many extensions provided by the community that make adding new functionality easy.
1. https://docs.pylonsproject.org/projects/waitress/en/latest/
> Waitress is meant to be a production-quality pure-Python WSGI server with very acceptable performance. It has no dependencies except ones which live in the Python standard library. It runs on CPython on Unix and Windows under Python 2.7+ and Python 3.5+. It is also known to run on PyPy 1.6.0 on UNIX. It supports HTTP/1.0 and HTTP/1.1.
Right now, anki does not support fields passing file names directly to HTML audio tags, but this can be easily done with (https://github.com/ankitects/anki/pull 540 - Added arguments to the sound tag) plus the commit https://github.com/evandroforks/anki/commit/826a97df61b99814041c41c0f2c84268280ed8ad, the HTML5 audio tag can be used like this:
```html
// Audio = [sound:myfile.mp3|onlyfilename]
<audio id="elem_audio" src="{{Audio}}" controls controlsList="nodownload"></audio>
```
![image](https://user-images.githubusercontent.com/5332158/79063736-c539ad80-7c79-11ea-8420-40b72185f4e7.png)
# Conflicts:
# qt/aqt/mediasrv.py
2020-04-29 12:38:35 +02:00
|
|
|
import os
|
2019-12-20 10:19:03 +01:00
|
|
|
import re
|
Replaced the mediasrv.py SimpleHttp server by flask and waitress,
fixing HTML5 media support.
https://stackoverflow.com/questions/37044064/html-audio-cant-set-currenttime
https://stackoverflow.com/questions/21956683/enable-access-control-on-simple-http-server
https://stackoverflow.com/questions/5052635/what-is-relation-between-content-length-and-byte-ranges-in-http-1-1
https://stackoverflow.com/questions/16725907/google-app-engine-serving-mp3-for-audio-element-needs-content-range-header
I was trying to use HTML5 audio tag to display audios like:
```html
<audio id="elem_audio" src="myfile.mp3" controls></audio>
```
![image](https://user-images.githubusercontent.com/5332158/79063321-565b5500-7c77-11ea-9f8d-6e1df6f07892.png)
But the progress bar seek was not working. After researching, I found the problem was the HTML server not properly responding to the HTML5 header requests. The HTML server should respond to quite complicated things as 206 partial, properly handle keep-alive, provide media ranges and other HTTP headers: https://stackoverflow.com/questions/37044064/html-audio-cant-set-currenttime
To implement all these on the Simple HTTP server would be quite complicated. Then, instead, I imported the `flask` web server, which is quite simple and straight forward to use. Now, the back-end is using a secure complaint HTTP back-end:
1. https://palletsprojects.com/p/flask/
> Flask is a lightweight WSGI web application framework. It is designed to make getting started quick and easy, with the ability to scale up to complex applications. It began as a simple wrapper around Werkzeug and Jinja and has become one of the most popular Python web application frameworks.
>
> Flask offers suggestions, but doesn't enforce any dependencies or project layout. It is up to the developer to choose the tools and libraries they want to use. There are many extensions provided by the community that make adding new functionality easy.
1. https://docs.pylonsproject.org/projects/waitress/en/latest/
> Waitress is meant to be a production-quality pure-Python WSGI server with very acceptable performance. It has no dependencies except ones which live in the Python standard library. It runs on CPython on Unix and Windows under Python 2.7+ and Python 3.5+. It is also known to run on PyPy 1.6.0 on UNIX. It supports HTTP/1.0 and HTTP/1.1.
Right now, anki does not support fields passing file names directly to HTML audio tags, but this can be easily done with (https://github.com/ankitects/anki/pull 540 - Added arguments to the sound tag) plus the commit https://github.com/evandroforks/anki/commit/826a97df61b99814041c41c0f2c84268280ed8ad, the HTML5 audio tag can be used like this:
```html
// Audio = [sound:myfile.mp3|onlyfilename]
<audio id="elem_audio" src="{{Audio}}" controls controlsList="nodownload"></audio>
```
![image](https://user-images.githubusercontent.com/5332158/79063736-c539ad80-7c79-11ea-8420-40b72185f4e7.png)
# Conflicts:
# qt/aqt/mediasrv.py
2020-04-29 12:38:35 +02:00
|
|
|
import sys
|
2019-12-20 10:19:03 +01:00
|
|
|
import threading
|
2020-07-07 05:28:30 +02:00
|
|
|
import time
|
Replaced the mediasrv.py SimpleHttp server by flask and waitress,
fixing HTML5 media support.
https://stackoverflow.com/questions/37044064/html-audio-cant-set-currenttime
https://stackoverflow.com/questions/21956683/enable-access-control-on-simple-http-server
https://stackoverflow.com/questions/5052635/what-is-relation-between-content-length-and-byte-ranges-in-http-1-1
https://stackoverflow.com/questions/16725907/google-app-engine-serving-mp3-for-audio-element-needs-content-range-header
I was trying to use HTML5 audio tag to display audios like:
```html
<audio id="elem_audio" src="myfile.mp3" controls></audio>
```
![image](https://user-images.githubusercontent.com/5332158/79063321-565b5500-7c77-11ea-9f8d-6e1df6f07892.png)
But the progress bar seek was not working. After researching, I found the problem was the HTML server not properly responding to the HTML5 header requests. The HTML server should respond to quite complicated things as 206 partial, properly handle keep-alive, provide media ranges and other HTTP headers: https://stackoverflow.com/questions/37044064/html-audio-cant-set-currenttime
To implement all these on the Simple HTTP server would be quite complicated. Then, instead, I imported the `flask` web server, which is quite simple and straight forward to use. Now, the back-end is using a secure complaint HTTP back-end:
1. https://palletsprojects.com/p/flask/
> Flask is a lightweight WSGI web application framework. It is designed to make getting started quick and easy, with the ability to scale up to complex applications. It began as a simple wrapper around Werkzeug and Jinja and has become one of the most popular Python web application frameworks.
>
> Flask offers suggestions, but doesn't enforce any dependencies or project layout. It is up to the developer to choose the tools and libraries they want to use. There are many extensions provided by the community that make adding new functionality easy.
1. https://docs.pylonsproject.org/projects/waitress/en/latest/
> Waitress is meant to be a production-quality pure-Python WSGI server with very acceptable performance. It has no dependencies except ones which live in the Python standard library. It runs on CPython on Unix and Windows under Python 2.7+ and Python 3.5+. It is also known to run on PyPy 1.6.0 on UNIX. It supports HTTP/1.0 and HTTP/1.1.
Right now, anki does not support fields passing file names directly to HTML audio tags, but this can be easily done with (https://github.com/ankitects/anki/pull 540 - Added arguments to the sound tag) plus the commit https://github.com/evandroforks/anki/commit/826a97df61b99814041c41c0f2c84268280ed8ad, the HTML5 audio tag can be used like this:
```html
// Audio = [sound:myfile.mp3|onlyfilename]
<audio id="elem_audio" src="{{Audio}}" controls controlsList="nodownload"></audio>
```
![image](https://user-images.githubusercontent.com/5332158/79063736-c539ad80-7c79-11ea-8420-40b72185f4e7.png)
# Conflicts:
# qt/aqt/mediasrv.py
2020-04-29 12:38:35 +02:00
|
|
|
import traceback
|
2021-10-07 14:26:29 +02:00
|
|
|
from dataclasses import dataclass
|
2019-12-20 10:19:03 +01:00
|
|
|
from http import HTTPStatus
|
2016-07-07 15:39:48 +02:00
|
|
|
|
Replaced the mediasrv.py SimpleHttp server by flask and waitress,
fixing HTML5 media support.
https://stackoverflow.com/questions/37044064/html-audio-cant-set-currenttime
https://stackoverflow.com/questions/21956683/enable-access-control-on-simple-http-server
https://stackoverflow.com/questions/5052635/what-is-relation-between-content-length-and-byte-ranges-in-http-1-1
https://stackoverflow.com/questions/16725907/google-app-engine-serving-mp3-for-audio-element-needs-content-range-header
I was trying to use HTML5 audio tag to display audios like:
```html
<audio id="elem_audio" src="myfile.mp3" controls></audio>
```
![image](https://user-images.githubusercontent.com/5332158/79063321-565b5500-7c77-11ea-9f8d-6e1df6f07892.png)
But the progress bar seek was not working. After researching, I found the problem was the HTML server not properly responding to the HTML5 header requests. The HTML server should respond to quite complicated things as 206 partial, properly handle keep-alive, provide media ranges and other HTTP headers: https://stackoverflow.com/questions/37044064/html-audio-cant-set-currenttime
To implement all these on the Simple HTTP server would be quite complicated. Then, instead, I imported the `flask` web server, which is quite simple and straight forward to use. Now, the back-end is using a secure complaint HTTP back-end:
1. https://palletsprojects.com/p/flask/
> Flask is a lightweight WSGI web application framework. It is designed to make getting started quick and easy, with the ability to scale up to complex applications. It began as a simple wrapper around Werkzeug and Jinja and has become one of the most popular Python web application frameworks.
>
> Flask offers suggestions, but doesn't enforce any dependencies or project layout. It is up to the developer to choose the tools and libraries they want to use. There are many extensions provided by the community that make adding new functionality easy.
1. https://docs.pylonsproject.org/projects/waitress/en/latest/
> Waitress is meant to be a production-quality pure-Python WSGI server with very acceptable performance. It has no dependencies except ones which live in the Python standard library. It runs on CPython on Unix and Windows under Python 2.7+ and Python 3.5+. It is also known to run on PyPy 1.6.0 on UNIX. It supports HTTP/1.0 and HTTP/1.1.
Right now, anki does not support fields passing file names directly to HTML audio tags, but this can be easily done with (https://github.com/ankitects/anki/pull 540 - Added arguments to the sound tag) plus the commit https://github.com/evandroforks/anki/commit/826a97df61b99814041c41c0f2c84268280ed8ad, the HTML5 audio tag can be used like this:
```html
// Audio = [sound:myfile.mp3|onlyfilename]
<audio id="elem_audio" src="{{Audio}}" controls controlsList="nodownload"></audio>
```
![image](https://user-images.githubusercontent.com/5332158/79063736-c539ad80-7c79-11ea-8420-40b72185f4e7.png)
# Conflicts:
# qt/aqt/mediasrv.py
2020-04-29 12:38:35 +02:00
|
|
|
import flask
|
|
|
|
import flask_cors # type: ignore
|
2020-08-27 13:46:34 +02:00
|
|
|
from flask import Response, request
|
2020-06-06 00:44:54 +02:00
|
|
|
from waitress.server import create_server
|
Replaced the mediasrv.py SimpleHttp server by flask and waitress,
fixing HTML5 media support.
https://stackoverflow.com/questions/37044064/html-audio-cant-set-currenttime
https://stackoverflow.com/questions/21956683/enable-access-control-on-simple-http-server
https://stackoverflow.com/questions/5052635/what-is-relation-between-content-length-and-byte-ranges-in-http-1-1
https://stackoverflow.com/questions/16725907/google-app-engine-serving-mp3-for-audio-element-needs-content-range-header
I was trying to use HTML5 audio tag to display audios like:
```html
<audio id="elem_audio" src="myfile.mp3" controls></audio>
```
![image](https://user-images.githubusercontent.com/5332158/79063321-565b5500-7c77-11ea-9f8d-6e1df6f07892.png)
But the progress bar seek was not working. After researching, I found the problem was the HTML server not properly responding to the HTML5 header requests. The HTML server should respond to quite complicated things as 206 partial, properly handle keep-alive, provide media ranges and other HTTP headers: https://stackoverflow.com/questions/37044064/html-audio-cant-set-currenttime
To implement all these on the Simple HTTP server would be quite complicated. Then, instead, I imported the `flask` web server, which is quite simple and straight forward to use. Now, the back-end is using a secure complaint HTTP back-end:
1. https://palletsprojects.com/p/flask/
> Flask is a lightweight WSGI web application framework. It is designed to make getting started quick and easy, with the ability to scale up to complex applications. It began as a simple wrapper around Werkzeug and Jinja and has become one of the most popular Python web application frameworks.
>
> Flask offers suggestions, but doesn't enforce any dependencies or project layout. It is up to the developer to choose the tools and libraries they want to use. There are many extensions provided by the community that make adding new functionality easy.
1. https://docs.pylonsproject.org/projects/waitress/en/latest/
> Waitress is meant to be a production-quality pure-Python WSGI server with very acceptable performance. It has no dependencies except ones which live in the Python standard library. It runs on CPython on Unix and Windows under Python 2.7+ and Python 3.5+. It is also known to run on PyPy 1.6.0 on UNIX. It supports HTTP/1.0 and HTTP/1.1.
Right now, anki does not support fields passing file names directly to HTML audio tags, but this can be easily done with (https://github.com/ankitects/anki/pull 540 - Added arguments to the sound tag) plus the commit https://github.com/evandroforks/anki/commit/826a97df61b99814041c41c0f2c84268280ed8ad, the HTML5 audio tag can be used like this:
```html
// Audio = [sound:myfile.mp3|onlyfilename]
<audio id="elem_audio" src="{{Audio}}" controls controlsList="nodownload"></audio>
```
![image](https://user-images.githubusercontent.com/5332158/79063736-c539ad80-7c79-11ea-8420-40b72185f4e7.png)
# Conflicts:
# qt/aqt/mediasrv.py
2020-04-29 12:38:35 +02:00
|
|
|
|
2021-01-22 14:37:24 +01:00
|
|
|
import aqt
|
2020-11-09 10:45:14 +01:00
|
|
|
from anki import hooks
|
2021-10-14 11:22:47 +02:00
|
|
|
from anki.cards import CardId
|
2021-04-20 11:50:05 +02:00
|
|
|
from anki.collection import GraphPreferences, OpChanges
|
|
|
|
from anki.decks import UpdateDeckConfigs
|
2021-06-10 13:30:39 +02:00
|
|
|
from anki.models import NotetypeNames
|
2021-05-17 08:59:02 +02:00
|
|
|
from anki.scheduler.v3 import NextStates
|
2021-01-31 06:55:08 +01:00
|
|
|
from anki.utils import devMode, from_json_bytes
|
2021-06-10 13:30:39 +02:00
|
|
|
from aqt.changenotetype import ChangeNotetypeDialog
|
2021-04-22 02:55:32 +02:00
|
|
|
from aqt.deckoptions import DeckOptionsDialog
|
2021-04-20 11:50:05 +02:00
|
|
|
from aqt.operations.deck import update_deck_configs
|
2019-12-20 10:19:03 +01:00
|
|
|
from aqt.qt import *
|
2019-12-23 01:34:10 +01:00
|
|
|
|
2021-10-10 05:47:02 +02:00
|
|
|
app = flask.Flask(__name__, root_path="/fake")
|
Replaced the mediasrv.py SimpleHttp server by flask and waitress,
fixing HTML5 media support.
https://stackoverflow.com/questions/37044064/html-audio-cant-set-currenttime
https://stackoverflow.com/questions/21956683/enable-access-control-on-simple-http-server
https://stackoverflow.com/questions/5052635/what-is-relation-between-content-length-and-byte-ranges-in-http-1-1
https://stackoverflow.com/questions/16725907/google-app-engine-serving-mp3-for-audio-element-needs-content-range-header
I was trying to use HTML5 audio tag to display audios like:
```html
<audio id="elem_audio" src="myfile.mp3" controls></audio>
```
![image](https://user-images.githubusercontent.com/5332158/79063321-565b5500-7c77-11ea-9f8d-6e1df6f07892.png)
But the progress bar seek was not working. After researching, I found the problem was the HTML server not properly responding to the HTML5 header requests. The HTML server should respond to quite complicated things as 206 partial, properly handle keep-alive, provide media ranges and other HTTP headers: https://stackoverflow.com/questions/37044064/html-audio-cant-set-currenttime
To implement all these on the Simple HTTP server would be quite complicated. Then, instead, I imported the `flask` web server, which is quite simple and straight forward to use. Now, the back-end is using a secure complaint HTTP back-end:
1. https://palletsprojects.com/p/flask/
> Flask is a lightweight WSGI web application framework. It is designed to make getting started quick and easy, with the ability to scale up to complex applications. It began as a simple wrapper around Werkzeug and Jinja and has become one of the most popular Python web application frameworks.
>
> Flask offers suggestions, but doesn't enforce any dependencies or project layout. It is up to the developer to choose the tools and libraries they want to use. There are many extensions provided by the community that make adding new functionality easy.
1. https://docs.pylonsproject.org/projects/waitress/en/latest/
> Waitress is meant to be a production-quality pure-Python WSGI server with very acceptable performance. It has no dependencies except ones which live in the Python standard library. It runs on CPython on Unix and Windows under Python 2.7+ and Python 3.5+. It is also known to run on PyPy 1.6.0 on UNIX. It supports HTTP/1.0 and HTTP/1.1.
Right now, anki does not support fields passing file names directly to HTML audio tags, but this can be easily done with (https://github.com/ankitects/anki/pull 540 - Added arguments to the sound tag) plus the commit https://github.com/evandroforks/anki/commit/826a97df61b99814041c41c0f2c84268280ed8ad, the HTML5 audio tag can be used like this:
```html
// Audio = [sound:myfile.mp3|onlyfilename]
<audio id="elem_audio" src="{{Audio}}" controls controlsList="nodownload"></audio>
```
![image](https://user-images.githubusercontent.com/5332158/79063736-c539ad80-7c79-11ea-8420-40b72185f4e7.png)
# Conflicts:
# qt/aqt/mediasrv.py
2020-04-29 12:38:35 +02:00
|
|
|
flask_cors.CORS(app)
|
2017-09-16 04:19:44 +02:00
|
|
|
|
2019-12-23 01:34:10 +01:00
|
|
|
|
2021-10-07 14:26:29 +02:00
|
|
|
@dataclass
|
|
|
|
class LocalFileRequest:
|
|
|
|
# base folder, eg media folder
|
|
|
|
root: str
|
|
|
|
# path to file relative to root folder
|
|
|
|
path: str
|
|
|
|
|
|
|
|
|
2021-10-14 13:48:50 +02:00
|
|
|
@dataclass
|
|
|
|
class BundledFileRequest:
|
|
|
|
# path relative to aqt data folder
|
|
|
|
path: str
|
|
|
|
|
|
|
|
|
2021-10-07 14:26:29 +02:00
|
|
|
@dataclass
|
|
|
|
class NotFound:
|
|
|
|
message: str
|
|
|
|
|
|
|
|
|
|
|
|
DynamicRequest = Callable[[], Response]
|
|
|
|
|
|
|
|
|
2017-08-08 04:55:30 +02:00
|
|
|
class MediaServer(threading.Thread):
|
2016-07-07 15:39:48 +02:00
|
|
|
|
2017-08-08 06:56:34 +02:00
|
|
|
_ready = threading.Event()
|
2019-04-29 06:36:44 +02:00
|
|
|
daemon = True
|
2017-08-08 06:56:34 +02:00
|
|
|
|
2021-02-02 15:00:29 +01:00
|
|
|
def __init__(self, mw: aqt.main.AnkiQt) -> None:
|
|
|
|
super().__init__()
|
Replaced the mediasrv.py SimpleHttp server by flask and waitress,
fixing HTML5 media support.
https://stackoverflow.com/questions/37044064/html-audio-cant-set-currenttime
https://stackoverflow.com/questions/21956683/enable-access-control-on-simple-http-server
https://stackoverflow.com/questions/5052635/what-is-relation-between-content-length-and-byte-ranges-in-http-1-1
https://stackoverflow.com/questions/16725907/google-app-engine-serving-mp3-for-audio-element-needs-content-range-header
I was trying to use HTML5 audio tag to display audios like:
```html
<audio id="elem_audio" src="myfile.mp3" controls></audio>
```
![image](https://user-images.githubusercontent.com/5332158/79063321-565b5500-7c77-11ea-9f8d-6e1df6f07892.png)
But the progress bar seek was not working. After researching, I found the problem was the HTML server not properly responding to the HTML5 header requests. The HTML server should respond to quite complicated things as 206 partial, properly handle keep-alive, provide media ranges and other HTTP headers: https://stackoverflow.com/questions/37044064/html-audio-cant-set-currenttime
To implement all these on the Simple HTTP server would be quite complicated. Then, instead, I imported the `flask` web server, which is quite simple and straight forward to use. Now, the back-end is using a secure complaint HTTP back-end:
1. https://palletsprojects.com/p/flask/
> Flask is a lightweight WSGI web application framework. It is designed to make getting started quick and easy, with the ability to scale up to complex applications. It began as a simple wrapper around Werkzeug and Jinja and has become one of the most popular Python web application frameworks.
>
> Flask offers suggestions, but doesn't enforce any dependencies or project layout. It is up to the developer to choose the tools and libraries they want to use. There are many extensions provided by the community that make adding new functionality easy.
1. https://docs.pylonsproject.org/projects/waitress/en/latest/
> Waitress is meant to be a production-quality pure-Python WSGI server with very acceptable performance. It has no dependencies except ones which live in the Python standard library. It runs on CPython on Unix and Windows under Python 2.7+ and Python 3.5+. It is also known to run on PyPy 1.6.0 on UNIX. It supports HTTP/1.0 and HTTP/1.1.
Right now, anki does not support fields passing file names directly to HTML audio tags, but this can be easily done with (https://github.com/ankitects/anki/pull 540 - Added arguments to the sound tag) plus the commit https://github.com/evandroforks/anki/commit/826a97df61b99814041c41c0f2c84268280ed8ad, the HTML5 audio tag can be used like this:
```html
// Audio = [sound:myfile.mp3|onlyfilename]
<audio id="elem_audio" src="{{Audio}}" controls controlsList="nodownload"></audio>
```
![image](https://user-images.githubusercontent.com/5332158/79063736-c539ad80-7c79-11ea-8420-40b72185f4e7.png)
# Conflicts:
# qt/aqt/mediasrv.py
2020-04-29 12:38:35 +02:00
|
|
|
self.is_shutdown = False
|
2021-10-07 14:23:00 +02:00
|
|
|
# map of webview ids to pages
|
|
|
|
self._page_html: dict[int, str] = {}
|
2019-02-26 13:07:06 +01:00
|
|
|
|
2021-02-01 14:28:21 +01:00
|
|
|
def run(self) -> None:
|
Replaced the mediasrv.py SimpleHttp server by flask and waitress,
fixing HTML5 media support.
https://stackoverflow.com/questions/37044064/html-audio-cant-set-currenttime
https://stackoverflow.com/questions/21956683/enable-access-control-on-simple-http-server
https://stackoverflow.com/questions/5052635/what-is-relation-between-content-length-and-byte-ranges-in-http-1-1
https://stackoverflow.com/questions/16725907/google-app-engine-serving-mp3-for-audio-element-needs-content-range-header
I was trying to use HTML5 audio tag to display audios like:
```html
<audio id="elem_audio" src="myfile.mp3" controls></audio>
```
![image](https://user-images.githubusercontent.com/5332158/79063321-565b5500-7c77-11ea-9f8d-6e1df6f07892.png)
But the progress bar seek was not working. After researching, I found the problem was the HTML server not properly responding to the HTML5 header requests. The HTML server should respond to quite complicated things as 206 partial, properly handle keep-alive, provide media ranges and other HTTP headers: https://stackoverflow.com/questions/37044064/html-audio-cant-set-currenttime
To implement all these on the Simple HTTP server would be quite complicated. Then, instead, I imported the `flask` web server, which is quite simple and straight forward to use. Now, the back-end is using a secure complaint HTTP back-end:
1. https://palletsprojects.com/p/flask/
> Flask is a lightweight WSGI web application framework. It is designed to make getting started quick and easy, with the ability to scale up to complex applications. It began as a simple wrapper around Werkzeug and Jinja and has become one of the most popular Python web application frameworks.
>
> Flask offers suggestions, but doesn't enforce any dependencies or project layout. It is up to the developer to choose the tools and libraries they want to use. There are many extensions provided by the community that make adding new functionality easy.
1. https://docs.pylonsproject.org/projects/waitress/en/latest/
> Waitress is meant to be a production-quality pure-Python WSGI server with very acceptable performance. It has no dependencies except ones which live in the Python standard library. It runs on CPython on Unix and Windows under Python 2.7+ and Python 3.5+. It is also known to run on PyPy 1.6.0 on UNIX. It supports HTTP/1.0 and HTTP/1.1.
Right now, anki does not support fields passing file names directly to HTML audio tags, but this can be easily done with (https://github.com/ankitects/anki/pull 540 - Added arguments to the sound tag) plus the commit https://github.com/evandroforks/anki/commit/826a97df61b99814041c41c0f2c84268280ed8ad, the HTML5 audio tag can be used like this:
```html
// Audio = [sound:myfile.mp3|onlyfilename]
<audio id="elem_audio" src="{{Audio}}" controls controlsList="nodownload"></audio>
```
![image](https://user-images.githubusercontent.com/5332158/79063736-c539ad80-7c79-11ea-8420-40b72185f4e7.png)
# Conflicts:
# qt/aqt/mediasrv.py
2020-04-29 12:38:35 +02:00
|
|
|
try:
|
|
|
|
if devMode:
|
|
|
|
# idempotent if logging has already been set up
|
|
|
|
logging.basicConfig()
|
2020-07-07 02:50:12 +02:00
|
|
|
logging.getLogger("waitress").setLevel(logging.ERROR)
|
Replaced the mediasrv.py SimpleHttp server by flask and waitress,
fixing HTML5 media support.
https://stackoverflow.com/questions/37044064/html-audio-cant-set-currenttime
https://stackoverflow.com/questions/21956683/enable-access-control-on-simple-http-server
https://stackoverflow.com/questions/5052635/what-is-relation-between-content-length-and-byte-ranges-in-http-1-1
https://stackoverflow.com/questions/16725907/google-app-engine-serving-mp3-for-audio-element-needs-content-range-header
I was trying to use HTML5 audio tag to display audios like:
```html
<audio id="elem_audio" src="myfile.mp3" controls></audio>
```
![image](https://user-images.githubusercontent.com/5332158/79063321-565b5500-7c77-11ea-9f8d-6e1df6f07892.png)
But the progress bar seek was not working. After researching, I found the problem was the HTML server not properly responding to the HTML5 header requests. The HTML server should respond to quite complicated things as 206 partial, properly handle keep-alive, provide media ranges and other HTTP headers: https://stackoverflow.com/questions/37044064/html-audio-cant-set-currenttime
To implement all these on the Simple HTTP server would be quite complicated. Then, instead, I imported the `flask` web server, which is quite simple and straight forward to use. Now, the back-end is using a secure complaint HTTP back-end:
1. https://palletsprojects.com/p/flask/
> Flask is a lightweight WSGI web application framework. It is designed to make getting started quick and easy, with the ability to scale up to complex applications. It began as a simple wrapper around Werkzeug and Jinja and has become one of the most popular Python web application frameworks.
>
> Flask offers suggestions, but doesn't enforce any dependencies or project layout. It is up to the developer to choose the tools and libraries they want to use. There are many extensions provided by the community that make adding new functionality easy.
1. https://docs.pylonsproject.org/projects/waitress/en/latest/
> Waitress is meant to be a production-quality pure-Python WSGI server with very acceptable performance. It has no dependencies except ones which live in the Python standard library. It runs on CPython on Unix and Windows under Python 2.7+ and Python 3.5+. It is also known to run on PyPy 1.6.0 on UNIX. It supports HTTP/1.0 and HTTP/1.1.
Right now, anki does not support fields passing file names directly to HTML audio tags, but this can be easily done with (https://github.com/ankitects/anki/pull 540 - Added arguments to the sound tag) plus the commit https://github.com/evandroforks/anki/commit/826a97df61b99814041c41c0f2c84268280ed8ad, the HTML5 audio tag can be used like this:
```html
// Audio = [sound:myfile.mp3|onlyfilename]
<audio id="elem_audio" src="{{Audio}}" controls controlsList="nodownload"></audio>
```
![image](https://user-images.githubusercontent.com/5332158/79063736-c539ad80-7c79-11ea-8420-40b72185f4e7.png)
# Conflicts:
# qt/aqt/mediasrv.py
2020-04-29 12:38:35 +02:00
|
|
|
|
2021-04-15 13:15:29 +02:00
|
|
|
desired_host = os.getenv("ANKI_API_HOST", "127.0.0.1")
|
2020-07-02 19:30:43 +02:00
|
|
|
desired_port = int(os.getenv("ANKI_API_PORT", "0"))
|
2020-12-16 06:09:30 +01:00
|
|
|
self.server = create_server(
|
|
|
|
app,
|
2021-04-15 13:15:29 +02:00
|
|
|
host=desired_host,
|
2020-12-16 06:09:30 +01:00
|
|
|
port=desired_port,
|
|
|
|
clear_untrusted_proxy_headers=True,
|
|
|
|
)
|
Replaced the mediasrv.py SimpleHttp server by flask and waitress,
fixing HTML5 media support.
https://stackoverflow.com/questions/37044064/html-audio-cant-set-currenttime
https://stackoverflow.com/questions/21956683/enable-access-control-on-simple-http-server
https://stackoverflow.com/questions/5052635/what-is-relation-between-content-length-and-byte-ranges-in-http-1-1
https://stackoverflow.com/questions/16725907/google-app-engine-serving-mp3-for-audio-element-needs-content-range-header
I was trying to use HTML5 audio tag to display audios like:
```html
<audio id="elem_audio" src="myfile.mp3" controls></audio>
```
![image](https://user-images.githubusercontent.com/5332158/79063321-565b5500-7c77-11ea-9f8d-6e1df6f07892.png)
But the progress bar seek was not working. After researching, I found the problem was the HTML server not properly responding to the HTML5 header requests. The HTML server should respond to quite complicated things as 206 partial, properly handle keep-alive, provide media ranges and other HTTP headers: https://stackoverflow.com/questions/37044064/html-audio-cant-set-currenttime
To implement all these on the Simple HTTP server would be quite complicated. Then, instead, I imported the `flask` web server, which is quite simple and straight forward to use. Now, the back-end is using a secure complaint HTTP back-end:
1. https://palletsprojects.com/p/flask/
> Flask is a lightweight WSGI web application framework. It is designed to make getting started quick and easy, with the ability to scale up to complex applications. It began as a simple wrapper around Werkzeug and Jinja and has become one of the most popular Python web application frameworks.
>
> Flask offers suggestions, but doesn't enforce any dependencies or project layout. It is up to the developer to choose the tools and libraries they want to use. There are many extensions provided by the community that make adding new functionality easy.
1. https://docs.pylonsproject.org/projects/waitress/en/latest/
> Waitress is meant to be a production-quality pure-Python WSGI server with very acceptable performance. It has no dependencies except ones which live in the Python standard library. It runs on CPython on Unix and Windows under Python 2.7+ and Python 3.5+. It is also known to run on PyPy 1.6.0 on UNIX. It supports HTTP/1.0 and HTTP/1.1.
Right now, anki does not support fields passing file names directly to HTML audio tags, but this can be easily done with (https://github.com/ankitects/anki/pull 540 - Added arguments to the sound tag) plus the commit https://github.com/evandroforks/anki/commit/826a97df61b99814041c41c0f2c84268280ed8ad, the HTML5 audio tag can be used like this:
```html
// Audio = [sound:myfile.mp3|onlyfilename]
<audio id="elem_audio" src="{{Audio}}" controls controlsList="nodownload"></audio>
```
![image](https://user-images.githubusercontent.com/5332158/79063736-c539ad80-7c79-11ea-8420-40b72185f4e7.png)
# Conflicts:
# qt/aqt/mediasrv.py
2020-04-29 12:38:35 +02:00
|
|
|
if devMode:
|
|
|
|
print(
|
|
|
|
"Serving on http://%s:%s"
|
2020-08-02 02:22:21 +02:00
|
|
|
% (self.server.effective_host, self.server.effective_port) # type: ignore
|
Replaced the mediasrv.py SimpleHttp server by flask and waitress,
fixing HTML5 media support.
https://stackoverflow.com/questions/37044064/html-audio-cant-set-currenttime
https://stackoverflow.com/questions/21956683/enable-access-control-on-simple-http-server
https://stackoverflow.com/questions/5052635/what-is-relation-between-content-length-and-byte-ranges-in-http-1-1
https://stackoverflow.com/questions/16725907/google-app-engine-serving-mp3-for-audio-element-needs-content-range-header
I was trying to use HTML5 audio tag to display audios like:
```html
<audio id="elem_audio" src="myfile.mp3" controls></audio>
```
![image](https://user-images.githubusercontent.com/5332158/79063321-565b5500-7c77-11ea-9f8d-6e1df6f07892.png)
But the progress bar seek was not working. After researching, I found the problem was the HTML server not properly responding to the HTML5 header requests. The HTML server should respond to quite complicated things as 206 partial, properly handle keep-alive, provide media ranges and other HTTP headers: https://stackoverflow.com/questions/37044064/html-audio-cant-set-currenttime
To implement all these on the Simple HTTP server would be quite complicated. Then, instead, I imported the `flask` web server, which is quite simple and straight forward to use. Now, the back-end is using a secure complaint HTTP back-end:
1. https://palletsprojects.com/p/flask/
> Flask is a lightweight WSGI web application framework. It is designed to make getting started quick and easy, with the ability to scale up to complex applications. It began as a simple wrapper around Werkzeug and Jinja and has become one of the most popular Python web application frameworks.
>
> Flask offers suggestions, but doesn't enforce any dependencies or project layout. It is up to the developer to choose the tools and libraries they want to use. There are many extensions provided by the community that make adding new functionality easy.
1. https://docs.pylonsproject.org/projects/waitress/en/latest/
> Waitress is meant to be a production-quality pure-Python WSGI server with very acceptable performance. It has no dependencies except ones which live in the Python standard library. It runs on CPython on Unix and Windows under Python 2.7+ and Python 3.5+. It is also known to run on PyPy 1.6.0 on UNIX. It supports HTTP/1.0 and HTTP/1.1.
Right now, anki does not support fields passing file names directly to HTML audio tags, but this can be easily done with (https://github.com/ankitects/anki/pull 540 - Added arguments to the sound tag) plus the commit https://github.com/evandroforks/anki/commit/826a97df61b99814041c41c0f2c84268280ed8ad, the HTML5 audio tag can be used like this:
```html
// Audio = [sound:myfile.mp3|onlyfilename]
<audio id="elem_audio" src="{{Audio}}" controls controlsList="nodownload"></audio>
```
![image](https://user-images.githubusercontent.com/5332158/79063736-c539ad80-7c79-11ea-8420-40b72185f4e7.png)
# Conflicts:
# qt/aqt/mediasrv.py
2020-04-29 12:38:35 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
self._ready.set()
|
|
|
|
self.server.run()
|
|
|
|
|
|
|
|
except Exception:
|
|
|
|
if not self.is_shutdown:
|
|
|
|
raise
|
|
|
|
|
2021-02-01 13:08:56 +01:00
|
|
|
def shutdown(self) -> None:
|
Replaced the mediasrv.py SimpleHttp server by flask and waitress,
fixing HTML5 media support.
https://stackoverflow.com/questions/37044064/html-audio-cant-set-currenttime
https://stackoverflow.com/questions/21956683/enable-access-control-on-simple-http-server
https://stackoverflow.com/questions/5052635/what-is-relation-between-content-length-and-byte-ranges-in-http-1-1
https://stackoverflow.com/questions/16725907/google-app-engine-serving-mp3-for-audio-element-needs-content-range-header
I was trying to use HTML5 audio tag to display audios like:
```html
<audio id="elem_audio" src="myfile.mp3" controls></audio>
```
![image](https://user-images.githubusercontent.com/5332158/79063321-565b5500-7c77-11ea-9f8d-6e1df6f07892.png)
But the progress bar seek was not working. After researching, I found the problem was the HTML server not properly responding to the HTML5 header requests. The HTML server should respond to quite complicated things as 206 partial, properly handle keep-alive, provide media ranges and other HTTP headers: https://stackoverflow.com/questions/37044064/html-audio-cant-set-currenttime
To implement all these on the Simple HTTP server would be quite complicated. Then, instead, I imported the `flask` web server, which is quite simple and straight forward to use. Now, the back-end is using a secure complaint HTTP back-end:
1. https://palletsprojects.com/p/flask/
> Flask is a lightweight WSGI web application framework. It is designed to make getting started quick and easy, with the ability to scale up to complex applications. It began as a simple wrapper around Werkzeug and Jinja and has become one of the most popular Python web application frameworks.
>
> Flask offers suggestions, but doesn't enforce any dependencies or project layout. It is up to the developer to choose the tools and libraries they want to use. There are many extensions provided by the community that make adding new functionality easy.
1. https://docs.pylonsproject.org/projects/waitress/en/latest/
> Waitress is meant to be a production-quality pure-Python WSGI server with very acceptable performance. It has no dependencies except ones which live in the Python standard library. It runs on CPython on Unix and Windows under Python 2.7+ and Python 3.5+. It is also known to run on PyPy 1.6.0 on UNIX. It supports HTTP/1.0 and HTTP/1.1.
Right now, anki does not support fields passing file names directly to HTML audio tags, but this can be easily done with (https://github.com/ankitects/anki/pull 540 - Added arguments to the sound tag) plus the commit https://github.com/evandroforks/anki/commit/826a97df61b99814041c41c0f2c84268280ed8ad, the HTML5 audio tag can be used like this:
```html
// Audio = [sound:myfile.mp3|onlyfilename]
<audio id="elem_audio" src="{{Audio}}" controls controlsList="nodownload"></audio>
```
![image](https://user-images.githubusercontent.com/5332158/79063736-c539ad80-7c79-11ea-8420-40b72185f4e7.png)
# Conflicts:
# qt/aqt/mediasrv.py
2020-04-29 12:38:35 +02:00
|
|
|
self.is_shutdown = True
|
2020-08-02 02:22:21 +02:00
|
|
|
sockets = list(self.server._map.values()) # type: ignore
|
Replaced the mediasrv.py SimpleHttp server by flask and waitress,
fixing HTML5 media support.
https://stackoverflow.com/questions/37044064/html-audio-cant-set-currenttime
https://stackoverflow.com/questions/21956683/enable-access-control-on-simple-http-server
https://stackoverflow.com/questions/5052635/what-is-relation-between-content-length-and-byte-ranges-in-http-1-1
https://stackoverflow.com/questions/16725907/google-app-engine-serving-mp3-for-audio-element-needs-content-range-header
I was trying to use HTML5 audio tag to display audios like:
```html
<audio id="elem_audio" src="myfile.mp3" controls></audio>
```
![image](https://user-images.githubusercontent.com/5332158/79063321-565b5500-7c77-11ea-9f8d-6e1df6f07892.png)
But the progress bar seek was not working. After researching, I found the problem was the HTML server not properly responding to the HTML5 header requests. The HTML server should respond to quite complicated things as 206 partial, properly handle keep-alive, provide media ranges and other HTTP headers: https://stackoverflow.com/questions/37044064/html-audio-cant-set-currenttime
To implement all these on the Simple HTTP server would be quite complicated. Then, instead, I imported the `flask` web server, which is quite simple and straight forward to use. Now, the back-end is using a secure complaint HTTP back-end:
1. https://palletsprojects.com/p/flask/
> Flask is a lightweight WSGI web application framework. It is designed to make getting started quick and easy, with the ability to scale up to complex applications. It began as a simple wrapper around Werkzeug and Jinja and has become one of the most popular Python web application frameworks.
>
> Flask offers suggestions, but doesn't enforce any dependencies or project layout. It is up to the developer to choose the tools and libraries they want to use. There are many extensions provided by the community that make adding new functionality easy.
1. https://docs.pylonsproject.org/projects/waitress/en/latest/
> Waitress is meant to be a production-quality pure-Python WSGI server with very acceptable performance. It has no dependencies except ones which live in the Python standard library. It runs on CPython on Unix and Windows under Python 2.7+ and Python 3.5+. It is also known to run on PyPy 1.6.0 on UNIX. It supports HTTP/1.0 and HTTP/1.1.
Right now, anki does not support fields passing file names directly to HTML audio tags, but this can be easily done with (https://github.com/ankitects/anki/pull 540 - Added arguments to the sound tag) plus the commit https://github.com/evandroforks/anki/commit/826a97df61b99814041c41c0f2c84268280ed8ad, the HTML5 audio tag can be used like this:
```html
// Audio = [sound:myfile.mp3|onlyfilename]
<audio id="elem_audio" src="{{Audio}}" controls controlsList="nodownload"></audio>
```
![image](https://user-images.githubusercontent.com/5332158/79063736-c539ad80-7c79-11ea-8420-40b72185f4e7.png)
# Conflicts:
# qt/aqt/mediasrv.py
2020-04-29 12:38:35 +02:00
|
|
|
for socket in sockets:
|
|
|
|
socket.handle_close()
|
|
|
|
# https://github.com/Pylons/webtest/blob/4b8a3ebf984185ff4fefb31b4d0cf82682e1fcf7/webtest/http.py#L93-L104
|
|
|
|
self.server.task_dispatcher.shutdown()
|
2016-07-07 15:39:48 +02:00
|
|
|
|
2021-02-01 13:08:56 +01:00
|
|
|
def getPort(self) -> int:
|
2017-08-08 06:56:34 +02:00
|
|
|
self._ready.wait()
|
2020-08-02 02:22:21 +02:00
|
|
|
return int(self.server.effective_port) # type: ignore
|
2017-08-08 06:56:34 +02:00
|
|
|
|
2021-10-07 14:23:00 +02:00
|
|
|
def set_page_html(self, id: int, html: str) -> None:
|
|
|
|
self._page_html[id] = html
|
|
|
|
|
|
|
|
def get_page_html(self, id: int) -> str | None:
|
|
|
|
return self._page_html.get(id)
|
|
|
|
|
|
|
|
def clear_page_html(self, id: int) -> None:
|
|
|
|
try:
|
|
|
|
del self._page_html[id]
|
|
|
|
except KeyError:
|
|
|
|
pass
|
|
|
|
|
2018-11-12 10:35:23 +01:00
|
|
|
|
2021-10-14 13:48:50 +02:00
|
|
|
def _mime_for_path(path: str) -> str:
|
|
|
|
"Mime type for provided path/filename."
|
|
|
|
if path.endswith(".css"):
|
|
|
|
# some users may have invalid mime type in the Windows registry
|
|
|
|
return "text/css"
|
|
|
|
elif path.endswith(".js"):
|
|
|
|
return "application/javascript"
|
|
|
|
else:
|
|
|
|
# autodetect
|
|
|
|
mime, _encoding = mimetypes.guess_type(path)
|
|
|
|
return mime or "application/octet-stream"
|
|
|
|
|
|
|
|
|
2021-10-07 14:26:29 +02:00
|
|
|
def _handle_local_file_request(request: LocalFileRequest) -> Response:
|
|
|
|
directory = request.root
|
|
|
|
path = request.path
|
Replaced the mediasrv.py SimpleHttp server by flask and waitress,
fixing HTML5 media support.
https://stackoverflow.com/questions/37044064/html-audio-cant-set-currenttime
https://stackoverflow.com/questions/21956683/enable-access-control-on-simple-http-server
https://stackoverflow.com/questions/5052635/what-is-relation-between-content-length-and-byte-ranges-in-http-1-1
https://stackoverflow.com/questions/16725907/google-app-engine-serving-mp3-for-audio-element-needs-content-range-header
I was trying to use HTML5 audio tag to display audios like:
```html
<audio id="elem_audio" src="myfile.mp3" controls></audio>
```
![image](https://user-images.githubusercontent.com/5332158/79063321-565b5500-7c77-11ea-9f8d-6e1df6f07892.png)
But the progress bar seek was not working. After researching, I found the problem was the HTML server not properly responding to the HTML5 header requests. The HTML server should respond to quite complicated things as 206 partial, properly handle keep-alive, provide media ranges and other HTTP headers: https://stackoverflow.com/questions/37044064/html-audio-cant-set-currenttime
To implement all these on the Simple HTTP server would be quite complicated. Then, instead, I imported the `flask` web server, which is quite simple and straight forward to use. Now, the back-end is using a secure complaint HTTP back-end:
1. https://palletsprojects.com/p/flask/
> Flask is a lightweight WSGI web application framework. It is designed to make getting started quick and easy, with the ability to scale up to complex applications. It began as a simple wrapper around Werkzeug and Jinja and has become one of the most popular Python web application frameworks.
>
> Flask offers suggestions, but doesn't enforce any dependencies or project layout. It is up to the developer to choose the tools and libraries they want to use. There are many extensions provided by the community that make adding new functionality easy.
1. https://docs.pylonsproject.org/projects/waitress/en/latest/
> Waitress is meant to be a production-quality pure-Python WSGI server with very acceptable performance. It has no dependencies except ones which live in the Python standard library. It runs on CPython on Unix and Windows under Python 2.7+ and Python 3.5+. It is also known to run on PyPy 1.6.0 on UNIX. It supports HTTP/1.0 and HTTP/1.1.
Right now, anki does not support fields passing file names directly to HTML audio tags, but this can be easily done with (https://github.com/ankitects/anki/pull 540 - Added arguments to the sound tag) plus the commit https://github.com/evandroforks/anki/commit/826a97df61b99814041c41c0f2c84268280ed8ad, the HTML5 audio tag can be used like this:
```html
// Audio = [sound:myfile.mp3|onlyfilename]
<audio id="elem_audio" src="{{Audio}}" controls controlsList="nodownload"></audio>
```
![image](https://user-images.githubusercontent.com/5332158/79063736-c539ad80-7c79-11ea-8420-40b72185f4e7.png)
# Conflicts:
# qt/aqt/mediasrv.py
2020-04-29 12:38:35 +02:00
|
|
|
try:
|
|
|
|
isdir = os.path.isdir(os.path.join(directory, path))
|
|
|
|
except ValueError:
|
2020-07-03 01:38:27 +02:00
|
|
|
return flask.make_response(
|
2021-02-11 01:09:06 +01:00
|
|
|
f"Path for '{directory} - {path}' is too long!",
|
2020-07-03 01:38:27 +02:00
|
|
|
HTTPStatus.BAD_REQUEST,
|
Replaced the mediasrv.py SimpleHttp server by flask and waitress,
fixing HTML5 media support.
https://stackoverflow.com/questions/37044064/html-audio-cant-set-currenttime
https://stackoverflow.com/questions/21956683/enable-access-control-on-simple-http-server
https://stackoverflow.com/questions/5052635/what-is-relation-between-content-length-and-byte-ranges-in-http-1-1
https://stackoverflow.com/questions/16725907/google-app-engine-serving-mp3-for-audio-element-needs-content-range-header
I was trying to use HTML5 audio tag to display audios like:
```html
<audio id="elem_audio" src="myfile.mp3" controls></audio>
```
![image](https://user-images.githubusercontent.com/5332158/79063321-565b5500-7c77-11ea-9f8d-6e1df6f07892.png)
But the progress bar seek was not working. After researching, I found the problem was the HTML server not properly responding to the HTML5 header requests. The HTML server should respond to quite complicated things as 206 partial, properly handle keep-alive, provide media ranges and other HTTP headers: https://stackoverflow.com/questions/37044064/html-audio-cant-set-currenttime
To implement all these on the Simple HTTP server would be quite complicated. Then, instead, I imported the `flask` web server, which is quite simple and straight forward to use. Now, the back-end is using a secure complaint HTTP back-end:
1. https://palletsprojects.com/p/flask/
> Flask is a lightweight WSGI web application framework. It is designed to make getting started quick and easy, with the ability to scale up to complex applications. It began as a simple wrapper around Werkzeug and Jinja and has become one of the most popular Python web application frameworks.
>
> Flask offers suggestions, but doesn't enforce any dependencies or project layout. It is up to the developer to choose the tools and libraries they want to use. There are many extensions provided by the community that make adding new functionality easy.
1. https://docs.pylonsproject.org/projects/waitress/en/latest/
> Waitress is meant to be a production-quality pure-Python WSGI server with very acceptable performance. It has no dependencies except ones which live in the Python standard library. It runs on CPython on Unix and Windows under Python 2.7+ and Python 3.5+. It is also known to run on PyPy 1.6.0 on UNIX. It supports HTTP/1.0 and HTTP/1.1.
Right now, anki does not support fields passing file names directly to HTML audio tags, but this can be easily done with (https://github.com/ankitects/anki/pull 540 - Added arguments to the sound tag) plus the commit https://github.com/evandroforks/anki/commit/826a97df61b99814041c41c0f2c84268280ed8ad, the HTML5 audio tag can be used like this:
```html
// Audio = [sound:myfile.mp3|onlyfilename]
<audio id="elem_audio" src="{{Audio}}" controls controlsList="nodownload"></audio>
```
![image](https://user-images.githubusercontent.com/5332158/79063736-c539ad80-7c79-11ea-8420-40b72185f4e7.png)
# Conflicts:
# qt/aqt/mediasrv.py
2020-04-29 12:38:35 +02:00
|
|
|
)
|
2018-11-12 10:35:23 +01:00
|
|
|
|
2020-06-19 00:58:39 +02:00
|
|
|
directory = os.path.realpath(directory)
|
|
|
|
path = os.path.normpath(path)
|
2020-07-11 02:53:41 +02:00
|
|
|
fullpath = os.path.abspath(os.path.join(directory, path))
|
2020-06-19 00:58:39 +02:00
|
|
|
|
|
|
|
# protect against directory transversal: https://security.openstack.org/guidelines/dg_using-file-paths.html
|
|
|
|
if not fullpath.startswith(directory):
|
2020-07-03 01:38:27 +02:00
|
|
|
return flask.make_response(
|
2021-02-11 01:09:06 +01:00
|
|
|
f"Path for '{directory} - {path}' is a security leak!",
|
2020-07-03 01:38:27 +02:00
|
|
|
HTTPStatus.FORBIDDEN,
|
2020-06-19 00:58:39 +02:00
|
|
|
)
|
|
|
|
|
Replaced the mediasrv.py SimpleHttp server by flask and waitress,
fixing HTML5 media support.
https://stackoverflow.com/questions/37044064/html-audio-cant-set-currenttime
https://stackoverflow.com/questions/21956683/enable-access-control-on-simple-http-server
https://stackoverflow.com/questions/5052635/what-is-relation-between-content-length-and-byte-ranges-in-http-1-1
https://stackoverflow.com/questions/16725907/google-app-engine-serving-mp3-for-audio-element-needs-content-range-header
I was trying to use HTML5 audio tag to display audios like:
```html
<audio id="elem_audio" src="myfile.mp3" controls></audio>
```
![image](https://user-images.githubusercontent.com/5332158/79063321-565b5500-7c77-11ea-9f8d-6e1df6f07892.png)
But the progress bar seek was not working. After researching, I found the problem was the HTML server not properly responding to the HTML5 header requests. The HTML server should respond to quite complicated things as 206 partial, properly handle keep-alive, provide media ranges and other HTTP headers: https://stackoverflow.com/questions/37044064/html-audio-cant-set-currenttime
To implement all these on the Simple HTTP server would be quite complicated. Then, instead, I imported the `flask` web server, which is quite simple and straight forward to use. Now, the back-end is using a secure complaint HTTP back-end:
1. https://palletsprojects.com/p/flask/
> Flask is a lightweight WSGI web application framework. It is designed to make getting started quick and easy, with the ability to scale up to complex applications. It began as a simple wrapper around Werkzeug and Jinja and has become one of the most popular Python web application frameworks.
>
> Flask offers suggestions, but doesn't enforce any dependencies or project layout. It is up to the developer to choose the tools and libraries they want to use. There are many extensions provided by the community that make adding new functionality easy.
1. https://docs.pylonsproject.org/projects/waitress/en/latest/
> Waitress is meant to be a production-quality pure-Python WSGI server with very acceptable performance. It has no dependencies except ones which live in the Python standard library. It runs on CPython on Unix and Windows under Python 2.7+ and Python 3.5+. It is also known to run on PyPy 1.6.0 on UNIX. It supports HTTP/1.0 and HTTP/1.1.
Right now, anki does not support fields passing file names directly to HTML audio tags, but this can be easily done with (https://github.com/ankitects/anki/pull 540 - Added arguments to the sound tag) plus the commit https://github.com/evandroforks/anki/commit/826a97df61b99814041c41c0f2c84268280ed8ad, the HTML5 audio tag can be used like this:
```html
// Audio = [sound:myfile.mp3|onlyfilename]
<audio id="elem_audio" src="{{Audio}}" controls controlsList="nodownload"></audio>
```
![image](https://user-images.githubusercontent.com/5332158/79063736-c539ad80-7c79-11ea-8420-40b72185f4e7.png)
# Conflicts:
# qt/aqt/mediasrv.py
2020-04-29 12:38:35 +02:00
|
|
|
if isdir:
|
2020-07-03 01:38:27 +02:00
|
|
|
return flask.make_response(
|
2021-02-11 01:09:06 +01:00
|
|
|
f"Path for '{directory} - {path}' is a directory (not supported)!",
|
2020-07-03 01:38:27 +02:00
|
|
|
HTTPStatus.FORBIDDEN,
|
2019-12-23 01:34:10 +01:00
|
|
|
)
|
2019-03-02 18:57:51 +01:00
|
|
|
|
2020-06-22 11:11:50 +02:00
|
|
|
try:
|
2021-10-14 13:48:50 +02:00
|
|
|
mimetype = _mime_for_path(fullpath)
|
2020-07-07 02:50:12 +02:00
|
|
|
if os.path.exists(fullpath):
|
|
|
|
return flask.send_file(fullpath, mimetype=mimetype, conditional=True)
|
|
|
|
else:
|
2021-10-07 14:26:29 +02:00
|
|
|
print(f"Not found: {path}")
|
2020-08-31 05:29:28 +02:00
|
|
|
return flask.make_response(
|
2021-10-07 14:26:29 +02:00
|
|
|
f"Invalid path: {path}",
|
2020-08-31 05:29:28 +02:00
|
|
|
HTTPStatus.NOT_FOUND,
|
|
|
|
)
|
Replaced the mediasrv.py SimpleHttp server by flask and waitress,
fixing HTML5 media support.
https://stackoverflow.com/questions/37044064/html-audio-cant-set-currenttime
https://stackoverflow.com/questions/21956683/enable-access-control-on-simple-http-server
https://stackoverflow.com/questions/5052635/what-is-relation-between-content-length-and-byte-ranges-in-http-1-1
https://stackoverflow.com/questions/16725907/google-app-engine-serving-mp3-for-audio-element-needs-content-range-header
I was trying to use HTML5 audio tag to display audios like:
```html
<audio id="elem_audio" src="myfile.mp3" controls></audio>
```
![image](https://user-images.githubusercontent.com/5332158/79063321-565b5500-7c77-11ea-9f8d-6e1df6f07892.png)
But the progress bar seek was not working. After researching, I found the problem was the HTML server not properly responding to the HTML5 header requests. The HTML server should respond to quite complicated things as 206 partial, properly handle keep-alive, provide media ranges and other HTTP headers: https://stackoverflow.com/questions/37044064/html-audio-cant-set-currenttime
To implement all these on the Simple HTTP server would be quite complicated. Then, instead, I imported the `flask` web server, which is quite simple and straight forward to use. Now, the back-end is using a secure complaint HTTP back-end:
1. https://palletsprojects.com/p/flask/
> Flask is a lightweight WSGI web application framework. It is designed to make getting started quick and easy, with the ability to scale up to complex applications. It began as a simple wrapper around Werkzeug and Jinja and has become one of the most popular Python web application frameworks.
>
> Flask offers suggestions, but doesn't enforce any dependencies or project layout. It is up to the developer to choose the tools and libraries they want to use. There are many extensions provided by the community that make adding new functionality easy.
1. https://docs.pylonsproject.org/projects/waitress/en/latest/
> Waitress is meant to be a production-quality pure-Python WSGI server with very acceptable performance. It has no dependencies except ones which live in the Python standard library. It runs on CPython on Unix and Windows under Python 2.7+ and Python 3.5+. It is also known to run on PyPy 1.6.0 on UNIX. It supports HTTP/1.0 and HTTP/1.1.
Right now, anki does not support fields passing file names directly to HTML audio tags, but this can be easily done with (https://github.com/ankitects/anki/pull 540 - Added arguments to the sound tag) plus the commit https://github.com/evandroforks/anki/commit/826a97df61b99814041c41c0f2c84268280ed8ad, the HTML5 audio tag can be used like this:
```html
// Audio = [sound:myfile.mp3|onlyfilename]
<audio id="elem_audio" src="{{Audio}}" controls controlsList="nodownload"></audio>
```
![image](https://user-images.githubusercontent.com/5332158/79063736-c539ad80-7c79-11ea-8420-40b72185f4e7.png)
# Conflicts:
# qt/aqt/mediasrv.py
2020-04-29 12:38:35 +02:00
|
|
|
|
|
|
|
except Exception as error:
|
|
|
|
if devMode:
|
|
|
|
print(
|
|
|
|
"Caught HTTP server exception,\n%s"
|
|
|
|
% "".join(traceback.format_exception(*sys.exc_info())),
|
|
|
|
)
|
|
|
|
|
|
|
|
# swallow it - user likely surfed away from
|
|
|
|
# review screen before an image had finished
|
|
|
|
# downloading
|
2020-08-31 05:29:28 +02:00
|
|
|
return flask.make_response(
|
|
|
|
str(error),
|
|
|
|
HTTPStatus.INTERNAL_SERVER_ERROR,
|
|
|
|
)
|
Replaced the mediasrv.py SimpleHttp server by flask and waitress,
fixing HTML5 media support.
https://stackoverflow.com/questions/37044064/html-audio-cant-set-currenttime
https://stackoverflow.com/questions/21956683/enable-access-control-on-simple-http-server
https://stackoverflow.com/questions/5052635/what-is-relation-between-content-length-and-byte-ranges-in-http-1-1
https://stackoverflow.com/questions/16725907/google-app-engine-serving-mp3-for-audio-element-needs-content-range-header
I was trying to use HTML5 audio tag to display audios like:
```html
<audio id="elem_audio" src="myfile.mp3" controls></audio>
```
![image](https://user-images.githubusercontent.com/5332158/79063321-565b5500-7c77-11ea-9f8d-6e1df6f07892.png)
But the progress bar seek was not working. After researching, I found the problem was the HTML server not properly responding to the HTML5 header requests. The HTML server should respond to quite complicated things as 206 partial, properly handle keep-alive, provide media ranges and other HTTP headers: https://stackoverflow.com/questions/37044064/html-audio-cant-set-currenttime
To implement all these on the Simple HTTP server would be quite complicated. Then, instead, I imported the `flask` web server, which is quite simple and straight forward to use. Now, the back-end is using a secure complaint HTTP back-end:
1. https://palletsprojects.com/p/flask/
> Flask is a lightweight WSGI web application framework. It is designed to make getting started quick and easy, with the ability to scale up to complex applications. It began as a simple wrapper around Werkzeug and Jinja and has become one of the most popular Python web application frameworks.
>
> Flask offers suggestions, but doesn't enforce any dependencies or project layout. It is up to the developer to choose the tools and libraries they want to use. There are many extensions provided by the community that make adding new functionality easy.
1. https://docs.pylonsproject.org/projects/waitress/en/latest/
> Waitress is meant to be a production-quality pure-Python WSGI server with very acceptable performance. It has no dependencies except ones which live in the Python standard library. It runs on CPython on Unix and Windows under Python 2.7+ and Python 3.5+. It is also known to run on PyPy 1.6.0 on UNIX. It supports HTTP/1.0 and HTTP/1.1.
Right now, anki does not support fields passing file names directly to HTML audio tags, but this can be easily done with (https://github.com/ankitects/anki/pull 540 - Added arguments to the sound tag) plus the commit https://github.com/evandroforks/anki/commit/826a97df61b99814041c41c0f2c84268280ed8ad, the HTML5 audio tag can be used like this:
```html
// Audio = [sound:myfile.mp3|onlyfilename]
<audio id="elem_audio" src="{{Audio}}" controls controlsList="nodownload"></audio>
```
![image](https://user-images.githubusercontent.com/5332158/79063736-c539ad80-7c79-11ea-8420-40b72185f4e7.png)
# Conflicts:
# qt/aqt/mediasrv.py
2020-04-29 12:38:35 +02:00
|
|
|
|
|
|
|
|
2021-10-14 13:48:50 +02:00
|
|
|
def _builtin_data(path: str) -> bytes:
|
|
|
|
"""Return data from file in aqt/data folder.
|
|
|
|
Path must use forward slash separators."""
|
|
|
|
# overriden location?
|
|
|
|
if data_folder := os.getenv("ANKI_DATA_FOLDER"):
|
|
|
|
full_path = os.path.join(data_folder, path)
|
|
|
|
with open(full_path, "rb") as f:
|
|
|
|
return f.read()
|
|
|
|
else:
|
2021-10-28 10:46:45 +02:00
|
|
|
if isWin and not getattr(sys, "frozen", False):
|
2021-10-14 13:48:50 +02:00
|
|
|
# default Python resource loader expects backslashes on Windows
|
|
|
|
path = path.replace("/", "\\")
|
|
|
|
reader = aqt.__loader__.get_resource_reader("aqt") # type: ignore
|
|
|
|
with reader.open_resource(path) as f:
|
|
|
|
return f.read()
|
|
|
|
|
|
|
|
|
|
|
|
def _handle_builtin_file_request(request: BundledFileRequest) -> Response:
|
|
|
|
path = request.path
|
|
|
|
mimetype = _mime_for_path(path)
|
|
|
|
data_path = f"data/web/{path}"
|
|
|
|
try:
|
|
|
|
data = _builtin_data(data_path)
|
|
|
|
return Response(data, mimetype=mimetype)
|
|
|
|
except FileNotFoundError:
|
|
|
|
return flask.make_response(
|
|
|
|
f"Invalid path: {path}",
|
|
|
|
HTTPStatus.NOT_FOUND,
|
|
|
|
)
|
|
|
|
except Exception as error:
|
|
|
|
if devMode:
|
|
|
|
print(
|
|
|
|
"Caught HTTP server exception,\n%s"
|
|
|
|
% "".join(traceback.format_exception(*sys.exc_info())),
|
|
|
|
)
|
|
|
|
|
|
|
|
# swallow it - user likely surfed away from
|
|
|
|
# review screen before an image had finished
|
|
|
|
# downloading
|
|
|
|
return flask.make_response(
|
|
|
|
str(error),
|
|
|
|
HTTPStatus.INTERNAL_SERVER_ERROR,
|
|
|
|
)
|
|
|
|
|
|
|
|
|
2021-10-07 14:26:29 +02:00
|
|
|
@app.route("/<path:pathin>", methods=["GET", "POST"])
|
|
|
|
def handle_request(pathin: str) -> Response:
|
|
|
|
request = _extract_request(pathin)
|
|
|
|
if devMode:
|
|
|
|
print(f"{time.time():.3f} {flask.request.method} /{pathin}")
|
|
|
|
|
|
|
|
if isinstance(request, NotFound):
|
|
|
|
print(request.message)
|
|
|
|
return flask.make_response(
|
|
|
|
f"Invalid path: {pathin}",
|
|
|
|
HTTPStatus.NOT_FOUND,
|
|
|
|
)
|
|
|
|
elif callable(request):
|
|
|
|
return _handle_dynamic_request(request)
|
2021-10-14 13:48:50 +02:00
|
|
|
elif isinstance(request, BundledFileRequest):
|
|
|
|
return _handle_builtin_file_request(request)
|
2021-10-07 14:26:29 +02:00
|
|
|
elif isinstance(request, LocalFileRequest):
|
|
|
|
return _handle_local_file_request(request)
|
|
|
|
else:
|
|
|
|
return flask.make_response(
|
|
|
|
f"unexpected request: {pathin}",
|
|
|
|
HTTPStatus.FORBIDDEN,
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
def _extract_internal_request(
|
|
|
|
path: str,
|
2021-10-14 13:48:50 +02:00
|
|
|
) -> BundledFileRequest | DynamicRequest | NotFound | None:
|
2021-10-07 14:26:29 +02:00
|
|
|
"Catch /_anki references and rewrite them to web export folder."
|
|
|
|
prefix = "_anki/"
|
|
|
|
if not path.startswith(prefix):
|
|
|
|
return None
|
|
|
|
|
|
|
|
dirname = os.path.dirname(path)
|
|
|
|
filename = os.path.basename(path)
|
|
|
|
additional_prefix = None
|
2020-11-01 05:26:58 +01:00
|
|
|
|
2021-10-07 14:26:29 +02:00
|
|
|
if dirname == "_anki":
|
|
|
|
if flask.request.method == "POST":
|
|
|
|
return _extract_collection_post_request(filename)
|
2021-10-07 14:23:00 +02:00
|
|
|
elif get_handler := _extract_dynamic_get_request(filename):
|
|
|
|
return get_handler
|
2021-10-14 13:48:50 +02:00
|
|
|
|
2020-11-01 05:26:58 +01:00
|
|
|
# remap legacy top-level references
|
2021-10-07 14:26:29 +02:00
|
|
|
base, ext = os.path.splitext(filename)
|
|
|
|
if ext == ".css":
|
|
|
|
additional_prefix = "css/"
|
|
|
|
elif ext == ".js":
|
|
|
|
if base in ("browsersel", "jquery-ui", "jquery", "plot"):
|
|
|
|
additional_prefix = "js/vendor/"
|
|
|
|
else:
|
|
|
|
additional_prefix = "js/"
|
|
|
|
# handle requests for vendored libraries
|
|
|
|
elif dirname == "_anki/js/vendor":
|
|
|
|
base, ext = os.path.splitext(filename)
|
Replaced the mediasrv.py SimpleHttp server by flask and waitress,
fixing HTML5 media support.
https://stackoverflow.com/questions/37044064/html-audio-cant-set-currenttime
https://stackoverflow.com/questions/21956683/enable-access-control-on-simple-http-server
https://stackoverflow.com/questions/5052635/what-is-relation-between-content-length-and-byte-ranges-in-http-1-1
https://stackoverflow.com/questions/16725907/google-app-engine-serving-mp3-for-audio-element-needs-content-range-header
I was trying to use HTML5 audio tag to display audios like:
```html
<audio id="elem_audio" src="myfile.mp3" controls></audio>
```
![image](https://user-images.githubusercontent.com/5332158/79063321-565b5500-7c77-11ea-9f8d-6e1df6f07892.png)
But the progress bar seek was not working. After researching, I found the problem was the HTML server not properly responding to the HTML5 header requests. The HTML server should respond to quite complicated things as 206 partial, properly handle keep-alive, provide media ranges and other HTTP headers: https://stackoverflow.com/questions/37044064/html-audio-cant-set-currenttime
To implement all these on the Simple HTTP server would be quite complicated. Then, instead, I imported the `flask` web server, which is quite simple and straight forward to use. Now, the back-end is using a secure complaint HTTP back-end:
1. https://palletsprojects.com/p/flask/
> Flask is a lightweight WSGI web application framework. It is designed to make getting started quick and easy, with the ability to scale up to complex applications. It began as a simple wrapper around Werkzeug and Jinja and has become one of the most popular Python web application frameworks.
>
> Flask offers suggestions, but doesn't enforce any dependencies or project layout. It is up to the developer to choose the tools and libraries they want to use. There are many extensions provided by the community that make adding new functionality easy.
1. https://docs.pylonsproject.org/projects/waitress/en/latest/
> Waitress is meant to be a production-quality pure-Python WSGI server with very acceptable performance. It has no dependencies except ones which live in the Python standard library. It runs on CPython on Unix and Windows under Python 2.7+ and Python 3.5+. It is also known to run on PyPy 1.6.0 on UNIX. It supports HTTP/1.0 and HTTP/1.1.
Right now, anki does not support fields passing file names directly to HTML audio tags, but this can be easily done with (https://github.com/ankitects/anki/pull 540 - Added arguments to the sound tag) plus the commit https://github.com/evandroforks/anki/commit/826a97df61b99814041c41c0f2c84268280ed8ad, the HTML5 audio tag can be used like this:
```html
// Audio = [sound:myfile.mp3|onlyfilename]
<audio id="elem_audio" src="{{Audio}}" controls controlsList="nodownload"></audio>
```
![image](https://user-images.githubusercontent.com/5332158/79063736-c539ad80-7c79-11ea-8420-40b72185f4e7.png)
# Conflicts:
# qt/aqt/mediasrv.py
2020-04-29 12:38:35 +02:00
|
|
|
|
2021-10-07 14:26:29 +02:00
|
|
|
if base == "jquery":
|
|
|
|
base = "jquery.min"
|
|
|
|
additional_prefix = "js/vendor/"
|
Replaced the mediasrv.py SimpleHttp server by flask and waitress,
fixing HTML5 media support.
https://stackoverflow.com/questions/37044064/html-audio-cant-set-currenttime
https://stackoverflow.com/questions/21956683/enable-access-control-on-simple-http-server
https://stackoverflow.com/questions/5052635/what-is-relation-between-content-length-and-byte-ranges-in-http-1-1
https://stackoverflow.com/questions/16725907/google-app-engine-serving-mp3-for-audio-element-needs-content-range-header
I was trying to use HTML5 audio tag to display audios like:
```html
<audio id="elem_audio" src="myfile.mp3" controls></audio>
```
![image](https://user-images.githubusercontent.com/5332158/79063321-565b5500-7c77-11ea-9f8d-6e1df6f07892.png)
But the progress bar seek was not working. After researching, I found the problem was the HTML server not properly responding to the HTML5 header requests. The HTML server should respond to quite complicated things as 206 partial, properly handle keep-alive, provide media ranges and other HTTP headers: https://stackoverflow.com/questions/37044064/html-audio-cant-set-currenttime
To implement all these on the Simple HTTP server would be quite complicated. Then, instead, I imported the `flask` web server, which is quite simple and straight forward to use. Now, the back-end is using a secure complaint HTTP back-end:
1. https://palletsprojects.com/p/flask/
> Flask is a lightweight WSGI web application framework. It is designed to make getting started quick and easy, with the ability to scale up to complex applications. It began as a simple wrapper around Werkzeug and Jinja and has become one of the most popular Python web application frameworks.
>
> Flask offers suggestions, but doesn't enforce any dependencies or project layout. It is up to the developer to choose the tools and libraries they want to use. There are many extensions provided by the community that make adding new functionality easy.
1. https://docs.pylonsproject.org/projects/waitress/en/latest/
> Waitress is meant to be a production-quality pure-Python WSGI server with very acceptable performance. It has no dependencies except ones which live in the Python standard library. It runs on CPython on Unix and Windows under Python 2.7+ and Python 3.5+. It is also known to run on PyPy 1.6.0 on UNIX. It supports HTTP/1.0 and HTTP/1.1.
Right now, anki does not support fields passing file names directly to HTML audio tags, but this can be easily done with (https://github.com/ankitects/anki/pull 540 - Added arguments to the sound tag) plus the commit https://github.com/evandroforks/anki/commit/826a97df61b99814041c41c0f2c84268280ed8ad, the HTML5 audio tag can be used like this:
```html
// Audio = [sound:myfile.mp3|onlyfilename]
<audio id="elem_audio" src="{{Audio}}" controls controlsList="nodownload"></audio>
```
![image](https://user-images.githubusercontent.com/5332158/79063736-c539ad80-7c79-11ea-8420-40b72185f4e7.png)
# Conflicts:
# qt/aqt/mediasrv.py
2020-04-29 12:38:35 +02:00
|
|
|
|
2021-10-07 14:26:29 +02:00
|
|
|
elif base == "jquery-ui":
|
|
|
|
base = "jquery-ui.min"
|
|
|
|
additional_prefix = "js/vendor/"
|
|
|
|
|
|
|
|
elif base == "browsersel":
|
|
|
|
base = "css_browser_selector.min"
|
|
|
|
additional_prefix = "js/vendor/"
|
Replaced the mediasrv.py SimpleHttp server by flask and waitress,
fixing HTML5 media support.
https://stackoverflow.com/questions/37044064/html-audio-cant-set-currenttime
https://stackoverflow.com/questions/21956683/enable-access-control-on-simple-http-server
https://stackoverflow.com/questions/5052635/what-is-relation-between-content-length-and-byte-ranges-in-http-1-1
https://stackoverflow.com/questions/16725907/google-app-engine-serving-mp3-for-audio-element-needs-content-range-header
I was trying to use HTML5 audio tag to display audios like:
```html
<audio id="elem_audio" src="myfile.mp3" controls></audio>
```
![image](https://user-images.githubusercontent.com/5332158/79063321-565b5500-7c77-11ea-9f8d-6e1df6f07892.png)
But the progress bar seek was not working. After researching, I found the problem was the HTML server not properly responding to the HTML5 header requests. The HTML server should respond to quite complicated things as 206 partial, properly handle keep-alive, provide media ranges and other HTTP headers: https://stackoverflow.com/questions/37044064/html-audio-cant-set-currenttime
To implement all these on the Simple HTTP server would be quite complicated. Then, instead, I imported the `flask` web server, which is quite simple and straight forward to use. Now, the back-end is using a secure complaint HTTP back-end:
1. https://palletsprojects.com/p/flask/
> Flask is a lightweight WSGI web application framework. It is designed to make getting started quick and easy, with the ability to scale up to complex applications. It began as a simple wrapper around Werkzeug and Jinja and has become one of the most popular Python web application frameworks.
>
> Flask offers suggestions, but doesn't enforce any dependencies or project layout. It is up to the developer to choose the tools and libraries they want to use. There are many extensions provided by the community that make adding new functionality easy.
1. https://docs.pylonsproject.org/projects/waitress/en/latest/
> Waitress is meant to be a production-quality pure-Python WSGI server with very acceptable performance. It has no dependencies except ones which live in the Python standard library. It runs on CPython on Unix and Windows under Python 2.7+ and Python 3.5+. It is also known to run on PyPy 1.6.0 on UNIX. It supports HTTP/1.0 and HTTP/1.1.
Right now, anki does not support fields passing file names directly to HTML audio tags, but this can be easily done with (https://github.com/ankitects/anki/pull 540 - Added arguments to the sound tag) plus the commit https://github.com/evandroforks/anki/commit/826a97df61b99814041c41c0f2c84268280ed8ad, the HTML5 audio tag can be used like this:
```html
// Audio = [sound:myfile.mp3|onlyfilename]
<audio id="elem_audio" src="{{Audio}}" controls controlsList="nodownload"></audio>
```
![image](https://user-images.githubusercontent.com/5332158/79063736-c539ad80-7c79-11ea-8420-40b72185f4e7.png)
# Conflicts:
# qt/aqt/mediasrv.py
2020-04-29 12:38:35 +02:00
|
|
|
|
2021-10-07 14:26:29 +02:00
|
|
|
if additional_prefix:
|
|
|
|
oldpath = path
|
|
|
|
path = f"{prefix}{additional_prefix}{base}{ext}"
|
|
|
|
print(f"legacy {oldpath} remapped to {path}")
|
2020-06-26 02:42:10 +02:00
|
|
|
|
2021-10-14 13:48:50 +02:00
|
|
|
return BundledFileRequest(path=path[len(prefix) :])
|
2019-12-23 01:34:10 +01:00
|
|
|
|
2021-10-07 14:26:29 +02:00
|
|
|
|
|
|
|
def _extract_addon_request(path: str) -> LocalFileRequest | NotFound | None:
|
|
|
|
"Catch /_addons references and rewrite them to addons folder."
|
|
|
|
prefix = "_addons/"
|
|
|
|
if not path.startswith(prefix):
|
2020-08-04 01:54:17 +02:00
|
|
|
return None
|
|
|
|
|
2021-10-07 14:26:29 +02:00
|
|
|
addon_path = path[len(prefix) :]
|
|
|
|
|
|
|
|
try:
|
|
|
|
manager = aqt.mw.addonManager
|
|
|
|
except AttributeError as error:
|
|
|
|
if devMode:
|
|
|
|
print(f"_redirectWebExports: {error}")
|
2020-08-04 01:54:17 +02:00
|
|
|
return None
|
|
|
|
|
2021-10-07 14:26:29 +02:00
|
|
|
try:
|
|
|
|
addon, sub_path = addon_path.split("/", 1)
|
|
|
|
except ValueError:
|
|
|
|
return None
|
|
|
|
if not addon:
|
|
|
|
return None
|
2020-11-09 10:45:14 +01:00
|
|
|
|
2021-10-07 14:26:29 +02:00
|
|
|
pattern = manager.getWebExports(addon)
|
|
|
|
if not pattern:
|
|
|
|
return None
|
|
|
|
|
|
|
|
if re.fullmatch(pattern, sub_path):
|
|
|
|
return LocalFileRequest(root=manager.addonsFolder(), path=addon_path)
|
|
|
|
|
|
|
|
return NotFound(message=f"couldn't locate item in add-on folder {path}")
|
|
|
|
|
|
|
|
|
2021-10-14 13:48:50 +02:00
|
|
|
def _extract_request(
|
|
|
|
path: str,
|
|
|
|
) -> LocalFileRequest | BundledFileRequest | DynamicRequest | NotFound:
|
2021-10-07 14:26:29 +02:00
|
|
|
if internal := _extract_internal_request(path):
|
|
|
|
return internal
|
|
|
|
elif addon := _extract_addon_request(path):
|
|
|
|
return addon
|
|
|
|
|
|
|
|
if not aqt.mw.col:
|
|
|
|
return NotFound(message=f"collection not open, ignore request for {path}")
|
|
|
|
|
|
|
|
path = hooks.media_file_filter(path)
|
|
|
|
return LocalFileRequest(root=aqt.mw.col.media.dir(), path=path)
|
2020-07-02 19:30:43 +02:00
|
|
|
|
|
|
|
|
2020-08-27 13:46:34 +02:00
|
|
|
def graph_data() -> bytes:
|
|
|
|
args = from_json_bytes(request.data)
|
2021-01-31 06:55:08 +01:00
|
|
|
return aqt.mw.col.graph_data(search=args["search"], days=args["days"])
|
2020-08-27 13:46:34 +02:00
|
|
|
|
|
|
|
|
2021-01-22 20:05:28 +01:00
|
|
|
def graph_preferences() -> bytes:
|
2021-01-31 06:55:08 +01:00
|
|
|
return aqt.mw.col.get_graph_preferences()
|
2021-01-21 03:25:14 +01:00
|
|
|
|
|
|
|
|
2021-01-22 14:37:24 +01:00
|
|
|
def set_graph_preferences() -> None:
|
2021-01-31 06:55:08 +01:00
|
|
|
prefs = GraphPreferences()
|
|
|
|
prefs.ParseFromString(request.data)
|
|
|
|
aqt.mw.col.set_graph_preferences(prefs)
|
2021-01-21 16:16:58 +01:00
|
|
|
|
|
|
|
|
2020-08-27 13:46:34 +02:00
|
|
|
def congrats_info() -> bytes:
|
2021-08-02 08:05:18 +02:00
|
|
|
if not aqt.mw.col.sched._is_finished():
|
|
|
|
aqt.mw.taskman.run_on_main(lambda: aqt.mw.moveToState("review"))
|
2021-01-31 06:55:08 +01:00
|
|
|
return aqt.mw.col.congrats_info()
|
2020-08-27 13:46:34 +02:00
|
|
|
|
|
|
|
|
2021-03-26 12:22:37 +01:00
|
|
|
def i18n_resources() -> bytes:
|
|
|
|
args = from_json_bytes(request.data)
|
|
|
|
return aqt.mw.col.i18n_resources(modules=args["modules"])
|
|
|
|
|
|
|
|
|
2021-04-18 03:56:41 +02:00
|
|
|
def deck_configs_for_update() -> bytes:
|
2021-04-12 06:18:30 +02:00
|
|
|
args = from_json_bytes(request.data)
|
2021-05-19 08:20:25 +02:00
|
|
|
msg = aqt.mw.col.decks.get_deck_configs_for_update(deck_id=args["deckId"])
|
|
|
|
msg.have_addons = aqt.mw.addonManager.dirty
|
|
|
|
return msg.SerializeToString()
|
2021-04-12 06:18:30 +02:00
|
|
|
|
|
|
|
|
2021-04-20 11:50:05 +02:00
|
|
|
def update_deck_configs_request() -> bytes:
|
|
|
|
# the regular change tracking machinery expects to be started on the main
|
|
|
|
# thread and uses a callback on success, so we need to run this op on
|
|
|
|
# main, and return immediately from the web request
|
|
|
|
|
|
|
|
input = UpdateDeckConfigs()
|
|
|
|
input.ParseFromString(request.data)
|
|
|
|
|
|
|
|
def on_success(changes: OpChanges) -> None:
|
2021-04-22 02:55:32 +02:00
|
|
|
if isinstance(window := aqt.mw.app.activeWindow(), DeckOptionsDialog):
|
|
|
|
window.reject()
|
2021-04-20 11:50:05 +02:00
|
|
|
|
|
|
|
def handle_on_main() -> None:
|
|
|
|
update_deck_configs(parent=aqt.mw, input=input).success(
|
|
|
|
on_success
|
|
|
|
).run_in_background()
|
|
|
|
|
|
|
|
aqt.mw.taskman.run_on_main(handle_on_main)
|
|
|
|
return b""
|
|
|
|
|
|
|
|
|
2021-05-17 08:59:02 +02:00
|
|
|
def next_card_states() -> bytes:
|
|
|
|
if states := aqt.mw.reviewer.get_next_states():
|
|
|
|
return states.SerializeToString()
|
|
|
|
else:
|
|
|
|
return b""
|
|
|
|
|
|
|
|
|
|
|
|
def set_next_card_states() -> bytes:
|
|
|
|
key = request.headers.get("key", "")
|
|
|
|
input = NextStates()
|
|
|
|
input.ParseFromString(request.data)
|
|
|
|
aqt.mw.reviewer.set_next_states(key, input)
|
|
|
|
return b""
|
|
|
|
|
|
|
|
|
2021-06-10 13:30:39 +02:00
|
|
|
def notetype_names() -> bytes:
|
|
|
|
msg = NotetypeNames(entries=aqt.mw.col.models.all_names_and_ids())
|
|
|
|
return msg.SerializeToString()
|
|
|
|
|
|
|
|
|
|
|
|
def change_notetype_info() -> bytes:
|
|
|
|
args = from_json_bytes(request.data)
|
|
|
|
return aqt.mw.col.models.change_notetype_info(
|
|
|
|
old_notetype_id=args["oldNotetypeId"], new_notetype_id=args["newNotetypeId"]
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
def change_notetype() -> bytes:
|
|
|
|
data = request.data
|
|
|
|
|
|
|
|
def handle_on_main() -> None:
|
|
|
|
window = aqt.mw.app.activeWindow()
|
|
|
|
if isinstance(window, ChangeNotetypeDialog):
|
|
|
|
window.save(data)
|
|
|
|
|
|
|
|
aqt.mw.taskman.run_on_main(handle_on_main)
|
|
|
|
return b""
|
|
|
|
|
|
|
|
|
2021-09-08 09:22:30 +02:00
|
|
|
def complete_tag() -> bytes:
|
|
|
|
return aqt.mw.col.tags.complete_tag(request.data)
|
|
|
|
|
|
|
|
|
2021-10-14 11:22:47 +02:00
|
|
|
def card_stats() -> bytes:
|
2021-10-14 11:10:06 +02:00
|
|
|
args = from_json_bytes(request.data)
|
|
|
|
return aqt.mw.col.card_stats_data(CardId(args["cardId"]))
|
2021-10-14 11:22:47 +02:00
|
|
|
|
|
|
|
|
2021-10-07 14:23:00 +02:00
|
|
|
# these require a collection
|
2021-01-22 14:37:24 +01:00
|
|
|
post_handlers = {
|
|
|
|
"graphData": graph_data,
|
|
|
|
"graphPreferences": graph_preferences,
|
|
|
|
"setGraphPreferences": set_graph_preferences,
|
2021-04-18 03:56:41 +02:00
|
|
|
"deckConfigsForUpdate": deck_configs_for_update,
|
2021-04-20 11:50:05 +02:00
|
|
|
"updateDeckConfigs": update_deck_configs_request,
|
2021-05-17 08:59:02 +02:00
|
|
|
"nextCardStates": next_card_states,
|
|
|
|
"setNextCardStates": set_next_card_states,
|
2021-06-10 13:30:39 +02:00
|
|
|
"changeNotetypeInfo": change_notetype_info,
|
|
|
|
"notetypeNames": notetype_names,
|
|
|
|
"changeNotetype": change_notetype,
|
2021-03-26 12:22:37 +01:00
|
|
|
"i18nResources": i18n_resources,
|
2021-01-22 14:37:24 +01:00
|
|
|
"congratsInfo": congrats_info,
|
2021-09-08 09:22:30 +02:00
|
|
|
"completeTag": complete_tag,
|
2021-10-14 11:22:47 +02:00
|
|
|
"cardStats": card_stats,
|
2021-01-22 14:37:24 +01:00
|
|
|
}
|
2020-08-27 13:46:34 +02:00
|
|
|
|
|
|
|
|
2021-10-07 14:26:29 +02:00
|
|
|
def _extract_collection_post_request(path: str) -> DynamicRequest | NotFound:
|
2020-08-27 13:46:34 +02:00
|
|
|
if not aqt.mw.col:
|
2021-10-07 14:26:29 +02:00
|
|
|
return NotFound(message=f"collection not open, ignore request for {path}")
|
|
|
|
if handler := post_handlers.get(path):
|
|
|
|
# convert bytes/None into response
|
|
|
|
def wrapped() -> Response:
|
|
|
|
if data := handler():
|
2021-01-29 05:37:29 +01:00
|
|
|
response = flask.make_response(data)
|
|
|
|
response.headers["Content-Type"] = "application/binary"
|
|
|
|
else:
|
|
|
|
response = flask.make_response("", HTTPStatus.NO_CONTENT)
|
2021-10-07 14:26:29 +02:00
|
|
|
return response
|
|
|
|
|
|
|
|
return wrapped
|
2020-08-27 13:46:34 +02:00
|
|
|
else:
|
2021-10-07 14:26:29 +02:00
|
|
|
return NotFound(message=f"{path} not found")
|
2021-01-22 14:37:24 +01:00
|
|
|
|
2021-10-07 14:26:29 +02:00
|
|
|
|
|
|
|
def _handle_dynamic_request(request: DynamicRequest) -> Response:
|
|
|
|
try:
|
|
|
|
return request()
|
|
|
|
except Exception as e:
|
|
|
|
return flask.make_response(str(e), HTTPStatus.INTERNAL_SERVER_ERROR)
|
2021-10-07 14:23:00 +02:00
|
|
|
|
|
|
|
|
|
|
|
def legacy_page_data() -> Response:
|
|
|
|
id = int(request.args["id"])
|
|
|
|
if html := aqt.mw.mediaServer.get_page_html(id):
|
|
|
|
return Response(html, mimetype="text/html")
|
|
|
|
else:
|
|
|
|
return flask.make_response("page not found", HTTPStatus.NOT_FOUND)
|
|
|
|
|
|
|
|
|
|
|
|
# this currently only handles a single method; in the future, idempotent
|
|
|
|
# requests like i18nResources should probably be moved here
|
|
|
|
def _extract_dynamic_get_request(path: str) -> DynamicRequest | None:
|
|
|
|
if path == "legacyPageData":
|
|
|
|
return legacy_page_data
|
|
|
|
else:
|
|
|
|
return None
|