Re: FR: Option to terminate page rendering from an Action nicely
Nagy Gabor <[email protected]>
| Newsgroups | gmane.comp.bug-tracking.roundup.user |
|---|---|
| Message-ID | <20210831013511.37404b03@Dell> |
Dear Ralf and John, Thank you both for your replies. I like both proposals, and I find John's concept elegant. I also agree with Ralf that the handling of return values of Actions should be documented. PS. A bit off-topic in this thread, but John's email reminded me that I do not really like the current implementation of ExportCSVAction in cgi/actions.py (or the index templates in the sample trackers, it depends on your point of view): In my opinion, ExportCSVAction and the index templates _should_ somehow share the code which renders the "cells of the table" of the index view: We should export precisely what the user sees. However, instead of code sharing, there are many hardcoded stuff in ExportCSVAction (see the 'name' vs. 'realname' handling etc.). Regards, Gábor > Hi Ralf and Nagy: > > In message <[email protected]>, > Ralf Schlatterbeck writes: > >Hi Nagy, see below for my fix, it probably is a good idea to put that > >into some lib shipped with roundup and document the behaviour. > > I just implmented > > https://wiki.roundup-tracker.org/QueryResultPieCharts > > using pygal. > > I didn't send a header or write anything at all to the client from the > handler. I returned the svg image at the end of the handler rather > than returning '\n'. This called write_html which delivered it > (compressed with brotli) to the client. > > I think this path should work for any bytestream provided the > content-type header is properly set. It may be a side effect of the > work I did to add compression in the current development code, but I > don't think so. > > I think the only reason to write directly from the handler would be if > the returned item is too large to build all at one. In the csv case, > it looks like one line of the csv output is written as it iterates > over all the data. > > If you are building the whole returned file in memory, make sure to > turn it into bytes and try sending is a the handler return value. > > -- rouilj > > >On Fri, Aug 06, 2021 at 09:12:50PM +0200, Nagy Gabor wrote: > >> > >> Based on ExportCSVAction, I wrote an ExportXLSAction using > >> xslxwriter. Everything worked fine on Linux systems, but MS Office > >> always reported corrupted xlsx file, which seemed OK after > >> applying Office's repair. Mystery... > >> > >> After hours of debugging, I found the bug: > >> > >> First I realized that the problem is that my generated .xlsx file > >> is correct, but it is served with a '\n' character added to the > >> end of the file. Analogously to > >> cgi.actions.ExportCSVAction.handle(), the last line of my handle > >> method was also return '\n'. We are getting closer: Yes, the > >> returned string is appended to the served content, this is > >> verified for different strings. At this point I believed that I am > >> done, but neither return '' nor return None worked. In these cases > >> the issue.index template file is rendered into the xlsx binary. > >> Hmmm. So I have to looked into Roundup's code deeper, and I found > >> the relevant code in cgi/client.py (lines 685-696, inner_main() > >> method of Client class): > >> > >> if csrf_ok: > >> # csrf checks pass. Run actions etc. > >> # possibly handle a form submit action (may > >> change # self.classname and self.template, and may also > >> # append error/ok_messages) > >> html = self.handle_action() > >> else: > >> html = None > >> > >> if html: > >> self.write_html(html) > >> return > >> # now render the page > >> # we don't want clients caching our dynamic pages > >> > >> This means that if the action's handle() returns anything which > >> evaluates to True in the "if html" condition, then it is added to > >> the page, and the rendering is done; otherwise the rendering goes > >> on. > >> > >> My feature request is to add a nice possibility for the Action to > >> terminate the page rendering. (Maybe by raising an exception, > >> which is handled by the except part of inner_main.) I've just > >> added an "if html == True: > >> return" > >> test before the "if html:" test, and my Action returns True. (This > >> is an ugly solution, but it should work, because > >> self.write_html(True) induces an error, so probably no other > >> Action returns True, because with the old code, that would lead to > >> an exception.) > > > >I'm using the following class in my actions: > > > >class True_Value (type ("")): > > """ A class that evaluates to True but can return a zero-length > > string. We use this as return value from a handle routine where the > > output happend to the file descriptor > > """ > > def __bool__ (self): > > return True > > > >Note that for Python2 you want to add > > __nonzero__ = __bool__ > > > >I'm returning an instance of that class which appends an empty > >string. > > > >Ralf > >-- > >Dr. Ralf Schlatterbeck Tel: +43/2243/26465-16 > >Open Source Consulting www: www.runtux.com > >Reichergasse 131, A-3411 Weidling email: [email protected] > > > > > >_______________________________________________ > >Roundup-users mailing list > >[email protected] > >https://lists.sourceforge.net/lists/listinfo/roundup-users > > -- > -- rouilj > John Rouillard > =========================================================================== > My employers don't acknowledge my existence much less my opinions. > > > _______________________________________________ > Roundup-users mailing list > [email protected] > https://lists.sourceforge.net/lists/listinfo/roundup-users _______________________________________________ Roundup-users mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/roundup-users