deffcode 0.2.5__py3-none-any.whl → 0.2.6__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
deffcode/ffdecoder.py CHANGED
@@ -19,6 +19,7 @@ limitations under the License.
19
19
  """
20
20
 
21
21
  # import the necessary packages
22
+ import platform
22
23
  import logging
23
24
  import numpy as np
24
25
  import subprocess as sp
@@ -106,10 +107,16 @@ class FFdecoder:
106
107
  # handles user-defined parameters
107
108
  self.__extra_params = {}
108
109
 
109
- # handle process to be frames written
110
+ # handles process to be frames written
110
111
  self.__process = None
111
112
 
112
- # handle exclusive metadata
113
+ # handles disabling window for ffmpeg subprocess on Windows
114
+ self.__ffmpeg_window_disabler_patch = False
115
+
116
+ # checks machine OS
117
+ self.__machine_OS = platform.system()
118
+
119
+ # handles exclusive metadata
113
120
  self.__ff_pixfmt_metadata = None # metadata
114
121
  self.__raw_frame_num = None # raw-frame number
115
122
  self.__raw_frame_pixfmt = None # raw-frame pixformat
@@ -127,23 +134,26 @@ class FFdecoder:
127
134
  # operation mode variable
128
135
  self.__opmode = None
129
136
 
130
- # handle termination
137
+ # handles termination
131
138
  self.__terminate_stream = False
132
139
 
133
140
  # cleans and reformat user-defined parameters
134
141
  self.__extra_params = {
135
- str(k).strip(): str(v).strip()
136
- if not (v is None) and not isinstance(v, (dict, list, int, float, tuple))
137
- else v
142
+ str(k).strip(): (
143
+ str(v).strip()
144
+ if not (v is None)
145
+ and not isinstance(v, (dict, list, int, float, tuple))
146
+ else v
147
+ )
138
148
  for k, v in ffparams.items()
139
149
  }
140
150
 
141
- # handle custom Sourcer API params
151
+ # handles custom Sourcer API params
142
152
  sourcer_params = self.__extra_params.pop("-custom_sourcer_params", {})
143
153
  # reset improper values
144
154
  sourcer_params = {} if not isinstance(sourcer_params, dict) else sourcer_params
145
155
 
146
- # handle user ffmpeg pre-headers(parameters such as `-re`) parameters (must be a list)
156
+ # handles user ffmpeg pre-headers(parameters such as `-re`) parameters (must be a list)
147
157
  self.__ffmpeg_prefixes = self.__extra_params.pop("-ffprefixes", [])
148
158
  # check if not valid type
149
159
  if not isinstance(self.__ffmpeg_prefixes, list):
@@ -205,9 +215,29 @@ class FFdecoder:
205
215
  if not (isinstance(self.__cv_patch, bool)):
206
216
  self.__cv_patch = False
207
217
  self.__verbose_logs and logger.critical(
208
- "Enforcing OpenCV compatibility patch for YUV/NV frames."
218
+ "Enforcing OpenCV compatibility patch for YUV/NV video frames."
209
219
  )
210
220
 
221
+ # handle disabling window for ffmpeg subprocess on Windows OS
222
+ # this patch prevents ffmpeg creation window from opening when
223
+ # building exe files
224
+ ffmpeg_window_disabler_patch = self.__extra_params.pop(
225
+ "-disable_ffmpeg_window", False
226
+ )
227
+ if ffmpeg_window_disabler_patch and isinstance(
228
+ ffmpeg_window_disabler_patch, bool
229
+ ):
230
+ # check if value is valid
231
+ if self.__machine_OS != "Windows" or self.__verbose_logs:
232
+ logger.warning(
233
+ "Optional `-disable_ffmpeg_window` flag is only available on Windows OS with `verbose=False`. Discarding!"
234
+ )
235
+ else:
236
+ self.__ffmpeg_window_disabler_patch = ffmpeg_window_disabler_patch
237
+ else:
238
+ # handle improper values
239
+ self.__ffmpeg_window_disabler_patch = False
240
+
211
241
  # handle pass-through audio mode works in conjunction with WriteGear [TODO]
212
242
  self.__passthrough_mode = self.__extra_params.pop("-passthrough_audio", False)
213
243
  if not (isinstance(self.__passthrough_mode, bool)):
@@ -288,7 +318,6 @@ class FFdecoder:
288
318
  self.__custom_resolution = None
289
319
 
290
320
  def formulate(self):
291
-
292
321
  """
