]> diplodocus.org Git - flac-archive/blob - taglib.cc
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=439790
[flac-archive] / taglib.cc
1 #include <attachedpictureframe.h>
2 #include <id3v2tag.h>
3 #include <mpegfile.h>
4
5 extern "C" {
6
7 #include <errno.h>
8
9 #include <Python.h>
10
11 static PyObject *taglib_error;
12
13 static PyObject *
14 taglib_apic(const char *fn, PyObject *list)
15 {
16 TagLib::MPEG::File *f;
17 TagLib::ID3v2::Tag *t;
18 PyObject *tuple, *description, *description_utf8;
19 int i, type, width, height, depth, colors, len;
20 const char *mime_type, *description_utf8_s, *image;
21 TagLib::ByteVector *bv;
22 TagLib::ID3v2::AttachedPictureFrame *p;
23
24 /* GAH! Opening the file is entangled with allocating the object;
25 * if this fails, am i out of memory, or is there a problem with
26 * the file? Hate C++... */
27 f = new TagLib::MPEG::File (fn);
28 if (f == 0) {
29 return PyErr_NoMemory();
30 }
31
32 t = f->ID3v2Tag(true);
33 if (t == 0) {
34 PyErr_SetString(taglib_error, "taglib failed to return ID3v2");
35 return 0;
36 }
37
38 for (i = 0; i < PyList_Size(list); i++) {
39 tuple = PyList_GetItem(list, i);
40 if (!PyArg_ParseTuple(tuple, "isUiiiis#",
41 &type, &mime_type, &description, &width, &height, &depth, &colors, &image, &len)) {
42 return 0;
43 }
44
45 description_utf8 = PyUnicode_AsEncodedString(description, "utf8",
46 "strict");
47 if (description_utf8 == 0) {
48 return 0;
49 }
50
51 description_utf8_s = PyString_AsString(description_utf8);
52 if (description_utf8_s == 0) {
53 return 0;
54 }
55
56 bv = new TagLib::ByteVector (image, len);
57 if (bv == 0) {
58 return PyErr_NoMemory();
59 }
60
61 p = new TagLib::ID3v2::AttachedPictureFrame;
62 if (p == 0) {
63 return PyErr_NoMemory();
64 }
65
66 /* Um, look at all these void-returning functions. I'm sure
67 * they can fail, i just have no way to detect it... */
68 p->setType((TagLib::ID3v2::AttachedPictureFrame::Type)type);
69 p->setMimeType(mime_type);
70 p->setDescription(description_utf8_s);
71 p->setTextEncoding(TagLib::String::UTF8);
72 // taglib doesn't support width, height, depth, colors.
73 p->setPicture(*bv);
74
75 // another void-returning function that i bet fails
76 t->addFrame(p);
77 }
78
79 errno = 0;
80 if (!f->save()) {
81 if (errno != 0) {
82 PyErr_SetFromErrnoWithFilename(PyExc_IOError, (char *)fn);
83 } else {
84 PyErr_SetString(taglib_error, "taglib failed to save");
85 }
86 return 0;
87 }
88
89 Py_INCREF(Py_None);
90 return Py_None;
91 }
92
93 static PyObject *
94 add_apic_frame_to_mp3(PyObject *self, PyObject *args)
95 {
96 const char *fn;
97 PyObject *list;
98
99 if (!PyArg_ParseTuple(args, "sO", &fn, &list)) {
100 return 0;
101 }
102
103 return taglib_apic(fn, list);
104 }
105
106 static
107 PyMethodDef methods[] = {
108 {"add_apic_frame_to_mp3", add_apic_frame_to_mp3, METH_VARARGS,
109 "document me"},
110 {0, 0, 0, 0}
111 };
112
113 PyMODINIT_FUNC
114 inittaglib(void)
115 {
116 PyObject *m = Py_InitModule("taglib", methods);
117 if (m == NULL) {
118 return;
119 }
120
121 taglib_error = PyErr_NewException("flac_archive.taglib.error", 0, 0);
122 if (taglib_error == 0) {
123 return;
124 }
125 PyModule_AddObject(m, "error", taglib_error);
126 }
127
128 }