~r-d-vaughan/lossless-cut/trunk

« back to all changes in this revision

Viewing changes to lossless_cut/usr/share/lossless_cut/importcode/utilities.py

  • Committer: R.D. Vaughan
  • Date: 2012-11-26 21:02:45 UTC
  • Revision ID: rdvlaunchpad@gmail.com-20121126210245-bpb185lpx6ap8q9a
lossless-cut 0.2.0 release - Bug fix and new config file section, see change log

Show diffs side-by-side

added added

removed removed

Lines of Context:
222
222
    return a configuration dictionary
223
223
    """
224
224
    err_invalid_variable  = _(
225
 
'''The value for the configuration file variable "%%s" is invalid.
 
225
u'''The value for the configuration file variable "%%s" is invalid.
226
226
Check the "%s" for valid options.''') % common.CONFIG_FILE
227
227
    err_true_false = _(
228
 
'''The value for the configuration file variable "%s" is invalid.
 
228
u'''The value for the configuration file variable "%s" is invalid.
229
229
It must be either "true" or "false".''')
230
230
    err_bad_path = _(
231
 
'''The value for the configuration file variable "%s" is invalid.
 
231
u'''The value for the configuration file variable "%s" is invalid.
232
232
The directory path "%s" does not exist.
233
233
%s''')
234
234
    err_read_write = _(
235
 
'''The script does not have read and write permissions for the "%s" variables
 
235
u'''The script does not have read and write permissions for the "%s" variables
236
236
path: "%s"''')
237
237
    err_working_diskspace = _(
238
 
'''There is not enough available disk space in the working directory "%s" available "%s" bytes
 
238
u'''There is not enough available disk space in the working directory "%s" available "%s" bytes
239
239
to loss less cut recording "%s", size "%s" bytes.''')
240
240
    err_missing_subtitle_args = _(
241
 
'''The "%%s" subtitle utility arguments variable is missing from the
 
241
u'''The "%%s" subtitle utility arguments variable is missing from the
242
242
configuration file "%s".''') % common.CONFIG_FILE
243
243
    err_concert_cuts_0 = _(
244
 
'''The track numbers option "-T" must only be accompanied with the
 
244
u'''The track numbers option "-T" must only be accompanied with the
245
245
Stip option "-S".''')
246
246
    err_concert_cuts_1 = _(
247
 
'''The Concert Cuts option "-C" must be accompanied with either a "-e" export
 
247
u'''The Concert Cuts option "-C" must be accompanied with either a "-e" export
248
248
or a "-m" move option. Replace "-r" is not valid.''')
249
249
    err_concert_cuts_2 = _(
250
 
'''The Concert Cuts option "-C" configuration file
 
250
u'''The Concert Cuts option "-C" configuration file
251
251
"%s" does not exist.''')
252
252
    err_invalid_sequence_number  = _(
253
 
'''The value for the configuration file variable "%s" must end with
 
253
u'''The value for the configuration file variable "%s" must end with
254
254
a valid integer in the format "delete_rec_01".
255
255
''')
256
 
    err_cannot_create_cfg_file = _(
257
 
u'''Could not create the "%s" file in directory "%s". This is likely a
258
 
directory Read/Write permission issue but check the error message
259
 
below to confirm, aborting script.
260
 
Error: %s''')
 
256
    err_no_jobid = _(
 
257
u'''There must be a -j "%%JOBID%%" command line argument present when
 
258
you use the "error_detection" configuration variables.
 
259
You have the following "error_detection" configuration variables active:
 
260
%s
 
261
''')
 
262
    err_invalid_jobid = _(
 
263
u'''The job ID -j "%%JOBID%%" command line argument must be an integer.
 
264
Your invalid JobID is "%s".
 
265
''')
 
266
    err_invalid_detection_values = _(
 
267
u'''The error detection variable "%s" with configuration arguments:
 
268
%s
 
269
is not valid.
 
270
You may not have replaced all instances of ";" semicolons with "\\;" or
 
271
have not provided all four required arguments. Check the
 
272
configuration file documentation for the "error_detection" section.
 
273
''')
261
274
    #
262
275
    configuration = {}
263
276
    #
269
282
    configuration['remove_recorded'] = []
270
283
    configuration['mkvmerge_cut_addon'] = None
271
284
    configuration['mkvmerge_merge_addon'] = None
 
285
    configuration['error_detection'] = []
272
286
    #
273
287
    ## Initialize the default DVB Subtitle settings
274
288
    for key in common.DEFAULT_CONFIG_SETTINGS[
282
296
    ## Check if this config file is old and does not have a
283
297
    ## "dvb_subtitles" section. Add the default one if it is missing.
284
298
    if "dvb_subtitles" not in cfg.sections():
285
 
        fileh = open(common.CONFIG_FILE, 'r')
286
 
        init_config = fileh.read()
287
 
        fileh.close()
288
 
        #
289
 
        fileh = open(common.INIT_DVB_SUBTITLE_CONFIG_FILE, 'r')
290
 
        cr = u''
291
 
        if init_config[-1:] != u'\n':
292
 
            cr = u'\n'
293
 
        init_config += cr + (fileh.read() % configuration)
294
 
        fileh.close()
295
 
        #
296
 
        # Save the new configuration file
297
 
        try:
298
 
            fileh = open(common.CONFIG_FILE, 'w')
299
 
        except IOError, errmsg:
300
 
            # TRANSLATORS: Please leave %s as it is,
301
 
            # because it is needed by the program.
302
 
            # Thank you for contributing to this project.
303
 
            directory, basefilename = os.path.split(common.CONFIG_FILE)
304
 
            sys.stderr.write(err_cannot_create_cfg_file %
305
 
                    (basefilename, directory, errmsg))
306
 
            exit(1)
307
 
        fileh.write(init_config)
308
 
        fileh.close()
309
 
        #
310
 
        ## Reinitialize the config file structure
311
 
        cfg.read(common.CONFIG_FILE)
 
299
        add_new_cfg_section(configuration,
 
300
                    common.INIT_DVB_SUBTITLE_CONFIG_FILE, cfg)
312
301
    #
313
302
    ## Check if this config file is old and does not have a
314
303
    ## "remove_recorded" section. Add the default one if it is missing.
315
304
    if "remove_recorded" not in cfg.sections():
316
 
        fileh = open(common.CONFIG_FILE, 'r')
317
 
        init_config = fileh.read()
318
 
        fileh.close()
319
 
        #
320
 
        fileh = open(common.INIT_REMOVE_RECORDING_CONFIG_FILE, 'r')
321
 
        cr = u''
322
 
        if init_config[-1:] != u'\n':
323
 
            cr = u'\n'
324
 
        init_config += cr + fileh.read()
325
 
        fileh.close()
326
 
        #
327
 
        # Save the new configuration file
328
 
        try:
329
 
            fileh = open(common.CONFIG_FILE, 'w')
330
 
        except IOError, errmsg:
331
 
            # TRANSLATORS: Please leave %s as it is,
332
 
            # because it is needed by the program.
333
 
            # Thank you for contributing to this project.
334
 
            directory, basefilename = os.path.split(common.CONFIG_FILE)
335
 
            sys.stderr.write(err_cannot_create_cfg_file %
336
 
                    (basefilename, directory, errmsg))
337
 
            exit(1)
338
 
        fileh.write(init_config)
339
 
        fileh.close()
340
 
        #
341
 
        ## Reinitialize the config file structure
342
 
        cfg.read(common.CONFIG_FILE)
 
305
        add_new_cfg_section(configuration,
 
306
                    common.INIT_REMOVE_RECORDING_CONFIG_FILE, cfg)
343
307
    #
344
308
    ## Check if this config file is old and does not have a
345
309
    ## "mkvmerge_user_settings" section. Add the default one if
346
310
    ## it is missing.
347
311
    if "mkvmerge_user_settings" not in cfg.sections():
348
 
        fileh = open(common.CONFIG_FILE, 'r')
349
 
        init_config = fileh.read()
350
 
        fileh.close()
351
 
        #
352
 
        fileh = open(common.INIT_MKVMERGE_USER_SETTINGS_CONFIG_FILE, 'r')
353
 
        cr = u''
354
 
        if init_config[-1:] != u'\n':
355
 
            cr = u'\n'
356
 
        init_config += cr + fileh.read()
357
 
        fileh.close()
358
 
        #
359
 
        # Save the new configuration file
360
 
        try:
361
 
            fileh = open(common.CONFIG_FILE, 'w')
362
 
        except IOError, errmsg:
363
 
            # TRANSLATORS: Please leave %s as it is,
364
 
            # because it is needed by the program.
365
 
            # Thank you for contributing to this project.
366
 
            directory, basefilename = os.path.split(common.CONFIG_FILE)
367
 
            sys.stderr.write(err_cannot_create_cfg_file %
368
 
                    (basefilename, directory, errmsg))
369
 
            exit(1)
370
 
        fileh.write(init_config)
371
 
        fileh.close()
372
 
        #
373
 
        ## Reinitialize the config file structure
374
 
        cfg.read(common.CONFIG_FILE)
 
312
        add_new_cfg_section(configuration,
 
313
                    common.INIT_MKVMERGE_USER_SETTINGS_CONFIG_FILE, cfg)
 
314
    #
 
315
    ## Check if this config file is old and does not have a
 
316
    ## "error_detection" section. Add the default one if
 
317
    ## it is missing.
 
318
    if "error_detection" not in cfg.sections():
 
319
        add_new_cfg_section(configuration,
 
320
                    common.INIT_ERROR_DETECTION_CONFIG_FILE, cfg)
375
321
    #
376
322
    for section in cfg.sections():
377
323
        if section[:5] == 'File ':
643
589
                    raise Exception(err_invalid_variable %
644
590
                                                option)
645
591
                continue
 
592
        if section == 'error_detection':
 
593
            keys = ['type', 'threshold', 'bash_command', 'comment_string' ]
 
594
            for option in cfg.options(section):
 
595
                try:
 
596
                    error_args_dict = {}
 
597
                    for key in keys:
 
598
                        error_args_dict[key] = None
 
599
                    #
 
600
                    original_args = unicode(cfg.get(section, option),
 
601
                                        'utf8')
 
602
                    error_args = original_args.replace(
 
603
                                            '\\;', u';').strip().split(',')
 
604
                    # Clean up and empty args
 
605
                    if not error_args[-1]:
 
606
                        del(error_args[-1])
 
607
                    #
 
608
                    if len(error_args) > 4:
 
609
                        raise Exception(
 
610
_(u'''"%s" has too many arguments "%s" detected, there can only be four.
 
611
Arguments: %s
 
612
Resulting argument list: %s''') % (option, len(error_args),
 
613
                                    original_args, error_args))
 
614
                    #
 
615
                    for count in range(len(error_args)):
 
616
                        error_args_dict[keys[count]] = \
 
617
                                                error_args[count].strip()
 
618
                    #
 
619
                    if not error_args_dict['type'] in ['alert', 'abort']:
 
620
                        raise Exception(
 
621
_(u' Invalid error type "%s" must be "alert" or "abort"') %
 
622
                            error_args_dict['type'])
 
623
                    #
 
624
                    try:
 
625
                        error_args_dict['threshold'] = \
 
626
                                        int(error_args_dict['threshold'])
 
627
                    except (TypeError, ValueError):
 
628
                        raise Exception(
 
629
_(u' Threshold value "%s" must be an integer.') %
 
630
                                        error_args_dict['threshold'])
 
631
                    #
 
632
                    if not error_args_dict['bash_command']:
 
633
                        raise Exception(
 
634
_(u' A bash command must be provided.'))
 
635
                    #
 
636
                    #
 
637
                    ## Verify that each variable has a valid argument
 
638
                    for key in keys:
 
639
                        if error_args_dict[key] == None:
 
640
                            raise Exception(
 
641
                                err_invalid_detection_values % (
 
642
                                                    option, original_args))
 
643
                    #
 
644
                    configuration['error_detection'].append(error_args_dict)
 
645
                #
 
646
                except Exception, errmsg:
 
647
                    error_message = err_invalid_variable % option
 
648
                    error_message += u'\n\n%s' % errmsg
 
649
                    raise Exception(error_message)
 
650
                continue
646
651
    #
647
652
    ## Change any configuration settings as dictated
648
653
    ## by the command line options
667
672
        ## Check if the Concert Cut option is being used
668
673
        configuration['concertcuts'] = opts.concertcuts
669
674
        if opts.concertcuts:
670
 
            if (not opts.mythvideo_export and not opts.movepath) or \
671
 
                    opts.replace_recorded:
 
675
            if not opts.mythvideo_export and not opts.movepath:
672
676
                raise Exception(err_concert_cuts_1)
 
677
            if opts.replace_recorded:
 
678
                raise Exception(_(
 
679
'''Concert cuts do not support the "-r" replace option.'''))
673
680
            #
674
681
            if opts.concertcuts != True:
675
682
                if opts.concertcuts[0] == '~':
710
717
            fileh = open(common.INIT_PROJECTX_INI_FILE, 'r')
711
718
            configuration['projectx_ini'] = (fileh.read() % configuration)
712
719
            fileh.close()
 
720
        #
 
721
        configuration['jobid'] = opts.jobid
 
722
        if configuration['error_detection']:
 
723
            if not opts.jobid:
 
724
                raise Exception(err_no_jobid %
 
725
                            configuration['error_detection'])
 
726
            try:
 
727
                configuration['jobid'] = long(opts.jobid)
 
728
            except (TypeError, ValueError):
 
729
                raise Exception(err_invalid_jobid % opts.jobid)
713
730
    #
714
731
    if not ll_report and not load_db:
715
732
        if opts.logpath:
942
959
    variable = '%ARTIST%'
943
960
    if configuration['concertcuts'].find(variable) != -1 and \
944
961
            not configuration['artist']:
945
 
                        raise Exception(err_invalid_format %
946
 
                            (configuration['concertcuts'],
947
 
                            variable, 'artist'))
 
962
        raise Exception(err_invalid_format %
 
963
            (configuration['concertcuts'],
 
964
            variable, 'artist'))
948
965
    variable = '%ALBUM%'
949
966
    if configuration['concertcuts'].find(variable) != -1 and \
950
967
            not configuration['album']:
951
 
                        raise Exception(err_invalid_format %
952
 
                            (configuration['concertcuts'],
953
 
                            variable, 'album'))
 
968
        raise Exception(err_invalid_format %
 
969
            (configuration['concertcuts'],
 
970
            variable, 'album'))
954
971
    #
955
972
    return
956
973
#
1230
1247
    #
1231
1248
    return timestamp
1232
1249
#
1233
 
##### Commented out in case ffmpeg cuts every gets supported
1234
 
#def make_ffmpeg_cut(start_secs, end_secs):
1235
 
#    '''Take a floating point number pair of fractional seconds and
1236
 
#    convert into a starttime and duration to be used by ffmpeg/avconv to
1237
 
#    create a cut segment.
1238
 
#    return a string in the form
1239
 
#            "-ss 00:00:00.123456789 -t 00:10:00.987654321"
1240
 
#    '''
1241
 
#    starttime = unicode((datetime.min +
1242
 
#                        timedelta(0,int(start_secs))).time().strftime(
1243
 
#                        '%H:%M:%S') + (u'%0.09f' % (
1244
 
#                        start_secs - int(start_secs)))[1:])
1245
 
#    #
1246
 
#    duration_secs = end_secs - start_secs
1247
 
#    duration = unicode((datetime.min +
1248
 
#                        timedelta(0,int(duration_secs))).time().strftime(
1249
 
#                        '%H:%M:%S') + (u'%0.09f' % (
1250
 
#                        duration_secs - int(duration_secs)))[1:])
1251
 
#    #
1252
 
#    return u"-ss %s -t %s" % (starttime, duration)
1253
 
##
1254
1250
def display_recorded_info(configuration, logger=False):
1255
1251
    ''' Display information about the recorded video.
1256
1252
    return verbage if there is no logger specified
1341
1337
        # TRANSLATORS: Please leave %s as it is,
1342
1338
        # because it is needed by the program.
1343
1339
        # Thank you for contributing to this project.
1344
 
        sys.stderr.write(
1345
 
_(u'''Mediainfo failed to get track information for
 
1340
        verbage = _(
 
1341
u'''Mediainfo failed to get track information for
1346
1342
video file "%s", aborting script.
1347
1343
Error: %s
1348
 
''') % (video_file, result[1]))
 
1344
''') % (video_file, result[1])
 
1345
        logger.critical(verbage)
 
1346
        sys.stderr.write(verbage)
1349
1347
        exit(1)
1350
1348
    #
1351
1349
    # Create an etree structure from the mediainfo XML
1403
1401
                        one_track[element] = None
1404
1402
                tracks['%s_details' % track_type].append(one_track)
1405
1403
    #
 
1404
    ## Video FPS, Height, Width and scan type (p or i)
 
1405
    tracks['video_track_details'] = {}
 
1406
    if len(tracks['video']):
 
1407
        for key in ['Width', 'Height', 'Original_frame_rate', 'Scan_type',]:
 
1408
            tracks['video_track_details'][key] = None
 
1409
            data = element_filter(tracks['video'][0], element = key)
 
1410
            if data:
 
1411
                if data[0].endswith('pixels'):
 
1412
                    data[0] = data[0].replace('pixels',
 
1413
                                    u'').replace(' ', u'').strip()
 
1414
                if data[0].find(' ') != -1:
 
1415
                    tracks['vide_tracko_details'][key] = \
 
1416
                                data[0][:data[0].find(' ')].strip()
 
1417
                else:
 
1418
                    tracks['video_track_details'][key] = data[0]
 
1419
            elif key == 'Original_frame_rate':
 
1420
                #
 
1421
                ## Special processing for frame rate
 
1422
                try:
 
1423
                    tracks['video_track_details']['Original_frame_rate'] = \
 
1424
                        element_filter(tracks['video'][0],
 
1425
                                            element = u'Frame_rate')[0]
 
1426
                except IndexError:
 
1427
                    # TRANSLATORS: Please leave %s as it is,
 
1428
                    # because it is needed by the program.
 
1429
                    # Thank you for contributing to this project.
 
1430
                    verbage = _(
 
1431
u'''Mediainfo failed to find FPS video track information for
 
1432
video file "%s", aborting script.
 
1433
''') % (video_file)
 
1434
                    logger.critical(verbage)
 
1435
                    sys.stderr.write(verbage)
 
1436
                    exit(1)
 
1437
                #
 
1438
                tracks['video_track_details']['Original_frame_rate'] = \
 
1439
                    tracks['video_track_details'][
 
1440
                            'Original_frame_rate'].replace(
 
1441
                                 'fps', u'').replace('.', u'').strip()
 
1442
    #
1406
1443
    ## Check for SRT tracks and gather info about those tracks
1407
1444
    ## Also check for DVB Subtitle tracks and calculate a usable ms delay
1408
1445
    ## value from the "Delay_relative_to_video" element string
1496
1533
    fileh = open(common.INIT_MKVMERGE_USER_SETTINGS_CONFIG_FILE, 'r')
1497
1534
    init_config += u'\n' + fileh.read()
1498
1535
    fileh.close()
 
1536
    # Add the error detection User Settings configuration section
 
1537
    fileh = open(common.INIT_ERROR_DETECTION_CONFIG_FILE, 'r')
 
1538
    init_config += u'\n' + fileh.read()
 
1539
    fileh.close()
1499
1540
    #
1500
1541
    # Add the default configuration settings
1501
1542
    init_config = init_config % common.DEFAULT_CONFIG_SETTINGS
1517
1558
    fileh.close()
1518
1559
    #
1519
1560
    return
 
1561
#
 
1562
def add_new_cfg_section(configuration, section, cfg):
 
1563
    ''' Concatinate a new configuration section.
 
1564
    return nothing
 
1565
    '''
 
1566
    err_cannot_create_cfg_file = _(
 
1567
u'''Could not create the "%s" file in directory "%s". This is likely a
 
1568
directory Read/Write permission issue but check the error message
 
1569
below to confirm, aborting script.
 
1570
Error: %s''')
 
1571
    #
 
1572
    fileh = open(common.CONFIG_FILE, 'r')
 
1573
    init_config = fileh.read()
 
1574
    fileh.close()
 
1575
    #
 
1576
    fileh = open(section, 'r')
 
1577
    new_line = u''
 
1578
    if init_config[-1:] != u'\n':
 
1579
        new_line = u'\n'
 
1580
    init_config += new_line + (fileh.read() % configuration)
 
1581
    fileh.close()
 
1582
    #
 
1583
    # Save the new configuration file
 
1584
    try:
 
1585
        fileh = open(common.CONFIG_FILE, 'w')
 
1586
    except IOError, errmsg:
 
1587
        directory, basefilename = os.path.split(common.CONFIG_FILE)
 
1588
        verbage = err_cannot_create_cfg_file % \
 
1589
                (basefilename, directory, errmsg)
 
1590
        raise Exception(verbage)
 
1591
    #
 
1592
    fileh.write(init_config)
 
1593
    fileh.close()
 
1594
    #
 
1595
    ## Reinitialize the config file structure
 
1596
    cfg.read(common.CONFIG_FILE)
 
1597
    #
 
1598
    return