Pymecavideo 8.0
Étude cinématique à l'aide de vidéos
globdef.py
1# -*- coding: utf-8 -*-
2"""
3 suivi_auto, a module for pymecavideo:
4 a program to track moving points in a video frameset
5
6 Copyright (C) 2007 Jean-Baptiste Butet <ashashiwa@gmail.com>
7 Copyright (C) 2023 Georges Khaznadar <georgesk@debian.org>
8
9 This program is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
21"""
22
23from version import Version
24from PyQt6.QtCore import QStandardPaths, QTimer
25from PyQt6.QtGui import QPixmap, QCursor
26from PyQt6.QtWidgets import QApplication
27
28import subprocess, os, sys, re
29licence = {}
30licence['en'] = """
31 pymecavideo version %s:
32
33 a program to track moving points in a video frameset
34
35 Copyright (C) 2007-2008 Jean-Baptiste Butet <ashashiwa@gmail.com>
36
37 Copyright (C) 2007-2018 Georges Khaznadar <georgesk.debian.org>
38
39 This program is free software: you can redistribute it and/or modify
40 it under the terms of the GNU General Public License as published by
41 the Free Software Foundation, either version 3 of the License, or
42 (at your option) any later version.
43
44 This program is distributed in the hope that it will be useful,
45 but WITHOUT ANY WARRANTY; without even the implied warranty of
46 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
47 GNU General Public License for more details.
48
49 You should have received a copy of the GNU General Public License
50 along with this program. If not, see <http://www.gnu.org/licenses/>.
51"""
52
53licence['fr'] = u"""
54 pymecavideo version %s :
55
56 un programme pour tracer les trajectoires des points dans une vidéo.
57
58 Copyright (C) 2007-2008 Jean-Baptiste Butet <ashashiwa@gmail.com>
59
60 Copyright (C) 2007-2018 Georges Khaznadar <georgesk.debian.org>
61
62 Ce projet est un logiciel libre : vous pouvez le redistribuer, le modifier selon les terme de la GPL (GNU Public License) dans les termes de la Free Software Foundation concernant la version 3 ou plus de la dite licence.
63
64 Ce programme est fait avec l'espoir qu'il sera utile mais SANS AUCUNE GARANTIE. Lisez la licence pour plus de détails.
65
66 <http://www.gnu.org/licenses/>.
67"""
68
69
70#
71# Version de pymecavideo
72#
73VERSION = Version
74
75
76def testerDossier(listDir, defaut=""):
77 for dir_ in listDir:
78 if os.path.exists(dir_):
79 return dir_
80 return defaut
81
82
83FILE_ENCODING = sys.getfilesystemencoding()
84DEFAUT_ENCODING = "utf-8"
85
86######################################################################################
87
88
89def toFileEncoding(path):
90 try:
91 path = path.decode(DEFAUT_ENCODING)
92 return path.encode(FILE_ENCODING)
93 except:
94 return path
95#######################################################################################
96# HOME_PATH : Dossier des documents
97# APP_PATH : Dossier du lancement de l'application pymecavideo
98#CONF_PATH : Sous linux, ça donnera /home/<user>/.local/share/pymecavideo
99# DATA_PATH : Dossier contenant les datas, selon scenario
100#ICON_PATH : DATA_PATH / icones
101#LANG_PATH : DATA_PATH / lang
102#HELP_PATH : DATA_PATH / lang
103#VIDEO_PATH : DATA_PATH / videos
104
105
106# APP_PATH
107
108 #
109 # Les deuxlignes suivantes permettent de lancer le script pymecavideo.py depuis n'importe
110 # quel répertoire sans que l'utilisation de chemins
111 # relatifs ne soit perturbée
112 #
113PATH = os.path.dirname(os.path.abspath(sys.argv[0]))
114sys.path.append(PATH)
115APP_PATH = PATH
116
117# DATA_PATH
118if sys.platform == 'win32':
119 DATA_PATH = os.path.join(APP_PATH, "data")
120else:
121 DATA_PATH = testerDossier(
122 (os.path.join("..", "data"), '/usr/share/pymecavideo/data',))
123
124# CONF_PATH
125CONF_PATH = os.path.join(
126 QStandardPaths.writableLocation(QStandardPaths.StandardLocation.AppLocalDataLocation),
127 "pymecavideo"
128)
129
130# HOME_PATH
131HOME_PATH = QStandardPaths.writableLocation(QStandardPaths.StandardLocation.HomeLocation)
132
133# DOCUMENTS_PATH
134DOCUMENT_PATH = QStandardPaths.writableLocation(QStandardPaths.StandardLocation.DocumentsLocation)
135
136# DOSSIERS
137#
138# dossier des icones
139#
140ICON_PATH = testerDossier(
141 (os.path.join(DATA_PATH, "icones"), os.path.join("..", "data", "icones"),
142 '/usr/share/python3-mecavideo/icones',
143 '/usr/share/pymecavideo/icones',
144 '/usr/share/icons')
145)
146
147#
148# Dossier des langues
149#
150LANG_PATH = testerDossier((os.path.join(DATA_PATH, "lang"), os.path.join("..", "data", "lang"),
151 '/usr/share/pyshared/pymecavideo/lang', '/usr/share/python3-mecavideo/lang',
152 '/usr/share/pymecavideo/lang'))
153#
154# Dossier des vidéos
155#
156VIDEO_PATH = testerDossier((os.path.join(DATA_PATH, "video"), os.path.join("..", "data", "video"),
157 '/usr/share/pyshared/pymecavideo/video', '/usr/share/python3-mecavideo/video',
158 '/usr/share/pymecavideo/video'))
159
160#
161# Dossier de l'aide
162#
163HELP_PATH = testerDossier((os.path.join(DATA_PATH, "help"), os.path.join("..", "data", "help"), "/usr/share/doc/python-mecavideo/html",
164 "/usr/share/doc/HTML/fr/pymecavideo"))
165
166
167ERROR_FILE = os.path.join(CONF_PATH, 'pymecavideo.exe' + '.log')
168
169
170def GetChildStdErr():
171 """ Renvoie le handler par défaut pour les Popen()
172 (pour contourner un bug ... sous windows)
173 """
174 if sys.platform == 'win32':
175 import win32process
176
177 if hasattr(sys.stderr, 'fileno'):
178 childstderr = sys.stderr
179 elif hasattr(sys.stderr, '_file') and hasattr(sys.stderr._file, 'fileno'):
180 childstderr = sys.stderr._file
181 else:
182 # Give up and point child stderr at nul
183 childStderrPath = 'nul'
184 childstderr = open(childStderrPath, 'a')
185 return childstderr, win32process.CREATE_NO_WINDOW
186 else:
187 return None, 0
188
189cible_icon = os.path.join(ICON_PATH, "curseur_cible.svg")
190
191inhibitions = []; # liste de mots-clés pour inhiber des actions trop rapides
192
193def inhibe(motcle, duree):
194 """
195 Qt 5.15 a un bug : certains évenements sont lancés deux fois
196 On peut y remédier avec un timer.
197
198 Cette fonction teste si un mot-clé est dans la liste globdef.inhibe
199 s'il n'y est pas, elle l'y place et fait en sorte de l'effacer
200 après une durée de duree millisecondes
201
202 @param motcle le mot-clé d'inhibition
203 @param duree la durée du tabou sur le mot-clé
204
205 @return vrai si le mot-clé est encore là dans la liste des inhibitions,
206 faux s'il n'était pas là (et alors il y est placé pour quelques temps)
207 """
208 result = motcle in inhibitions
209 if not result:
210 inhibitions.append(motcle)
211 def efface(mot):
212 def callback():
213 if mot in inhibitions:
214 inhibitions.remove(mot)
215 return
216 return callback
217 QTimer.singleShot(duree, efface(motcle))
218 return result
219
220# modèle pour reconnaître des flottants, voir
221# https://stackoverflow.com/questions/12929308/python-regular-expression-that-matches-floating-point-numbers
222
223pattern_float = re.compile(r'^[+-]?(\d+(\.\d*)?|\.\d+)([eE][+-]?\d+)?$')
224
225import functools
226def time_it(func):
227 """Timestamp decorator for dedicated functions"""
228 @functools.wraps(func)
229 def wrapper(*args, **kwargs):
230 start = time.time()
231 result = func(*args, **kwargs)
232 elapsed = time.time() - start
233 mlsec = repr(elapsed).split('.')[1][:3]
234 readable = time.strftime(
235 "%H:%M:%S.{}".format(mlsec), time.gmtime(elapsed))
236 print('Function "{}": {} sec'.format(func.__name__, readable))
237 return result
238 return wrapper
239