0

I have a flask page that auto-updates from a log file:

@app.route('/console-refresh')
def refresh():
    global previouscontent
    previouscontent = ""
    def generate_response():
        global previouscontent
        with open("logfile", "r") as f:
            while True:
                f.seek(0)
                content = f.read()
                if content.find(previouscontent) != 0:
                    yield "\b" * len(previouscontent)
                    previouscontent = ""
                yield content[len(previouscontent):]
                previouscontent = content
                sleep(1)
    return app.response_class(generate_response(), mimetype="text/plain")

The line yield "\b" * len(previouscontent) is intended to clear the output. With a print it works, but when I try to use it in my flask page, it shows this.

What is the HTML equivalent of \b?

Else how do I clear the yield output?

Thanks

Solution:

class RefreshHandler:
    def __init__(self):
        self.previous_content = ""

    def generate_response(self):
        while True:
            with open("logfile", "r") as f:
                content = f.read()
                if content.find(self.previous_content) != 0:
                    yield '<meta http-equiv = "refresh" content = "0">'
                    return
                yield content[len(self.previous_content):]
                self.previous_content = content
                sleep(1)


@app.route('/console-refresh')
def refresh():
    return app.response_class(RefreshHandler().generate_response(), mimetype="text/html")

RefreshHandler().generate_response() is where you add your yields. Each time there is a yield string, it is added to the output. To restart from the beginnning, the block

                    yield '<meta http-equiv = "refresh" content = "0">'
                    return

will refresh the page on the client side and end the stream.

Unfortunately there is still a problem: How to add this to another html page without JavaScript?

Elevator9253
  • 61
  • 1
  • 9
  • Is you intention to show always the entire file and update as it grows, or only the last second? – bereal Sep 03 '21 at 12:32
  • I want to be able to see the logfile as it was in the last second. It's basically my way of making an alternative to auto refreshing. – Elevator9253 Sep 03 '21 at 12:40
  • Then I don't understand, why do you want to erase the past lines? – bereal Sep 03 '21 at 12:48
  • If the log file gets cleared (which is going to happen), I want the view to restart from the beginning and not to continue the previous log. – Elevator9253 Sep 03 '21 at 12:57
  • 1
    Ah I see. I'm afraid, once you yield anything, there's no takesies backsies. You'll have to force page cleanup or reload on the client side with JS somehow. (The task sounds like a nice exercise with WebSockets.) – bereal Sep 03 '21 at 13:04
  • Isn't it possible to answer to the client with the stream, and THEN a redirection so that the output can be cleared? – Elevator9253 Sep 04 '21 at 10:37
  • Server-side redirection happens via HTTP headers, and by the time the streaming starts, they are already sent. So, I don't think there's a way to do that without support on the client side. – bereal Sep 04 '21 at 11:05
  • 1
    I found the way: I use `yield ''` and then `return` when I want to restart from the beginning. It takes more than half a second but at least it's a way to do it. I also changed `mimetype` to `text/html` in the return. – Elevator9253 Sep 04 '21 at 11:10
  • If `text/html` is ok for you, you can wipe the entire page without reloading it by sending e.g. ``; – bereal Sep 04 '21 at 16:04
  • But that uses javascript... The idea was to find something JS-free. – Elevator9253 Sep 05 '21 at 10:36

0 Answers0