[xiph-cvs] cvs commit: vorbis-python/test comment.py
Andrew Catham Master of Python
andrew at xiph.org
Sun Jan 27 18:52:15 PST 2002
andrew 02/01/27 18:52:14
Modified: . ChangeLog README
src pyvorbisinfo.c
Added: test comment.py
Log:
2002-01-27 Andrew H. Chatham <andrew.chatham at duke.edu>
* test/comment.py: Added
* pyvorbisinfo.c (del_comment), (find_tag_insensitive): Added.
You can now delete comments.
* README: Explain how to delete comments
Revision Changes Path
1.10 +6 -0 vorbis-python/ChangeLog
Index: ChangeLog
===================================================================
RCS file: /usr/local/cvsroot/vorbis-python/ChangeLog,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- ChangeLog 2002/01/27 11:18:23 1.9
+++ ChangeLog 2002/01/28 02:52:13 1.10
@@ -1,4 +1,10 @@
2002-01-27 Andrew H. Chatham <andrew.chatham at duke.edu>
+ * test/comment.py: Added
+ * pyvorbisinfo.c (del_comment), (find_tag_insensitive): Added.
+ You can now delete comments.
+ * README: Explain how to delete comments
+
+2002-01-27 Andrew H. Chatham <andrew.chatham at duke.edu>
* bump to version 0.5
2002-01-27 Andrew H. Chatham <andrew.chatham at duke.edu>
<p><p>1.5 +8 -3 vorbis-python/README
Index: README
===================================================================
RCS file: /usr/local/cvsroot/vorbis-python/README,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- README 2002/01/27 11:14:19 1.4
+++ README 2002/01/28 02:52:13 1.5
@@ -77,9 +77,14 @@
Each entry in the "dictionary" is a list of values. Each key is
treated as case-insensitive. If you use Python >= 1.6, the values (but
-not keys) will be unicode strings. Note that I have not yet
-implemented deleting a key, since I have yet to find a good way to
-implement this.
+not keys) will be unicode strings.
+
+To delete a comment entry, you just do "del v[key]". This will delete
+_all_ tags which have that key (there may be more than one). This is
+implemented by just creating a new comment structure and copying in
+every comment that doesn't match the one you want to delete, so if you
+plan to delete or replace a lot of keys, it might be faster to just
+construct a new object.
You can also get the comments from an existing file by opening that
file as a VorbisFile object and then calling .comment() on it. This is
<p><p>1.6 +202 -178 vorbis-python/src/pyvorbisinfo.c
Index: pyvorbisinfo.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis-python/src/pyvorbisinfo.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- pyvorbisinfo.c 2002/01/27 11:14:19 1.5
+++ pyvorbisinfo.c 2002/01/28 02:52:14 1.6
@@ -27,8 +27,8 @@
METH_VARARGS, py_ov_info_clear_doc},
{"analysis_init", py_vorbis_analysis_init,
METH_VARARGS, py_vorbis_analysis_init_doc},
- {"blocksize", py_vorbis_info_blocksize,
- METH_VARARGS, py_vorbis_info_blocksize_doc},
+ {"blocksize", py_vorbis_info_blocksize,
+ METH_VARARGS, py_vorbis_info_blocksize_doc},
{NULL, NULL}
};
@@ -71,20 +71,20 @@
{
py_vinfo *newobj;
newobj = (py_vinfo *) PyObject_NEW(py_vinfo,
- &py_vinfo_type);
+ &py_vinfo_type);
newobj->vi = *vi;
return (PyObject *) newobj;
}
static char *py_info_new_kw[] = {"channels", "rate", "max_bitrate",
- "nominal_bitrate", "min_bitrate", "quality",
- NULL};
+ "nominal_bitrate", "min_bitrate", "quality",
+ NULL};
PyObject *
py_info_new(PyObject *self, PyObject *args, PyObject *kwdict)
{
long channels, rate, max_bitrate, nominal_bitrate, min_bitrate;
- double quality = -1.0;
+ double quality = -1.0;
vorbis_info vi;
int res;
@@ -94,19 +94,19 @@
nominal_bitrate = 128000;
min_bitrate = -1;
if (!PyArg_ParseTupleAndKeywords(args, kwdict,
- "|llllld", py_info_new_kw,
- &channels, &rate, &max_bitrate,
- &nominal_bitrate, &min_bitrate, &quality))
+ "|llllld", py_info_new_kw,
+ &channels, &rate, &max_bitrate,
+ &nominal_bitrate, &min_bitrate, &quality))
return NULL;
vorbis_info_init(&vi);
- if (quality > 0.0) {
- res = vorbis_encode_init_vbr(&vi, channels, rate, quality);
- } else {
- res = vorbis_encode_init(&vi, channels, rate,
- max_bitrate, nominal_bitrate,
- min_bitrate);
- }
+ if (quality > 0.0) {
+ res = vorbis_encode_init_vbr(&vi, channels, rate, quality);
+ } else {
+ res = vorbis_encode_init(&vi, channels, rate,
+ max_bitrate, nominal_bitrate,
+ min_bitrate);
+ }
if (res != 0) {
vorbis_info_clear(&vi);
@@ -143,13 +143,13 @@
py_vorbis_info_blocksize(PyObject *self, PyObject *args)
{
vorbis_info *vi = PY_VINFO(self);
- int res, zo;
-
- if (!PyArg_ParseTuple(args, "l", &zo))
- return NULL;
-
- res = vorbis_info_blocksize(vi, zo);
- return PyInt_FromLong(res);
+ int res, zo;
+
+ if (!PyArg_ParseTuple(args, "l", &zo))
+ return NULL;
+
+ res = vorbis_info_blocksize(vi, zo);
+ return PyInt_FromLong(res);
}
static PyObject *
@@ -253,16 +253,16 @@
METH_VARARGS, py_comment_items_doc},
{"values", py_comment_values,
METH_VARARGS, py_comment_values_doc},
- {"write_to", py_comment_write_to,
- METH_VARARGS, py_comment_write_to_doc},
- {"append_to", py_comment_append_to,
- METH_VARARGS, py_comment_append_to_doc},
+ {"write_to", py_comment_write_to,
+ METH_VARARGS, py_comment_write_to_doc},
+ {"append_to", py_comment_append_to,
+ METH_VARARGS, py_comment_append_to_doc},
{NULL, NULL}
};
static int py_comment_length(py_vcomment *);
static int py_comment_assign(py_vcomment *,
- PyObject *, PyObject *);
+ PyObject *, PyObject *);
static PyObject *py_comment_subscript(py_vcomment *, PyObject *);
static PyMappingMethods py_vcomment_Mapping_Methods = {
@@ -325,10 +325,10 @@
py_vcomment *newobj;
newobj = (py_vcomment *) PyObject_NEW(py_vcomment,
- &py_vcomment_type);
+ &py_vcomment_type);
newobj->vc = vc;
newobj->parent = parent;
- newobj->malloced = 0;
+ newobj->malloced = 0;
Py_XINCREF(parent);
return (PyObject *) newobj;
}
@@ -342,18 +342,18 @@
return NULL;
newobj = (py_vcomment *) PyObject_NEW(py_vcomment,
- &py_vcomment_type);
- if (!newobj)
- return NULL;
+ &py_vcomment_type);
+ if (!newobj)
+ return NULL;
newobj->parent = NULL;
- newobj->malloced = 1;
- newobj->vc = (vorbis_comment *) malloc(sizeof(vorbis_comment));
- if (!newobj->vc) {
- PyErr_SetString(PyExc_MemoryError, "Could not create vorbis_comment");
- return NULL;
- }
- vorbis_comment_init(newobj->vc);
+ newobj->malloced = 1;
+ newobj->vc = (vorbis_comment *) malloc(sizeof(vorbis_comment));
+ if (!newobj->vc) {
+ PyErr_SetString(PyExc_MemoryError, "Could not create vorbis_comment");
+ return NULL;
+ }
+ vorbis_comment_init(newobj->vc);
return (PyObject *) newobj;
}
@@ -381,11 +381,12 @@
Py_DECREF(ovc_self->parent); /* parent will clear for us */
} else {
vorbis_comment_clear(ovc_self->vc);
- }
- if (ovc_self->malloced)
- free(ovc_self->vc);
+ }
+ if (ovc_self->malloced) {
+ free(ovc_self->vc);
+ }
- PyMem_DEL(self);
+ PyMem_DEL(self);
}
static PyObject*
@@ -407,7 +408,7 @@
static PyObject *
py_comment_subscript(py_vcomment *self,
- PyObject *keyobj)
+ PyObject *keyobj)
{
char *res, *tag;
int cur = 0;
@@ -443,22 +444,72 @@
return retlist;
}
+#define UPPER(x) (((x) <= 'z' && (x) >= 'a') ? (x) - 'a' + 'A' : (x))
+/* Return whether tag is of the form query=... */
+static int
+find_tag_insensitive(char *tag, char *key)
+{
+ int k;
+ for (k = 0; key[k] != 0 && tag[k] != 0; k++) {
+ if (UPPER(key[k]) != UPPER(tag[k])) {
+ return 0;
+ }
+ }
+ if (tag[k] != '=') {
+ return 0;
+ }
+ return 1;
+}
+
+/*
+ Create a new vorbis_comment, copy every comment from the old
+ vorbis_comment which does not start with the given key, and set the
+ new comment struct into the py_vcomment Object
+*/
+static void
+del_comment(py_vcomment *self, char *key)
+{
+ vorbis_comment *vc = malloc(sizeof(vorbis_comment));
+ int k;
+ vorbis_comment_init(vc);
+
+ /* TODO: Vendor tag */
+ for (k = 0; k < self->vc->comments; k++) {
+ if (!find_tag_insensitive(self->vc->user_comments[k], key)) {
+ vorbis_comment_add(vc, self->vc->user_comments[k]);
+ }
+ }
+
+ /* Get rid of the old comment structure */
+ if (self->parent) {
+ Py_DECREF(self->parent); /* parent will clear for us */
+ } else {
+ vorbis_comment_clear(self->vc);
+ }
+ if (self->malloced) {
+ free(self->vc);
+ }
+ /* The new vorbis_comment was malloced */
+ self->malloced = 1;
+ self->vc = vc;
+}
+
static int
py_comment_assign(py_vcomment *self,
- PyObject *keyobj, PyObject *valobj)
+ PyObject *keyobj, PyObject *valobj)
{
vorbis_comment *vc = PY_VCOMMENT(self);
char *tag, *val;
- if (!PyString_Check(keyobj)) {
+ if (!PyString_Check(keyobj)) {
PyErr_SetString(PyExc_KeyError, "Keys may only be ASCII strings");
return -1;
+ }
+
+ if (valobj == NULL) {
+ del_comment(self, PyString_AsString(keyobj));
+ return 0;
}
-
- if (valobj == NULL) {
- PyErr_SetString(PyExc_NotImplementedError, "Cannot yet delete comments");
- return -1;
- }
if (PyString_Check(valobj)) {
val = PyString_AsString(valobj);
@@ -476,7 +527,6 @@
}
tag = PyString_AsString(keyobj);
-
vorbis_comment_add_tag(vc, tag, val);
return 0;
}
@@ -681,32 +731,32 @@
#endif
if (!item)
- goto error;
+ goto error;
if (make_caps_key(key, keylen)) { /* overwrites key */
- Py_DECREF(item);
- goto error;
+ Py_DECREF(item);
+ goto error;
}
/* GetItem borrows a reference */
if ((curlist = PyDict_GetItemString(retdict, key))) {
- /* A list already exists for that key */
- if (PyList_Append(curlist, item) < 0) {
- Py_DECREF(item);
- goto error;
- }
+ /* A list already exists for that key */
+ if (PyList_Append(curlist, item) < 0) {
+ Py_DECREF(item);
+ goto error;
+ }
} else {
- /* Add a new list in that position */
- curlist = PyList_New(1);
- PyList_SET_ITEM(curlist, 0, item);
- Py_INCREF(item);
-
- /* this does not steal a reference */
- PyDict_SetItemString(retdict, key, curlist);
- Py_DECREF(curlist);
+ /* Add a new list in that position */
+ curlist = PyList_New(1);
+ PyList_SET_ITEM(curlist, 0, item);
+ Py_INCREF(item);
+
+ /* this does not steal a reference */
+ PyDict_SetItemString(retdict, key, curlist);
+ Py_DECREF(curlist);
}
Py_DECREF(item);
}
@@ -724,129 +774,103 @@
/* Helper function which writes/appends comments to a file */
static PyObject*
write_comments(vorbis_comment *vc, const char *filename, int append)
-{
- vcedit_state *state;
- vorbis_comment *file_comments;
- FILE *in_file, *out_file;
- int k;
- char *tempfile = malloc(strlen(filename) + sizeof(".pytemp"));
- strcpy(tempfile, filename);
- strcat(tempfile, ".pytemp");
-
- /* Open the file */
- in_file = fopen(filename, "r");
- if (!in_file) {
- printf("No in file %s\n", filename);
- PyErr_SetFromErrno(PyExc_IOError);
- return NULL;
- }
- out_file = fopen(tempfile, "wb");
- if (!out_file) {
- fclose(in_file);
- printf("No out file\n");
- PyErr_SetFromErrno(PyExc_IOError);
- return NULL;
- }
-
- state = vcedit_new_state();
-
- /* Make sure it's a vorbis file */
- if (vcedit_open(state, in_file) < 0) {
- char buff[256];
- snprintf(buff, sizeof(buff), "Could not open file %s as vorbis: %s",
- filename,
- vcedit_error(state));
- PyErr_SetString(Py_VorbisError, buff);
-
- vcedit_clear(state);
- fclose(in_file);
- fclose(out_file);
-
- return NULL;
- }
-
- /* Get the vorbis comments that are already in the file,
- and clear if necessary */
- file_comments = vcedit_comments(state);
- if (!append) {
- vorbis_comment_clear(file_comments);
- vorbis_comment_init(file_comments);
- }
-
- /* Append all the comments we already have in vc */
- for (k = 0; k < vc->comments; k++) {
- vorbis_comment_add(file_comments, vc->user_comments[k]);
- }
-
- if (vcedit_write(state, out_file) < 0) {
- char buff[256];
- snprintf(buff, sizeof(buff), "Could not write comments to file: %s",
- vcedit_error(state));
- PyErr_SetString(Py_VorbisError, buff);
-
- vcedit_clear(state);
- fclose(in_file);
- fclose(out_file);
-
- return NULL;
- }
-
- vcedit_clear(state);
-
- fclose(in_file);
- fclose(out_file);
-
- if (rename(tempfile, filename)) {
- PyErr_SetFromErrno(PyExc_IOError);
- return NULL;
- }
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-static PyObject *
-py_comment_append_to(PyObject *self, PyObject *args)
{
- vorbis_comment *vc = PY_VCOMMENT(self);
- const char *filename;
- if (!PyArg_ParseTuple(args, "s", &filename))
- return NULL;
-
- return write_comments(vc, filename, 1);
-}
-
-static PyObject *
-py_comment_write_to(PyObject *self, PyObject *args)
-{
- vorbis_comment *vc = PY_VCOMMENT(self);
- const char *filename;
- if (!PyArg_ParseTuple(args, "s", &filename))
- return NULL;
-
- return write_comments(vc, filename, 0);
-}
-
-
-
-
-
-
-
-
+ vcedit_state *state;
+ vorbis_comment *file_comments;
+ FILE *in_file, *out_file;
+ int k;
+ char *tempfile = malloc(strlen(filename) + sizeof(".pytemp"));
+ strcpy(tempfile, filename);
+ strcat(tempfile, ".pytemp");
+
+ /* Open the file */
+ in_file = fopen(filename, "r");
+ if (!in_file) {
+ PyErr_SetFromErrno(PyExc_IOError);
+ return NULL;
+ }
+ out_file = fopen(tempfile, "wb");
+ if (!out_file) {
+ fclose(in_file);
+ PyErr_SetFromErrno(PyExc_IOError);
+ return NULL;
+ }
+ state = vcedit_new_state();
+ /* Make sure it's a vorbis file */
+ if (vcedit_open(state, in_file) < 0) {
+ char buff[256];
+ snprintf(buff, sizeof(buff), "Could not open file %s as vorbis: %s",
+ filename,
+ vcedit_error(state));
+ PyErr_SetString(Py_VorbisError, buff);
+ vcedit_clear(state);
+ fclose(in_file);
+ fclose(out_file);
+ return NULL;
+ }
+ /* Get the vorbis comments that are already in the file,
+ and clear if necessary */
+ file_comments = vcedit_comments(state);
+ if (!append) {
+ vorbis_comment_clear(file_comments);
+ vorbis_comment_init(file_comments);
+ }
+ /* Append all the comments we already have in vc */
+ for (k = 0; k < vc->comments; k++) {
+ vorbis_comment_add(file_comments, vc->user_comments[k]);
+ }
+ if (vcedit_write(state, out_file) < 0) {
+ char buff[256];
+ snprintf(buff, sizeof(buff), "Could not write comments to file: %s",
+ vcedit_error(state));
+ PyErr_SetString(Py_VorbisError, buff);
+ vcedit_clear(state);
+ fclose(in_file);
+ fclose(out_file);
+ return NULL;
+ }
+ vcedit_clear(state);
+ fclose(in_file);
+ fclose(out_file);
+ if (rename(tempfile, filename)) {
+ PyErr_SetFromErrno(PyExc_IOError);
+ return NULL;
+ }
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+static PyObject *
+py_comment_append_to(PyObject *self, PyObject *args)
+{
+ vorbis_comment *vc = PY_VCOMMENT(self);
+ const char *filename;
+ if (!PyArg_ParseTuple(args, "s", &filename))
+ return NULL;
+ return write_comments(vc, filename, 1);
+}
+static PyObject *
+py_comment_write_to(PyObject *self, PyObject *args)
+{
+ vorbis_comment *vc = PY_VCOMMENT(self);
+ const char *filename;
+ if (!PyArg_ParseTuple(args, "s", &filename))
+ return NULL;
+ return write_comments(vc, filename, 0);
+}
<p><p>1.1 vorbis-python/test/comment.py
Index: comment.py
===================================================================
#!/usr/bin/python
from ogg.vorbis import VorbisComment
def test():
x = VorbisComment()
x['hey'] = 'you'
x['me'] = 'them'
x['hEy'] = 'zoo'
x['whee'] = 'them'
x['Hey'] = 'boo'
del x['hey']
try:
print x['hey'] # should fail
assert(0)
except KeyError: pass
while 1:
test()
<p><p><p>--- >8 ----
List archives: http://www.xiph.org/archives/
Ogg project homepage: http://www.xiph.org/ogg/
To unsubscribe from this list, send a message to 'cvs-request at xiph.org'
containing only the word 'unsubscribe' in the body. No subject is needed.
Unsubscribe messages sent to the list will be ignored/filtered.
More information about the commits
mailing list