Back to index

eyed3  0.6.18
Public Member Functions | Public Attributes | Static Public Attributes | Private Member Functions
tag.Tag Class Reference

List of all members.

Public Member Functions

def __init__
def clear
def __iter__
def next
def link
def update
def remove
def getArtist
def getAlbum
def getTitle
def getDate
def getYear
def getGenre
def getTrackNum
def getDiscNum
def getComments
def getLyrics
def getImages
def getObjects
def getURLs
def getUserTextFrames
def getCDID
def getVersion
def getVersionStr
def strToUnicode
def setArtist
def setAlbum
def setTitle
def setDate
def setGenre
def setTrackNum
def setDiscNum
def setNum
def addComment
def addLyrics
def addUserTextFrame
def addUserURLFrame
def removeUserTextFrame
def removeUserURLFrame
def removeComments
def removeLyrics
def removeImages
def addImage
def addObject
def getPlayCount
def setPlayCount
def incrementPlayCount
def getUniqueFileIDs
def addUniqueFileID
def getBPM
def setBPM
def getPublisher
def setPublisher
def isV1
def isV2
def setVersion
def setTextFrame
def setURLFrame
def setTextEncoding
def tagToString
def toInt
def getComment

Public Attributes

 header

Static Public Attributes

 encoding = DEFAULT_ENCODING;
tuple header = TagHeader()
tuple extendedHeader = ExtendedTagHeader()
 frames = None;
 iterIndex = None;
 linkedFile = None;
 do_tdtg = True

Private Member Functions

def _getNum
def _prettyTrack
def _subst
def __saveV1Tag
def _fixToWidth
def __loadV1Tag
def __saveV2Tag
def __loadV2Tag
def __padDateField
def __copyRemaining

Detailed Description

Definition at line 384 of file tag.py.


Constructor & Destructor Documentation

def tag.Tag.__init__ (   self,
  fileName = None 
)

Definition at line 411 of file tag.py.

00411 
00412    def __init__(self, fileName = None):
00413       if fileName:
00414          self.linkedFile = LinkedFile(fileName);
00415       self.clear();

Here is the call graph for this function:


Member Function Documentation

def tag.Tag.__copyRemaining (   self,
  src_fp,
  dest_fp 
) [private]

Definition at line 1395 of file tag.py.

01395 
01396    def __copyRemaining(self, src_fp, dest_fp):
01397        # Write audio data in chunks
01398        done = False
01399        amt = 1024 * 512
01400        while not done:
01401            data = src_fp.read(amt)
01402            if data:
01403                dest_fp.write(data)
01404            else:
01405                done = True
01406            del data

Here is the caller graph for this function:

def tag.Tag.__iter__ (   self)

Definition at line 422 of file tag.py.

00422 
00423    def __iter__(self):
00424       if len(self.frames):
00425          self.iterIndex = 0;
00426       else:
00427          self.iterIndex = None;
00428       return self;

def tag.Tag.__loadV1Tag (   self,
  f 
) [private]

Definition at line 1142 of file tag.py.

01142 
01143    def __loadV1Tag(self, f):
01144       if isinstance(f, str) or isinstance(f, unicode):
01145          fp = file(f, "rb")
01146          closeFile = 1;
01147       else:
01148          fp = f;
01149          closeFile = 0;
01150 
01151       # Seek to the end of the file where all ID3v1 tags are written.
01152       fp.seek(0, 2);
01153       strip_chars = string.whitespace + "\x00";
01154       if fp.tell() > 127:
01155          fp.seek(-128, 2);
01156          id3tag = fp.read(128);
01157          if id3tag[0:3] == "TAG":
01158             TRACE_MSG("Located ID3 v1 tag");
01159             # 1.0 is implied until a 1.1 feature is recognized.
01160             self.setVersion(ID3_V1_0);
01161 
01162             title = re.sub("\x00+$", "", id3tag[3:33].strip(strip_chars));
01163             TRACE_MSG("Tite: " + title);
01164             if title:
01165                self.setTitle(unicode(title, "latin1"));
01166 
01167             artist = re.sub("\x00+$", "", id3tag[33:63].strip(strip_chars));
01168             TRACE_MSG("Artist: " + artist);
01169             if artist:
01170                self.setArtist(unicode(artist, "latin1"));
01171 
01172             album = re.sub("\x00+$", "", id3tag[63:93].strip(strip_chars));
01173             TRACE_MSG("Album: " + album);
01174             if album:
01175                self.setAlbum(unicode(album, "latin1"));
01176 
01177             year = re.sub("\x00+$", "", id3tag[93:97].strip(strip_chars));
01178             TRACE_MSG("Year: " + year);
01179             try:
01180                if year and int(year):
01181                   self.setDate(year);
01182             except ValueError:
01183                # Bogus year strings.
01184                pass;
01185 
01186             if re.sub("\x00+$", "", id3tag[97:127]):
01187                comment = id3tag[97:127];
01188                TRACE_MSG("Comment: " + comment);
01189                if comment[-2] == "\x00" and comment[-1] != "\x00":
01190                   # Parse track number (added to ID3v1.1) if present.
01191                   TRACE_MSG("Comment contains track number per v1.1 spec");
01192                   track = ord(comment[-1]);
01193                   self.setTrackNum((track, None));
01194                   TRACE_MSG("Track: " + str(track));
01195                   TRACE_MSG("Track Num found, setting version to v1.1s");
01196                   self.setVersion(ID3_V1_1);
01197                   comment = comment[:-2];
01198                else:
01199                   track = None
01200                comment = re.sub("\x00+$", "", comment).rstrip();
01201                TRACE_MSG("Comment: " + comment);
01202                if comment:
01203                   self.addComment(unicode(comment, 'latin1'),
01204                                   ID3_V1_COMMENT_DESC);
01205 
01206             genre = ord(id3tag[127:128])
01207             TRACE_MSG("Genre ID: " + str(genre));
01208             self.setGenre(genre);
01209 
01210       if closeFile:
01211          fp.close()
01212       return len(self.frames);

