[gtkmm-documentation] tools/make_screenshots: Update and translate to Python



commit 6eb28d57f3dcaee483cbf1e255912f70470fe361
Author: Kjell Ahlstedt <kjellahlstedt gmail com>
Date:   Thu Jan 21 18:18:07 2021 +0100

    tools/make_screenshots: Update and translate to Python
    
    Replace the Perl and shell scripts by a Python script.
    Update the list of example programs to run.

 tools/make_screenshots/README              |  23 ++---
 tools/make_screenshots/make_screenshots.pl | 105 ---------------------
 tools/make_screenshots/make_screenshots.py | 145 +++++++++++++++++++++++++++++
 tools/make_screenshots/make_screenshots.sh |  11 ---
 tools/make_screenshots/progs-and-figs.txt  |  56 ++++++-----
 5 files changed, 185 insertions(+), 155 deletions(-)
---
diff --git a/tools/make_screenshots/README b/tools/make_screenshots/README
index 9cb6dd5..123c0dd 100644
--- a/tools/make_screenshots/README
+++ b/tools/make_screenshots/README
@@ -1,31 +1,22 @@
 gtkmm-documentation/tools/make_screenshots/README
 
-2012-06-09 Kjell Ahlstedt
-
 See also bug https://bugzilla.gnome.org/show_bug.cgi?id=677292
 "Semi-automatic generation of screenshots for the gtkmm tutorial"
 
--- make_screenshots.pl is a Perl script which is a first attempt at an automatic
+make_screenshots.py is a Python script which is an attempt at an automatic
 screenshot generator. It's not fully automatic, though. It generates
 screenshots by starting an example program and saving a screenshot of the
 program's window as it looks just after start-up.
 
-63 screenshots are shown in the tutorial. 47 of them will be correctly
-generated in this simple way. The other 16 screenshots require some kind of
+69 screenshots are shown in the tutorial. 45 of them will be correctly
+generated in this simple way. The other 24 screenshots require some kind of
 user input or a specific location of the cursor before they are saved.
 
-Most example programs must be built before make_screenshots.pl is executed.
-'make check' does that.
+Most example programs must be built before make_screenshots.py is executed.
+'make check' or 'ninja examples' does that.
 
 The screenshots are saved by gnome-screenshot.
-The gnome-screenshot bugs https://bugzilla.gnome.org/show_bug.cgi?id=129768 and
-https://bugzilla.gnome.org/show_bug.cgi?id=594141 must have been implemented
-(added in the git repository 2012-05-23 and 2012-05-24).
-
--- make_screenshots.sh is a shell script that calls make_screenshots.pl with
-appropriate parameters.
-
--- progs-and-figs.txt is input data to make_screenshots.pl.
 
-At present make_screenshots.sh is not called from any Makefile.
+progs-and-figs.txt is input data to make_screenshots.py.
 
