[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