Here is the call graph for this function:

Here is the caller graph for this function:

def tag.Tag.__loadV2Tag (   self,
  f 
) [private]

Definition at line 1344 of file tag.py.

01344 
01345    def __loadV2Tag(self, f):
01346       if isinstance(f, str) or isinstance(f, unicode):
01347          fp = file(f, "rb")
01348          closeFile = 1;
01349       else:
01350          fp = f;
01351          closeFile = 0;
01352 
01353       padding = -1;
01354       try:
01355          # Look for a tag and if found load it.
01356          if not self.header.parse(fp):
01357             return -1;
01358 
01359          # Read the extended header if present.
01360          if self.header.extended:
01361             self.extendedHeader.parse(fp, self.header);
01362 
01363          # Header is definitely there so at least one frame *must* follow.
01364          self.frames.setTagHeader(self.header);
01365          padding = self.frames.parse(fp, self.header, self.extendedHeader);
01366          TRACE_MSG("Tag contains %d bytes of padding." % padding);
01367       except FrameException, ex:
01368          fp.close();
01369          raise TagException(str(ex));
01370       except TagException:
01371          fp.close();
01372          raise;
01373 
01374       if closeFile:
01375          fp.close();
01376       return padding;

Here is the call graph for this function:

Here is the caller graph for this function:

def tag.Tag.__padDateField (   self,
  f 
) [private]

Definition at line 1385 of file tag.py.

01385 
01386    def __padDateField(self, f):
01387       fStr = str(f);
01388       if len(fStr) == 2:
01389          pass;
01390       elif len(fStr) == 1:
01391          fStr = "0" + fStr;
01392       else:
01393          raise TagException("Invalid date field: " + fStr);
01394       return fStr;

Here is the caller graph for this function:

def tag.Tag.__saveV1Tag (   self,
  version 
) [private]

Definition at line 1082 of file tag.py.

01082 
01083    def __saveV1Tag(self, version):
01084       assert(version & ID3_V1);
01085 
01086       # Build tag buffer.
01087       tag = "TAG";
01088       tag += self._fixToWidth(self.getTitle().encode("latin_1"), 30);
01089       tag += self._fixToWidth(self.getArtist().encode("latin_1"), 30);
01090       tag += self._fixToWidth(self.getAlbum().encode("latin_1"), 30);
01091       y = self.getYear();
01092       if y is None:
01093           y = "";
01094       tag += self._fixToWidth(y.encode("latin_1"), 4);
01095 
01096       cmt = "";
01097       for c in self.getComments():
01098          if c.description == ID3_V1_COMMENT_DESC:
01099             cmt = c.comment;
01100             # We prefer this one over "";
01101             break; 
01102          elif c.description == "":
01103             cmt = c.comment;
01104             # Keep searching in case we find the description eyeD3 uses.
01105       cmt = self._fixToWidth(cmt.encode("latin_1"), 30);
01106       if version != ID3_V1_0:
01107          track = self.getTrackNum()[0];
01108          if track != None:
01109             cmt = cmt[0:28] + "\x00" + chr(int(track) & 0xff);
01110       tag += cmt;
01111 
01112       if not self.getGenre() or self.getGenre().getId() is None:
01113          genre = 0;
01114       else:
01115          genre = self.getGenre().getId();
01116       tag += chr(genre & 0xff);
01117 
01118       assert(len(tag) == 128);
01119 
01120       tagFile = file(self.linkedFile.name, "r+b");
01121       # Write the tag over top an original or append it.
01122       try:
01123          tagFile.seek(-128, 2);
01124          if tagFile.read(3) == "TAG":
01125             tagFile.seek(-128, 2);
01126          else:
01127             tagFile.seek(0, 2);
01128       except IOError:
01129          # File is smaller than 128 bytes.
01130          tagFile.seek(0, 2);
01131 
01132       tagFile.write(tag);
01133       tagFile.flush();
01134       tagFile.close();

Here is the call graph for this function:

Here is the caller graph for this function:

def tag.Tag.__saveV2Tag (   self,
  version 
) [private]

Definition at line 1213 of file tag.py.

