tictacsync 1.0.2a0__py3-none-any.whl → 1.1.0a0__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.

Potentially problematic release.


This version of tictacsync might be problematic. Click here for more details.

@@ -18,6 +18,8 @@ M4V SVI 3GP 3G2 MXF ROQ NSV FLV F4V F4P F4A F4B 3GP AA AAC AAX ACT AIFF ALAC
18
18
  AMR APE AU AWB DSS DVF FLAC GSM IKLAX IVS M4A M4B M4P MMF MP3 MPC MSV NMF
19
19
  OGG OGA MOGG OPUS RA RM RAW RF64 SLN TTA VOC VOX WAV WMA WV WEBM 8SVX CDA MOV AVI BWF""".split()
20
20
 
21
+ audio_ext = 'aiff wav mp3'.split()
22
+
21
23
  from dataclasses import dataclass
22
24
  import ffmpeg, os, sys, shutil
23
25
  from os import listdir
@@ -37,9 +39,11 @@ from itertools import groupby
37
39
  try:
38
40
  from . import multi2polywav
39
41
  from . import mamsync
42
+ from . import mamconf
40
43
  except:
41
44
  import multi2polywav
42
45
  import mamsync
46
+ import mamconf
43
47
 
44
48
  MCCDIR = 'SyncedMulticamClips'
45
49
  SYNCEDFOLDER = 'SyncedMedia'
@@ -264,7 +268,7 @@ class Scanner:
264
268
  """
265
269
  logger.debug(f'on entry synced_root: {synced_root}')
266
270
  if synced_root != None: # mam mode
267
- p = Path(platformdirs.user_data_dir('mamsync', 'plutz'))/mamsync.LOG_FILE
271
+ p = Path(platformdirs.user_data_dir('mamsync', 'plutz'))/mamconf.LOG_FILE
268
272
  with open(p, 'r') as fh:
269
273
  done = set(fh.read().split()) # sets of strings of abs path
270
274
  logger.debug(f'done clips: {pformat(done)}')
@@ -282,29 +286,6 @@ class Scanner:
282
286
  continue
283
287
  else:
284
288
  clip_paths.append(raw_path)
285
- ############################################################ MOVE
286
- elif synced_root != None: # MAM mode
287
- #non AV files and directories
288
- synced_path = Path(synced_root)/str(raw_path)[1:] # cant join abs. paths
289
- if raw_path.is_dir():
290
- synced_path.mkdir(parents=True, exist_ok=True)
291
- continue
292
- # if here, it's a file
293
- if not synced_path.exists():
294
- print(f'will mirror non AV file at {synced_path}')
295
- logger.debug(f'will mirror non AV file at {synced_path}')
296
- shutil.copy2(raw_path, synced_path)
297
- continue
298
- # file exists, check if same
299
- same = filecmp.cmp(raw_path, synced_path, shallow=False)
300
- logger.debug(f'copy exists of:\n{raw_path}\n{synced_path}')
301
- if not same:
302
- print(f'file changed, copying again\n{raw_path}')
303
- shutil.copy2(raw_path, synced_path)
304
- else:
305
- logger.debug('same content, next')
306
- continue # next raw_path in loop
307
- ###################################################################
308
289
  if some_done:
309
290
  print('Somme media files were already synced...')
310
291
  logger.debug('found media files %s'%clip_paths)
tictacsync/entry.py CHANGED
@@ -164,13 +164,14 @@ def main():
164
164
  quit()
165
165
  if args.verbose_output:
166
166
  logger.add(sys.stderr, level="DEBUG")
167
- # logger.add(sys.stdout, filter=lambda r: r["function"] == "move_multicam_to_dir")
168
- # logger.add(sys.stdout, filter=lambda r: r["function"] == "_merge_audio_and_video")
167
+
168
+ # logger.add(sys.stdout, filter=lambda r: r["function"] == "_write_ISOs")
169
+ logger.add(sys.stdout, filter=lambda r: r["function"] == "_build_and_write_audio")
169
170
  #
170
171
  # logger.add(sys.stdout, filter="__main__")
171
172
  # logger.add(sys.stdout, filter="yaltc")
172
173
 
173
- logger.add(sys.stdout, filter=lambda r: r["function"] == "start_proj")
174
+ # logger.add(sys.stdout, filter=lambda r: r["function"] == "move_multicam_to_dir")
174
175
  # logger.add(sys.stdout, filter=lambda r: r["function"] == "_dev_type_for_name")