+make_screenshots.py is not called from any Makefile or meson.build file.
diff --git a/tools/make_screenshots/make_screenshots.py b/tools/make_screenshots/make_screenshots.py
new file mode 100755
index 0000000..484a5f9
--- /dev/null
+++ b/tools/make_screenshots/make_screenshots.py
@@ -0,0 +1,145 @@
+#!/usr/bin/env python3
+
+# Generate screenshots for the gtkmm tutorial.
+#
+# This Python script starts one or more programs, one at a time. The started
+# programs are assumed to open a window. The script catches a screenshot of
+# each started program's window.
+# The script can't correctly generate screenshots that require some kind of
+# user input before or after the program has been started.
+#
+# Which programs to start and where to save the screenshots is read from a
+# file, where each line contains
+#   program [parameter-to-program...] figure [delay-in-seconds] [# comment]
+# Lines that don't contain both 'program' and 'figure' are ignored.
+
+# The screenshots are saved by gnome-screenshot.
+
+# make_screenshots.py [option...] [input-file]
+# Options:
+# --program-src-prefix=SRCDIR      Default: $GMMPROC_GEN_SOURCE_DIR/gtkmm-documentation/examples or 
../../examples
+# --program-build-prefix=BUILDDIR  Default: $GMMPROC_GEN_BUILD_DIR/gtkmm-documentation/examples or SRCDIR
+# --figure-dir=FIGUREDIR           Default: newfigures
+# input-file                       Default: progs-and-figs.txt
+
+# When the default values of SRCDIR and BUILDDIR are computed, it's assumed that
+# this script is stored two directory levels below gtkmm-documentation, e.g.
+# in gtkmm-documentation/tools/make_screenshots/.
+# 'gtkmm-documentation' is just a typical directory name. Other directory names
+# are possible.
+
+import os
+import sys
+import argparse
+import time
+import signal
+import subprocess
+
+# Compute default values of SRCDIR and BUILDDIR.
+pkg_dir = os.path.abspath(sys.argv[0])
+for i in range(3):
+  pkg_dir = os.path.dirname(pkg_dir)
+pkg_name = os.path.basename(pkg_dir)
+if not pkg_name:
+  pkg_name = 'gtkmm-documentation'
+
+gmmproc_gen_source_dir = os.environ.get('GMMPROC_GEN_SOURCE_DIR', None)
+if gmmproc_gen_source_dir:
+  src_default = os.path.join(gmmproc_gen_source_dir, pkg_name, 'examples')
+else: 
+  src_default = os.path.join(pkg_dir, 'examples')
+
+gmmproc_gen_build_dir = os.environ.get('GMMPROC_GEN_BUILD_DIR', None)
+if gmmproc_gen_build_dir:
+  build_default = os.path.join(gmmproc_gen_build_dir, pkg_name, 'examples')
+else: 
+  build_default = gmmproc_gen_source_dir
+
+parser = argparse.ArgumentParser(
+  formatter_class=argparse.RawTextHelpFormatter,
+  description='Make screenshots for the gtkmm tutorial.')
+parser.add_argument('--program-src-prefix', metavar='SRCDIR',
+  dest='src_prefix', default=src_default,
+  help='source directory prefix (default: %(default)s)')
+parser.add_argument('--program-build-prefix', metavar='BUILDDIR',
+  dest='build_prefix', default=build_default,
+  help='build directory prefix (default: %(default)s)')
+parser.add_argument('--figure-dir', metavar='FIGUREDIR',
+  dest='figure_dir', default='newfigures',
+  help='figure directory (default: %(default)s)')
+parser.add_argument('input_file', nargs='?',
+  default='progs-and-figs.txt',
+  help='''file format, each line:
+program [parameter-to-program...] figure [delay-in-seconds] [# comment]
+(default: %(default)s) ''')
+
+# Parse arguments.
+args = parser.parse_args()
+
+with open(args.input_file, mode='r') as infile:
+
+  # Create the figure directory, if it does not exist.
+  os.makedirs(args.figure_dir, exist_ok=True)
+
+  for line in infile:
+    # Remove comments.
+    # Split the remainder of the line into blank-separated fields.
+    fields = line.split('#')[0].split()
+
+    # Skip lines with less than two fields.
+    # These are blank lines, comment lines, and lines with the name of a program
+    # from which no screenshot is required.
+    if len(fields) < 2:
+      continue
+
+    delay = 2;
+    if len(fields) >= 3 and fields[-1].isdecimal():
+      # The last field consists of only decimal digits. It's the required delay.
+      delay = int(fields.pop())
+
+    program = os.path.join(args.build_prefix, fields[0])
+    program_src_dir = os.path.join(args.src_prefix, os.path.dirname(fields[0]))
+    figure = os.path.join(args.figure_dir, fields[-1])
+    cmd_pars = fields[:-1]
+
+    print('Making screenshot from', fields[0])
+
+    process_id = os.fork()
+    if not process_id:
+      # Child process.
+      # Execute the program in its source directory.
+      # Some programs will find necessary data files only if they are executed in
+      # their source directory.
+      try:
+        os.chdir(program_src_dir)
+      except OSError:
+        print("Can't chdir to", program_src_dir)
+        sys.exit(1)
+      try:
+        os.execv(program, cmd_pars)
+        # os.execv() does not return.
+      except OSError:
+        print("Can't execute program", program)
+        sys.exit(1)
+
+    # Parent process.
+    # Wait for the child process to show its main window.
+    time.sleep(delay)
+
+    # Reap the child process, if it has become a zombie.
+    os.waitpid(process_id, os.WNOHANG)
+
+    # Check if the child process still exists.
+    try:
+      os.kill(process_id, 0)
+    except ProcessLookupError:
+      print("Could not start program from line:", line)
+      sys.exit(1)
+
+    result = subprocess.run(['gnome-screenshot', '--window', '--file='+figure])
+    os.kill(process_id, signal.SIGKILL)
+    if result.returncode:
+      print("Can't save screenshot from line:", line)
+      sys.exit(result.returncode)
+
+sys.exit(0)
diff --git a/tools/make_screenshots/progs-and-figs.txt b/tools/make_screenshots/progs-and-figs.txt
index 075c3f1..0265d5f 100644
--- a/tools/make_screenshots/progs-and-figs.txt
+++ b/tools/make_screenshots/progs-and-figs.txt
@@ -1,39 +1,49 @@
-# check_PROGRAMS in gtkmm-documentation/examples and corresponding screenshots
+# 'ninja examples' in gtkmm-documentation and corresponding screenshots
 #
 # A program with neither a screenshot name nor a comment is not shown in the
 # gtkmm tutorial.
 # Some comments, e.g. 'after user input' and 'with pointer', indicate that