01213 
01214    def __saveV2Tag(self, version):
01215       assert(version & ID3_V2);
01216       TRACE_MSG("Rendering tag version: " + versionToString(version));
01217 
01218       self.setVersion(version);
01219 
01220       currPadding = 0;
01221       currTagSize = 0
01222       # We may be converting from 1.x to 2.x so we need to find any
01223       # current v2.x tag otherwise we're gonna hork the file.
01224       tmpTag = Tag();
01225       if tmpTag.link(self.linkedFile.name, ID3_V2):
01226          TRACE_MSG("Found current v2.x tag:");
01227          currTagSize = tmpTag.linkedFile.tagSize;
01228          TRACE_MSG("Current tag size: %d" % currTagSize);
01229          currPadding = tmpTag.linkedFile.tagPadding;
01230          TRACE_MSG("Current tag padding: %d" % currPadding);
01231 
01232       if self.do_tdtg:
01233           t = time.strftime("%Y-%m-%dT%H:%M:%S", time.gmtime());
01234           # Tag it!
01235           if self.header.minorVersion == 4:
01236               # TDTG for 2.4
01237               h = FrameHeader(self.header);
01238               h.id = "TDTG";
01239               dateFrame = DateFrame(h, date_str = self.strToUnicode(t),
01240                                     encoding = self.encoding);
01241               self.frames.removeFramesByID("TDTG");
01242               self.frames.addFrame(dateFrame);
01243           else:
01244               # TXXX (Tagging time) for older versions
01245               self.frames.removeFramesByID("TDTG");
01246               self.addUserTextFrame('Tagging time', t)
01247 
01248       # Render all frames first so the data size is known for the tag header.
01249       frameData = "";
01250       for f in self.frames:
01251          TRACE_MSG("Rendering frame: " + f.header.id);
01252          raw_frame = f.render();
01253          TRACE_MSG("Rendered %d bytes" % len(raw_frame));
01254          frameData += raw_frame;
01255       # Handle the overall tag header unsync bit.  Frames themselves duplicate
01256       # this bit.
01257       if self.header.unsync:
01258           TRACE_MSG("Unsyncing all frames (sync-safe)");
01259           frameData = frames.unsyncData(frameData);
01260 
01261       rewriteFile = 0;
01262       paddingSize = 0;
01263       DEFAULT_PADDING = 1024
01264       def compute_padding():
01265           if currPadding <= DEFAULT_PADDING:
01266               return DEFAULT_PADDING
01267           else:
01268               return currPadding
01269 
01270       # Extended header
01271       extHeaderData = "";
01272       if self.header.extended:
01273          # This is sorta lame.  We don't know the total framesize until
01274          # this is rendered, yet we can't render it witout knowing the
01275          # amount of padding for the crc.  Force it.
01276          rewriteFile = 1;
01277          TRACE_MSG("Rendering extended header");
01278          paddingSize = compute_padding()
01279          extHeaderData += self.extendedHeader.render(self.header, frameData,
01280                                                      paddingSize);
01281 
01282       new_size = 10 + len(extHeaderData) + len(frameData) + paddingSize
01283       if rewriteFile or new_size >= currTagSize:
01284          TRACE_MSG("File rewrite required");
01285          rewriteFile = 1;
01286          if paddingSize <= 0:
01287              paddingSize = compute_padding()
01288       elif paddingSize <= 0:
01289          paddingSize = currTagSize - (new_size - 10)
01290       TRACE_MSG("Adding %d bytes of padding" % paddingSize)
01291       frameData += ("\x00" * paddingSize);
01292 
01293       # Recompute with padding
01294       new_size = 10 + len(extHeaderData) + len(frameData)
01295       header_tag_size = new_size - 10
01296 
01297       # Render the tag header.
01298       TRACE_MSG("Rendering %s tag header with size %d" %
01299                 (versionToString(self.getVersion()), header_tag_size))
01300       headerData = self.header.render(header_tag_size)
01301 
01302       # Assemble frame.
01303       tagData = headerData + extHeaderData + frameData;
01304 
01305       # Write the tag.
01306       if not rewriteFile:
01307          tagFile = file(self.linkedFile.name, "r+b");
01308          TRACE_MSG("Writing %d bytes of tag data" % len(tagData));
01309          tagFile.write(tagData);
01310          tagFile.close();
01311       else:
01312          # Open tmp file
01313          tmpName = tempfile.mktemp();
01314          tmpFile = file(tmpName, "w+b");
01315          TRACE_MSG("Writing %d bytes of tag data" % len(tagData));
01316          tmpFile.write(tagData);
01317 
01318          # Write audio data in chunks
01319          tagFile = file(self.linkedFile.name, "rb");
01320          if currTagSize != 0:
01321              seek_point = currTagSize + 10
01322          else:
01323              seek_point = 0
01324          TRACE_MSG("Seeking to beginning of audio data, byte %d (%x)" %
01325                    (seek_point, seek_point))
01326          tagFile.seek(seek_point)
01327          self.__copyRemaining(tagFile, tmpFile);
01328 
01329          tagFile.close();
01330          tmpFile.close();
01331 
01332          # Move tmp to orig.
01333          shutil.copyfile(tmpName, self.linkedFile.name);
01334          os.unlink(tmpName);
01335 
01336       # Update our state.
01337       TRACE_MSG("Tag write complete.  Updating state.");
01338       self.linkedFile.tagPadding = paddingSize;
01339       # XXX: getSize could cache sizes so to prevent rendering again.
01340       self.linkedFile.tagSize = self.frames.getSize();
01341 

Here is the call graph for this function:

Here is the caller graph for this function:

def tag.Tag._fixToWidth (   self,
  s,
  n 
) [private]

Definition at line 1135 of file tag.py.

01135 
01136    def _fixToWidth(self, s, n):
01137       retval = str(s);
01138       retval = retval[0:n];
01139       retval = retval + ("\x00" * (n - len(retval)));
01140       return retval;

Here is the caller graph for this function:

def tag.Tag._getNum (   self,
  fid 
) [private]

Definition at line 653 of file tag.py.

00653 
00654    def _getNum(self, fid):
00655       tn = None
00656       tt = None
00657       f = self.frames[fid];
00658       if f:
00659          n = f[0].text.split('/')
00660          if len(n) == 1:
00661             tn = self.toInt(n[0])
00662          elif len(n) == 2:
00663             tn = self.toInt(n[0])
00664             tt = self.toInt(n[1])
00665       return (tn, tt)

Here is the call graph for this function:

Here is the caller graph for this function:

def tag.Tag._prettyTrack (   self,
  track 
) [private]

Definition at line 1066 of file tag.py.

01066 
01067    def _prettyTrack(self, track):
01068        if not track:
01069            return None
01070        track_str = str(track)
01071        if len(track_str) == 1:
01072            track_str = "0" + track_str
01073        return track_str

Here is the caller graph for this function:

def tag.Tag._subst (   self,
  name,
  pattern,
  repl 
) [private]

Definition at line 1074 of file tag.py.

01074 
01075    def _subst(self, name, pattern, repl):
01076        regex = re.compile(pattern)
01077        if regex.search(name) and repl:
01078            # No '/' characters allowed
01079            (repl, subs) = re.compile("/").subn("-", repl);
01080            (name, subs) = regex.subn(repl, name)
01081        return name;

Here is the caller graph for this function:

def tag.Tag.addComment (   self,
  cmt,
  desc = u"",
  lang = DEFAULT_LANG 
)

Definition at line 853 of file tag.py.

