c79deb301511fcf0de0ed376c7746e4902804472
chmalee
  Fri May 5 16:59:33 2023 -0700
Experiment number one, can succesfully upload a file and store it via
hgCustom. New userdata library for managing where to store the files

Get skeleton structure of new cgi together

More work in progress, mostly stubbing out the CGI

More work in progress, mostly stubbing out the html page

diff --git src/hg/lib/userdata.c src/hg/lib/userdata.c
new file mode 100644
index 0000000..a85f6cf
--- /dev/null
+++ src/hg/lib/userdata.c
@@ -0,0 +1,57 @@
+/* userdata.c - code for managing data stored on a per user basis */
+
+/* Copyright (C) 2014 The Regents of the University of California 
+ * See kent/LICENSE or http://genome.ucsc.edu/license/ for licensing information. */
+
+
+#include "common.h"
+#include "hash.h"
+#include "portable.h"
+#include "trashDir.h"
+#include "md5.h"
+#include "hgConfig.h"
+#include "dystring.h"
+#include "cheapcgi.h"
+#include "customFactory.h"
+
+static char *getDataDir(char *userName)
+/* Return the full path to the user specific data directory, can be configured via hg.conf
+ * on hgwdev, this is /data/apache/userdata/userStore/hash/userName/
+ * on the RR, this is /userdata/userStore/hash/userName/ */
+{
+char *userDataBaseDir = cfgOption("userDataDir");
+if (!userDataBaseDir  || isEmpty(userDataBaseDir))
+    errAbort("hgCustom: trying to save user file but no userDataDir defined in hg.conf");
+if (userDataBaseDir[0] != '/')
+    errAbort("config setting userDataDir must be an absolute path (starting with '/')");
+
+char *encUserName = cgiEncode(userName);
+char *userPrefix = md5HexForString(encUserName);
+userPrefix[2] = '\0';
+
+struct dyString *newDataDir = dyStringNew(0);
+dyStringPrintf(newDataDir, "%s/%s/%s/", 
+    userDataBaseDir, userPrefix, encUserName);
+
+return dyStringCannibalize(&newDataDir);
+}
+
+char *storeUserFile(char *userName, char *newFileName, void *data, size_t dataSize)
+/* Give a fileName and a data stream, write the data to:
+ * userdata/userStore/hashedUserName/userName/fileName
+ * where hashedUserName is based on the md5sum of the userName
+ * to prevent proliferation of too many directories. 
+ *
+ * After sucessfully saving the file, return a web accessible url
+ * to the file. */
+{
+char *userDir = getDataDir(userName);
+makeDirsOnPath(userDir);
+char *pathToFile = catTwoStrings(userDir, newFileName);
+FILE *newFile = mustOpen(pathToFile, "wb");
+// the data will start with a line feed so get rid of that
+mustWrite(newFile, data, dataSize);
+// missing an EOF?
+carefulClose(&newFile);
+return pathToFile;
+}