Browse Source

pyqt workaround

HEAD
T-bone 6 years ago
parent
commit
83f7affcb9
2 changed files with 122 additions and 1 deletions
  1. 117
    0
      akvo/thirdparty/build_ui.py
  2. 5
    1
      setup.py

+ 117
- 0
akvo/thirdparty/build_ui.py View File

@@ -0,0 +1,117 @@
1
+# -*- coding: utf-8 -*-
2
+"""
3
+Distutils extension for PyQt/PySide applications
4
+"""
5
+import glob
6
+import os
7
+import subprocess
8
+import sys
9
+
10
+from setuptools import Command
11
+
12
+from .config import Config
13
+from .hooks import load_hooks
14
+from .utils import build_args, write_message
15
+
16
+
17
+class build_ui(Command):
18
+    """
19
+    Builds the Qt ui files as described in pyuic.json (or pyuic.cfg).
20
+    """
21
+    user_options = [
22
+        ('force', None,
23
+         'Force flag, will force recompilation of every ui/qrc file'),
24
+    ]
25
+
26
+    def initialize_options(self):
27
+        self.force = False
28
+        self._hooks = load_hooks()
29
+
30
+    def finalize_options(self):
31
+        try:
32
+            self.cfg = Config()
33
+            self.cfg.load()
34
+        except (IOError, OSError):
35
+            write_message('cannot open pyuic.json (or pyuic.cfg)', 'red')
36
+            self.cfg = None
37
+
38
+    def is_outdated(self, src, dst, ui):
39
+        if src.endswith('.qrc') or self.force:
40
+            return True
41
+        outdated = (not os.path.exists(dst) or
42
+                    (os.path.getmtime(src) > os.path.getmtime(dst)))
43
+        if not outdated and not ui:
44
+            # for qrc files, we need to check each individual resources.
45
+            # If one of them is newer than the dst file, the qrc file must be
46
+            # considered as outdated
47
+            # file paths are relative to the qrc file path
48
+            qrc_dirname = os.path.dirname(src)
49
+            with open(src, 'r') as f:
50
+                lines = f.read().splitlines()
51
+                lines = [l for l in lines if '<file>' in l]
52
+            cwd = os.getcwd()
53
+            os.chdir(qrc_dirname)
54
+            for line in lines:
55
+                filename = line.replace('<file>', '').replace(
56
+                    '</file>', '').strip()
57
+                filename = os.path.abspath(filename)
58
+                if os.path.getmtime(filename) > os.path.getmtime(dst):
59
+                    outdated = True
60
+                    break
61
+            os.chdir(cwd)
62
+        return outdated
63
+
64
+    def run(self):
65
+        if not self.cfg:
66
+            return
67
+        for glob_exp, dest in self.cfg.files:
68
+            for src in glob.glob(glob_exp):
69
+                if not os.path.exists(src):
70
+                    write_message('skipping target %s, file not found' % src, 'yellow')
71
+                    continue
72
+                src = os.path.join(os.getcwd(), src)
73
+                dst = os.path.join(os.getcwd(), dest)
74
+                ui = True
75
+                if src.endswith('.ui'):
76
+                    ext = '_ui.py'
77
+                    cmd = self.cfg.uic_command()
78
+                elif src.endswith('.qrc'):
79
+                    ui = False
80
+                    ext = '_rc.py'
81
+                    cmd = self.cfg.rcc_command()
82
+                else:
83
+                    continue
84
+                filename = os.path.split(src)[1]
85
+                filename = os.path.splitext(filename)[0]
86
+                dst = os.path.join(dst, filename + ext)
87
+                try:
88
+                    os.makedirs(os.path.split(dst)[0])
89
+                except OSError:
90
+                    pass
91
+
92
+                if self.is_outdated(src, dst, ui):
93
+                    try:
94
+                        cmd = build_args(cmd, src, dst)
95
+                        subprocess.check_call(cmd)
96
+                        cmd = ' '.join(cmd)
97
+                    except subprocess.CalledProcessError as e:
98
+                        if e.output:
99
+                            write_message(cmd, 'yellow')
100
+                            write_message(e.output.decode(sys.stdout.encoding), 'red')
101
+                        else:
102
+                            write_message(cmd, 'red')
103
+                    except OSError as e:
104
+                        write_message(cmd, 'yellow')
105
+                        write_message(str(e), 'red')
106
+                    else:
107
+                        write_message(cmd, 'green')
108
+                    for hookname in self.cfg.hooks:
109
+                        try:
110
+                            hook = self._hooks[hookname]
111
+                        except KeyError:
112
+                            write_message('warning, unknonw hook: %r' % hookname, 'yellow')
113
+                        else:
114
+                            write_message('running hook %r' % hookname, 'blue')
115
+                            hook(dst)
116
+                else:
117
+                    write_message('skipping %s, up to date' % src)

+ 5
- 1
setup.py View File

@@ -3,7 +3,11 @@
3 3
 # Requires PyQt5 and compiltion of GUI files via pyuic 
4 4
 from setuptools import setup, Extension
5 5
 from setuptools.command.build_py import build_py
6
-from pyqt_distutils.build_ui import build_ui
6
+
7
+try:
8
+    from pyqt_distutils.build_ui import build_ui
9
+except:
10
+    from thirdparty import buuild_ui
7 11
 
8 12
 class custom_build_py(build_py):
9 13
     def run(self):

Loading…
Cancel
Save