00853 
00854    def addComment(self, cmt, desc = u"", lang = DEFAULT_LANG):
00855       if not cmt:
00856          # A little more then a call to removeFramesByID is involved since we
00857          # need to look at more than the frame ID.
00858          comments = self.frames[COMMENT_FID];
00859          for c in comments:
00860             if c.lang == lang and c.description == desc:
00861                self.frames.remove(c);
00862                break;
00863       else:
00864          self.frames.setCommentFrame(self.strToUnicode(cmt),
00865                                      self.strToUnicode(desc),
00866                                      lang, self.encoding);

Here is the call graph for this function:

Here is the caller graph for this function:

def tag.Tag.addImage (   self,
  type,
  image_file_path,
  desc = u"" 
)

Definition at line 920 of file tag.py.

00920 
00921    def addImage(self, type, image_file_path, desc = u""):
00922        if image_file_path:
00923            image_frame = ImageFrame.create(type, image_file_path, desc);
00924            self.frames.addFrame(image_frame);
00925        else:
00926            image_frames = self.frames[IMAGE_FID];
00927            for i in image_frames:
00928                if i.pictureType == type:
00929                    self.frames.remove(i);
00930                    break;

Here is the call graph for this function:

def tag.Tag.addLyrics (   self,
  lyr,
  desc = u"",
  lang = DEFAULT_LANG 
)

Definition at line 868 of file tag.py.

00868 
00869    def addLyrics(self, lyr, desc = u"", lang = DEFAULT_LANG):
00870       if not lyr:
00871          # A little more than a call to removeFramesByID is involved since we
00872          # need to look at more than the frame ID.
00873          lyrics = self.frames[LYRICS_FID];
00874          for l in lyrics:
00875             if l.lang == lang and l.description == desc:
00876                self.frames.remove(l);
00877                break;
00878       else:
00879          self.frames.setLyricsFrame(self.strToUnicode(lyr),
00880                                      self.strToUnicode(desc),
00881                                      lang, self.encoding);

Here is the call graph for this function:

def tag.Tag.addObject (   self,
  object_file_path,
  mime = "",
  desc = u"",
  filename = None 
)

Definition at line 932 of file tag.py.

00932 
00933                  filename = None ):
00934        object_frames = self.frames[OBJECT_FID];
00935        for i in object_frames:
00936            if i.description == desc:
00937                self.frames.remove(i);
00938        if object_file_path:
00939            object_frame = ObjectFrame.create(object_file_path, mime, desc,
00940                                              filename);
00941            self.frames.addFrame(object_frame);

Here is the caller graph for this function:

def tag.Tag.addUniqueFileID (   self,
  owner_id,
  id 
)

Definition at line 972 of file tag.py.

00972 
00973    def addUniqueFileID(self, owner_id, id):
00974       if not id:
00975          ufids = self.frames[UNIQUE_FILE_ID_FID];
00976          for ufid in ufids:
00977              if ufid.owner_id == owner_id:
00978                  self.frames.remove(ufid);
00979                  break;
00980       else:
00981          self.frames.setUniqueFileIDFrame(owner_id, id);

def tag.Tag.addUserTextFrame (   self,
  desc,
  text 
)

Definition at line 883 of file tag.py.

00883 
00884    def addUserTextFrame(self, desc, text):
00885       if not text:
00886          u_frames = self.frames[USERTEXT_FID]
00887          for u in u_frames:
00888             if u.description == desc:
00889                self.frames.remove(u);
00890                break
00891       else:
00892          self.frames.setUserTextFrame(self.strToUnicode(text),
00893                                       self.strToUnicode(desc), self.encoding);

Here is the call graph for this function:

Here is the caller graph for this function:

def tag.Tag.addUserURLFrame (   self,
  desc,
  url 
)

Definition at line 894 of file tag.py.

00894 
00895    def addUserURLFrame(self, desc, url):
00896       if not url:
00897          u_frames = self.frames[USERURL_FID]
00898          for u in u_frames:
00899             if u.description == desc:
00900                self.frames.remove(u)
00901                break
00902       else:
00903          self.frames.setUserURLFrame(str(url), self.strToUnicode(desc),
00904                                      self.encoding)

Here is the call graph for this function:

Here is the caller graph for this function:

def tag.Tag.clear (   self)

Definition at line 416 of file tag.py.

00416 
00417    def clear(self):
00418       self.header = TagHeader();
00419       self.frames = FrameSet(self.header);
00420       self.iterIndex = None;

Here is the caller graph for this function:

def tag.Tag.getAlbum (   self)

Definition at line 607 of file tag.py.

00607 
00608    def getAlbum(self):
00609       f = self.frames[ALBUM_FID];
00610       if f:
00611          return f[0].text;
00612       else:
00613          return u"";

Here is the caller graph for this function:

def tag.Tag.getArtist (   self,
  artistID = ARTIST_FIDS 
)

Definition at line 595 of file tag.py.

00595 
00596    def getArtist(self, artistID = ARTIST_FIDS):
00597       if isinstance(artistID, list):
00598          frameIDs = artistID;
00599       else:
00600          frameIDs = [artistID];
00601 
00602       for fid in frameIDs:
00603          f = self.frames[fid];
00604          if f:
00605              return f[0].text;
00606       return u"";

Here is the caller graph for this function:

def tag.Tag.getBPM (   self)

Definition at line 982 of file tag.py.

00982 
00983    def getBPM(self):
00984       bpm = self.frames[BPM_FID];
00985       if bpm:
00986           try:
00987               bpm = float(bpm[0].text)
00988           except ValueError:
00989               # Invalid bpm value, in the spirit of not crashing...
00990               bpm = 0.0
00991           finally:
00992               # Round floats since the spec says this is an integer
00993               return int(round(bpm))
00994       else:
00995           return None;

def tag.Tag.getCDID (   self)

Definition at line 710 of file tag.py.

00710 
00711    def getCDID(self):
00712       return self.frames[CDID_FID];

def tag.Tag.getComment (   self)

