[gimp-web] tools: make a gimputils module with `oc` and `version` submodules.



commit 30a3c8658ad21af8a8cdcddc48b341cb7bc4b3fb
Author: Jehan <jehan girinstud io>
Date:   Mon Sep 26 12:41:30 2022 +0200

    tools: make a gimputils module with `oc` and `version` submodules.
    
    - Previously created gimpoc is now gimputils.oc.
    - gimputils.oc now provides a new get_stats() function to be used soon.
    - find_latest() function extracted from gimp-check-mirrors.py into a
      dedicated gimputils.version module, to be reused from more scripts.
      Also adding a validate() function.

 tools/downloads/gimp-check-mirrors.py          |  72 +--------------
 tools/downloads/{gimpoc.py => gimputils/oc.py} |  23 ++++-
 tools/downloads/gimputils/version.py           | 118 +++++++++++++++++++++++++
 3 files changed, 141 insertions(+), 72 deletions(-)
---
diff --git a/tools/downloads/gimp-check-mirrors.py b/tools/downloads/gimp-check-mirrors.py
index 760bbdd1..eddc6617 100755
--- a/tools/downloads/gimp-check-mirrors.py
+++ b/tools/downloads/gimp-check-mirrors.py
@@ -1,5 +1,6 @@
 #!/usr/bin/env python3
 
+import gimputils.version
 import os
 import argparse
 import concurrent.futures
@@ -24,75 +25,6 @@ def load_url(url, timeout):
     with requests.head(url, timeout=timeout) as conn:
         return conn
 
-def find_latest():
-    # Just parse the HTML with some regexp as it is not xhtml and it
-    # cannot be parsed by a proper XML parser.
-    latest = []
-    base_url = 'https://download.gimp.org/gimp/'
-
-    # Find latest series.
-    major = 0
-    minor = 0
-    html = requests.get(base_url).text
-    pattern = re.compile('<a href="v([0-9]+)\.([0-9]+)/"')
-    for match in pattern.finditer(html):
-      if int(match.group(2)) % 2 == 1:
-        # Ignore development versions.
-        pass
-      elif int(match.group(1)) > major:
-        major = int(match.group(1))
-        minor = int(match.group(2))
-      elif int(match.group(1)) == major and int(match.group(2)) > minor:
-        minor = int(match.group(2))
-
-    # Find latest tarball.
-    micro = 0
-    base_path = 'v{}.{}/'.format(major, minor)
-    html = requests.get('{}{}'.format(base_url, base_path)).text
-    pattern = re.compile('<a href="0.0_LATEST-IS-{}.{}.([0-9]+)"'.format(major, minor))
-    match = pattern.search(html)
-    micro = int(match.group(1))
-
-    latest = [ "{}gimp-{}.{}.{}.tar.bz2".format(base_path, major, minor, micro) ]
-
-    # Find latest Windows installer
-    found = False
-    rev = None
-    path = '{}windows/'.format(base_path)
-    html = requests.get('{}{}'.format(base_url, path)).text
-    pattern = re.compile('<a href="gimp-{}\\.{}\\.{}-setup(-([0-9]+))?\\.exe"'.format(major, minor, micro))
-    for m in pattern.finditer(html):
-      found = True
-      if m.group(2) is not None:
-        if rev is None or rev < int(m.group(2)):
-          rev = int(m.group(2))
-
-    if found:
-      latest += ["{}gimp-{}.{}.{}-setup{}.exe".format(path, major, minor, micro,
-                                                      '-{}'.format(rev) if rev is not None else '')]
-    else:
-      sys.stderr.write("WARNING: no Windows installer.\n\n")
-
-    # Find latest macOS DMG
-    found = False
-    rev = None
-    path = '{}macos/'.format(base_path)
-    html = requests.get('{}{}'.format(base_url, path)).text
-    pattern = re.compile('<a href="gimp-{}\\.{}\\.{}-x86_64(-([0-9]+))?\\.dmg"'.format(major, minor, micro))
-    for m in pattern.finditer(html):
-      found = True
-      if m.group(2) is not None:
-        if rev is None or rev < int(m.group(2)):
-          rev = int(m.group(2))
-
-    if found:
-      latest += ["{}gimp-{}.{}.{}-x86_64{}.dmg".format(path, major, minor, micro,
-                                                       '-{}'.format(rev) if rev is not None else '')]
-    else:
-      sys.stderr.write("WARNING: no macOS DMG package.\n\n")
-
-    return latest
-
 def verify_remote(uri, future):
   success     = False
   status      = None
@@ -135,7 +67,7 @@ def verify_remote(uri, future):
 
 if len(args.uris) == 0:
     print("No URIs given as argument. Trying to guess the last packages.")
-    local_uris = find_latest()
+    local_uris = gimputils.version.find_latest()
 else:
     # get local path
     local_uris = []
