[1] | 1 | from zope import interface |
---|
| 2 | from zope import component |
---|
| 3 | |
---|
| 4 | from p4a.audio.interfaces import IAudio, IAudioEnhanced |
---|
| 5 | from Products.ATContentTypes.interface import IATFile |
---|
| 6 | from p4a.audio.atct._atct import _ATCTFileAudio |
---|
| 7 | from p4a.audiopatch.interfaces import IAudioEncoded |
---|
| 8 | |
---|
| 9 | from zope.app.annotation.interfaces import IAnnotations |
---|
| 10 | from persistent.dict import PersistentDict |
---|
| 11 | |
---|
| 12 | from zope.event import notify |
---|
| 13 | from p4a.audiopatch.events import AudioEncodingChangedEvent |
---|
| 14 | |
---|
| 15 | from p4a.fileimage import utils |
---|
| 16 | from p4a.audio.mp3.thirdparty import eyeD3 |
---|
| 17 | import os |
---|
| 18 | |
---|
| 19 | |
---|
| 20 | #need to override existing adapter form IATFile to IAudio |
---|
| 21 | @interface.implementer(IAudio) |
---|
| 22 | @component.adapter(IATFile) |
---|
| 23 | def ATCTFileAudioOverriding(context): |
---|
| 24 | if not IAudioEnhanced.providedBy(context): |
---|
| 25 | return None |
---|
| 26 | return _ATCTFileAudioEncoded(context) |
---|
| 27 | |
---|
| 28 | |
---|
| 29 | @interface.implementer(IAudioEncoded) |
---|
| 30 | @component.adapter(IATFile) |
---|
| 31 | def ATCTFileAudioEncoded(context): |
---|
| 32 | if not IAudioEnhanced.providedBy(context): |
---|
| 33 | return None |
---|
| 34 | return _ATCTFileAudioEncoded(context) |
---|
| 35 | |
---|
| 36 | class _ATCTFileAudioEncoded(_ATCTFileAudio): |
---|
| 37 | """An IAudioEncoded adapter that handle ATCT based file content. |
---|
| 38 | """ |
---|
| 39 | interface.implements(IAudioEncoded) |
---|
| 40 | |
---|
| 41 | ENCODING_KEY = "p4a.patch.adapters.ATCTFileAudioEncoded" |
---|
| 42 | |
---|
| 43 | def __init__(self, context): |
---|
| 44 | _ATCTFileAudio.__init__(self, context) |
---|
| 45 | annotations = IAnnotations(context) |
---|
| 46 | self.encoding_data = annotations.get(self.ENCODING_KEY, None) |
---|
| 47 | if self.encoding_data == None: |
---|
| 48 | self.encoding_data = PersistentDict() |
---|
| 49 | annotations[self.ENCODING_KEY] = self.encoding_data |
---|
| 50 | self.encoding_data['encoding'] = "" |
---|
| 51 | self.encoding_data['original_encoding'] = "" |
---|
| 52 | |
---|
| 53 | def getEncoding(self): |
---|
| 54 | """get encoding""" |
---|
| 55 | return self.encoding_data['encoding'] |
---|
| 56 | |
---|
| 57 | def setEncoding(self, value): |
---|
| 58 | """set encoding""" |
---|
| 59 | self.encoding_data['encoding'] = value |
---|
| 60 | notify(AudioEncodingChangedEvent(self.context)) |
---|
| 61 | |
---|
| 62 | encoding = property(getEncoding, setEncoding) |
---|
| 63 | |
---|
| 64 | def get_original_encoding(self): |
---|
| 65 | if not self.encoding_data['original_encoding'] and self.audio_type == "MP3": |
---|
| 66 | filename = utils.write_ofsfile_to_tempfile(self.context.getRawFile()) |
---|
| 67 | tag = eyeD3.Tag() |
---|
| 68 | tag.link(filename) |
---|
| 69 | for f in tag.frames: |
---|
| 70 | if self.encoding_data['original_encoding']: break |
---|
| 71 | if isinstance(f, eyeD3.frames.TextFrame): |
---|
| 72 | self.encoding_data['original_encoding'] = eyeD3.id3EncodingToString(f.encoding) |
---|
| 73 | os.remove(filename) |
---|
| 74 | return self.encoding_data['original_encoding'] |
---|
| 75 | |
---|
| 76 | def set_original_encoding(self, value): |
---|
| 77 | self.encoding_data['original_encoding'] = value |
---|
| 78 | |
---|
| 79 | original_encoding = property(get_original_encoding, set_original_encoding) |
---|
| 80 | |
---|
| 81 | @property |
---|
| 82 | def title(self): |
---|
| 83 | data = self.audio_data.get('title', None) |
---|
| 84 | if self.audio_type == "MP3" and self.encoding and self.original_encoding and isinstance(data, unicode): |
---|
| 85 | data = data.encode(self.original_encoding, 'replace').decode(self.encoding, 'replace') |
---|
| 86 | return data |
---|
| 87 | |
---|
| 88 | @property |
---|
| 89 | def artist(self): |
---|
| 90 | data = self.audio_data.get('artist', None) |
---|
| 91 | if self.audio_type == "MP3" and self.encoding and self.original_encoding and isinstance(data, unicode): |
---|
| 92 | data = data.encode(self.original_encoding, 'replace').decode(self.encoding, 'replace') |
---|
| 93 | return data |
---|
| 94 | |
---|
| 95 | @property |
---|
| 96 | def album(self): |
---|
| 97 | data = self.audio_data.get('album', None) |
---|
| 98 | if self.audio_type == "MP3" and self.encoding and self.original_encoding and isinstance(data, unicode): |
---|
| 99 | data = data.encode(self.original_encoding, 'replace').decode(self.encoding, 'replace') |
---|
| 100 | return data |
---|
| 101 | |
---|
| 102 | @property |
---|
| 103 | def comment(self): |
---|
| 104 | data = self.audio_data.get('comment', None) |
---|
| 105 | if self.audio_type == "MP3" and self.encoding and self.original_encoding and isinstance(data, unicode): |
---|
| 106 | data = data.encode(self.original_encoding, 'replace').decode(self.encoding, 'replace') |
---|
| 107 | return data |
---|
| 108 | |
---|
| 109 | def __str__(self): |
---|
| 110 | return '<p4a.audiopatch.adapters.ATCTFileAudioEncoded title=%s>' % self.title |
---|
| 111 | __repr__ = __str__ |
---|