175
176
  # logger.add(sys.stdout, filter=lambda r: r["function"] == "scan_media_and_build_devices_UID")
176
177
 
@@ -203,20 +204,7 @@ def main():
203
204
  maxch = len(devices)
204
205
  for i, d in enumerate(devices):
205
206
  print('\t%i - %s'%(i+1, d.name))
206
- while True:
207
- print('\nEnter your choice:', end='')
208
- choice = input()
209
- try:
210
- choice = int(choice)
211
- except:
212
- print('Please use numeric digits.')
213
- continue
214
- if choice not in list(range(1, maxch + 1)):
215
- print('Please enter a number in [1..%i]'%maxch)
216
- continue
217
- break
218
- ref_device = list(devices)[choice - 1]
219
- # ref_device = list(devices)[3 - 1]
207
+ ref_device = list(devices)[3 - 1]
220
208
  print('When only audio recordings are present, ISOs files will be cut and written.')
221
209
  if not args.terse:
222
210
  if scanner.input_structure == 'ordered':
@@ -265,7 +253,7 @@ def main():
265
253
  for rec in recordings:
266
254
  # print(rec, rec.device == ref_device)
267
255
  if rec.device == ref_device:
268
- rec.is_reference = True
256
+ rec.is_audio_reference = True
269
257
  if not args.terse:
270
258
  table = Table(title="tictacsync results")
271
259
  table.add_column("Recording\n", justify="center", style='gold1')
@@ -319,11 +307,19 @@ def main():
319
307
  # output_dir = args.o
320
308
  # if args.verbose_output or args.terse: # verbose, so no progress bars
321
309
  print('Merging...')
310
+ # for merger in matcher.mergers:
311
+ # merger.build_audio_and_write_merged_media(top_dir,
312
+ # args.dont_write_cam_folder,
313
+ # asked_ISOs,
314
+ # audio_REC_only)
322
315
  for merger in matcher.mergers:
323
- merger.build_audio_and_write_merged_media(top_dir,
324
- args.dont_write_cam_folder,
325
- asked_ISOs,
326
- audio_REC_only)
316
+ if audio_REC_only:
317
+ # rare
318
+ merger._build_and_write_audio(top_dir)
319
+ else:
320
+ # almost always syncing audio to video clips
321
+ merger._build_audio_and_write_video(top_dir,
322
+ args.dont_write_cam_folder, asked_ISOs)
327
323
  if not args.terse:
328
324
  print("\n")
329
325
  # find out where files were written
@@ -337,23 +333,24 @@ def main():
337
333
  nameAnd2Parents = Path('').joinpath(*final_p.parts[-2:])
338
334
  print(' became [gold1]%s[/gold1]'%nameAnd2Parents)
339
335
  # matcher._build_otio_tracks_for_cam()
340
- matcher.set_up_clusters() # multicam
341
- matcher.shrink_gaps_between_takes(args.timelineoffset)
342
- logger.debug('matcher.multicam_clips_clusters %s'%
343
- pformat(matcher.multicam_clips_clusters))
344
- # clusters is list of {'end': t1, 'start': t2, 'vids': [r1,r3]}
345
- # really_clusters is True if one of them has len() > 1
346
- really_clusters = any([len(cl['vids']) > 1 for cl
347
- in matcher.multicam_clips_clusters])
348
- if really_clusters:
349
- if scanner.input_structure == 'loose':
350
- print('\nThere are synced multicam clips but without structured folders')
351
- print('they were not grouped together under the same folder.')
336
+ if not audio_REC_only:
337
+ matcher.set_up_clusters() # multicam
338
+ matcher.shrink_gaps_between_takes(args.timelineoffset)
339
+ logger.debug('matcher.multicam_clips_clusters %s'%
340
+ pformat(matcher.multicam_clips_clusters))
341
+ # clusters is list of {'end': t1, 'start': t2, 'vids': [r1,r3]}
342
+ # really_clusters is True if one of them has len() > 1
343
+ really_clusters = any([len(cl['vids']) > 1 for cl
344
+ in matcher.multicam_clips_clusters])
345
+ if really_clusters:
346
+ if scanner.input_structure == 'loose':
347
+ print('\nThere are synced multicam clips but without structured folders')
348
+ print('they were not grouped together under the same folder.')
349
+ else:
350
+ matcher.move_multicam_to_dir()
352
351
  else:
