DMZ
19:34 02-06-2010 Python GTP
Давно не выкладывал полезного ненужного кода...

Питоний модуль для вытаскивания исполнителя/названия трека из gpt/gp3/gp4/gp5 файлов

Основа нашлась в глубинах Google Code Search, а потом опробована на over 9000 файлов из несортированной свалки. А там были файлы, наверное, всех версий. Ну кроме шестой, конечно

Лицензия — BSD, все дела

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import struct
import sys
from locale import getpreferredencoding
class NotGPFile(Exception):
    pass
 
class GuitarProFileSimple(object):
    _encoding = getpreferredencoding()
 
    def read_long_string(self, fo):
        s = fo.read(4)
        size = struct.unpack('l', s)[0]
        s = fo.read(1)
        if size == 0:
            size = ord(s)
 
        string = fo.read(size - 1)
 
        return string.decode(self._encoding)
 
    def read_byte_string(self, fo):
        s = fo.read(1)
        size_block = ord(s)
        s = fo.read(1)
        size_string = ord(s)
 
        string = fo.read(size_string)
 
        fo.read(size_block - size_string - 1)
 
        return string.decode(self._encoding)
 
    def __init__(self, fo):
        fo.seek(0)
 
        head = fo.read(20)
 
        header_len = 0
        if head[1:19] == "FICHIER GUITAR PRO":
            header_len = 19
            fo.read(1)
 
        if head[1:20] == "FICHIER GUITARE PRO":
            header_len = 20
            fo.read(2)
 
        if header_len:
            self.version = fo.read(4)
            hsize = ord(head[0])
            fo.seek(hsize + 5 + 1)
 
            if self.version in ['1T\x03\x04']:
                fo.read(3)
                title = self.read_byte_string(fo)
                subtitle = ''
                artist = self.read_byte_string(fo)
            elif self.version in ['1.04', '1.02', '1.03']:
                title = self.read_byte_string(fo)
                subtitle = ''
                artist = self.read_byte_string(fo)
            elif self.version in ['2.21']:
                fo.read(1)
                title = self.read_byte_string(fo)
                subtitle = ''
                artist = self.read_byte_string(fo)
            else:
                fo.read(1)
                title = self.read_long_string(fo)
                subtitle = self.read_long_string(fo)
                artist = self.read_long_string(fo)
 
            if title:
                if subtitle:
                    self.title = '%s (%s)' % (title, subtitle)
                else:
                    self.title = title
            else:
                if subtitle:
                    self.title = title
                else:
                    self.title = ''
 
            self.artist = artist or ''
 
            return
 
        raise NotGPFile(u'Not a GP file')