diff --git a/tools/downloads/gimpoc.py b/tools/downloads/gimputils/oc.py
similarity index 86%
rename from tools/downloads/gimpoc.py
rename to tools/downloads/gimputils/oc.py
index 84fe84bf..202d9d7d 100644
--- a/tools/downloads/gimpoc.py
+++ b/tools/downloads/gimputils/oc.py
@@ -1,7 +1,7 @@
 #!/usr/bin/env python3
 
 """
-gimpoc.py -- Module to interact with GIMP's OpenShift instance
+gimputils.oc -- Module to interact with GIMP's OpenShift instance
 Copyright (C) 2022 Jehan
 
 This program is free software: you can redistribute it and/or modify
@@ -82,7 +82,7 @@ def setup(keep_oc, download_oc):
     else:
       err_msg = "The file '{}' didn't exists. Do not use --no-download-oc option.\n".format(oc)
     raise Error(os.EX_UNAVAILABLE, err_msg)
-  
+
   return keep_oc
 
 def cleanup(keep_oc):
@@ -151,3 +151,22 @@ def get_mirrors(podname):
     return mirrors
   except subprocess.CalledProcessError:
     raise Error(os.EX_UNAVAILABLE, 'OpenShift command failed. Please check the code.\n')
+
+def get_stats(podname, file, day):
+  if file[0] != '/':
+    # mirrorbits returns output with prepended slash.
+    file = '/' + file
+  try:
+    # mb stats file /gimp/v2.10/windows/gimp-2.10.32-setup.exe
+    output = subprocess.check_output(oc + " exec {}  -- mb stats -start-date {} -end-date {} file 
{}".format(podname, day, day, file), shell=True)
+    lines = output.decode('utf-8').split('\n')
+    stats = None
+    for l in lines:
+      if l.startswith('{}:'.format(file)):
+        stats = int(l.split()[1])
+        break
+    if stats is None:
+      raise Error(os.EX_UNAVAILABLE, 'No stats for "{}".\n'.format(file))
+    return stats
+  except subprocess.CalledProcessError:
+    raise Error(os.EX_UNAVAILABLE, 'OpenShift command failed. Please check the code.\n')
diff --git a/tools/downloads/gimputils/version.py b/tools/downloads/gimputils/version.py
new file mode 100644
index 00000000..f767ba08
--- /dev/null
+++ b/tools/downloads/gimputils/version.py
@@ -0,0 +1,118 @@
+#!/usr/bin/env python3
+
+"""
+gimputils.version -- Module to process GIMP's versions
+Copyright (C) 2022 Jehan
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <https://www.gnu.org/licenses/>.
+"""
+
+import os
+import re
+import requests
+
+class Error(Exception):
+  '''
+  Exception raised by API in this module.
+
+  Attributes:
+      code: exit code which we advise to use with sys.exit() if you
+            consider this a fatale error.
+      message: message to output on stderr.
+  '''
+
+  def __init__(self, error, message):
+      self.code = code
+      self.message = message
+      super().__init__(self.message)
+
+def validate(version):
+  match = re.match('^([0-9]+)\\.([0-9]+)\\.([0-9]+)$', version)
+  if match is None:
+    raise Error(os.EX_USAGE, 'Invalid version {}'.format(version))
+  else:
+    major = int(match.group(1))
+    minor = int(match.group(2))
+    micro = int(match.group(3))
+    stable = (minor % 2 == 0)
+    return major, minor, micro, stable
+
+def find_latest():
+  # Just parse the HTML with some regexp as it is not xhtml and it
+  # cannot be parsed by a proper XML parser.
+  latest = []
+  base_url = 'https://download.gimp.org/'
+
+  # Find latest series.
+  major = 0
+  minor = 0
+  html = requests.get(base_url + 'gimp').text
+  pattern = re.compile('<a href="v([0-9]+)\.([0-9]+)/"')
+  for match in pattern.finditer(html):
+    if int(match.group(2)) % 2 == 1:
+      # Ignore development versions.
+      pass
+    elif int(match.group(1)) > major:
+      major = int(match.group(1))
+      minor = int(match.group(2))
+    elif int(match.group(1)) == major and int(match.group(2)) > minor:
+      minor = int(match.group(2))
+
+  # Find latest tarball.
+  micro = 0
+  base_path = 'gimp/v{}.{}/'.format(major, minor)
+  html = requests.get('{}{}'.format(base_url, base_path)).text
+  pattern = re.compile('<a href="0.0_LATEST-IS-{}.{}.([0-9]+)"'.format(major, minor))
+  match = pattern.search(html)
+  micro = int(match.group(1))
+
+  latest = [ "{}gimp-{}.{}.{}.tar.bz2".format(base_path, major, minor, micro) ]
+
+  # Find latest Windows installer
+  found = False
+  rev = None
+  path = '{}windows/'.format(base_path)
+  html = requests.get('{}{}'.format(base_url, path)).text
+  pattern = re.compile('<a href="gimp-{}\\.{}\\.{}-setup(-([0-9]+))?\\.exe"'.format(major, minor, micro))
+  for m in pattern.finditer(html):
+    found = True
+    if m.group(2) is not None:
+      if rev is None or rev < int(m.group(2)):
+        rev = int(m.group(2))
+
+  if found:
+    latest += ["{}gimp-{}.{}.{}-setup{}.exe".format(path, major, minor, micro,
+                                                    '-{}'.format(rev) if rev is not None else '')]
+  else:
+    sys.stderr.write("WARNING: no Windows installer.\n\n")
+
+  # Find latest macOS DMG
+  found = False
+  rev = None
+  path = '{}osx/'.format(base_path)
+  html = requests.get('{}{}'.format(base_url, path)).text
+  pattern = re.compile('<a href="gimp-{}\\.{}\\.{}-x86_64(-([0-9]+))?\\.dmg"'.format(major, minor, micro))
+  for m in pattern.finditer(html):
+    found = True
+    if m.group(2) is not None:
+      if rev is None or rev < int(m.group(2)):
+        rev = int(m.group(2))
+
+  if found:
+    latest += ["{}gimp-{}.{}.{}-x86_64{}.dmg".format(path, major, minor, micro,
+                                                     '-{}'.format(rev) if rev is not None else '')]
+  else:
+    sys.stderr.write("WARNING: no macOS DMG package.\n\n")
+
+  return latest


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