Definition at line 1411 of file tag.py.

01411 
01412    def getComment(self):
01413       f = self.frames[COMMENT_FID];
01414       if f:
01415          return f[0].comment;
01416       else:
01417          return None;
01418 

def tag.Tag.getComments (   self)

Definition at line 680 of file tag.py.

00680 
00681    def getComments(self):
00682       return self.frames[COMMENT_FID];

Here is the caller graph for this function:

def tag.Tag.getDate (   self,
  fid = None 
)

Definition at line 627 of file tag.py.

00627 
00628    def getDate(self, fid = None):
00629        if not fid:
00630            for fid in DATE_FIDS:
00631                if self.frames[fid]:
00632                    return self.frames[fid];
00633            return None;
00634        return self.frames[fid];

Here is the caller graph for this function:

def tag.Tag.getDiscNum (   self)

Definition at line 674 of file tag.py.

00674 
00675    def getDiscNum(self):
00676       return self._getNum(DISCNUM_FID)

Here is the call graph for this function:

def tag.Tag.getGenre (   self)

Definition at line 644 of file tag.py.

00644 
00645    def getGenre(self):
00646       f = self.frames[GENRE_FID];
00647       if f and f[0].text:
00648          g = Genre();
00649          g.parse(f[0].text);
00650          return g;
00651       else:
00652          return None;

Here is the caller graph for this function:

def tag.Tag.getImages (   self)

Definition at line 690 of file tag.py.

00690 
00691    def getImages(self):
00692       return self.frames[IMAGE_FID];

def tag.Tag.getLyrics (   self)

Definition at line 686 of file tag.py.

00686 
00687    def getLyrics(self):
00688       return self.frames[LYRICS_FID];

def tag.Tag.getObjects (   self)

Definition at line 694 of file tag.py.

00694 
00695    def getObjects(self):
00696       return self.frames[OBJECT_FID];

def tag.Tag.getPlayCount (   self)

Definition at line 942 of file tag.py.

00942 
00943    def getPlayCount(self):
00944        if self.frames[PLAYCOUNT_FID]:
00945            pc = self.frames[PLAYCOUNT_FID][0];
00946            assert(isinstance(pc, PlayCountFrame));
00947            return pc.count;
00948        else:
00949            return None;

Here is the caller graph for this function:

def tag.Tag.getPublisher (   self)

Definition at line 999 of file tag.py.

00999 
01000    def getPublisher(self):
01001       pub = self.frames[PUBLISHER_FID];
01002       if pub:
01003           return pub[0].text or None;

def tag.Tag.getTitle (   self,
  titleID = TITLE_FID 
)

Definition at line 620 of file tag.py.

00620 
00621    def getTitle(self, titleID = TITLE_FID):
00622       f = self.frames[titleID];
00623       if f:
00624          return f[0].text;
00625       else:
00626          return u"";

Here is the caller graph for this function:

def tag.Tag.getTrackNum (   self)

Definition at line 669 of file tag.py.

00669 
00670    def getTrackNum(self):
00671       return self._getNum(TRACKNUM_FID)

Here is the call graph for this function:

Here is the caller graph for this function:

def tag.Tag.getUniqueFileIDs (   self)

Definition at line 969 of file tag.py.

00969 
00970    def getUniqueFileIDs(self):
00971        return self.frames[UNIQUE_FILE_ID_FID];

def tag.Tag.getURLs (   self)

Definition at line 700 of file tag.py.

00700 
00701    def getURLs(self):
00702        urls = []
00703        for fid in URL_FIDS:
00704            urls.extend(self.frames[fid])
00705        urls.extend(self.frames[USERURL_FID])
00706        return urls

def tag.Tag.getUserTextFrames (   self)

Definition at line 707 of file tag.py.

00707 
00708    def getUserTextFrames(self):
00709       return self.frames[USERTEXT_FID];

def tag.Tag.getVersion (   self)

Definition at line 713 of file tag.py.

00713 
00714    def getVersion(self):
00715       return self.header.version;

Here is the caller graph for this function:

def tag.Tag.getVersionStr (   self)

Definition at line 716 of file tag.py.

00716 
00717    def getVersionStr(self):
00718       return versionToString(self.header.version);

Here is the call graph for this function:

def tag.Tag.getYear (   self,
  fid = None 
)

Definition at line 635 of file tag.py.

00635 
00636    def getYear(self, fid = None):
00637        dateFrame = self.getDate(fid);
00638        if dateFrame:
00639            return dateFrame[0].getYear();
00640        else:
00641            return None;

Here is the call graph for this function:

Here is the caller graph for this function:

def tag.Tag.incrementPlayCount (   self,
  n = 1 
)

Definition at line 962 of file tag.py.

00962 
00963    def incrementPlayCount(self, n = 1):
00964        pc = self.getPlayCount();
00965        if pc != None:
00966            self.setPlayCount(pc + n);
00967        else:
00968            self.setPlayCount(n);

Here is the call graph for this function:

def tag.Tag.isV1 (   self)

Definition at line 1008 of file tag.py.

01008 
01009    def isV1(self):
      return self.header.majorVersion == 1;
def tag.Tag.isV2 (   self)

Definition at line 1010 of file tag.py.

01010 
01011    def isV2(self):
01012       return self.header.majorVersion == 2;

def tag.Tag.link (   self,
  f,
  v = ID3_ANY_VERSION 
)

Definition at line 447 of file tag.py.

