FE 'tkGooie' Utilities

'INTERNETtools' group

A Tk GUI to
Get Comics
via HTTP

(FE = Freedom Environment)

The FE 'GetComics' tkGooie
---
with a list of comics sites
in the listbox on the left
(sites that worked
in 2014)

FE Home Page > FE Downloads Page >

FE 'tkGooies' Description Page >

FE 'tkGooies' 'INTERNETtools' Page >

This
'GetComics_viaHTTP'
tkGooie code Page

INTRODUCTION to
Tcl-Tk code for Tk-GUI
'GetComics_viaHTTP'

In my first dozen or so years of Tcl-Tk programming (circa 2000 to 2013), I never did any socket programming with Tcl-Tk.

However, on my Tk-scripts 'to-do' list (that I started in 2012), I put the item 'tkGetToons' - to fetch some of my favorite cartoons from Internet sites that offer them --- for example,

  • Agnes
  • Baby Blues
  • Bizarro
  • Dilbert
  • Doonesbury
  • Rhymes with Orange
  • Speed Bump
  • Zits

and perhaps the sites of some editorial-page political cartoonists.

I was inspired to add that 'to do' item to my list on seeing the page titled 'Daily Dilbert' on the Tcler's Wiki wiki.tcl.tk web site.

The several code samples contributed on that page use the HTTP protocol (and the 'http' Tcl package) to retrieve cartoons from the internet.

Thanks to an updated code 'snippet', contributed by 's_m' (Stefano Mimmi) in 2013, on that 'Daily Dilbert' page, I found code on which my generalized comics-retrieval utility could be based.

That generalized code is the subject of this page.


THE GOALS

I tried out the Dilbert-code of 's_m' and was pleased to find that it worked.

    (The Tcl 'http' package was available in the Tcl-Tk 8.5 installation on my desktop computer.

    However, I also have a little Acer netbook computer that I often use to test Tk scripts in its Linux environment.

    For some reason, unbeknownst to me at this time, the Tcl-Tk 8.5 installation on that netbook computer does not include the 'http' package.

    So I did all my testing,as well as development, on my desktop computer.)

The Dilbert-code of 's_m' retrieved the Dilbert 'cartoon-of-the-day'.

Super! However --- I wanted to do more than that --- I wanted to be able to retrieve any of the old Dilbert cartoons from a Dilbert archive site.

And not just Dilbert. I wanted to be able to retrieve old cartoons from archive sites like those of Doonesbury, Rhymes with Orange, Speed Bump, and Zits --- and allow for easily adding more sites in the future.

In particular, my goals for the Tcl-Tk script were:

  • provide a GUI for selecting a comic archive site
    (via a 'listbox' on the GUI)

  • allow the user to specify an 'index' to a particular comic
    (typically year-month-day)

  • put the image on a SCROLLABLE Tk canvas
    (to allow for large cartoons)

  • provide a 'SaveAsGIF' button to allow for easily saving the image to local computer storage
    (similar to the 'Save' option that 's_m' had provided)

  • provide a 'Help' button to explain the utility

  • make the interface easy-to-use
    (mostly mouse-clicks rather than keyboard keying)


SCREENSHOT OF THE GUI

On the basis of those goals, I ended up with the GUI seen in the following image.

Note the entry fields for year-month-day. Fortunately, all the archive sites that I have implemented so far allow for specifying a particular comic by year-month-day.

If necessary, in the future, more widgets could be added to the GUI to handle different methods of 'indexing' archived comics. And the 'indexing' widgets on the GUI could be activated/deactivated according to the archive site selected by the user.

NOTE:
On either side of the Day entry field, there are buttons labeled '>' and '<'.

Those buttons are to provide a way to easiliy decrement and increment the day-number --- by simply clicking on those buttons, rather than keying into the Day entry field.

Those decrement/increment buttons call on decrement/increment procs that handle transitioning day number into a different month or year.

The procs take into account whether a month has 30 or 31 or 28 or 29 days.

Note also the scrollbars on the 'canvas' widget. They come in handy for large comic images like the following.

Some comics are a single panel, in which case the scrollbars of the canvas are not needed --- as in the following.

