chiark / gitweb /
Synchronize from trunk
[disorder] / lib / trackdb-playlists.c
index 133e8b75ee7624346b6696388005365ba578497a..27d33193feb7f6db8e7898785467178ed084a199 100644 (file)
@@ -32,6 +32,8 @@
 #include "log.h"
 #include "configuration.h"
 #include "vector.h"
+#include "eventlog.h"
+#include "validity.h"
 
 static int trackdb_playlist_get_tid(const char *name,
                                     const char *who,
@@ -53,43 +55,6 @@ static int trackdb_playlist_delete_tid(const char *name,
                                        const char *who,
                                        DB_TXN *tid);
 
-/** @brief Parse a playlist name
- * @param name Playlist name
- * @param ownerp Where to put owner, or NULL
- * @param sharep Where to put default sharing, or NULL
- * @return 0 on success, -1 on error
- *
- * Playlists take the form USER.PLAYLIST or just PLAYLIST.  The PLAYLIST part
- * is alphanumeric and nonempty.  USER is a username (see valid_username()).
- */
-int playlist_parse_name(const char *name,
-                        char **ownerp,
-                        char **sharep) {
-  const char *dot = strchr(name, '.'), *share;
-  char *owner;
-
-  if(dot) {
-    /* Owned playlist */
-    owner = xstrndup(name, dot - name);
-    if(!valid_username(owner))
-      return -1;
-    if(!valid_username(dot + 1))
-      return -1;
-    share = "private";
-  } else {
-    /* Shared playlist */
-    if(!valid_username(name))
-      return -1;
-    owner = 0;
-    share = "shared";
-  }
-  if(ownerp)
-    *ownerp = owner;
-  if(sharep)
-    *sharep = xstrdup(share);
-  return 0;
-}
-
 /** @brief Check read access rights
  * @param name Playlist name
  * @param who Who wants to read
@@ -159,7 +124,7 @@ int trackdb_playlist_get(const char *name,
   int e;
 
   if(playlist_parse_name(name, 0, 0)) {
-    error(0, "invalid playlist name '%s'", name);
+    disorder_error(0, "invalid playlist name '%s'", name);
     return EINVAL;
   }
   WITH_TRANSACTION(trackdb_playlist_get_tid(name, who,
@@ -185,7 +150,7 @@ static int trackdb_playlist_get_tid(const char *name,
     return e;
   /* Get sharability */
   if(!(s = kvp_get(k, "sharing"))) {
-    error(0, "playlist '%s' has no 'sharing' key", name);
+    disorder_error(0, "playlist '%s' has no 'sharing' key", name);
     s = "private";
   }
   /* Check the read is allowed */
@@ -196,12 +161,12 @@ static int trackdb_playlist_get_tid(const char *name,
     *sharep = xstrdup(s);
   /* Get track count */
   if(!(s = kvp_get(k, "count"))) {
-    error(0, "playlist '%s' has no 'count' key", name);
+    disorder_error(0, "playlist '%s' has no 'count' key", name);
     s = "0";
   }
   ntracks = atoi(s);
   if(ntracks < 0) {
-    error(0, "playlist '%s' has negative count", name);
+    disorder_error(0, "playlist '%s' has negative count", name);
     ntracks = 0;
   }
   /* Return track count */
@@ -215,7 +180,7 @@ static int trackdb_playlist_get_tid(const char *name,
     for(int n = 0; n < ntracks; ++n) {
       snprintf(b, sizeof b, "%d", n);
       if(!(s = kvp_get(k, b))) {
-        error(0, "playlist '%s' lacks track %d", name, n);
+        disorder_error(0, "playlist '%s' lacks track %d", name, n);
         s = "unknown";
       }
       tracks[n] = xstrdup(s);
@@ -229,6 +194,7 @@ static int trackdb_playlist_get_tid(const char *name,
 
 /** @brief Modify or create a playlist
  * @param name Playlist name
+ * @param who User modifying playlist
  * @param tracks List of tracks to set, or NULL to leave alone
  * @param ntracks Length of @p tracks
  * @param share Sharing status, or NULL to leave alone
@@ -258,7 +224,7 @@ int trackdb_playlist_set(const char *name,
   char *owner;
   
   if(playlist_parse_name(name, &owner, 0)) {
-    error(0, "invalid playlist name '%s'", name);
+    disorder_error(0, "invalid playlist name '%s'", name);
     return EINVAL;
   }
   /* Check valid share types */
@@ -267,13 +233,13 @@ int trackdb_playlist_set(const char *name,
       /* Playlists with an owner must be public or private */
       if(strcmp(share, "public")
          && strcmp(share, "private")) {
-        error(0, "playlist '%s' must be public or private", name);
+        disorder_error(0, "playlist '%s' must be public or private", name);
         return EINVAL;
       }
     } else {
       /* Playlists with no owner must be shared */
       if(strcmp(share, "shared")) {
-        error(0, "playlist '%s' must be shared", name);
+        disorder_error(0, "playlist '%s' must be shared", name);
         return EINVAL;
       }
     }        
@@ -293,6 +259,7 @@ static int trackdb_playlist_set_tid(const char *name,
   struct kvp *k;
   int e;
   const char *s;
+  const char *event = "playlist_modified";
 
   if((e = trackdb_getdata(trackdb_playlistsdb, name, &k, tid))
      && e != DB_NOTFOUND)
@@ -311,10 +278,11 @@ static int trackdb_playlist_set_tid(const char *name,
     k = 0;
     kvp_set(&k, "count", 0);
     kvp_set(&k, "sharing", defshare);
+    event = "playlist_created";
   }
   /* Check that the modification is allowed */
   if(!(s = kvp_get(k, "sharing"))) {
-    error(0, "playlist '%s' has no 'sharing' key", name);
+    disorder_error(0, "playlist '%s' has no 'sharing' key", name);
     s = "private";
   }
   if(!playlist_may_write(name, who, s))
@@ -331,7 +299,7 @@ static int trackdb_playlist_set_tid(const char *name,
 
     /* Sanity check track count */
     if(ntracks < 0 || ntracks > config->playlist_max) {
-      error(0, "invalid track count %d", ntracks);
+      disorder_error(0, "invalid track count %d", ntracks);
       return EINVAL;
     }
     /* Set the tracks */
@@ -354,7 +322,11 @@ static int trackdb_playlist_set_tid(const char *name,
     kvp_set(&k, "count", b);
   }
   /* Store the resulting record */
-  return trackdb_putdata(trackdb_playlistsdb, name, k, tid, 0);
+  e = trackdb_putdata(trackdb_playlistsdb, name, k, tid, 0);
+  /* Log the event */
+  if(!e)
+    eventlog(event, name, kvp_get(k, "sharing"), (char *)0);
+  return e;
 }
 
 /** @brief Get a list of playlists
@@ -390,11 +362,11 @@ static int trackdb_playlist_list_tid(const char *who,
 
     /* Extract owner; malformed names are skipped */
     if(playlist_parse_name(name, &owner, 0)) {
-      error(0, "invalid playlist name '%s' found in database", name);
+      disorder_error(0, "invalid playlist name '%s' found in database", name);
       continue;
     }
     if(!share) {
-      error(0, "playlist '%s' has no 'sharing' key", name);
+      disorder_error(0, "playlist '%s' has no 'sharing' key", name);
       continue;
     }
     /* Always list public and shared playlists
@@ -414,7 +386,7 @@ static int trackdb_playlist_list_tid(const char *who,
   case DB_LOCK_DEADLOCK:
     return e;
   default:
-    fatal(0, "c->c_get: %s", db_strerror(e));
+    disorder_fatal(0, "c->c_get: %s", db_strerror(e));
   }
   vector_terminate(v);
   if(playlistsp)
@@ -441,7 +413,7 @@ int trackdb_playlist_delete(const char *name,
   char *owner;
   
   if(playlist_parse_name(name, &owner, 0)) {
-    error(0, "invalid playlist name '%s'", name);
+    disorder_error(0, "invalid playlist name '%s'", name);
     return EINVAL;
   }
   /* We've checked as much as we can for now, now go and attempt the change */
@@ -462,13 +434,16 @@ static int trackdb_playlist_delete_tid(const char *name,
     return e;
   /* Check that modification is allowed */
   if(!(s = kvp_get(k, "sharing"))) {
-    error(0, "playlist '%s' has no 'sharing' key", name);
+    disorder_error(0, "playlist '%s' has no 'sharing' key", name);
     s = "private";
   }
   if(!playlist_may_write(name, who, s))
     return EACCES;
   /* Delete the playlist */
-  return trackdb_delkey(trackdb_playlistsdb, name, tid);
+  e = trackdb_delkey(trackdb_playlistsdb, name, tid);
+  if(!e)
+    eventlog("playlist_deleted", name, 0);
+  return e;
 }
 
 /*