Changeset 1797

Show
Ignore:
Timestamp:
11/14/08 17:48:21 (16 months ago)
Author:
JensDiemer
Message:

CodeSnippets/VideoTools?: many updates for eac3to.py

Location:
CodeSnippets/VideoTools
Files:
5 modified

Legend:

Unmodified
Added
Removed
  • CodeSnippets/VideoTools/eac3to.py

    r1789 r1797  
    55""" 
    66 
    7 import os, sys, time, datetime, subprocess, logging 
     7import os, sys, glob, time, datetime, subprocess, logging 
     8from pprint import pprint 
     9 
     10import Tkinter as tk 
    811 
    912import win32api 
    1013 
    1114from shared.config import VideoToolsConfig 
    12 from shared.tools import askopenfilename2, askdirectory2 
     15from shared.tk_tools import askopenfilename2, askdirectory2, TkListbox 
     16from shared.tools import make_slug, human_filesize 
    1317 
    1418DEBUG = False 
     
    1620 
    1721 
    18 class StreamInfo(object): 
    19     def __init__(self, filename, txt_filter, parameter=[]): 
    20         self.filename = filename 
    21         self.txt_filter = txt_filter 
    22         self.parameter = parameter 
     22VIDEO_EXT = ".mkv" # ToDo: Should go into the config 
     23 
     24STREAMINFOS = [ 
     25    { 
     26        "txt_filter": ("Chapters",), 
     27        "ext": ".txt", 
     28    }, 
     29    { 
     30        "txt_filter": ("h264", "VC-1", "MPEG2",), 
     31        "ext": VIDEO_EXT 
     32    }, 
     33    { 
     34        "txt_filter": ("DTS Hi-Res",), 
     35        "ext": ".dtshr", 
     36    }, 
     37    { 
     38        "txt_filter": ("DTS",), 
     39        "ext": ".dts", 
     40    }, 
     41    { 
     42        "txt_filter": ("Subtitle",), 
     43        "ext": ".sup", 
     44    }, 
     45] 
     46 
     47 
     48 
     49class Drive(dict): 
     50    def __init__(self, driveletter, cfg): 
     51        self["letter"] = driveletter 
     52        self.cfg = cfg 
     53 
     54        self["vol_info"] = None 
     55        self["lable"] = None 
     56 
     57        self["stream_dir"] = os.path.join(driveletter, cfg["stream_dir"]) 
     58 
     59    def set_vol_info(self, vol_info): 
     60        self["vol_info"] = vol_info 
     61        self["lable"] = vol_info[0] 
     62         
     63    def debug(self): 
     64        print "_"*79 
     65        print "Drive debug:" 
     66        pprint(self) 
     67        print "-"*79 
    2368 
    2469    def __str__(self): 
    25         return "<StreamInfo %s (%s)>" % ( 
    26             self.filename, self.parameter 
     70        return "<Drive '%s'>" % self["letter"] 
     71#    def __repr__(self): 
     72#        return self.__str__() 
     73 
     74 
     75 
     76 
     77 
     78 
     79 
     80 
     81class VideoFile(dict): 
     82    def __init__(self, name, drive, abs_path, stat, cfg): 
     83        self["name"] = name # Filename 
     84 
     85        self["fn"], self.ext = os.path.splitext(self["name"]) 
     86 
     87        self["drive"] = drive # class "Drive" 
     88        self["abs_path"] = abs_path # File path + filename 
     89        self["stat"] = stat # os.stat 
     90         
     91        self.cfg = cfg 
     92 
     93        self["out_path"] = os.path.join(cfg["out_dir"], drive["lable"]) 
     94 
     95        self["name_prefix"] = self["name"].replace(".", "_") 
     96 
     97        self["eac3to_txt_path"] = os.path.join( 
     98            self["out_path"], 
     99            "%s_eac3to.txt" % self["name_prefix"] 
    27100        ) 
    28     def __repr__(self): 
    29         return self.__str__() 
    30  
    31  
    32 VIDEO_EXT = "mkv" # ToDo: Should go into the config 
    33  
    34 STREAMINFOS = [ 
    35     StreamInfo( 
    36         filename = "chapters.txt", 
    37         txt_filter = ("Chapters",), 
    38     ), 
    39     StreamInfo( 
    40         filename = "h264."+VIDEO_EXT, 
    41         txt_filter = ("h264",), 
    42     ), 
    43     StreamInfo( 
    44         filename = "VC1."+VIDEO_EXT, 
    45         txt_filter = ("VC-1",), 
    46     ), 
    47     StreamInfo( 
    48         filename = "MPEG2."+VIDEO_EXT, 
    49         txt_filter = ("MPEG2",), 
    50     ), 
    51     StreamInfo( 
    52         filename = "ger 384KBits.ac3", 
    53         txt_filter = ("German",), 
    54         parameter = ["-384", "-down6", "-quality=4"], 
    55     ), 
    56 ] 
    57  
    58  
    59  
    60 class Drive(object): 
    61     def __init__(self, driveletter, cfg): 
    62         self.letter = driveletter 
    63         self.cfg = cfg 
    64  
    65         self.vol_info = None 
    66         self.lable = None 
    67  
    68         self.stream_dir = os.path.join(driveletter, cfg["stream_dir"]) 
    69  
    70     def set_vol_info(self, vol_info): 
    71         self.vol_info = vol_info 
    72         self.lable = vol_info[0] 
    73  
    74     def __str__(self): 
    75         return "<Drive '%s'>" % self.letter 
    76     def __repr__(self): 
    77         return self.__str__() 
    78  
    79  
    80 class Files(list): 
    81     def print_info(self): 
    82         for file in self: 
    83             print file.abs_path, 
    84             size = file.stat.st_size/1024.0/1024.0/1024.0 
    85             print "%.1f GB" % size 
    86             print "output path....:", file.output_path 
    87             print "log file path..:", file.log_file_path 
    88             print 
    89  
    90  
    91  
    92  
    93  
    94  
    95  
    96  
    97  
    98  
    99 class VideoFile(object): 
    100     def __init__(self, name, drive, abs_path, stat, cfg): 
    101         self.name = name # Filename 
    102  
    103         self.fn, self.ext = os.path.splitext(self.name) 
    104  
    105         self.drive = drive # class "Drive" 
    106         self.abs_path = abs_path # File path + filename 
    107         self.stat = stat # os.stat 
    108          
    109         self.cfg = cfg 
    110  
    111         self.output_path = os.path.join(cfg["out_dir"], drive.lable) 
    112  
    113         log_fn = "%s.log" % self.name.replace(".", "_") 
    114         self.log_file_path = os.path.join(self.output_path, log_fn) 
    115  
    116         self.streams = None # set in self.parse_streaminfo() 
     101 
     102        self["log_file_path"] = os.path.join( 
     103            self["out_path"], 
     104            "%s.log" % self["name_prefix"] 
     105        ) 
     106        self.log_file = file(self["log_file_path"], "a") 
     107        self.log("Start logging") 
     108 
     109        self["streams"] = None # set in self.parse_streaminfo() 
    117110 
    118111    def create_outdir(self): 
    119         if not os.path.isdir(self.output_path): 
    120             os.makedirs(self.output_path) 
     112        if not os.path.isdir(self["out_path"]): 
     113            os.makedirs(self["out_path"]) 
    121114 
    122115    #------------------------------------------------------------------------- 
    123  
    124     def open_log(self): 
    125         """ 
    126         Open the log file 
    127         """ 
    128         self.log_file = file(self.log_file_path, "a") 
    129         self.log("Start logging") 
    130116 
    131117    def log(self, txt): 
     
    140126    #------------------------------------------------------------------------- 
    141127 
    142     def get_command(self): 
    143         cmds = [self.cfg["eac3to"], self.abs_path] 
    144         for no, stream in self.streams: 
    145             #~ print stream 
    146             out_name = "%s_%s" % (self.fn, stream.filename) 
    147             out_fn = os.path.join(self.output_path, out_name) 
    148             cmds.append("%s: %s" % (no, out_fn)) 
    149  
    150             if stream.parameter: 
    151                 cmds += stream.parameter 
    152  
    153         return " ".join(cmds) 
    154  
    155     def parse_line(self, no, info): 
    156         def in_list(txt, l): 
    157             for item in l: 
    158                 if item in txt: 
    159                     return True 
    160             return False 
    161  
    162         for stream_info in STREAMINFOS: 
    163             if in_list(info, stream_info.txt_filter): 
    164                 self.streams.append([no, stream_info]) 
     128    def get_command(self, stream_selection): 
     129        cmd = [self.cfg["eac3to"], self["abs_path"]] 
     130         
     131        value_dict = {} 
     132        for k,v in self["streams"].iteritems(): 
     133#            print k,v 
     134            if v not in value_dict: 
     135                value_dict[v] = [] 
     136         
     137            value_dict[v].append(k) 
     138         
     139#        pprint(value_dict) 
     140 
     141        def get_file_ext(stream_txt): 
     142            def in_list(txt, l): 
     143                for item in l: 
     144                    if item in txt: 
     145                        return True 
     146                return False 
     147             
     148            for stream_info in STREAMINFOS: 
     149                if in_list(stream_txt, stream_info["txt_filter"]): 
     150                    return stream_info["ext"] 
     151                 
     152            raise RuntimeError( 
     153                "No STREAMINFOS entry matched for '%s'" % stream_txt 
     154            ) 
     155         
     156        selected_streams = {} 
     157        for stream_txt in stream_selection: 
     158            try: 
     159                ids = value_dict[stream_txt] 
     160            except KeyError: 
     161                print "Stream '%s' doesn't exist. Skip file." % stream_txt 
    165162                return 
     163             
     164            file_ext = get_file_ext(stream_txt) 
     165             
     166            for id in ids: 
     167                filename = "%s - %i - %s%s" % ( 
     168                    self["name_prefix"], 
     169                    id, 
     170                    make_slug(stream_txt), 
     171                    file_ext, 
     172                ) 
     173                out_filepath = os.path.join(self["out_path"], filename) 
     174                 
     175                cmd.append("%i:" % id) 
     176                cmd.append(out_filepath) 
     177                         
     178        return cmd 
    166179 
    167180 
    168181    def parse_streaminfo(self, txt): 
    169         self.streams = [] 
     182        self["streams"] = {} 
    170183        lines = txt.splitlines() 
    171184        lines = lines[1:] 
    172185        for line in lines: 
    173             #~ print ">", line 
     186            if DEBUG: 
     187                print ">", line 
    174188            no, info = line.split(":",1) 
    175             no = int(no) 
     189             
     190            try: 
     191                no = int(no) 
     192            except ValueError: 
     193                continue 
     194             
    176195            info = info.strip() 
    177             if info.startswith("Subtitle"): 
    178                 # Skip all subtitle streams 
    179                 continue 
    180  
    181             self.parse_line(no, info) 
    182  
     196             
     197            self["streams"][no] = info 
     198  
    183199 
    184200    def get_stream_info(self): 
    185         cmd = [self.cfg["eac3to"], self.abs_path] 
    186         print "run '%s'..." % " ".join(cmd) 
    187         process, output = subprocess2(cmd) 
    188         return process, output 
     201        """ 
     202        Run eac3to and cache the output data. 
     203        """ 
     204        if os.path.isfile(self["eac3to_txt_path"]): 
     205            print "Use existing eac3to output from cache file '%s'..." % ( 
     206                self["eac3to_txt_path"] 
     207            ) 
     208            f = file(self["eac3to_txt_path"], "r") 
     209            output = f.read() 
     210            f.close() 
     211        else: 
     212            # run eac3to and save the output data into self["eac3to_txt_path"] 
     213            cmd = [self.cfg["eac3to"], self["abs_path"]] 
     214            print "run '%s'..." % " ".join(cmd) 
     215            process, output = subprocess2(cmd) 
     216             
     217            f = file(self["eac3to_txt_path"], "w") 
     218            f.write(output) 
     219            f.close() 
     220             
     221        return output 
    189222 
    190223    #------------------------------------------------------------------------- 
     224     
     225    def debug(self): 
     226        print "_"*79 
     227        print "VideoFile debug:" 
     228        pprint(self) 
     229        print "-"*79 
    191230 
    192231    def __str__(self): 
    193         return "<File '%s'>" % self.abs_path 
    194     def __repr__(self): 
    195         return self.__str__() 
    196  
    197  
    198  
     232        return "<File '%s'>" % self["abs_path"] 
     233 
     234 
     235#------------------------------------------------------------------------------ 
    199236 
    200237 
     
    217254            continue 
    218255 
    219         if os.path.isdir(drive.stream_dir): 
     256        if os.path.isdir(drive["stream_dir"]): 
    220257            drive.set_vol_info(vol_info) 
    221258            result.append(drive) 
     
    225262 
    226263 
     264def choose_drive(cfg): 
     265    """ 
     266    Choose a stream dir manuely. 
     267    """ 
     268    path = askopenfilename2( 
     269        title = "Choose the stream dir:", 
     270        initialdir = cfg["last sourcedir"], 
     271        filetypes = [('M2TS File','*.m2ts')], 
     272    ) 
     273     
     274    vol_info = path.replace("\\", "_").replace(":","_") # Fallback 
     275    for part in reversed(path.split(os.sep)[:-1]): 
     276        # Use the last part of the path as a vol_info 
     277        if part.upper() not in ("BDMV", "STREAM"): 
     278            vol_info = part 
     279            break 
     280     
     281    drive = Drive(os.path.splitdrive(path)[0], cfg) 
     282    drive["stream_dir"] = os.path.split(path)[0] 
     283    drive.set_vol_info((vol_info,)) 
     284     
     285    drive.debug() 
     286     
     287    drives = [drive,] 
     288     
     289    cfg["last sourcedir"] = path 
     290     
     291    return drives 
     292 
     293 
     294#------------------------------------------------------------------------------ 
     295 
    227296 
    228297def get_stream_files(drives, skip_size): 
    229     files = Files() 
     298    files = [] 
    230299    for drive in drives: 
    231300        print drive, 
    232         path = drive.stream_dir 
     301        path = drive["stream_dir"] 
    233302        print path 
    234303        if not os.path.isdir(path): 
     
    236305            continue 
    237306         
    238         for fn in sorted(os.listdir(path)): 
    239             abs_path = os.path.join(path, fn) 
     307        glob_path = os.path.join(path, cfg["glob"]) 
     308        print "Looking in", glob_path 
     309        file_list = glob.glob(glob_path) 
     310        print "Files found:", file_list 
     311        for abs_path in sorted(file_list): 
     312            filename = os.path.basename(abs_path) 
     313             
    240314            stat = os.stat(abs_path) 
    241             size = stat.st_size 
    242             if size<cfg["skip_size"]: 
    243                 # Skip small files 
    244                 continue 
    245  
    246             f = VideoFile(fn, drive, abs_path, stat, cfg) 
     315 
     316#            print (filename, drive, abs_path, stat, cfg) 
     317            f = VideoFile(filename, drive, abs_path, stat, cfg) 
    247318            files.append(f) 
    248319 
     
    263334 
    264335 
     336def select_videofiles(videofiles): 
     337    """ 
     338    Select witch founded files should be recordnized. 
     339    """ 
     340    activated = [] 
     341    item_list = [] 
     342    for index, videofile in enumerate(videofiles): 
     343        filesize = videofile["stat"].st_size 
     344         
     345        line = "%s - %s" % (videofile["abs_path"], human_filesize(filesize)) 
     346        item_list.append(line) 
     347         
     348        if filesize>cfg["skip_size"]: 
     349            activated.append(index) 
     350     
     351#    size = stat.st_size 
     352#    if size<cfg["skip_size"]: 
     353#        # Skip small files 
     354#        continue   
     355     
     356    lb = TkListbox( 
     357        title = "Please select", 
     358        lable = "Please select files witch should be converted:", 
     359        items = item_list, 
     360        activated = activated 
     361    ) 
     362    print "selected items:" 
     363    pprint(lb.selection) # list of selected items. 
     364     
     365    curselection = lb.curselection # tuple containing index of selected items 
     366    print "curselection:", curselection       
     367         
     368    new_list = [ 
     369        item 
     370        for index, item in enumerate(videofiles) 
     371        if index in curselection 
     372    ] 
     373 
     374    return new_list 
     375 
     376 
     377 
     378 
    265379 
    266380def subprocess2(cmd): 
     381    print "_"*80 
     382    print "subprocess2():" 
     383    pprint(cmd) 
     384    print " -"*40 
    267385    process = subprocess.Popen( 
    268386        cmd, 
     
    294412    return process, output 
    295413 
    296  
     414     
     415def select_streams(videofiles): 
     416    """ 
     417    select witch streams should be convert. 
     418    """ 
     419    print "*"*79 
     420    streams_txt = [] 
     421    for videofile in videofiles: 
     422#        videofile.debug() 
     423        for stream_txt in videofile["streams"].values(): 
     424            if not stream_txt in streams_txt: 
     425                streams_txt.append(stream_txt) 
     426#     
     427#    lb = TkListbox( 
     428#        title = "Please select", 
     429#        lable = "Please select streams:", 
     430#        items = streams_txt 
     431#    ) 
     432#    print lb.selection 
     433     
     434    selection = TkListbox( 
     435        title = "Please select", 
     436        lable = "Please select streams:", 
     437        items = streams_txt 
     438    ).selection 
     439     
     440    return selection 
     441 
     442def convert_streams(videofile, stream_selection): 
     443    print "convert_streams():", videofile, stream_selection 
     444    videofile.debug() 
     445     
     446     
    297447 
    298448 
     
    304454        print "DEBUG!!!" 
    305455        drive = Drive("d:", cfg) 
    306         drive.stream_dir = r"d:\TEST\BDMV\STREAM" 
     456        drive["stream_dir"] = r"d:\TEST\BDMV\STREAM" 
    307457        drive.set_vol_info(("TEST_LABLE",)) 
    308458        drives = [drive,] 
     
    313463 
    314464    if not drives: 
    315         print "No drives with stream files found -> abort, ok." 
    316         sys.exit() 
    317  
    318     files = get_stream_files(drives, cfg) 
    319     files.print_info() 
    320      
    321     if not files: 
     465        print "No drives with stream files found -> choose manuel" 
     466        drives = choose_drive(cfg) 
     467 
     468    # Get from all path all m2ts files 
     469    videofiles = get_stream_files(drives, cfg) 
     470 
     471    # Select via Tk the files witch realy convert 
     472    videofiles = select_videofiles(videofiles) 
     473     
     474    if not videofiles: 
    322475        print "No stream files found -> abort, ok." 
    323476        sys.exit() 
    324477 
    325     if not continue_loop(): 
    326         print "Abort, ok." 
    327         sys.exit() 
    328  
    329     for videofile in files: 
     478#    if not continue_loop(): 
     479#        print "Abort, ok." 
     480#        sys.exit() 
     481 
     482    for videofile in videofiles: 
    330483        print videofile 
    331484 
    332485        videofile.create_outdir() 
    333         videofile.open_log() 
    334  
    335         #~ file.parse_streaminfo(txt) 
    336         process, output = videofile.get_stream_info() 
     486 
     487        output = videofile.get_stream_info() 
    337488        print "-"*80 
    338489        videofile.log("eac2to analyse output: %s" % output.lstrip("- ")) 
    339490        videofile.parse_streaminfo(output) 
    340491 
    341         cmd = videofile.get_command() 
     492        if videofile["streams"]: 
     493            print "Streams found:", videofile["streams"] 
     494        else: 
     495            print "ERROR: No streams found!" 
     496            continue 
     497         
     498 
     499 
     500    stream_selection = select_streams(videofiles) 
     501    print "selected streams:", stream_selection 
     502 
     503    for videofile in videofiles: 
     504        print videofile 
     505        cmd = videofile.get_command(stream_selection) 
     506 
    342507        videofile.log("run: %s" % cmd) 
    343         print cmd 
    344508        if DEBUG: 
    345509            print "DEBUG, skip real run..." 
    346510        else: 
    347511            process, output = subprocess2(cmd) 
    348         videofile.log("eac2to output: %s" % output.lstrip("- ")) 
     512            videofile.log("eac2to output: %s" % output.lstrip("- ")) 
    349513 
    350514        videofile.close_log() 
    351          
    352         break 
     515        print "-"*79 
    353516 
    354517    print " -- END -- " 
  • CodeSnippets/VideoTools/setup.py

    r1790 r1797  
    55""" 
    66 
     7from shared.tk_tools import simple_input 
    78from shared.config import VideoToolsConfig, DEFAULT_CONFIG 
     9 
     10def set_skip_size(cfg): 
     11     
     12    raw_skip_size = simple_input(       
     13        title="Setup m2ts file skip size:", 
     14        pre_lable="m2ts file skip size:", 
     15        init_value=cfg["skip_size"], 
     16        post_lable="(in Bytes)", 
     17    ) 
     18    cfg["skip_size"] = int(raw_skip_size) 
     19 
    820 
    921if __name__ == "__main__": 
     
    1628        # No new config file created, and out dir requested in the past 
    1729        cfg.ask_out_dir() 
     30     
     31    set_skip_size(cfg) 
    1832         
     33    cfg.save_config() 
    1934    cfg.debug() 
  • CodeSnippets/VideoTools/shared/config.py

    r1790 r1797  
    66from ConfigParser import RawConfigParser 
    77 
    8 from tools import askopenfilename2, askdirectory2 
     8from tk_tools import askopenfilename2, askdirectory2 
    99 
    1010 
     
    1414    "out_dir": "", 
    1515 
    16     "skip_size": 100 * 1024 * 1024, 
     16    "glob": "*.m2ts", 
     17    "skip_size": 200 * 1024 * 1024, 
    1718    "stream_dir": "BDMV\\STREAM", 
    1819    "out_video_ext": "mkv", 
     
    3940class PickleConfig(dict): 
    4041 
    41     def __init__(self): 
    42         self.update(DEFAULT_CONFIG) 
     42    def __init__(self, filename, defaults={}): 
     43        self.filename = filename 
    4344         
    44         if os.path.isfile(CONFIG_FILENAME): 
     45        self.update(defaults) 
     46         
     47        if not os.path.isfile(self.filename): 
     48            print "Info: Config file '%s' doesn't exist, yet." % self.filename 
     49        else: 
     50            print "Reading '%s'..." % self.filename 
    4551            try: 
    46                 f = file(CONFIG_FILENAME, "r") 
     52                f = file(filename, "r") 
    4753            except IOError, err: 
    4854                print "Error reading config:", err 
     
    5157                f.close() 
    5258                self.update(pickle_data) 
     59         
    5360 
    5461    def save_config(self): 
    55         print "Save config to '%s'..." % CONFIG_FILENAME, 
    56         f = file(CONFIG_FILENAME, "w") 
     62        print "Save '%s'..." % self.filename, 
     63        f = file(self.filename, "w") 
    5764        pickle.dump(self, f) 
    5865        f.close() 
     
    6067 
    6168    def debug(self): 
    62         print "Debug config:" 
     69        print "PickleConfig debug:" 
    6370        pprint(self) 
    6471        print "-"*80 
     
    6875class VideoToolsConfig(PickleConfig): 
    6976    def __init__(self): 
    70         super(VideoToolsConfig, self).__init__() 
     77        super(VideoToolsConfig, self).__init__(CONFIG_FILENAME, DEFAULT_CONFIG) 
    7178         
    7279        # Check/set the path to all EXE files 
     
    97104        ) 
    98105        self.out_dir_set = True 
    99         self.save_config() 
    100106         
    101107 
     
    103109    from pprint import pprint 
    104110 
    105     CONFIG_FILENAME = "config_test.ini" 
    106     if os.path.isfile(CONFIG_FILENAME): 
    107         os.remove(CONFIG_FILENAME) 
     111    test_config = "config_test.ini" 
     112    if os.path.isfile(test_config): 
     113        os.remove(test_config) 
    108114 
    109115    # Simple Test 
    110     c = PickleConfig() 
     116    c = PickleConfig(test_config, DEFAULT_CONFIG) 
    111117    c.debug() 
    112118    print "-"*80 
     
    118124    print "-"*80 
    119125    # Reopen the written ini file: 
    120     c = PickleConfig() 
     126    c = PickleConfig(test_config) 
    121127    c.debug() 
  • CodeSnippets/VideoTools/shared/tools.py

    r1789 r1797  
    11# -*- coding: utf-8 -*- 
    22 
    3 import os, sys 
    4  
    5 import Tkinter as tk 
    6 from tkFileDialog import askopenfilename, askdirectory 
    7  
    8 def _ask(method, *args, **kwargs): 
    9     root = tk.Tk() 
    10     kwargs["parent"] = root 
    11     path = method(*args, **kwargs) 
    12     root.destroy() 
    13      
    14     if path == "": # Nothing selected. 
    15         sys.exit() 
    16      
    17     return os.path.normpath(path) 
    18  
    19 def askdirectory2(*args, **kwargs): 
    20     return _ask(askdirectory, *args, **kwargs) 
     3import os, sys, string 
    214 
    225 
    23 def askopenfilename2(*args, **kwargs): 
    24     return _ask(askopenfilename, *args, **kwargs) 
     6def human_filesize(bytes): 
     7    """ 
     8    >>> human_filesize(1*1024) 
     9    '1.0KB' 
     10    >>> human_filesize(1*1024*1024) 
     11    '1.0MB' 
     12    >>> human_filesize(1.5*1024*1024) 
     13    '1.5MB' 
     14    """ 
     15    bytes = float(bytes) 
     16    for unit in ['bytes','KB','MB','GB','TB']: 
     17        if bytes < 1000: 
     18            return "%s%s" % (round(bytes,1), unit) 
     19        bytes /= 1024.0 
     20 
     21 
     22 
     23 
     24ALLOW_CHARS = string.ascii_letters + string.digits + "+-,." 
     25 
     26def make_slug(txt, join_string=" ", allow_chars=ALLOW_CHARS): 
     27    """ 
     28    delete all non-ALLOW_CHARS characters 
     29     
     30    >>> make_slug("a test") 
     31    'a test' 
     32    >>> make_slug("") 
     33    '' 
     34    >>> make_slug("A other test 1*2/3\\4/*/*/5") 
     35    'A other test 1 2 3 5' 
     36    """ 
     37    parts = [""] 
     38    for char in txt: 
     39        if char not in allow_chars: 
     40            if parts[-1] != "": 
     41                # No double "-" e.g.: "foo - bar" -> "foo-bar" not "foo---bar"    
     42                parts.append("") 
     43        else: 
     44            parts[-1] += char 
     45 
     46    item_name = join_string.join(parts) 
     47    item_name = item_name.strip(join_string) 
     48     
     49    return item_name 
     50 
     51 
     52 
     53def makeUnique(item_name, name_list, max_no=1000): 
     54    """ 
     55    returns a unique shortcut. 
     56    - delete all non-ALLOW_CHARS characters. 
     57    - if the shotcut already exists in name_list -> add a sequential number 
     58     
     59    >>> makeUnique("two", ["one", "two", "three"]) 
     60    'two1' 
     61    >>> makeUnique("two", ["one", "three"]) 
     62    'two' 
     63    >>> makeUnique("two", ["one", "two", "two1", "three"]) 
     64    'two2' 
     65    >>> makeUnique("", []) 
     66    '' 
     67    """ 
     68    name_list2 = [i.lower() for i in name_list] 
     69 
     70    # make double shortcut unique (add a new free sequential number) 
     71    if item_name.lower() in name_list2: 
     72        for i in xrange(1, max_no): 
     73            testname = "%s%i" % (item_name, i) 
     74            if testname.lower() not in name_list2: 
     75                item_name = testname 
     76                break 
     77 
     78    return item_name 
     79 
     80 
     81if __name__ == "__main__": 
     82    import doctest 
     83    doctest.testmod(verbose=False) 
     84    print "DocTest end." 
  • CodeSnippets/VideoTools/Templatemaker.py

    r1790 r1797  
    88 
    99from shared.config import VideoToolsConfig 
    10 from shared.tools import askopenfilename2 
     10from shared.tk_tools import askopenfilename2 
    1111 
    1212