-# screenshots will not be correctly generated by the Perl script make_screenshots.pl.
-# 2012-05-28
+# screenshots will not be correctly generated by the Python script make_screenshots.py.
+# 2021-01-20
 
-book/alignment/example                           alignment.png
-book/application/simple/example
+book/actionbar/example
 book/application/command_line_handling/example
-book/application/app_menu/example
+book/application/menubar/example
+book/application/simple/example
 book/aspectframe/example                         aspectframe.png
 book/assistant/example                           assistant.png      # after user input
 book/base/base                                 # no screenshot
 book/box/example 1                               box_packing1.png
 book/box/example 2                               box_packing2.png
+book/buildapp/step1/exampleapp                   buildapp_trivial_app.png
+book/buildapp/step2/exampleapp                   buildapp_populating_window.png
+book/buildapp/step3/exampleapp <filenames>       buildapp_opening_files.png # after user input
+book/buildapp/step4/exampleapp <filenames>       buildapp_menu.png          # after user input
+book/buildapp/step5/exampleapp                   buildapp_pref_dialog.png   # after user input
+book/buildapp/step6/exampleapp <filenames>       buildapp_search_bar.png    # after user input
+book/buildapp/step7/exampleapp <filenames>       buildapp_side_bar.png      # after user input
+book/buildapp/step8/exampleapp <filenames>       buildapp_properties.png    # after user input
+book/buildapp/step9/exampleapp <filenames>       buildapp_header_bar.png    # after user input
 book/builder/basic/example                     # no screenshot
 book/builder/derived/example                   # no screenshot
-book/buttonbox/example                           buttonbox.png
 book/buttons/button/buttons                      buttons.png
 book/buttons/checkbutton/example                 checkbutton.png
-book/buttons/filechooserbutton/example
 book/buttons/radiobutton/radiobuttons            radiobuttons.png
+book/buttons/scalebutton/example
 book/buttons/togglebutton/example
+book/buttons/volumebutton/example
 book/clipboard/ideal/example                     clipboard_ideal.png
 book/clipboard/simple/example                    clipboard_simple.png
 book/combobox/complex/example                    combobox_complex.png
-book/combobox/text/example                       combobox_text.png
 book/combobox/entry_complex/example              comboboxentry_complex.png
 book/combobox/entry_text/example                 comboboxentry_text.png
+book/combobox/text/example                       combobox_text.png
 book/custom/custom_container/example             custom_container.png
 book/custom/custom_widget/example                custom_widget.png
