1# -*- coding: utf-8 -*- 2# Copyright (C) 2005 Michael Urman 3# 4# This program is free software; you can redistribute it and/or modify 5# it under the terms of the GNU General Public License as published by 6# the Free Software Foundation; either version 2 of the License, or 7# (at your option) any later version. 8 9from ._util import loadfile 10 11 12class PaddingInfo(object): 13 """PaddingInfo() 14 15 Abstract padding information object. 16 17 This will be passed to the callback function that can be used 18 for saving tags. 19 20 :: 21 22 def my_callback(info: PaddingInfo): 23 return info.get_default_padding() 24 25 The callback should return the amount of padding to use (>= 0) based on 26 the content size and the padding of the file after saving. The actual used 27 amount of padding might vary depending on the file format (due to 28 alignment etc.) 29 30 The default implementation can be accessed using the 31 :meth:`get_default_padding` method in the callback. 32 33 Attributes: 34 padding (`int`): The amount of padding left after saving in bytes 35 (can be negative if more data needs to be added as padding is 36 available) 37 size (`int`): The amount of data following the padding 38 """ 39 40 def __init__(self, padding, size): 41 self.padding = padding 42 self.size = size 43 44 def get_default_padding(self): 45 """The default implementation which tries to select a reasonable 46 amount of padding and which might change in future versions. 47 48 Returns: 49 int: Amount of padding after saving 50 """ 51 52 high = 1024 * 10 + self.size // 100 # 10 KiB + 1% of trailing data 53 low = 1024 + self.size // 1000 # 1 KiB + 0.1% of trailing data 54 55 if self.padding >= 0: 56 # enough padding left 57 if self.padding > high: 58 # padding too large, reduce 59 return low 60 # just use existing padding as is 61 return self.padding 62 else: 63 # not enough padding, add some 64 return low 65 66 def _get_padding(self, user_func): 67 if user_func is None: 68 return self.get_default_padding() 69 else: 70 return user_func(self) 71 72 def __repr__(self): 73 return "<%s size=%d padding=%d>" % ( 74 type(self).__name__, self.size, self.padding) 75 76 77class Tags(object): 78 """`Tags` is the base class for many of the tag objects in Mutagen. 79 80 In many cases it has a dict like interface. 81 """ 82 83 __module__ = "mutagen" 84 85 def pprint(self): 86 """ 87 Returns: 88 text: tag information 89 """ 90 91 raise NotImplementedError 92 93 94class Metadata(Tags): 95 """Metadata(filething=None, **kwargs) 96 97 Args: 98 filething (filething): a filename or a file-like object or `None` 99 to create an empty instance (like ``ID3()``) 100 101 Like :class:`Tags` but for standalone tagging formats that are not 102 solely managed by a container format. 103 104 Provides methods to load, save and delete tags. 105 """ 106 107 __module__ = "mutagen" 108 109 def __init__(self, *args, **kwargs): 110 if args or kwargs: 111 self.load(*args, **kwargs) 112 113 @loadfile() 114 def load(self, filething, **kwargs): 115 raise NotImplementedError 116 117 @loadfile(writable=False) 118 def save(self, filething=None, **kwargs): 119 """save(filething=None, **kwargs) 120 121 Save changes to a file. 122 123 Args: 124 filething (filething): or `None` 125 Raises: 126 MutagenError: if saving wasn't possible 127 """ 128 129 raise NotImplementedError 130 131 @loadfile(writable=False) 132 def delete(self, filething=None): 133 """delete(filething=None) 134 135 Remove tags from a file. 136 137 In most cases this means any traces of the tag will be removed 138 from the file. 139 140 Args: 141 filething (filething): or `None` 142 Raises: 143 MutagenError: if deleting wasn't possible 144 """ 145 146 raise NotImplementedError 147