353
- matcher.move_multicam_to_dir()
354
- else:
355
- logger.debug('not really a multicam cluster, nothing to move')
356
- sys.exit(0)
352
+ logger.debug('not really a multicam cluster, nothing to move')
353
+ sys.exit(0)
357
354
 
358
355
  if __name__ == '__main__':
359
356
  main()
tictacsync/mamconf.py ADDED
@@ -0,0 +1,175 @@
1
+ import argparse, platformdirs, configparser, sys
2
+ from loguru import logger
3
+ from pprint import pprint, pformat
4
+ from pathlib import Path
5
+
6
+
7
+ CONF_FILE = 'mamsync.cfg'
8
+ LOG_FILE = 'mamdone.txt'
9
+
10
+ logger.remove()
11
+ # logger.add(sys.stdout, level="DEBUG")
12
+ # logger.add(sys.stdout, filter=lambda r: r["function"] == "write_conf")
13
+
14
+
15
+ def print_out_conf(raw_root, synced_root, snd_root, proxies=''):
16
+ print(f'RAWROOT (source with TC): "{raw_root}"')
17
+ print(f'SYNCEDROOT (destination of synced folder): "{synced_root}"')
18
+ print(f'SNDROOT (destination of ISOs sound files): "{snd_root}"')
19
+ if proxies != '':
20
+ print(f'PROXIES (NLE proxy clips folder): "{proxies}"')
21
+
22
+ def write_conf(conf_key, conf_val):
23
+ # args are pahtlib.Paths.
24
+ # RAWROOT: files with TC (and ROLL folders), as is from cameras
25
+ # SYNCEDROOT: synced and no more TC (ROLL flattened)
26
+ # Writes configuration on filesystem for later retrieval
27
+ # Clears log of already synced clips.
28
+ conf_dir = platformdirs.user_config_dir('mamsync', 'plutz', ensure_exists=True)
29
+ current_values = dict(zip(['RAWROOT', 'SYNCEDROOT', 'SNDROOT', 'PROXIES'],
30
+ get_proj()))
31
+ logger.debug(f'old values {current_values}')
32
+ current_values[conf_key] = conf_val
33
+ logger.debug(f'updated values {current_values}')
34
+ conf_file = Path(conf_dir)/CONF_FILE
35
+ logger.debug('writing config in %s'%conf_file)
36
+ # print(f'\nWriting folders paths in configuration file "{conf_file}"')
37
+ # print_out_conf(raw_root, synced_root, snd_root)
38
+ conf_prs = configparser.ConfigParser()
39
+ conf_prs['SECTION1'] = current_values
40
+ with open(conf_file, 'w') as configfile_handle:
41
+ conf_prs.write(configfile_handle)
42
+ with open(conf_file, 'r') as configfile_handle:
43
+ logger.debug(f'config file content: \n{configfile_handle.read()}')
44
+
45
+ def get_proj(print_conf_stdout=False):
46
+ # check if user started a project before.
47
+ # stored in platformdirs.user_config_dir
48
+ # returns a tuple of strings (RAWROOT, SYNCEDROOTS, SNDROOT, PROXIES)
49
+ # if any, or a tuple of 4 empty strings '' otherwise.
50
+ # print location of conf file if print_conf_stdout
51
+ conf_dir = platformdirs.user_config_dir('mamsync', 'plutz')
52
+ conf_file = Path(conf_dir)/CONF_FILE
53
+ logger.debug('try reading config in %s'%conf_file)
54
+ if print_conf_stdout:
55
+ print(f'\nTrying to read configuration from file {conf_file}')
56
+ if conf_file.exists():
57
+ conf_prs = configparser.ConfigParser()
58
+ conf_prs.read(conf_file)
59
+ try:
60
+ RAWROOT = conf_prs.get('SECTION1', 'RAWROOT')
61
+ except configparser.NoOptionError:
62
+ RAWROOT = ''
63
+ try:
64
+ SYNCEDROOT = conf_prs.get('SECTION1', 'SYNCEDROOT')
65
+ except configparser.NoOptionError:
66
+ SYNCEDROOT = ''
67
+ try:
68
+ PROXIES = conf_prs.get('SECTION1', 'PROXIES')
69
+ except configparser.NoOptionError:
70
+ PROXIES = ''
71
+ try:
72
+ SNDROOT = conf_prs.get('SECTION1', 'SNDROOT')
73
+ except configparser.NoOptionError:
74
+ SNDROOT = ''
75
+ logger.debug('read from conf: RAWROOT= %s SYNCEDROOT= %s SNDROOT=%s PROXIES=%s'%
76
+ (RAWROOT, SYNCEDROOT, SNDROOT, PROXIES))
77
+ return RAWROOT, SYNCEDROOT, SNDROOT, PROXIES
78
+ else:
79
+ logger.debug(f'no config file found at {conf_file}')
80
+ print('No configuration found.')
81
+ return '', '', '', ''
82
+
83
+ def new_parser():
84
+ parser = argparse.ArgumentParser()
85
+ parser.add_argument('--rawroot',
86
+ nargs = 1,
87
+ dest='rawroot',
88
+ help='Sets new value for raw root folder (i.e.: clips with TC)')
89
+ parser.add_argument('--syncedroot',
90
+ nargs = 1,
91
+ dest='syncedroot',
92
+ help="""Sets where the synced files will be written, to be used by the NLE. Will contain a mirror copy of RAWROOT """)
93
+ parser.add_argument('--proxies',
94
+ nargs = 1,
95
+ dest='proxies',
96
+ help='Sets where the proxy files are stored by the NLE')
97
+ parser.add_argument('--sndfolder',
98
+ nargs = 1,
99
+ dest='sndfolder',
100
+ help='Sets new value for sound folder (where ISOs sound files will be stored)')
101
+ parser.add_argument('--clearconf',
102
+ action='store_true',
103
+ dest='clearconf',
104
+ help='Clear configured values.')
105
+ parser.add_argument('--showconf',
106
+ action='store_true',
107
+ dest='showconf',
108
+ help='Show current configured values.')
109
+ return parser
110
+
111
+ def main():
112
+ parser = new_parser()
113
+ args = parser.parse_args()
114
+ logger.debug(f'arguments from argparse {args}')
115
+ if args.rawroot:
116
+ val = args.rawroot[0]
117
+ write_conf('RAWROOT', val)
118
+ print(f'Set source folder of unsynced clips (rawroot) to:\n{val}')
119
+ sys.exit(0)
120
+ if args.syncedroot:
121
+ val = args.syncedroot[0]
122
+ write_conf('SYNCEDROOT', args.syncedroot[0])
123
+ print(f'Set destination folder of synced clips (syncedroot) to:\n{val}')
124
+ sys.exit(0)
125
+ if args.proxies:
126
+ val = args.proxies[0]
127
+ write_conf('PROXIES', args.proxies[0])
128
+ print(f'Set proxies folder to:\n{val}')
129
+ sys.exit(0)
130
+ if args.sndfolder:
131
+ val = args.sndfolder[0]
132
+ write_conf('SNDROOT', args.sndfolder[0])
133
+ print(f'Set destination folder of ISOs sound files (sndfolder) to:\n{val}')
134
+ sys.exit(0)
135
+ if args.clearconf:
136
+ write_conf('RAWROOT', '')
137
+ write_conf('SYNCEDROOT', '')
138
+ write_conf('SNDROOT', '')
139
+ write_conf('PROXIES', '')
140
+ print_out_conf('','','','')
141
+ sys.exit(0)
142
+ if args.showconf:
143
+ get_proj()
144
+ print_out_conf(*get_proj(True))
145
+ sys.exit(0)
146
+ # roots = get_proj(False)
147
+ # if any([r == '' for r in roots]):
148
+ # print("Can't sync if some folders are not set:")
149
+ # print_out_conf(*get_proj())
150
+ # print('Bye.')
151
+ # sys.exit(0)
152
+ # for r in roots:
153
+ # if not r.is_absolute():
154
+ # print(f'\rError: folder {r} must be an absolute path. Bye')
155
+ # sys.exit(0)
156
+ # if not r.exists():
157
+ # print(f'\rError: folder {r} does not exist. Bye')
158
+ # sys.exit(0)
159
+ # if not r.is_dir():
160
+ # print(f'\rError: path {r} is not a folder. Bye')
161
+ # sys.exit(0)
162
+ # raw_root, synced_root, snd_root = roots
163
+ # if args.sub_dir != None:
164
+ # top_dir = args.sub_dir
165
+ # logger.debug(f'sub _dir: {args.sub_dir}')
166
+ # if not Path(top_dir).exists():
167
+ # print(f"\rError: folder {top_dir} doesn't exist, bye.")
168
+ # sys.exit(0)
169
+ # else:
170
+ # top_dir = raw_root
171
+ # if args.resync:
172
+ # clear_log()
173
+
174
+ if __name__ == '__main__':
175
+ main()