TYPICAL SEQUENCE OF OPERATIONS WITH THE GUI

A 'listbox' on the GUI offers a list of comic archive sites from which to choose.

Step 1:

Click on a line of the listbox to choose a web-site. The web-site name is followed by a separation character (#) after which there may be some description of the web-site.

    (A '#' in column 1 of the line makes the line a comment line --- for example, to allow for indicating comics for which retrieval has not been implemented, and reminding the user to keep looking for a method to retrieve those comics.)

Step 2:

Date fields (year,month,day) provide the user a way to select a specific comic to retrieve --- if a web site supports retrieval by date.

    (If some sites offer a different way, from year-month-day, of identifying individual comics, this code could activate a different widget --- or widgets --- by which to specify a comic --- according to the site selected by the user.

    In that case, 'comic selection widgets' on the GUI may have to be activated or deactivated according to the site selected.)

The '<' and '>' buttons on either side of the Day entry field facilitate quickly scanning through cartoons of a given site, by successive days.

You can skip to a different year or month by simply entering a new number in the Year or Month entry fields.

Step 3:

After each date is set, click on the 'Retrieve' button to display the corresponding comic.

The 'Retrieve' button causes a series of Tcl 'http' commands to be issued, commands such as

  • http::config
  • http::geturl
  • http::data
  • http::cleanup

to get the comic file (GIF) data and display it in the canvas.

---

Error/Warning Popups:

Occasionally, at a comic archive site, there may not be a comic for a specified date.

In that case, you may see an error message popup in a window.

Simply dismiss the window and try another date.

Also, if your network connection is not active, you will get a popup that reminds you that you need to establish your internet connection.


DESCRIPTION OF THE CODE

Below, I provide the Tk script code for this 'get-comics' utility.

I follow my usual 'canonical' structure for Tk code for this Tk script:



  0) Set general window & widget parms (win-name, win-position,
     win-color-scheme, fonts-for-widgets, widget-geometry-parms,
     text-array-for-labels-etc, win-size-control).

  1a) Define ALL frames (and sub-frames, if any).
  1b) Pack   ALL frames and sub-frames.

  2) Define & pack all widgets in the frames, frame by frame.
              Within each frame, define ALL the widgets.
              Then pack the widgets.

  3) Define keyboard and mouse/touchpad/touch-sensitive-screen action
     BINDINGS, if needed.

  4) Define PROCS, if needed.

  5) Additional GUI initialization (typically with one or more of
     the procs), if needed.


This Tk coding structure is discussed in more detail on the page A Canonical Structure for Tk Code --- and variations.

This structure makes it easy for me to find code sections --- while generating and testing a Tk script, and when looking for code snippets to include in other scripts (code re-use).

I call your attention to step-zero.

One thing that I started doing in 2013 is use of a text-array for text in labels, buttons, and other widgets in the GUI.

This can make it easier for people to internationalize my scripts.

I will be using a text-array like this in most of my scripts in the future.

In this script, motivated by the many instances of popup messages in the code, I included message text in the text-array.


Experimenting with the GUI

As in all my scripts that use the 'pack' geometry manager (which is all of my 100-plus scripts, so far), I provide the four main 'pack' parameters --- '-side', '-anchor', '-fill', '-expand' --- on all of the 'pack' commands for the frames and widgets.

That helps me when I am initially testing the behavior of a GUI (the various widgets within it) as I resize the main window.

I think that I have used a pretty nice choice of the 'pack' parameters.

The label and button and year-month-day entry widgets stay fixed in size and relative-location if the window is re-sized --- while the comic-site 'entry' widget (that displays the site URL, grayed out) expands/contracts horizontally whenever the window is re-sized horizontally.

Also, the WIDTH of the 'listbox' stays FIXED, while the 'canvas' (and its scrollbars) can expand both horizontally and vertically --- allowing more room for the canvas (that is, large comics) if the user expands the window.

You can experiment with the '-side', '-anchor', '-fill', and '-expand' parameters on the 'pack' commands for the various frames and widgets --- to get the widget behavior that you want.

---

Additional experimentation:

You might want to change the fonts used for the various GUI widgets. For example, you could change '-weight' from 'bold' to 'normal' --- or '-slant' from 'roman' to 'italic'. Or change font families.