-book/dialogs/aboutdialog/example
+book/dialogs/aboutdialog/example                 dialogs_about.png               # after user input
 book/dialogs/colorchooserdialog/example          dialogs_colorchooserdialog.png  # after user input
 book/dialogs/filechooserdialog/example           dialogs_filechooser.png         # after user input
+book/dialogs/filechoosernative/example
 book/dialogs/fontchooserdialog/example           dialogs_fontchooserdialog.png   # after user input
 book/dialogs/messagedialog/example               dialogs_messagedialog.png       # after user input
 book/dialogs/simple/example
@@ -50,8 +60,8 @@ book/entry/completion/example                    entry_completion.png  # after u
 book/entry/icon/example                          entry_icon.png        # with unnecessary pointer
 book/entry/progress/example                      entry_progress.png 7  # with unnecessary pointer
 book/entry/simple/example                        entry.png
-book/eventbox/example                            eventbox.png
 book/expander/example
+book/flowbox/example
 book/frame/example                               frame.png
 book/giomm/directory_list/example
 book/giomm/getline/getline
@@ -62,38 +72,41 @@ book/giomm/usage/usage
 book/giomm/volumes/example
 book/giomm/write_file/example
 book/grid/example                                grid.png
+book/headerbar/example
 book/helloworld/helloworld                       helloworld.png
 book/helloworld2/helloworld2                     helloworld2.png
 book/iconview/example
 book/idle/idle                                 # no screenshot
 book/infobar/example                             infobar.png      # after user input, with unnecessary 
pointer
 book/input/example                             # no screenshot
-book/keyboard_events/simple/example              keyboardevents_simple.png
 book/keyboard_events/propagation/example         keyboardevents_propagation.png
+book/keyboard_events/simple/example              keyboardevents_simple.png
 book/label/example                               label.png
+book/listbox/example
+book/listmodel/example
 book/menus/main_menu/main_menu                   main_menu.png
-book/menus/popup/popup                           menu_popup.png   # after user input
-book/menus_and_toolbars/example
+book/menus/popup/example                         menu_popup.png   # after user input
+book/menus_and_toolbars/example                  menus_and_toolbars.png
+book/multithread/example                         multithread.png  # after user input
 book/notebook/example                            notebook.png
 book/paned/example                               paned.png        # after user input
+book/popover/example
 book/printing/advanced/example
 book/printing/simple/example                     printing.png
 book/progressbar/example                         progressbar.png 3
 book/range_widgets/example                       range_widgets.png
-book/recent_files/example                        recentchooserdialog.png  # after user input
+book/recent_files/example                        recentfiles.png   # after user input
+book/revealer/example
 book/scrolledwindow/example                      scrolledwindow.png
+book/searchbar/example
 book/signals/custom/example                    # no screenshot
-book/socket/plug
-book/socket/socket                               socket.png  # after plug has been started
-book/socket/socket                               socket-fail.png
 book/spinbutton/example                          spinbutton.png
-book/statusicon/example
 book/textview/example                            textview.png
 book/timeout/timeout                           # no screenshot
 book/toolbar/example
-book/toolpalette/example                         toolpalette.png 3 # with pointer
 book/tooltips/example                            tooltip.png       # ought to be with pointer
 book/treeview/combo_renderer/example
+book/treeview/custom_treemodel/example
 book/treeview/drag_and_drop/example              treeview_draganddrop.png     # after user input
 book/treeview/editable_cells/example             treeview_editablecells.png   # after unnecessary user input
 book/treeview/filter/example
@@ -105,7 +118,6 @@ book/treeview/popup/example                      treeview_popup.png  # after use
 book/treeview/tree/example                       treeview_tree.png   # after user input
 book/update_ui/example
 others/arrow/arrow
-others/arrow/direction
 others/calendar/calendar
 others/cellrenderercustom/cellrenderertoggle
 others/cellrenderercustom/testpopup
@@ -113,7 +125,5 @@ others/dnd/testdnd
 others/exception/exceptiontest
 others/idle/idle
 others/statusbar/statusbar
-others/stock/stock
 others/tictactoe/ttt_test
 others/treemodelcustom/example
-


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]