/** * Generate a list of all projects available on this server. */ function project_list_generate() { $api_vid = _project_release_get_api_vid(); $query = db_query("SELECT n.title, n.nid, n.vid, n.status, p.uri, u.name AS username FROM {node} n INNER JOIN {project_projects} p ON n.nid = p.nid INNER JOIN {users} u ON n.uid = u.uid"); $xml = ''; while ($project = db_fetch_object($query)) { $xml .= " <project>\n"; $xml .= ' <title>' . check_plain($project->title) . "</title>\n"; $xml .= ' <short_name>' . check_plain($project->uri) . "</short_name>\n"; $xml .= ' <link>' . prch_url("node/{$project->nid}") . "</link>\n"; $xml .= ' <dc:creator>' . check_plain($project->username) . "</dc:creator>\n"; $term_query = db_query("SELECT v.name AS vocab_name, v.vid, td.name AS term_name, td.tid FROM {term_node} tn INNER JOIN {term_data} td ON tn.tid = td.tid INNER JOIN {vocabulary} v ON td.vid = v.vid WHERE tn.vid = %d", $project->vid); $xml_terms = ''; while ($term = db_fetch_object($term_query)) { $xml_terms .= ' <term><name>' . check_plain($term->vocab_name) . '</name>'; $xml_terms .= '<value>' . check_plain($term->term_name) . "</value></term>\n"; } if (!empty($xml_terms)) { $xml .= " <terms>\n" . $xml_terms . " </terms>\n"; } if (!$project->status) { // If it's not published, we can skip the rest for this project. $xml .= " <project_status>unpublished</project_status>\n"; } else { $xml .= " <project_status>published</project_status>\n"; // Include a list of API terms if available. $term_query = db_query("SELECT DISTINCT(td.tid), td.name AS term_name FROM {project_release_nodes} prn INNER JOIN {term_data} td ON prn.version_api_tid = td.tid WHERE prn.pid = %d AND td.vid = %d ORDER BY td.weight ASC", $project->nid, $api_vid); $xml_api_terms = ''; while ($api_term = db_fetch_object($term_query)) { $xml_api_terms .= ' <api_version>' . check_plain($api_term->term_name) . "</api_version>\n"; } if (!empty($xml_api_terms)) { $xml .= " <api_versions>\n" . $xml_api_terms . " </api_versions>\n"; } } $xml .= " </project>\n"; } if (empty($xml)) { wd_err(array('message' => 'No projects found on this server.')); return FALSE; } project_release_history_write_xml($xml); }
/** * Update the DB with the new file info for a given release node. * * @todo This assumes 1:1 relationship of release nodes to files. */ function package_release_update_node($nid, $file_path) { global $dest_root, $task; $full_path = $dest_root . '/' . $file_path; // PHP will cache the results of stat() and give us stale answers // here, unless we manually tell it otherwise! clearstatcache(); // Now that we have the official file, compute some metadata: $file_name = basename($file_path); $file_date = filemtime($full_path); $file_size = filesize($full_path); $file_hash = md5_file($full_path); $file_mime = file_get_mimetype($full_path); $uid = db_result(db_query("SELECT n.uid FROM {node} n WHERE n.nid = %d", $nid)); // Finally, save this file to the DB. // First, see if we already have a file for this release node $file_data = db_fetch_object(db_query("SELECT * FROM {project_release_file} WHERE nid = %d GROUP BY nid ORDER BY fid DESC", $nid)); if (empty($file_data)) { // Don't have an file data for this release, insert a new record. db_query("INSERT INTO {files} (uid, filename, filepath, filemime, filesize, status, timestamp) VALUES (%d, '%s', '%s', '%s', %d, %d, %d)", $uid, $file_name, $file_path, $file_mime, $file_size, FILE_STATUS_PERMANENT, $file_date); $fid = db_last_insert_id('files', 'fid'); db_query("INSERT INTO {project_release_file} (fid, nid, filehash) VALUES (%d, %d, '%s')", $fid, $nid, $file_hash); } else { // Already have a file for this release, update it. db_query("UPDATE {files} SET uid = %d, filename = '%s', filepath = '%s', filemime = '%s', filesize = %d, status = %d, timestamp = %d WHERE fid = %d", $uid, $file_name, $file_path, $file_mime, $file_size, FILE_STATUS_PERMANENT, $file_date, $file_data->fid); db_query("UPDATE {project_release_file} SET filehash = '%s' WHERE fid = %d", $file_hash, $file_data->fid); } // Don't auto-publish security updates. if ($task == 'tag' && db_result(db_query("SELECT COUNT(*) FROM {term_node} WHERE nid = %d AND tid = %d", $nid, SECURITY_UPDATE_TID))) { watchdog('package_security', "Not auto-publishing security update release.", array(), WATCHDOG_NOTICE, l(t('view'), 'node/' . $nid)); return; } // Finally publish the node if it is currently unpublished. Instead of // directly updating {node}.status, we use node_save() so that other modules // which implement hook_nodeapi() will know that this node is now published. // However, we don't want to waste too much RAM by leaving all these loaded // nodes in RAM, so we reset the node_load() cache each time we call it. $status = db_result(db_query("SELECT status from {node} WHERE nid = %d", $nid)); if (empty($status)) { // If the site is using DB replication, force this node_load() to use the // primary database to avoid node_load() failures. if (function_exists('db_set_ignore_slave')) { db_set_ignore_slave(); } $node = node_load($nid, NULL, TRUE); if (!empty($node->nid)) { $node->status = 1; node_save($node); } else { wd_err('node_load(@nid) failed', array('@nid' => $nid)); } } }
/** * Update the DB with the new file info for a given release node. * * @param $nid * The node ID of the release node to update. * @param $files * Array of files to add to the release node. * @param $package_contents * Optional. Array of nids of releases contained in a release package. */ function package_release_update_node($nid, $files, $package_contents = array()) { global $drupal_root, $dest_root, $task; // PHP will cache the results of stat() and give us stale answers // here, unless we manually tell it otherwise! clearstatcache(); // Make sure we're back at the webroot so node_load() and node_save() // can always find any files they (and the hooks they invoke) need. if (!drupal_chdir($drupal_root)) { return FALSE; } // If the site is using DB replication, force this node_load() to use the // primary database to avoid node_load() failures. if (function_exists('db_set_ignore_slave')) { db_set_ignore_slave(); } // We don't want to waste too much RAM by leaving all these loaded nodes // in RAM, so we reset the node_load() cache each time we call it. $node = node_load($nid, NULL, TRUE); if (empty($node->nid)) { wd_err('node_load(@nid) failed', array('@nid' => $nid)); return FALSE; } foreach ($files as $file_path) { // Compute the metadata for this file that we care about. $full_path = $dest_root . '/' . $file_path; $file_name = basename($file_path); $file_date = filemtime($full_path); $file_size = filesize($full_path); $file_hash = md5_file($full_path); $file_mime = file_get_mimetype($full_path); // First, see if we already have this file for this release node $file_data = db_fetch_object(db_query("SELECT prf.* FROM {project_release_file} prf INNER JOIN {files} f ON prf.fid = f.fid WHERE prf.nid = %d AND f.filename = '%s'", $node->nid, $file_name)); // Insert or update the record in the DB as need. if (empty($file_data)) { // Don't have this file, insert a new record. db_query("INSERT INTO {files} (uid, filename, filepath, filemime, filesize, status, timestamp) VALUES (%d, '%s', '%s', '%s', %d, %d, %d)", $node->uid, $file_name, $file_path, $file_mime, $file_size, FILE_STATUS_PERMANENT, $file_date); $fid = db_last_insert_id('files', 'fid'); db_query("INSERT INTO {project_release_file} (fid, nid, filehash) VALUES (%d, %d, '%s')", $fid, $node->nid, $file_hash); } else { // Already have this file for this release, update it. db_query("UPDATE {files} SET uid = %d, filename = '%s', filepath = '%s', filemime = '%s', filesize = %d, status = %d, timestamp = %d WHERE fid = %d", $node->uid, $file_name, $file_path, $file_mime, $file_size, FILE_STATUS_PERMANENT, $file_date, $file_data->fid); db_query("UPDATE {project_release_file} SET filehash = '%s' WHERE fid = %d", $file_hash, $file_data->fid); } } // Store package contents if necessary. if (!empty($package_contents) && module_exists('project_package')) { foreach ($package_contents as $item_nid) { db_query("INSERT INTO {project_package_local_release_item} (package_nid, item_nid) VALUES (%d, %d)", $nid, $item_nid); } } // Don't auto-publish security updates. $security_update_tid = variable_get('project_release_security_update_tid', 0); if ($task == 'tag' && !empty($node->taxonomy[$security_update_tid])) { watchdog('package_security', 'Not auto-publishing security update release.', array(), WATCHDOG_NOTICE, l(t('view'), 'node/' . $node->nid)); return; } // Finally publish the node if it is currently unpublished. Instead of // directly updating {node}.status, we use node_save() so that other modules // which implement hook_nodeapi() will know that this node is now published. if (empty($node->status)) { $node->status = 1; node_save($node); } }
$_SERVER['REMOTE_ADDR'] = '127.0.0.1'; $_SERVER['REQUEST_URI'] = '/' . $script_name; $_SERVER['SCRIPT_NAME'] = '/' . $script_name; $_SERVER['PHP_SELF'] = '/' . $script_name; $_SERVER['SCRIPT_FILENAME'] = $_SERVER['PWD'] . '/' . $script_name; $_SERVER['PATH_TRANSLATED'] = $_SERVER['SCRIPT_FILENAME']; if (!chdir(DRUPAL_ROOT)) { print "ERROR: Can't chdir(DRUPAL_ROOT), aborting.\n"; exit(1); } // Make sure our umask is sane for generating directories and files. umask(022); require_once 'includes/bootstrap.inc'; drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL); if (!module_exists('project_usage')) { wd_err(t("ERROR: Project usage module does not exist, aborting.\n")); exit(1); } // Load the API functions we need for manipulating dates and timestamps. module_load_include('inc', 'project_usage', 'includes/date_api'); // ------------------------------------------------------------ // Call the daily and weekly processing tasks as needed. // ------------------------------------------------------------ $now = time(); // Figure out if it's been 24 hours since our last daily processing. if (variable_get('project_usage_last_daily', 0) <= $now - PROJECT_USAGE_DAY) { project_usage_process_daily(); variable_set('project_usage_last_daily', $now); } // We can't process the weekly data until the week has completed. To see if // there's data available: determine the last time we completed the weekly
/** * Initialize the tmp directory. Use different subdirs for building * snapshots than official tags, so there's no potential directory * collisions and race conditions if both are running at the same time * (due to how long it takes to complete a branch snapshot run, and * how often we run this for tag-based releases). */ function initialize_tmp_dir($task) { global $tmp_dir, $tmp_root, $rm; if (!is_dir($tmp_root) && !@mkdir($tmp_root, 0777, TRUE)) { wd_err("ERROR: mkdir(@dir) (tmp_root) failed", array('@dir' => $tmp_root)); exit(1); } // Use a tmp directory *specific* to this invocation, so that we don't // clobber other runs if the script is invoked twice (e.g. via cron and // manually, etc). $tmp_dir = $tmp_root . '/' . $task . '.' . getmypid(); if (is_dir($tmp_dir)) { // Make sure we start with a clean slate drupal_exec("{$rm} -rf {$tmp_dir}/*"); } else { if (!@mkdir($tmp_dir, 0777, TRUE)) { wd_err("ERROR: mkdir(@dir) failed", array('@dir' => $tmp_dir)); exit(1); } } }