2f0d3fa3d2bcbf3e23e834ca68565c470f73939d chmalee Mon Oct 21 12:32:08 2024 -0700 Back end for auto-generating a hub with every user upload done diff --git src/hg/lib/userdata.c src/hg/lib/userdata.c index 07438a7..dea277b 100644 --- src/hg/lib/userdata.c +++ src/hg/lib/userdata.c @@ -79,62 +79,105 @@ retUrl = dyStringCannibalize(&userDirDy); } return retUrl; } char *prefixUserFile(char *userName, char *fname) /* Allocate a new string that contains the full per-user path to fname, NULL otherwise */ { char *pathPrefix = getDataDir(userName); if (pathPrefix) return catTwoStrings(pathPrefix, fname); else return NULL; } -void addNewFileForUser(char *userName, char *fileName, long long fileSize, char *fileType, - time_t lastModified, char *hubName, char *db, char *location) +void addHubSpaceRowForFile(struct hubSpace *row) /* We created a file for a user, now add an entry to the hubSpace table for it */ { -struct hubSpace *row = NULL; -AllocVar(row); -row->userName = userName; -row->fileName = fileName; -row->fileSize = fileSize; -row->fileType = fileType; -row->creationTime = NULL; // automatically handled by mysql -row->lastModified = sqlUnixTimeToDate(&lastModified, TRUE); -row->hubNameList = hubName; -row->db = db; -row->location = location; -row->md5sum = md5HexForFile(row->location); struct sqlConnection *conn = hConnectCentral(); // now write out row to hubSpace table if (!sqlTableExistsOnMain(conn, "hubSpace")) { - errAbort("No hubSpace MySQL table is present. Please send an email to us describing the steps you took just before you got this error"); + errAbort("No hubSpace MySQL table is present. Please send an email to genome-www@soe.ucsc.edu describing the exact steps you took just before you got this error"); } -struct dyString *sqlUpdateStmt = dyStringNew(0); -sqlDyStringPrintf(sqlUpdateStmt, "insert into hubSpace values ('%s', '%s', %llu, " - "'%s', NULL, '%s', '', '%s', '%s', '%s')", - row->userName, row->fileName, row->fileSize, row->fileType, - row->lastModified, row->db, row->location, row->md5sum); -fprintf(stderr, "%s\n", sqlUpdateStmt->string); -fflush(stderr); -sqlUpdate(conn, sqlUpdateStmt->string); -hubSpaceFree(&row); +hubSpaceSaveToDb(conn, row, "hubSpace", 0); +} + +char *writeHubText(char *path, char *userName, char *encodedHubName, char *hubName, char *db) +/* Create a hub.txt file, optionally creating the directory holding it. For convenience, return + * the file name of the created hub, which can be freed. */ +{ +int oldUmask = 00; +oldUmask = umask(0); +makeDirsOnPath(path); +// restore umask +umask(oldUmask); +// now make the hub.txt with some basic information +char *hubFile = catTwoStrings(path, "/hub.txt"); +FILE *f = mustOpen(hubFile, "w"); +//fprintf(stderr, "would write \"hub %s\nemail %s\nshortLabel %s\nlongLabel %s\nuseOneFile on\n\ngenome %s\n\n\" to %s", hubName, emailForUserName(userName), hubName, hubName, db, hubFile); +fprintf(f, "hub %s\n" + "email %s\n" + "shortLabel %s\n" + "longLabel %s\n" + "useOneFile on\n" + "\n" + "genome %s\n" + "\n", + encodedHubName, emailForUserName(userName), hubName, hubName, db); +carefulClose(&f); +return hubFile; +} + +char *createNewTempHubForUpload(char *requestId, char *userName, char *db, char *trackFileName, char *trackType) +/* Creates a hub.txt for this upload with a random hub name. Returns the full path to the hub + * for convenience. */ +{ +char *encodedHubName = cgiEncodeFull(requestId); +char *path = prefixUserFile(userName, encodedHubName); +char *hubFileName = writeHubText(path, userName, encodedHubName, requestId, db); +char *encodedTrack = cgiEncodeFull(trackFileName); +struct dyString *trackFilePath = dyStringCreate("../%s", encodedTrack); +FILE *f = mustOpen(hubFileName, "a"); +fprintf(f, "track %s\n" + "bigDataUrl %s\n" + "type %s\n" + "shortLabel %s\n" + "longLabel %s\n" + "\n", + encodedTrack, dyStringCannibalize(&trackFilePath), + trackType, trackFileName, trackFileName); +carefulClose(&f); + +// we should update the mysql table now with a record of the hub.txt +struct hubSpace *row = NULL; +AllocVar(row); +row->userName = userName; +row->fileName = hubFileName; +row->fileSize = fileSize(hubFileName); +row->fileType = "hub"; +row->creationTime = NULL; +time_t lastModTime = fileModTime(hubFileName); +row->lastModified = sqlUnixTimeToDate(&lastModTime, TRUE); +row->hubNameList = ""; +row->db = db; +row->location = path; +row->md5sum = md5HexForFile(hubFileName); +addHubSpaceRowForFile(row); +return encodedHubName; } static void deleteHubSpaceRow(char *fname) /* Deletes a row from the hubspace table for a given fname */ { struct sqlConnection *conn = hConnectCentral(); struct dyString *deleteQuery = sqlDyStringCreate("delete from hubSpace where location='%s'", fname); sqlUpdate(conn, dyStringCannibalize(&deleteQuery)); } void removeFileForUser(char *fname, char *userName) /* Remove a file for this user if it exists */ { // The file to remove must be prefixed by the hg.conf userDataDir if (!startsWith(getDataDir(userName), fname)) @@ -158,59 +201,84 @@ struct fileInfo *f, *flist = listDirX(path, NULL, TRUE); for (f = flist; f != NULL; f = f->next) mustRemove(f->name); // now we have deleted all the files in the dir we can safely rmdir mustRemove(path); deleteHubSpaceRow(path); } } void uploadTrack() /* Saves a new track to the persistent storage for this user */ { //char *userName = getUserName(); } +static time_t getFileListLatestTime(struct userFiles *userFiles) +/* Return the greatest last access time of the files in userFiles->fileList */ +{ +if (!userFiles->fileList) + errAbort("no files in userFiles->fileList"); +time_t modTime = 0; +struct fileInfo *f; +for (f = userFiles->fileList; f != NULL; f = f->next) + { + if (f->lastAccess > modTime) + { + modTime = f->lastAccess; + } + } +return modTime; +} + +time_t getHubLatestTime(struct userHubs *hub) +/* Return the latest access time of the files in a hub */ +{ +// NOTE: every hub is guaranteed to have at least one file +return getFileListLatestTime(hub->fileList); +} + struct userFiles *listFilesForUserHub(char *userName, char *hubName) /* Get all the files for a particular hub for a particular user */ { struct userFiles *userListing; AllocVar(userListing); char *path = getHubDataDir(userName, hubName); struct fileInfo *fiList = listDirX(path,NULL,FALSE); userListing->userName = userName; userListing->fileList = fiList; return userListing; } struct userHubs *listHubsForUser(char *userName) /* Lists the directories for a particular user */ { struct userHubs *userHubs = NULL; char *path = getDataDir(userName); struct fileInfo *fi, *fiList = listDirX(path,NULL,FALSE); for (fi = fiList; fi != NULL; fi = fi->next) { if (fi->isDir) { struct userHubs *hub; AllocVar(hub); hub->hubName = cloneString(fi->name); hub->userName = cloneString(userName); char hubPath[PATH_LEN]; safef(hubPath, sizeof(hubPath), "%s%s", path, fi->name); struct userFiles *hubFileList = listFilesForUserHub(userName, hub->hubName); + hub->lastModified = getFileListLatestTime(hubFileList); hub->fileList = hubFileList; slAddHead(&userHubs, hub); } } return userHubs; } struct hubSpace *listFilesForUser(char *userName) /* Return the files the user has uploaded */ { struct sqlConnection *conn = hConnectCentral(); struct dyString *query = sqlDyStringCreate("select * from hubSpace where userName='%s' order by creationTime, fileName", userName); struct hubSpace *fileList = hubSpaceLoadByQuery(conn, dyStringCannibalize(&query)); return fileList; }