00447 
00448    def link(self, f, v = ID3_ANY_VERSION):
00449       self.linkedFile = None;
00450       self.clear();
00451 
00452       fileName = "";
00453       if isinstance(f, file):
00454          fileName = f.name;
00455       elif isinstance(f, str) or isinstance(f, unicode):
00456          fileName = f;
00457       else:
00458          raise TagException("Invalid type passed to Tag.link: " +
00459                             str(type(f)));
00460 
00461       if v != ID3_V1 and v != ID3_V2 and v != ID3_ANY_VERSION:
00462          raise TagException("Invalid version: " + hex(v));
00463 
00464       tagFound = 0;
00465       padding = 0;
00466       TRACE_MSG("Linking File: " + fileName);
00467       if v == ID3_V1:
00468          if self.__loadV1Tag(f):
00469             tagFound = 1;
00470       elif v == ID3_V2:
00471          padding = self.__loadV2Tag(f);
00472          if padding >= 0:
00473             tagFound = 1;
00474       elif v == ID3_ANY_VERSION:
00475          padding = self.__loadV2Tag(f);
00476          if padding >= 0:
00477             tagFound = 1;
00478          else:
00479             padding = 0;
00480             if self.__loadV1Tag(f):
00481                tagFound = 1;
00482 
00483       self.linkedFile = LinkedFile(fileName);
00484       if tagFound:
00485          # In the case of a v1.x tag this is zero.
00486          self.linkedFile.tagSize = self.header.tagSize;
00487          self.linkedFile.tagPadding = padding;
00488       else:
00489          self.linkedFile.tagSize = 0;
00490          self.linkedFile.tagPadding = 0;
00491       return tagFound;

Here is the call graph for this function:

def tag.Tag.next (   self)

Definition at line 429 of file tag.py.

00429 
00430    def next(self):
00431       if self.iterIndex == None or self.iterIndex == len(self.frames):
00432          raise StopIteration;
00433       frm = self.frames[self.iterIndex];
00434       self.iterIndex += 1;
00435       return frm;

def tag.Tag.remove (   self,
  version = ID3_CURRENT_VERSION 
)

Definition at line 536 of file tag.py.

00536 
00537    def remove(self, version = ID3_CURRENT_VERSION):
00538       if not self.linkedFile:
00539          raise TagException("The Tag is not linked to a file; nothing to "\
00540                             "remove.");
00541 
00542       if version == ID3_CURRENT_VERSION:
00543          version = self.getVersion();
00544 
00545       retval = 0;
00546       if version & ID3_V1 or version == ID3_ANY_VERSION:
00547          tagFile = file(self.linkedFile.name, "r+b");
00548          tagFile.seek(-128, 2);
00549          if tagFile.read(3) == "TAG":
00550             TRACE_MSG("Removing ID3 v1.x Tag");
00551             tagFile.seek(-3, 1);
00552             tagFile.truncate();
00553             retval |= 1;
00554          tagFile.close();
00555 
00556       if ((version & ID3_V2) or (version == ID3_ANY_VERSION)) and\
00557           self.header.tagSize:
00558          tagFile = file(self.linkedFile.name, "r+b");
00559          if tagFile.read(3) == "ID3":
00560             TRACE_MSG("Removing ID3 v2.x Tag");
00561             tagSize = self.header.tagSize + self.header.SIZE;
00562             tagFile.seek(tagSize);
00563 
00564             # Open tmp file
00565             tmpName = tempfile.mktemp();
00566             tmpFile = file(tmpName, "w+b");
00567 
00568             # Write audio data in chunks
00569             self.__copyRemaining(tagFile, tmpFile);
00570             tagFile.truncate();
00571             tagFile.close();
00572 
00573             tmpFile.close();
00574 
00575             # Move tmp to orig.
00576             shutil.copyfile(tmpName, self.linkedFile.name);
00577             os.unlink(tmpName);
00578 
00579             retval |= 1;
00580 
00581       return retval;

Here is the call graph for this function:

Here is the caller graph for this function:

def tag.Tag.removeComments (   self)

Definition at line 911 of file tag.py.

00911 
00912    def removeComments(self):
00913        return self.frames.removeFramesByID(COMMENT_FID);

def tag.Tag.removeImages (   self)

Definition at line 917 of file tag.py.

00917 
00918    def removeImages(self):
00919        return self.frames.removeFramesByID(IMAGE_FID)

def tag.Tag.removeLyrics (   self)

Definition at line 914 of file tag.py.

00914 
00915    def removeLyrics(self):
00916        return self.frames.removeFramesByID(LYRICS_FID);

def tag.Tag.removeUserTextFrame (   self,
  desc 
)

Definition at line 905 of file tag.py.

00905 
00906    def removeUserTextFrame(self, desc):
00907       self.addUserTextFrame(desc, "")

Here is the call graph for this function:

def tag.Tag.removeUserURLFrame (   self,
  desc 
)

Definition at line 908 of file tag.py.

00908 
00909    def removeUserURLFrame(self, desc):
00910       self.addUserURLFrame(desc, "")

Here is the call graph for this function:

def tag.Tag.setAlbum (   self,
  a 
)

Definition at line 734 of file tag.py.

00734 
00735    def setAlbum(self, a):
00736        self.setTextFrame(ALBUM_FID, self.strToUnicode(a));

Here is the call graph for this function:

Here is the caller graph for this function:

def tag.Tag.setArtist (   self,
  a,
  id = ARTIST_FID 
)

Definition at line 731 of file tag.py.

00731 
00732    def setArtist(self, a, id = ARTIST_FID):
00733        self.setTextFrame(id, self.strToUnicode(a));

Here is the call graph for this function:

Here is the caller graph for this function:

def tag.Tag.setBPM (   self,
  bpm 
)

Definition at line 996 of file tag.py.

00996 
00997    def setBPM(self, bpm):
00998        self.setTextFrame(BPM_FID, self.strToUnicode(str(bpm)))

Here is the call graph for this function:

def tag.Tag.setDate (   self,
  year,
  month = None,
  dayOfMonth = None,
  hour = None,
  minute = None,
  second = None,
  fid = None 
)

Definition at line 741 of file tag.py.