293
322
  This method formulates all necessary FFmpeg pipeline arguments and executes it inside the FFmpeg `subprocess` pipe.
294
323
 
@@ -420,13 +449,15 @@ class FFdecoder:
420
449
  else:
421
450
  logger.warning(
422
451
  "{} Switching to default `{}` pixel-format!".format(
423
- "Provided FFmpeg does not supports `{}` pixel-format.".format(
424
- self.__sourcer_metadata["output_frames_pixfmt"]
425
- if "output_frames_pixfmt" in self.__sourcer_metadata
426
- else self.__frame_format
427
- )
428
- if self.__frame_format != "null"
429
- else "No usable pixel-format defined.",
452
+ (
453
+ "Provided FFmpeg does not supports `{}` pixel-format.".format(
454
+ self.__sourcer_metadata["output_frames_pixfmt"]
455
+ if "output_frames_pixfmt" in self.__sourcer_metadata
456
+ else self.__frame_format
457
+ )
458
+ if self.__frame_format != "null"
459
+ else "No usable pixel-format defined."
460
+ ),
430
461
  default_pixfmt,
431
462
  )
432
463
  )
@@ -467,9 +498,9 @@ class FFdecoder:
467
498
  self.__raw_frame_pixfmt = rawframe_pixfmt
468
499
  # also override as metadata(if available)
469
500
  if "output_frames_pixfmt" in self.__sourcer_metadata:
470
- self.__sourcer_metadata[
471
- "output_frames_pixfmt"
472
- ] = self.__raw_frame_pixfmt
501
+ self.__sourcer_metadata["output_frames_pixfmt"] = (
502
+ self.__raw_frame_pixfmt
503
+ )
473
504
 
474
505
  # handle raw-frame resolution
475
506
  # notify FFmpeg `-s` parameter cannot be assigned directly
@@ -804,9 +835,11 @@ class FFdecoder:
804
835
  self.__verbose_logs and logger.info(
805
836
  "Updating `{}`{} metadata property to `{}`.".format(
806
837
  key,
807
- " and its counterpart"
808
- if key in counterpart_prop.values()
809
- else "",
838
+ (
839
+ " and its counterpart"
840
+ if key in counterpart_prop.values()
841
+ else ""
842
+ ),
810
843
  value[key],
811
844
  )
812
845
  )
@@ -838,7 +871,6 @@ class FFdecoder:
838
871
  raise ValueError("Invalid datatype metadata assigned. Aborting!")
839
872
 
840
873
  def __launch_FFdecoderline(self, input_params, output_params):
841
-
842
874
  """
843
875
  This Internal method executes FFmpeg pipeline arguments inside a `subprocess` pipe in a new process.
844
876
 
@@ -877,7 +909,13 @@ class FFdecoder:
877
909
  else:
878
910
  # In silent mode
879
911
  self.__process = sp.Popen(
880
- cmd, stdin=sp.DEVNULL, stdout=sp.PIPE, stderr=sp.DEVNULL
912
+ cmd,
913
+ stdin=sp.DEVNULL,
914
+ stdout=sp.PIPE,
915
+ stderr=sp.DEVNULL,
916
+ creationflags=( # this prevents ffmpeg creation window from opening when building exe files on Windows
917
+ sp.DETACHED_PROCESS if self.__ffmpeg_window_disabler_patch else 0
918
+ ),
881
919
  )
882
920
 
883
921
  def terminate(self):
@@ -898,9 +936,7 @@ class FFdecoder:
898
936
  # close `stdout` output
899
937
  self.__process.stdout and self.__process.stdout.close()
900
938
  # terminate/kill process if still processing
901
- if self.__process.poll() is None:
902
- # demuxers prefer kill
903
- self.__process.kill()
939
+ self.__process.poll() is None and self.__process.terminate()
904
940
  # wait if not exiting
905
941
  self.__process.wait()
906
942
  self.__process = None
deffcode/ffhelper.py CHANGED
@@ -342,14 +342,15 @@ def get_supported_demuxers(path):
342
342
 
343
343
  **Returns:** List of supported demuxers.
344
344
  """