In fact, you may NEED to change the font families, because the families I used may not be available on your computer --- and the default font that the 'wish' interpreter chooses may not be very pleasing.

I use variables to set geometry parameters of widgets --- parameters such as border-widths and padding. And I have included the '-relief' parameter on the definitions of frames and widgets.

Feel free to experiment with those 'appearance' parameters as well.

If you find the gray 'palette' of the GUI is not to your liking, you can change the value of the RGB parameter supplied to the 'tk_setPalette' command near the top of the code.


Some features in the code

There are plenty of comments in the code to describe what most of the code-sections are doing.

You can look at the top of the PROCS section of the code to see a list of the procs used in this script, along with brief descriptions of how they are called and what they do.

The main procs are :



   'get_site_selectedInListbox' - called via a button1-release binding on
                                  the listbox widget.

   'Retrieve'                   - called by the 'Retrieve' button.


   The following procs are called by the 'Retrieve' proc, depending on
   which site(/comic-strip) was selected from the listbox widget.

         'get_babyblues_comic'
         'get_bizzaro_comic'
         'get_dilbert_comic'
         'get_doonesbury_comic'
         'get_rhymeswithorange_comic'
         'get_speedbump_comic'
         'get_zits_comic'

   And there are the following 'utility' procs.

   'show_image_forPicURL'   - called by the 'get_*_comic' procs.
                              (To avoid repeating code that is common
                               to all the procs --- after the URL of the
                               image file has been determined.)

   'save_image_toLocalFile' - called via the 'SaveAsGIF' button.

   'date_increment'         - called via the '>' button
   'date_decrement'         - called via the '<' button

   'popup_msgVarWithScroll' - called via the 'Help' button --- and
                              used for warning/error messages.

   ---

   The 'http' package routines

   http::config
   http::geturl
   http::data
   http::cleanup

   are used in the 'get_*_comic' procs and the 'show_image_forPicURL' proc.


Comments in the Code

It is my hope that the copious comments in the code will help Tcl-Tk coding 'newbies' get started in making GUI's like this.

Without the comments, potential young Tcler's might be tempted to return to their iPhones and iPads and iPods --- to watch videos of Daniel Tosh providing people who have posted videos on the internet the opportunity for 'web redemption'.


The Tcl-Tk script CODE

Here is a link to CODE for the script 'get_comics.tk'.


INSTALLING THE SCRIPT:

For this 'get-comics' utility, a SINGLE Tkscript can be put in a sub-directory of the user's home directory, such as

$HOME/apps/tkGetComics.

Then the user can use their desktop system (such as Gnome or KDE) to set up the Tk script as an icon on the desktop.

Then the user can click on the desktop icon to startup the 'GetComics' GUI.


SOME POSSIBLE ENHANCEMENTS

This Tk script is the first utility that I have added to the 'INTERNETtools' group of the FE 'tkGooies' system.

I have many more scripts in various states of development --- in the other categories of 'done and to-do' projects for the FE 'tkGooies' system.

I must make some progress on them --- so I may not make more 'INTERNETtools' Tk GUI scripts for quite a while.

But I may return to this 'Get-Comics' Tk script, someday, to provide some enhancements, such as:

  • More Warning/Error Popups

    In using this utility, I may discover error conditions that I did not encounter in testing.

    I may add ways to 'trap' the errors and provide some pop-up messages in addition to the ones that I already implemented during the testing phase.

  • JPEG Support

    Some sites provide comics in JPEG-JFIF format rather than GIF (or PNG) format.

    In those cases, I could add some code, using the ImageMagick 'convert' command, to convert the JPEG file to a GIF (or PNG) file ('under the covers') --- and then place the GIF image on the Tk canvas.

  • Additonal Comics

    Some additional comics may be added.

    This involves adding 'listbox' entries and adding a 'get_*_comic' proc for each new comic archive site.

      AND ...
      Some sites will have to be removed. These sites change their HTML code all too frequently. In the process, they often make it much harder to fetch comics due to extra requirements imposed.

  • Accommodate web-site changes

    These comic archive sites occasionally change their web pages and the ways that they store and access the comics.

    If feasible, some of the 'get_*_comic' routines may need to be changed in coming months/years to keep up with the web-site changes.

    Unfortunately, some sites will simply have to be 'retired'.

    It would be nice if a 'fetch' method could be devised that worked on almost any comic archive site. But there is no 'standard' way that these sites are implemented. In fact, there is great variety in the ways they are implemented.