00741 
00742                hour = None, minute = None, second = None, fid = None):
00743       if not year and not fid:
00744           dateFrames = self.getDate();
00745           if dateFrames:
00746               self.frames.removeFramesByID(dateFrames[0].header.id)
00747           return
00748       elif not year:
00749           self.frames.removeFramesByID(fid)
00750       else:
00751           self.frames.removeFramesByID(frames.OBSOLETE_YEAR_FID)
00752 
00753       dateStr = self.strToUnicode(str(year));
00754       if len(dateStr) != 4:
00755          raise TagException("Invalid Year field: " + dateStr);
00756       if month:
00757          dateStr += "-" + self.__padDateField(month);
00758          if dayOfMonth:
00759             dateStr += "-" + self.__padDateField(dayOfMonth);
00760             if hour:
00761                dateStr += "T" + self.__padDateField(hour);
00762                if minute:
00763                   dateStr += ":" + self.__padDateField(minute);
00764                   if second:
00765                      dateStr += ":" + self.__padDateField(second);
00766 
00767       if not fid:
00768           fid = "TDRL";
00769       dateFrame = self.frames[fid];
00770       try:
00771          if dateFrame:
00772             dateFrame[0].setDate(self.encoding + dateStr);
00773          else:
00774             header = FrameHeader(self.header);
00775             header.id = fid;
00776             dateFrame = DateFrame(header, encoding = self.encoding,
00777                                   date_str = self.strToUnicode(dateStr));
00778             self.frames.addFrame(dateFrame);
00779       except FrameException, ex:
00780          raise TagException(str(ex));

Here is the call graph for this function:

Here is the caller graph for this function:

def tag.Tag.setDiscNum (   self,
  n,
  zeropad = True 
)

Definition at line 812 of file tag.py.

00812 
00813    def setDiscNum(self, n, zeropad = True):
00814       self.setNum(DISCNUM_FID, n, zeropad)

Here is the call graph for this function:

def tag.Tag.setGenre (   self,
  g 
)

Definition at line 784 of file tag.py.

00784 
00785    def setGenre(self, g):
00786       if g == None or g == "":
00787           self.frames.removeFramesByID(GENRE_FID);
00788           return;
00789 
00790       if isinstance(g, Genre):
00791           self.frames.setTextFrame(GENRE_FID, self.strToUnicode(str(g)),
00792                                    self.encoding);
00793       elif isinstance(g, str):
00794           gObj = Genre();
00795           gObj.parse(g);
00796           self.frames.setTextFrame(GENRE_FID, self.strToUnicode(str(gObj)),
00797                                    self.encoding);
00798       elif isinstance(g, int):
00799           gObj = Genre();
00800           gObj.id = g;
00801           self.frames.setTextFrame(GENRE_FID, self.strToUnicode(str(gObj)),
00802                                    self.encoding);
00803       else:
00804           raise TagException("Invalid type passed to setGenre: %s" +
00805                              str(type(g)));

Here is the call graph for this function:

Here is the caller graph for this function:

def tag.Tag.setNum (   self,
  fid,
  n,
  zeropad = True 
)

Definition at line 815 of file tag.py.

00815 
00816    def setNum(self, fid, n, zeropad = True):
00817       if n[0] == None and n[1] == None:
00818          self.frames.removeFramesByID(fid);
00819          return;
00820 
00821       totalStr = "";
00822       if n[1] != None:
00823          if zeropad and n[1] >= 0 and n[1] <= 9:
00824             totalStr = "0" + str(n[1]);
00825          else:
00826             totalStr = str(n[1]);
00827 
00828       t = n[0];
00829       if t == None:
00830          t = 0;
00831 
00832       trackStr = str(t);
00833 
00834       # Pad with zeros according to how large the total count is.
00835       if zeropad:
00836          if len(trackStr) == 1:
00837             trackStr = "0" + trackStr;
00838          if len(trackStr) < len(totalStr):
00839             trackStr = ("0" * (len(totalStr) - len(trackStr))) + trackStr;
00840 
00841       s = "";
00842       if trackStr and totalStr:
00843          s = trackStr + "/" + totalStr;
00844       elif trackStr and not totalStr:
00845          s = trackStr;
00846 
00847       self.frames.setTextFrame(fid, self.strToUnicode(s),
00848                                self.encoding);
00849 

Here is the call graph for this function:

Here is the caller graph for this function:

def tag.Tag.setPlayCount (   self,
  count 
)

Definition at line 950 of file tag.py.

00950 
00951    def setPlayCount(self, count):
00952        assert(count >= 0);
00953        if self.frames[PLAYCOUNT_FID]:
00954            pc = self.frames[PLAYCOUNT_FID][0];
00955            assert(isinstance(pc, PlayCountFrame));
00956            pc.count = count;
00957        else:
00958            frameHeader = FrameHeader(self.header);
00959            frameHeader.id = PLAYCOUNT_FID;
00960            pc = PlayCountFrame(frameHeader, count = count);
00961            self.frames.addFrame(pc);

Here is the caller graph for this function:

def tag.Tag.setPublisher (   self,
  p 
)

Definition at line 1004 of file tag.py.

01004 
01005    def setPublisher(self, p):
01006        self.setTextFrame(PUBLISHER_FID, self.strToUnicode(str(p)));

Here is the call graph for this function:

def tag.Tag.setTextEncoding (   self,
  enc 
)

Definition at line 1035 of file tag.py.

01035 
01036    def setTextEncoding(self, enc):
01037        if enc != LATIN1_ENCODING and enc != UTF_16_ENCODING and\
01038           enc != UTF_16BE_ENCODING and enc != UTF_8_ENCODING:
01039            raise TagException("Invalid encoding")
01040        elif self.getVersion() & ID3_V1 and enc != LATIN1_ENCODING:
01041            raise TagException("ID3 v1.x supports ISO-8859 encoding only")
01042        elif self.getVersion() <= ID3_V2_3 and enc == UTF_8_ENCODING:
01043            # This is unfortunate.
01044            raise TagException("UTF-8 is not supported by ID3 v2.3")
01045 
01046        self.encoding = enc
01047        for f in self.frames:
01048            f.encoding = enc