345
+ # extract and clean FFmpeg output
345
346
  demuxers = check_sp_output([path, "-hide_banner", "-demuxers"])
346
347
  splitted = [x.decode("utf-8").strip() for x in demuxers.split(b"\n")]
347
- supported_demuxers = splitted[splitted.index("--") + 1 : len(splitted) - 1]
348
- # compile regex
349
- finder = re.compile(r"\s\s[a-z0-9_,-]+\s+")
350
- # find all outputs
351
- outputs = finder.findall("\n".join(supported_demuxers))
352
- # return output findings
348
+ split_index = [idx for idx, s in enumerate(splitted) if "--" in s][0]
349
+ supported_demuxers = splitted[split_index + 1 : len(splitted) - 1]
350
+ # search all demuxers
351
+ outputs = [re.search(r"\s[a-z0-9_,-]{2,}\s", d) for d in supported_demuxers]
352
+ outputs = [o.group(0) for o in outputs if o]
353
+ # return demuxers output
353
354
  return [o.strip() if not ("," in o) else o.split(",")[-1].strip() for o in outputs]
354
355
 
355
356
 
@@ -518,10 +519,12 @@ def extract_device_n_demuxer(path, machine_OS=None, verbose=False):
518
519
  logger.info(
519
520
  "[{}]: {}".format(
520
521
  idx,
521
- dev
522
- if machine_OS != "Linux"
523
- else "{} at path `{}`".format(
524
- next(iter(dev.values()))[0], next(iter(dev.keys()))
522
+ (
523
+ dev
524
+ if machine_OS != "Linux"
525
+ else "{} at path `{}`".format(
526
+ next(iter(dev.values()))[0], next(iter(dev.keys()))
527
+ )
525
528
  ),
526
529
  )
527
530
  )
@@ -632,8 +635,11 @@ def is_valid_url(path, url=None, verbose=False):
632
635
  protocols = check_sp_output([path, "-hide_banner", "-protocols"])
633
636
  splitted = [x.decode("utf-8").strip() for x in protocols.split(b"\n")]
634
637
  supported_protocols = splitted[splitted.index("Output:") + 1 : len(splitted) - 1]
635
- # rtsp is a demuxer somehow
636
- supported_protocols += ["rtsp"] if "rtsp" in get_supported_demuxers(path) else []
638
+ # RTSP is a demuxer somehow
639
+ # support both RTSP and RTSPS(over SSL)
640
+ supported_protocols += (
641
+ ["rtsp", "rtsps"] if "rtsp" in get_supported_demuxers(path) else []
642
+ )
637
643
  # Test and return result whether scheme is supported
638
644
  if extracted_scheme_url and extracted_scheme_url in supported_protocols:
639
645
  verbose and logger.debug(
@@ -677,7 +683,7 @@ def check_sp_output(*args, **kwargs):
677
683
  retcode = process.poll()
678
684
  # handle return code
679
685
  if retcode and not (retrieve_stderr):
680
- logger.error("[Pipline-Error] :: {}".format(output.decode("utf-8")))
686
+ logger.error("[Pipeline-Error] :: {}".format(output.decode("utf-8")))
681
687
  cmd = kwargs.get("args")
682
688
  if cmd is None:
683
689
  cmd = args[0]
@@ -686,7 +692,7 @@ def check_sp_output(*args, **kwargs):
686
692
  raise error
687
693
  # raise error if no output
688
694
  bool(output) or bool(stderr) or logger.error(
689
- "[Pipline-Error] :: Pipline failed to exact any data from command: {}!".format(
695
+ "[Pipeline-Error] :: Pipeline failed to exact any data from command: {}!".format(
690
696
  args[0] if args else []
691
697
  )
692
698
  )
deffcode/sourcer.py CHANGED
@@ -87,7 +87,7 @@ class Sourcer:
87
87
  verbose (bool): enables/disables verbose.
88
88
  sourcer_params (dict): provides the flexibility to control supported internal and FFmpeg parameters.
89
89
  """
90
- # checks if machine in-use is running windows os or not
90
+ # checks machine OS
91
91
  self.__machine_OS = platform.system()
92
92
 
93
93
  # define internal parameters
@@ -100,9 +100,11 @@ class Sourcer:
100
100
 
101
101
  # sanitize sourcer_params
102
102
  self.__sourcer_params = {
103
- str(k).strip(): str(v).strip()
104
- if not isinstance(v, (dict, list, int, float, tuple))
105
- else v
103
+ str(k).strip(): (
104
+ str(v).strip()
105
+ if not isinstance(v, (dict, list, int, float, tuple))
106
+ else v
107
+ )
106
108
  for k, v in sourcer_params.items()
107
109
  }
108
110
 
@@ -199,6 +201,7 @@ class Sourcer:
199
201
 
200
202
  # various source stream params
201
203
  self.__default_video_resolution = "" # handles stream resolution
204
+ self.__default_video_orientation = "" # handles stream's video orientation
202
205
  self.__default_video_framerate = "" # handles stream framerate
203
206
  self.__default_video_bitrate = "" # handles stream's video bitrate
204
207
  self.__default_video_pixfmt = "" # handles stream's video pixfmt
@@ -218,6 +221,7 @@ class Sourcer:
218
221
  self.__output_frames_resolution = "" # handles output stream resolution
219
222
  self.__output_framerate = "" # handles output stream framerate
220
223
  self.__output_frames_pixfmt = "" # handles output frame pixel format
224
+ self.__output_orientation = "" # handles output frame orientation
221
225
 
222
226
  # check whether metadata probed or not?
223
227
  self.__metadata_probed = False
@@ -251,6 +255,7 @@ class Sourcer:
251
255
  if video_rfparams:
252
256
  self.__default_video_resolution = video_rfparams["resolution"]
253
257
  self.__default_video_framerate = video_rfparams["framerate"]
258
+ self.__default_video_orientation = video_rfparams["orientation"]
254
259
 
255
260
  # parse output parameters through filters (if available)
256
261
  if not (self.__metadata_output is None):
@@ -261,6 +266,7 @@ class Sourcer:
261
266
  if out_video_rfparams:
262
267
  self.__output_frames_resolution = out_video_rfparams["resolution"]
263
268
  self.__output_framerate = out_video_rfparams["framerate"]
269
+ self.__output_orientation = out_video_rfparams["orientation"]
264
270
  # parse output pixel-format
265
271
  self.__output_frames_pixfmt = self.__extract_video_pixfmt(
266
272
  default_stream=default_stream_indexes[0], extract_output=True
@@ -357,6 +363,7 @@ class Sourcer:
357
363
  "source_video_resolution": self.__default_video_resolution,
358
364
  "source_video_pixfmt": self.__default_video_pixfmt,
359
365
  "source_video_framerate": self.__default_video_framerate,
366
+ "source_video_orientation": self.__default_video_orientation,
360
367
  "source_video_decoder": self.__default_video_decoder,
361
368
  "source_duration_sec": self.__default_source_duration,
362
369
  "approx_video_nframes": (
@@ -385,6 +392,7 @@ class Sourcer:
385
392
  "output_frames_resolution": self.__output_frames_resolution,
386
393
  "output_frames_pixfmt": self.__output_frames_pixfmt,
387
394
  "output_framerate": self.__output_framerate,
395
+ "output_orientation": self.__output_orientation,
388
396
  }
389
397
  )
390
398
  else:
@@ -397,6 +405,7 @@ class Sourcer:
397
405
  "output_frames_resolution": self.__default_video_resolution,
398
406
  "output_frames_pixfmt": self.__default_video_pixfmt,
399
407
  "output_framerate": self.__default_video_framerate,
408
+ "output_orientation": self.__default_video_orientation,
400
409
  }
401
410
  )
402
411
  # log it
@@ -489,14 +498,18 @@ class Sourcer:
489
498
  self.__source_demuxer = source_demuxer
490
499
  self.__verbose_logs and logger.debug(
491
500
  "Successfully configured device `{}` at index `{}` with demuxer `{}`.".format(
492
- self.__extracted_devices_list[index]
493
- if self.__machine_OS != "Linux"
494
- else next(
495
- iter(self.__extracted_devices_list[index].values())
496
- )[0],
497
- index
498
- if index >= 0
499
- else len(self.__extracted_devices_list) + index,
501
+ (
502
+ self.__extracted_devices_list[index]
503
+ if self.__machine_OS != "Linux"
504
+ else next(
505
+ iter(self.__extracted_devices_list[index].values())
506
+ )[0]
507
+ ),
508
+ (
509
+ index
510
+ if index >= 0
511
+ else len(self.__extracted_devices_list) + index
512
+ ),
500
513
  self.__source_demuxer,
501
514
  )
502
515
  )
@@ -596,9 +609,11 @@ class Sourcer:
596
609
  ]
597
610
  if video_bitrate_text:
598
611
  selected_stream = video_bitrate_text[
599
- default_stream
600
- if default_stream > 0 and default_stream < len(video_bitrate_text)
601
- else 0
612
+ (
613
+ default_stream
614
+ if default_stream > 0 and default_stream < len(video_bitrate_text)
615
+ else 0
616
+ )
602
617
  ]
603
618
  filtered_bitrate = re.findall(
604
619
  r",\s[0-9]+\s\w\w[\/]s", selected_stream.strip()
@@ -630,9 +645,11 @@ class Sourcer:
630
645
  ]
631
646
  if meta_text:
632
647
  selected_stream = meta_text[
633
- default_stream
634
- if default_stream > 0 and default_stream < len(meta_text)
635
- else 0
648
+ (
649
+ default_stream
650
+ if default_stream > 0 and default_stream < len(meta_text)
651
+ else 0
652
+ )
636
653
  ]
637
654
  filtered_pixfmt = re.findall(
638
655
  r"Video:\s[a-z0-9_-]*", selected_stream.strip()
@@ -666,9 +683,11 @@ class Sourcer:
666
683
  )
667
684
  if meta_text:
668
685
  selected_stream = meta_text[
669
- default_stream
670
- if default_stream > 0 and default_stream < len(meta_text)
671
- else 0
686
+ (
687
+ default_stream
688
+ if default_stream > 0 and default_stream < len(meta_text)
689
+ else 0
690
+ )
672
691
  ]
673
692
  filtered_pixfmt = re.findall(
674
693
  r",\s[a-z][a-z0-9_-]*", selected_stream.strip()
@@ -695,9 +714,11 @@ class Sourcer:
695
714
  result = {}
696
715
  if meta_text:
697
716
  selected_stream = meta_text[
698
- default_stream
699
- if default_stream > 0 and default_stream < len(meta_text)
700
- else 0
717
+ (
718
+ default_stream
719
+ if default_stream > 0 and default_stream < len(meta_text)
720
+ else 0
721
+ )
701
722
  ]
702
723
  # filter data
703
724
  filtered_audio_bitrate = re.findall(
@@ -725,7 +746,7 @@ class Sourcer:
725
746
 
726
747
  def __extract_resolution_framerate(self, default_stream=0, extract_output=False):
727
748
  """
728
- This Internal method parses default video-stream resolution and framerate from metadata.
749
+ This Internal method parses default video-stream resolution, orientation, and framerate from metadata.
729
750
 
730
751
  Parameters:
731
752
  default_stream (int): selects specific audio-stream in case of multiple ones.
@@ -748,12 +769,30 @@ class Sourcer:
748
769
  if all(x in line for x in identifiers)
749
770
  ]
750
771
  )
772
+ # extract video orientation metadata if available
773
+ identifiers_orientation = ["displaymatrix:", "rotation"]
774
+ meta_text_orientation = (
775
+ [
776
+ line.strip()
777
+ for line in self.__ffsp_output.split("\n")
778
+ if all(x in line for x in identifiers_orientation)
779
+ ]
780
+ if not extract_output
781
+ else [
782
+ line.strip()
783
+ for line in self.__metadata_output.split("\n")
784
+ if all(x in line for x in identifiers_orientation)
785
+ ]
786
+ )
787
+ # use metadata if available
751
788
  result = {}
752
789
  if meta_text:
753
790
  selected_stream = meta_text[
754
- default_stream
755
- if default_stream > 0 and default_stream < len(meta_text)
756
- else 0
791
+ (
792
+ default_stream
793
+ if default_stream > 0 and default_stream < len(meta_text)
794
+ else 0
795
+ )
757
796
  ]
758
797
 
759
798
  # filter data
@@ -781,7 +820,23 @@ class Sourcer:
781
820
  if filtered_resolution:
782
821
  result["resolution"] = [int(x) for x in filtered_resolution[0]]
783
822
 
784
- return result if result and (len(result) == 2) else {}
823
+ # extract video orientation metadata
824
+ if meta_text_orientation:
825
+ selected_stream = meta_text_orientation[
826
+ (
827
+ default_stream
828
+ if default_stream > 0 and default_stream < len(meta_text)
829
+ else 0
830
+ )
831
+ ]
832
+ filtered_orientation = re.findall(
833
+ r"[-]?\d+\.\d+", selected_stream.strip()
834
+ )
835
+ result["orientation"] = float(filtered_orientation[0])
836
+ else:
837
+ result["orientation"] = 0.0
838
+
839
+ return result if result and (len(result) == 3) else {}
785
840
 
786
841
  def __extract_duration(self, inseconds=True):
787
842
  """
deffcode/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.2.5"
1
+ __version__ = "0.2.6"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: deffcode
3
- Version: 0.2.5
3
+ Version: 0.2.6
4
4
  Summary: A cross-platform High-performance & Flexible Real-time Video Frames Decoder in Python.
5
5
  Home-page: https://abhitronix.github.io/deffcode
6
6
  Author: Abhishek Thakur
@@ -23,11 +23,11 @@ Classifier: Intended Audience :: Developers
23
23
  Classifier: Intended Audience :: Science/Research
24
24
  Classifier: Intended Audience :: Education
25
25
  Classifier: License :: OSI Approved :: Apache Software License
26
- Classifier: Programming Language :: Python :: 3.7
27
26
  Classifier: Programming Language :: Python :: 3.8
28
27
  Classifier: Programming Language :: Python :: 3.9
29
28
  Classifier: Programming Language :: Python :: 3.10
30
- Requires-Python: >=3.7
29
+ Classifier: Programming Language :: Python :: 3.11
30
+ Requires-Python: >=3.8
31
31
  Description-Content-Type: text/markdown
32
32
  License-File: LICENSE
33
33
  Requires-Dist: cython
@@ -321,7 +321,7 @@ print(sourcer.retrieve_metadata(pretty_json=True))
321
321
 
322
322
  > We're happy to meet new contributors💗
323
323
 
324
- We welcome your contributions to help us improve and extend this project. If you want to get involved with VidGear development, checkout the **[Contribution Guidelines ▶️][contribute]**
324
+ We welcome your contributions to help us improve and extend this project. If you want to get involved with DeFFcode development, checkout the **[Contribution Guidelines ▶️][contribute]**
325
325
 
326
326
  We're offering support for DeFFcode on [**Gitter Community Channel**][gitter]. Come and join the conversation over there!
327
327
 
@@ -348,18 +348,18 @@ It is something I am doing with my own free time. But so much more needs to be d
348
348
 
349
349
  Here is a Bibtex entry you can use to cite this project in a publication:
350
350
 
351
- [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.7155399.svg)](https://doi.org/10.5281/zenodo.7155399)
351
+ [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.7523792.svg)](https://doi.org/10.5281/zenodo.7523792)
352
352
 
353
353
  ```BibTeX
354
354
  @software{deffcode,
355
- author = {Abhishek Singh Thakur},
356
- title = {abhiTronix/deffcode: v0.2.4},
357
- month = oct,
358
- year = 2022,
355
+ author = {Abhishek Thakur},
356
+ title = {abhiTronix/deffcode: v0.2.5},
357
+ month = jan,
358
+ year = 2023,
359
359
  publisher = {Zenodo},
360
- version = {v0.2.4},
361
- doi = {10.5281/zenodo.7155399},
362
- url = {https://doi.org/10.5281/zenodo.7155399}
360
+ version = {v0.2.5},
361
+ doi = {10.5281/zenodo.7523792},
362
+ url = {https://doi.org/10.5281/zenodo.7523792}
363
363
  }
364
364
  ```
365
365
 
@@ -0,0 +1,11 @@
1
+ deffcode/__init__.py,sha256=_WZUSTOnxtJLMQV7Bb70AyVPhfmhWf1OKOHbQhBaWzk,291
2
+ deffcode/ffdecoder.py,sha256=0JeDH7of9ovrdGOwYWYzyCPiOGDBS_UBXxD5DySjPOY,42988
3
+ deffcode/ffhelper.py,sha256=ReXn3zEkLY3VqhJlMmZATD5DDU-ad5auZ6q_oZ80E04,26821
4
+ deffcode/sourcer.py,sha256=T8eKJReox3jNPA8YTC7mZVzy4ZQgMzHvKuCMkqUjBqs,38110
5
+ deffcode/utils.py,sha256=LUnKF0MB9E02gK3CXccUVFBsHn6l8RRS5SzvV7SFySI,4929
6
+ deffcode/version.py,sha256=-PlEVSVU0gTlP_wD3xffzA9LlqJQ7GGQdBSP6mKnDvY,23
7
+ deffcode-0.2.6.dist-info/LICENSE,sha256=mBL-N_pLsrkx4_Ix9NCN51pxCeYcLpnTeTsj-18ub5I,12479
8
+ deffcode-0.2.6.dist-info/METADATA,sha256=-VfGa3dmH7FM495lsPl0YWKGPIakNwByXrb8457QRRE,33237
9
+ deffcode-0.2.6.dist-info/WHEEL,sha256=y4mX-SOX4fYIkonsAGA5N0Oy-8_gI4FXw5HNI1xqvWg,91
10
+ deffcode-0.2.6.dist-info/top_level.txt,sha256=1C-kyZgIKFviemaQMmhP0VKR3wkzEZcrf1o5oUckvHI,9
11
+ deffcode-0.2.6.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.38.4)
2
+ Generator: setuptools (70.2.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,11 +0,0 @@
1
- deffcode/__init__.py,sha256=_WZUSTOnxtJLMQV7Bb70AyVPhfmhWf1OKOHbQhBaWzk,291
2
- deffcode/ffdecoder.py,sha256=BcaxyQFswfLBiLfSCsYyZRTS7ka7RGnGEiB1CEBqEGw,41385
3
- deffcode/ffhelper.py,sha256=Gzyo8eHu7J6GVnVYVs2-GIxHeSd3AVy2id-N8LbhgwE,26563
4
- deffcode/sourcer.py,sha256=0iUD8nLVp3F8UnlFpm_wFtSz-ClHFiMtV1XQygW_04s,35874
5
- deffcode/utils.py,sha256=LUnKF0MB9E02gK3CXccUVFBsHn6l8RRS5SzvV7SFySI,4929
6
- deffcode/version.py,sha256=UrVWe9Q1Se9JzaYR6i-dvrfP7NV-jHi9kYGFTTlf00g,23
7
- deffcode-0.2.5.dist-info/LICENSE,sha256=mBL-N_pLsrkx4_Ix9NCN51pxCeYcLpnTeTsj-18ub5I,12479
8
- deffcode-0.2.5.dist-info/METADATA,sha256=QkiJMM83wEGE_nUgIX_OxS5C9GLQdkC5B9MDQ3q8lXM,33241
9
- deffcode-0.2.5.dist-info/WHEEL,sha256=2wepM1nk4DS4eFpYrW1TTqPcoGNfHhhO_i5m4cOimbo,92
10
- deffcode-0.2.5.dist-info/top_level.txt,sha256=1C-kyZgIKFviemaQMmhP0VKR3wkzEZcrf1o5oUckvHI,9
11
- deffcode-0.2.5.dist-info/RECORD,,