IN CONCLUSION

I want to thank those who authored the 'http' package ('beedub' and others?) that allowed me to avoid having to go a level lower --- into Tcl 'socket' programming.

Also many thanks to 's_m' for his 2013-code to get the Dilbert comic-of-the-day.

Furthermore, as I have said on several other code-donation pages on this FE web site ...

There's a lot to like about a utility that is 'free freedom' --- that is, no-cost and open-source so that you can modify/enhance/fix it without having to wait for someone else to do it for you (which may be never).

A BIG THANK YOU to Ousterhout for starting Tcl-Tk, and a BIG THANK YOU to the Tcl-Tk developers and maintainers who have kept the simply MAH-velous 'wish' interpreter going.


2014mar27 UPDATE

I improved the 'get_comics.tk' script in the following ways:

1) ADDED some comic strips -- Agnes, BabyBlues, Bizarro --- by adding some 'get_*_comic' procs and adding lines to the site-selection listbox.

2) ADDED date-range checks in all the get-comic procs, and added date-range info on the lines in the site-selection listbox.

3) ADDED code to the 'show_image_forPicURL' proc to convert a nonGIF file (such as JPEG or PNG) to a GIF file before loading the image data into a Tk 'photo' image and displaying the image on the canvas.

4) ADDED proc 'popmsg_forFailedGetURL' to use at 'http::geturl' statements in the 'get_*_comic' procs.

5) ADDED 'http::ncode' 404 checks in the 'get_*_comic' procs.

6) CHANGED '>' and '<' buttons to '+' and '-' buttons.

7) ADDED an image-size label above the canvas.

The following 3 images confirm that the Agnes, BabyBlues, and Bizarro comics were retrievable in 2014 March --- and the images show some of the (almost unnoticeable) changes to the GUI.

Note that the text lines in the site-selection listbox now indicate a date-range for the comics at a site.

Also notice the image-size that is now displayed just above the image.

(By the way, many of the Agnes comics 'miss the mark' for me, but the ones where the teacher sends her to the principal's office are usually quite good.)

These images also show that the '>' and '<' buttons have been changed to '+' and '-' buttons.

(Many of the old BabyBlues comics were in black-and-white on weekdays, but in color on Sundays.)

Unlike the other comics sites, the Bizarro cartoons are archived in JPEG format, not GIF.

That is a comic that motivated the update to the 'show_image_forPicURL' proc --- so that it now converts a non-GIF file (such as JPEG or PNG) to a GIF file before loading the image data into a Tk 'photo' image 'structure' and displaying the image on the canvas.

By comparing these 3 images to the several images at the top of this page, you can see that the '>' and '<' buttons are now '+' and '-' buttons --- and that the image-size label is new --- and that text in the listbox lines has been changed.

Among future enhancements that I am considering :

Adding some 'get_*_comic' procs for some political/editorial cartoons.

Bottom of this web page for
presenting Tcl-Tk code for a
Get Comic via HTTP 'app'
--- a utility in the FE 'tkGooies' system,
in the 'INTERNETtools' group.

To return to a previously visited web page location, click on the Back button of your web browser a sufficient number of times. OR, use the History-list option of your web browser.
OR ...

< Go to Top of Page, above. >

Page history:

The code was created in 2014 --- and posted 2014 Mar 08 at http://wiki.tcl.tk/39491.

This FE web page was created 2014 May 09.
(as a backup and alternative to the wiki.tcl.tk page)

Page was changed 2019 Mar 07.
(Added css and javascript to try to handle text-size for smartphones, esp. in portrait orientation.)

Page was changed 2019 Jun 17.
(Specified image widths in percents to size the images according to width of the browser window. Also added some web links.)


NOTE:
The code here MAY BECOME more 'up-to-date' than the code posted on the Tcler's Wiki ---
wiki.tcl-lang.org --- formerly wiki.tcl.tk.