Here is the call graph for this function:

def tag.Tag.setTextFrame (   self,
  fid,
  txt 
)

Definition at line 1023 of file tag.py.

01023 
01024    def setTextFrame(self, fid, txt):
01025        if not txt:
01026           self.frames.removeFramesByID(fid);
01027        else:
01028           self.frames.setTextFrame(fid, self.strToUnicode(txt), self.encoding);

Here is the call graph for this function:

Here is the caller graph for this function:

def tag.Tag.setTitle (   self,
  t,
  titleID = TITLE_FID 
)

Definition at line 737 of file tag.py.

00737 
00738    def setTitle(self, t, titleID = TITLE_FID):
00739        self.setTextFrame(titleID, self.strToUnicode(t));

Here is the call graph for this function:

Here is the caller graph for this function:

def tag.Tag.setTrackNum (   self,
  n,
  zeropad = True 
)

Definition at line 809 of file tag.py.

00809 
00810    def setTrackNum(self, n, zeropad = True):
00811       self.setNum(TRACKNUM_FID, n, zeropad)

Here is the call graph for this function:

Here is the caller graph for this function:

def tag.Tag.setURLFrame (   self,
  fid,
  url 
)

Definition at line 1029 of file tag.py.

01029 
01030    def setURLFrame(self, fid, url):
01031        if not url:
01032           self.frames.removeFramesByID(fid)
01033        else:
01034           self.frames.setURLFrame(fid, url)

def tag.Tag.setVersion (   self,
  v 
)

Definition at line 1013 of file tag.py.

01013 
01014    def setVersion(self, v):
01015       if v == ID3_V1:
01016          v = ID3_V1_1;
01017       elif v == ID3_V2:
01018          v = ID3_DEFAULT_VERSION;
01019 
01020       if v != ID3_CURRENT_VERSION:
01021          self.header.setVersion(v);
01022          self.frames.setTagHeader(self.header);

Here is the caller graph for this function:

def tag.Tag.strToUnicode (   self,
  s 
)

Definition at line 719 of file tag.py.

00719 
00720    def strToUnicode(self, s):
00721        t = type(s);
00722        if t != unicode and t == str:
00723            s = unicode(s, eyeD3.LOCAL_ENCODING);
00724        elif t != unicode and t != str:
00725            raise TagException("Wrong type passed to strToUnicode: %s" % str(t));
00726        return s;

Here is the caller graph for this function:

def tag.Tag.tagToString (   self,
  pattern 
)

Definition at line 1049 of file tag.py.

01049 
01050    def tagToString(self, pattern):
01051        # %A - artist
01052        # %a - album
01053        # %t - title
01054        # %n - track number
01055        # %N - track total
01056        # %Y - year 
01057        # %G - genre
01058        s = self._subst(pattern, "%A", self.getArtist())
01059        s = self._subst(s, "%a", self.getAlbum())
01060        s = self._subst(s, "%t", self.getTitle())
01061        s = self._subst(s, "%n", self._prettyTrack(self.getTrackNum()[0]))
01062        s = self._subst(s, "%N", self._prettyTrack(self.getTrackNum()[1]))
01063        s = self._subst(s, "%Y", self.getYear())
01064        s = self._subst(s, "%G", self.getGenre().name)
01065        return s

Here is the call graph for this function:

def tag.Tag.toInt (   self,
  s 
)

Definition at line 1377 of file tag.py.

01377 
01378    def toInt(self, s):
01379       try:
01380          return int(s);
01381       except ValueError:
01382          return None;
01383       except TypeError:
01384          return None;

Here is the caller graph for this function:

def tag.Tag.update (   self,
  version = ID3_CURRENT_VERSION,
  backup = 0 
)

Definition at line 495 of file tag.py.

00495 
00496    def update(self, version = ID3_CURRENT_VERSION, backup = 0):
00497       if not self.linkedFile:
00498          raise TagException("The Tag is not linked to a file.");
00499 
00500       if backup:
00501          shutil.copyfile(self.linkedFile.name, self.linkedFile.name + ".orig");
00502 
00503       self.setVersion(version);
00504       version = self.getVersion();
00505       if version == ID3_V2_2:
00506           raise TagException("Unable to write ID3 v2.2");
00507       # If v1.0 is being requested explicitly then so be it, if not and there is
00508       # a track number then bumping to v1.1 is /probably/ best.
00509       if self.header.majorVersion == 1 and self.header.minorVersion == 0 and\
00510          self.getTrackNum()[0] != None and version != ID3_V1_0:
00511          version = ID3_V1_1;
00512          self.setVersion(version);
00513 
00514       # If there are no frames then simply remove the current tag.
00515       if len(self.frames) == 0:
00516          self.remove(version);
00517          self.header = TagHeader();
00518          self.frames.setTagHeader(self.header);
00519          self.linkedFile.tagPadding = 0;
00520          self.linkedFile.tagSize = 0;
00521          return;
00522 
00523       if version & ID3_V1:
00524          self.__saveV1Tag(version);
00525          return 1;
00526       elif version & ID3_V2:
00527          self.__saveV2Tag(version);
00528          return 1;
00529       else:
00530          raise TagException("Invalid version: %s" % hex(version));
00531       return 0;

Here is the call graph for this function:


Member Data Documentation

tag.Tag.do_tdtg = True [static]

Definition at line 406 of file tag.py.

tag.Tag.encoding = DEFAULT_ENCODING; [static]

Definition at line 386 of file tag.py.

Definition at line 393 of file tag.py.

tag.Tag.frames = None; [static]

Definition at line 397 of file tag.py.

tuple tag.Tag.header = TagHeader() [static]

Definition at line 390 of file tag.py.

Definition at line 417 of file tag.py.

tag.Tag.iterIndex = None; [static]

Definition at line 400 of file tag.py.

tag.Tag.linkedFile = None; [static]

Definition at line 403 of file tag.py.


The documentation for this class was generated from the following file: