python-lottie  0.6.11+devcecd248
A framework to work with lottie files and telegram animated stickers (tgs)
import_export.py
Go to the documentation of this file.
1 import threading
2 from functools import reduce
3 from PyQt5 import QtCore, QtWidgets, QtGui
4 from PyQt5.QtCore import Qt
5 
6 from ..exporters.base import exporters
7 from ..importers.base import importers
8 from ..parsers.baseporter import IoProgressReporter, ExtraOption
9 
10 
12  def __init__(self):
13  self.dialogs = {}
14  self.threads = {}
15  self.lock = threading.Lock()
16  self.id = 0
17 
18  @classmethod
19  def set_global(cls):
20  IoProgressReporter.instance = cls()
21 
22  def gen_id(self, parent):
23  self.id += 1
24  with self.lock:
25  dialog = QtWidgets.QProgressDialog(parent)
26  dialog.setCancelButton(None)
27  dialog.setWindowModality(Qt.ApplicationModal)
28  self.dialogs[self.id] = dialog
29  return self.id
30 
31  def get_thread_dialog(self):
32  with self.lock:
33  id = threading.current_thread().ident
34  return self.dialogs[self.threads[id]]
35 
36  def setup(self, title, id):
37  with self.lock:
38  tid = threading.current_thread().ident
39  self.threads[tid] = id
40  dialog = self.dialogs[id]
41 
42  dialog.setWindowTitle(title)
43  dialog.hide()
44 
45  def report_progress(self, title, value, total):
46  dialog = self.get_thread_dialog()
47  dialog.show()
48  dialog.setValue(value)
49  dialog.setMaximum(total)
50  dialog.setLabelText(title)
51 
52  def report_message(self, message):
53  dialog = self.get_thread_dialog()
54  dialog.show()
55  dialog.setRange(0, 0)
56  dialog.setLabelText(message)
57 
58  def cleanup(self):
59  with self.lock:
60  id = threading.current_thread().ident
61  dialog = self.dialogs.pop(self.threads.pop(id))
62  dialog.hide()
63  dialog.deleteLater()
64 
65 
67  def __init__(self, porter):
68  self.porter = porter
69  self.file_filter = "%s (%s)" % (porter.name, " ".join("*.%s" % e for e in porter.extensions))
70  self._dialog = None
71  self.widgets = {}
72 
73  def _build_dialog(self):
74  self._dialog = QtWidgets.QDialog()
75  self._dialog.setWindowTitle("Export to %s" % self.porter.name)
76  layout = QtWidgets.QFormLayout()
77  self._dialog.setLayout(layout)
78 
79  for go in self.porter.generic_options:
80  self._generic_option(layout, go)
81 
82  for option in self.porter.extra_options:
83  self._add_option(layout, option)
84 
85  button_box = QtWidgets.QDialogButtonBox(QtWidgets.QDialogButtonBox.Ok | QtWidgets.QDialogButtonBox.Cancel)
86  button_box.accepted.connect(self._dialog.accept)
87  button_box.rejected.connect(self._dialog.reject)
88  layout.addRow(button_box)
89 
90  def _add_option(self, layout, option: ExtraOption):
91  if option.dest in self.widgets:
92  return
93  label = QtWidgets.QLabel(option.name.replace("_", " ").title())
94 
95  default = option.kwargs.get("default", None)
96  option_type = option.kwargs.get("type", str)
97 
98  if option.kwargs.get("action") == "store_true":
99  widget = QtWidgets.QCheckBox()
100  widget.setChecked(False)
101  getter = widget.isChecked
102  elif option.kwargs.get("action") == "store_false":
103  widget = QtWidgets.QCheckBox()
104  labtext = label.text()
105  if labtext.startswith("No "):
106  label.setText(labtext[3:])
107  widget.setChecked(True)
108  getter = widget.isChecked
109  elif "choices" in option.kwargs:
110  widget = QtWidgets.QComboBox()
111  for choice in option.kwargs["choices"]:
112  widget.addItem(str(choice))
113  if default:
114  widget.setCurrentText(str(default))
115  getter = lambda: option_type(widget.currentText())
116  elif option_type is int:
117  widget = QtWidgets.QSpinBox()
118  widget.setMinimum(-1000)
119  widget.setMaximum(1000)
120  if default is not None:
121  widget.setValue(int(default))
122  getter = widget.value
123  else:
124  widget = QtWidgets.QLineEdit()
125  if default is not None:
126  widget.setText(str(default))
127  getter = widget.text
128 
129  help = option.kwargs.get("help", "")
130  widget.setWhatsThis(help)
131  widget.setToolTip(help)
132 
133  widget.setObjectName(option.dest)
134  self.widgets[option.dest] = getter
135  layout.addRow(label, widget)
136 
137  @property
138  def needs_dialog(self):
139  return self.porter.generic_options or self.porter.extra_options
140 
141  @property
142  def dialog(self):
143  if not self._dialog:
144  self._build_dialog()
145  return self._dialog
146 
147  def get_options(self):
148  return {
149  name: getter()
150  for name, getter in self.widgets.items()
151  }
152 
153  def prompt_options(self, parent):
154  if self.needs_dialog:
155  self.dialog.setParent(parent)
156  self.dialog.setWindowFlags(Qt.Dialog)
157  if self.dialog.exec_() != QtWidgets.QDialog.DialogCode.Accepted:
158  return None
159 
160  return self.get_options()
161 
162  def _generic_option(self, layout, go):
163  pass
164 
165 
166 class GuiExporter(GuiBasePorter):
167  def _generic_option(self, layout, go):
168  if go == "pretty":
169  self._add_option(layout, ExtraOption("pretty", action="store_true", help="Pretty print"))
170  if go == "frame":
171  self._add_option(layout, ExtraOption("frame", type=int, help="Frame to extract"))
172 
173  @property
174  def exporter(self):
175  return self.porter
176 
177 
179  @property
180  def importer(self):
181  return self.porter
182 
183 
184 class ExportThread(QtCore.QThread):
185  def __init__(self, parent, exporter, animation, file_name, options):
186  super().__init__()
187  self.id = IoProgressReporter.instance.gen_id(parent)
188  self.animation = animation
189  self.exporter = exporter
190  self.file_name = file_name
191  self.options = options
192 
193  def run(self):
194  IoProgressReporter.instance.setup("Export to %s" % self.exporter.name, self.id)
195  try:
196  self.exporter.process(self.animation, self.file_name, **self.options)
197  except Exception:
198  IoProgressReporter.instance.report_message("Error on export")
199  IoProgressReporter.instance.cleanup()
200 
201 
202 gui_exporters = list(map(GuiExporter, exporters))
203 gui_importers = list(map(GuiImporter, importers))
204 
205 
206 def get_open_filename(parent, title, dirname):
207  extensions = reduce(lambda a, b: a | b, (set(gi.importer.extensions) for gi in gui_importers))
208  all_files = "All Supported Files (%s)" % " ".join("*.%s" % ex for ex in extensions)
209  filters = all_files + ";;" + ";;".join(ge.file_filter for ge in gui_importers)
210  file_name, filter = QtWidgets.QFileDialog.getOpenFileName(
211  parent, title, dirname, filters
212  )
213  if file_name:
214  if filter == all_files:
215  importer = gui_importer_from_filename(file_name)
216  if importer:
217  return file_name, importer
218  else:
219  for importer in gui_importers:
220  if importer.file_filter == filter:
221  return file_name, importer
222 
223  return None, None
224 
225 
226 def get_save_filename(parent, title, dirname):
227  extensions = reduce(lambda a, b: a | b, (set(gi.exporter.extensions) for gi in gui_exporters))
228  all_files = "All Supported Files (%s)" % " ".join("*.%s" % ex for ex in extensions)
229  filters = all_files + ";;" + ";;".join(ge.file_filter for ge in gui_exporters)
230  file_name, filter = QtWidgets.QFileDialog.getSaveFileName(
231  parent, title, dirname, filters
232  )
233 
234  if file_name:
235  if filter == all_files:
236  exporter = gui_exporter_from_filename(file_name)
237  if exporter:
238  return file_name, exporter
239  else:
240  for exporter in gui_exporters:
241  if exporter.file_filter == filter:
242  return file_name, exporter
243 
244  return None, None
245 
246 
247 def start_export(parent, exporter, animation, file_name, options):
248  thread = ExportThread(parent, exporter, animation, file_name, options)
249  thread.start()
250  return thread
251 
252 
254  importer = importers.get_from_filename(filename)
255  for gip in gui_importers:
256  if gip.importer is importer:
257  return gip
258  return None
259 
260 
262  exporter = exporters.get_from_filename(filename)
263  for gip in gui_exporters:
264  if gip.exporter is exporter:
265  return gip
266  return None
lottie.gui.import_export.GuiProgressReporter.cleanup
def cleanup(self)
Definition: import_export.py:58
lottie.gui.import_export.GuiProgressReporter.set_global
def set_global(cls)
Definition: import_export.py:19
lottie.gui.import_export.GuiProgressReporter.threads
threads
Definition: import_export.py:14
lottie.gui.import_export.gui_exporter_from_filename
def gui_exporter_from_filename(filename)
Definition: import_export.py:261
lottie.gui.import_export.ExportThread.file_name
file_name
Definition: import_export.py:190
lottie.gui.import_export.GuiProgressReporter.report_progress
def report_progress(self, title, value, total)
Definition: import_export.py:45
lottie.gui.import_export.GuiBasePorter._build_dialog
def _build_dialog(self)
Definition: import_export.py:73
lottie.gui.import_export.GuiBasePorter.prompt_options
def prompt_options(self, parent)
Definition: import_export.py:153
lottie.gui.import_export.ExportThread.run
def run(self)
Definition: import_export.py:193
lottie.gui.import_export.GuiProgressReporter.get_thread_dialog
def get_thread_dialog(self)
Definition: import_export.py:31
lottie.gui.import_export.get_save_filename
def get_save_filename(parent, title, dirname)
Definition: import_export.py:226
lottie.gui.import_export.GuiExporter.exporter
def exporter(self)
Definition: import_export.py:174
lottie.gui.import_export.ExportThread.id
id
Definition: import_export.py:187
lottie.gui.import_export.GuiProgressReporter.id
id
Definition: import_export.py:16
lottie.gui.import_export.ExportThread.__init__
def __init__(self, parent, exporter, animation, file_name, options)
Definition: import_export.py:185
lottie.gui.import_export.GuiProgressReporter.__init__
def __init__(self)
Definition: import_export.py:12
lottie.gui.import_export.GuiProgressReporter
Definition: import_export.py:11
lottie.gui.import_export.GuiBasePorter.file_filter
file_filter
Definition: import_export.py:69
lottie.gui.import_export.GuiBasePorter
Definition: import_export.py:66
lottie.gui.import_export.ExportThread.options
options
Definition: import_export.py:191
lottie.gui.import_export.GuiProgressReporter.lock
lock
Definition: import_export.py:15
lottie.gui.import_export.GuiBasePorter.needs_dialog
def needs_dialog(self)
Definition: import_export.py:138
lottie.gui.import_export.GuiBasePorter.__init__
def __init__(self, porter)
Definition: import_export.py:67
lottie.gui.import_export.GuiBasePorter.widgets
widgets
Definition: import_export.py:71
lottie.gui.import_export.ExportThread.exporter
exporter
Definition: import_export.py:189
lottie.gui.import_export.GuiBasePorter.porter
porter
Definition: import_export.py:68
lottie.gui.import_export.GuiProgressReporter.setup
def setup(self, title, id)
Definition: import_export.py:36
lottie.gui.import_export.GuiImporter
Definition: import_export.py:178
lottie.gui.import_export.ExportThread.animation
animation
Definition: import_export.py:188
lottie.gui.import_export.gui_importer_from_filename
def gui_importer_from_filename(filename)
Definition: import_export.py:253
lottie.parsers.baseporter.IoProgressReporter
Definition: baseporter.py:126
lottie.gui.import_export.GuiProgressReporter.report_message
def report_message(self, message)
Definition: import_export.py:52
lottie.gui.import_export.start_export
def start_export(parent, exporter, animation, file_name, options)
Definition: import_export.py:247
lottie.gui.import_export.GuiBasePorter.get_options
def get_options(self)
Definition: import_export.py:147
lottie.gui.import_export.GuiBasePorter._dialog
_dialog
Definition: import_export.py:70
lottie.gui.import_export.GuiBasePorter._add_option
def _add_option(self, layout, ExtraOption option)
Definition: import_export.py:90
lottie.gui.import_export.GuiImporter.importer
def importer(self)
Definition: import_export.py:180
lottie.gui.import_export.ExportThread
Definition: import_export.py:184
lottie.gui.import_export.GuiBasePorter.dialog
def dialog(self)
Definition: import_export.py:142
lottie.gui.import_export.GuiProgressReporter.dialogs
dialogs
Definition: import_export.py:13
lottie.gui.import_export.GuiBasePorter._generic_option
def _generic_option(self, layout, go)
Definition: import_export.py:162
lottie.gui.import_export.GuiProgressReporter.gen_id
def gen_id(self, parent)
Definition: import_export.py:22
lottie.gui.import_export.get_open_filename
def get_open_filename(parent, title, dirname)
Definition: import_export.py:206