#include <id3v2tag.h>
#include <mpegfile.h>
-extern "C" {
+#include <sys/types.h>
+#include <sys/stat.h>
#include <errno.h>
-
-#include <Python.h>
-
-static PyObject *taglib_error;
-
-static PyObject *
-taglib_apic(const char *fn, PyObject *list)
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+static const char *
+taglib_apic(const char *mp3_path, const char *image_bytes, size_t image_len,
+ const char *description_utf8, const char *mime_type)
{
TagLib::MPEG::File *f;
TagLib::ID3v2::Tag *t;
- PyObject *tuple, *description, *description_utf8;
- int i, type, width, height, depth, colors, len;
- const char *mime_type, *description_utf8_s, *image;
TagLib::ByteVector *bv;
TagLib::ID3v2::AttachedPictureFrame *p;
/* GAH! Opening the file is entangled with allocating the object;
* if this fails, am i out of memory, or is there a problem with
* the file? Hate C++... */
- f = new TagLib::MPEG::File (fn);
+ f = new TagLib::MPEG::File (mp3_path);
if (f == 0) {
- return PyErr_NoMemory();
+ return "new TagLib::MPEG::File failed";
}
t = f->ID3v2Tag(true);
if (t == 0) {
- PyErr_SetString(taglib_error, "taglib failed to return ID3v2");
- return 0;
+ return "taglib failed to return ID3v2";
}
- for (i = 0; i < PyList_Size(list); i++) {
- tuple = PyList_GetItem(list, i);
- if (!PyArg_ParseTuple(tuple, "isUiiiis#",
- &type, &mime_type, &description, &width, &height, &depth, &colors, &image, &len)) {
- return 0;
- }
-
- description_utf8 = PyUnicode_AsEncodedString(description, "utf8",
- "strict");
- if (description_utf8 == 0) {
- return 0;
- }
-
- description_utf8_s = PyString_AsString(description_utf8);
- if (description_utf8_s == 0) {
- return 0;
- }
-
- bv = new TagLib::ByteVector (image, len);
+ bv = new TagLib::ByteVector (image_bytes, image_len);
if (bv == 0) {
- return PyErr_NoMemory();
+ return "new TagLib::ByteVector failed";
}
p = new TagLib::ID3v2::AttachedPictureFrame;
if (p == 0) {
- return PyErr_NoMemory();
+ return "new TagLib::ID3v2::AttachedPictureFrame failed";
}
/* Um, look at all these void-returning functions. I'm sure
* they can fail, i just have no way to detect it... */
- p->setType((TagLib::ID3v2::AttachedPictureFrame::Type)type);
+ p->setType(TagLib::ID3v2::AttachedPictureFrame::FrontCover);
p->setMimeType(mime_type);
- p->setDescription(description_utf8_s);
- p->setTextEncoding(TagLib::String::UTF8);
- // taglib doesn't support width, height, depth, colors.
+ if (description_utf8 != 0) {
+ p->setDescription(description_utf8);
+ p->setTextEncoding(TagLib::String::UTF8);
+ }
p->setPicture(*bv);
// another void-returning function that i bet fails
t->addFrame(p);
- }
errno = 0;
if (!f->save()) {
if (errno != 0) {
- PyErr_SetFromErrnoWithFilename(PyExc_IOError, (char *)fn);
- } else {
- PyErr_SetString(taglib_error, "taglib failed to save");
+ return strerror(errno);
}
- return 0;
+ return "taglib failed to save";
}
- Py_INCREF(Py_None);
- return Py_None;
+ return 0;
}
-static PyObject *
-add_apic_frame_to_mp3(PyObject *self, PyObject *args)
+int
+main(int argc, char **argv)
{
- const char *fn;
- PyObject *list;
-
- if (!PyArg_ParseTuple(args, "sO", &fn, &list)) {
- return 0;
+ char *description = 0;
+ char *mime_type = 0;
+
+ int c;
+ while ((c = getopt(argc, argv, "d:m:")) != -1) {
+ switch (c) {
+ case 'd':
+ description = optarg;
+ break;
+ case 'm':
+ mime_type = optarg;
+ break;
+ default:
+ // getopt printed an error.
+ return 2;
+ }
}
- return taglib_apic(fn, list);
-}
+ if (mime_type == 0) {
+ fputs("must specify MIME type with -m\n", stderr);
+ return 2;
+ }
-static
-PyMethodDef methods[] = {
- {"add_apic_frame_to_mp3", add_apic_frame_to_mp3, METH_VARARGS,
- "document me"},
- {0, 0, 0, 0}
-};
+ argc -= optind; argv += optind;
-PyMODINIT_FUNC
-inittaglib(void)
-{
- PyObject *m = Py_InitModule("taglib", methods);
- if (m == NULL) {
- return;
+ if (argc == 0) {
+ fputs("must specify mp3 filename", stderr);
+ return 2;
}
-
- taglib_error = PyErr_NewException("flac_archive.taglib.error", 0, 0);
- if (taglib_error == 0) {
- return;
+ const char *mp3_path = argv[0];
+
+ char *image_bytes;
+ size_t image_len;
+ if (argc == 2) {
+ const char *image_path = argv[1];
+ int fd = open(image_path, O_RDONLY);
+ if (fd == -1) {
+ fprintf(stderr, "open(%s): %s\n", image_path, strerror(errno));
+ return 3;
+ }
+ struct stat st;
+ if (fstat(fd, &st) != 0) {
+ fprintf(stderr, "stat(%s): %s\n", image_path, strerror(errno));
+ return 3;
+ }
+ image_len = st.st_size;
+ image_bytes = (char *)malloc(image_len);
+ if (read(fd, image_bytes, image_len) != image_len) {
+ fprintf(stderr, "read(%s): %s\n", image_path, strerror(errno));
+ return 3;
+ }
+ } else {
+ fputs("not yet reading image from stdin\n", stderr);
+ return 3;
}
- PyModule_AddObject(m, "error", taglib_error);
-}
+ printf("mp3: %s imagelen: %ld desc: %s mime: %s\n",
+ mp3_path, (long)image_len, description, mime_type);
+ return 0;
+
+ const char *result = taglib_apic(mp3_path, image_bytes, image_len, description, mime_type);
+ if (result != 0) {
+ fprintf(stderr, "%s\n", result);
+ return 2;
+ }
+ return 0;
}