From: epg@pretzelnet.org <> Date: Fri, 2 Nov 2012 00:40:09 +0000 (-0700) Subject: rejigger this to a stand-alone tool rather than a py module X-Git-Url: https://diplodocus.org/git/flac-archive/commitdiff_plain/a2dfc17a7c6f6493b847d4bb648a53242f6d2de2?ds=sidebyside;hp=a15bfb31a6b4390a9ba2148e62d9517fdfa12356 rejigger this to a stand-alone tool rather than a py module --- diff --git a/taglib.cc b/taglib.cc index 1f04d16..3d28eb3 100644 --- a/taglib.cc +++ b/taglib.cc @@ -2,127 +2,139 @@ #include #include -extern "C" { +#include +#include #include - -#include - -static PyObject *taglib_error; - -static PyObject * -taglib_apic(const char *fn, PyObject *list) +#include +#include +#include +#include +#include + +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; }