Changeset - ff180c328353
[Not reviewed]
default
0 3 0
Nathan Brink (binki) - 14 years ago 2012-02-15 23:22:23
ohnobinki@ohnopublishing.net
Add support for displaying the friendly name of the department or course in the autocomplete.
3 files changed with 109 insertions and 11 deletions:
0 comments (0 inline, 0 general)
auto.php
Show inline comments
 
@@ -68,98 +68,115 @@ if (!count($term_parts)) {
 
if (!$school['crawled']) {
 
  clean_empty_exit();
 
}
 
$semester = school_semester_guess($school, FALSE);
 

	
 
$cache_dir = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'cache' . DIRECTORY_SEPARATOR . 'auto'
 
  . DIRECTORY_SEPARATOR . $school['id'] . DIRECTORY_SEPARATOR . $semester['id'] . DIRECTORY_SEPARATOR;
 

	
 
/*
 
 * autocomplete the list of departments. If the user has already
 
 * entered a valid department name _and_ delimitted it, however, go on
 
 * to the next autocompletion step.
 
 */
 
$term_strlen = strlen($term);
 
$dept_strlen = strlen($term_parts['department']);
 
$dept = $term_parts['department'];
 
if (!$getsections && count($term_parts) == 1 && $term_strlen == strlen($dept))
 
  {
 
    $dept_file = $cache_dir . '-depts';
 
    if (!file_exists($dept_file)) {
 
      clean_empty_exit();
 
    }
 
    $departments = unserialize(file_get_contents($dept_file));
 
    $json_depts = array();
 
    foreach ($departments as $key => $department) {
 
      if (!strncmp($department, $dept, $dept_strlen)) {
 
	$json_depts[] = $department;
 
    if (!empty($departments) && is_array($departments[0]))
 
      {
 
	/* New format with department names/labels */
 
	foreach ($departments as $department)
 
	  if (!strncmp($department['value'], $dept, $dept_strlen))
 
	    $json_depts[] = $department;
 
      }
 
    }
 
    else
 
      {
 
	/* Old format with just department id. */
 
	foreach ($departments as $department)
 
	  if (!strncmp($department, $dept, $dept_strlen))
 
	    $json_depts[] = $department;
 
      }
 

	
 
    echo json_encode($json_depts);
 
    exit(0);
 
  }
 

	
 
if ($getsections)
 
  {
 
    if (!isset($term_parts['course']))
 
      {
 
	/* user didn't give us enough information */
 
	header('HTTP/1.1 404: Nof found');
 
	header('Content-Type: text/plain; encoding=utf-8');
 
	echo 'Not a fully-qualified course name: ' . implode('-', $term_parts) . "\n";
 
	exit(0);
 
      }
 
    $section_file = $cache_dir . $dept . DIRECTORY_SEPARATOR . $term_parts['course'];
 
    if (file_exists($section_file))
 
      {
 
	readfile($section_file);
 
	exit(0);
 
      }
 
    /* Section not found! */
 
    header('HTTP/1.1 404: Not found');
 
    header('Content-Type: text/plain; encoding=utf-8');
 
    echo 'Could not find course ' . implode('-', $term_parts) . "\n";
 
    exit(0);
 
  }
 

	
 
/*
 
 * If a department is fully entered, life gets slightly more
 
 * complicated. I suppose I only want to autocomplete the first digit
 
 * of the course/class number. I.e., CS-2 for CS-262 for when the
 
 * student has entered CS- or 'CS'. But for now we can just dump the entire department at the user ;-).
 
 */
 
$classes_file = $cache_dir . $dept . '.sects';
 
if (file_exists($classes_file))
 
  {
 
    $classes = unserialize(file_get_contents($classes_file));
 
    $class_start = '';
 
    if (count($term_parts) > 1)
 
      $class_start = $term_parts['course'];
 
    $class_start_strlen = strlen($class_start);
 

	
 
    /* reduce/create resultset */
 
    $json_classes = array();
 
    foreach ($classes as $class)
 
      if (!strncmp($class, $class_start, $class_start_strlen))
 
	{
 
	  $json_classes[] = $dept . '-' . $class;
 
	}
 
    if (!empty($classes) && is_array($classes[0]))
 
      {
 
	foreach ($classes as $course)
 
	  if (!strncmp($course['value'], $class_start, $class_start_strlen))
 
	    $json_classes[] = $course;
 
      }
 
    else
 
      {
 
	/* Old format with just course id. */
 
	foreach ($classes as $class)
 
	  if (!strncmp($class, $class_start, $class_start_strlen))
 
	    $json_classes[] = $dept . '-' . $class;
 
      }
 

	
 
    echo json_encode($json_classes);
 
    exit(0);
 
  }
 

	
 
/**
 
 * Nothing caught
 
 */
 
clean_empty_exit();
 

	
 
/**
 
 * \brief
 
 *   Send an empty JSON array and exit.
 
 */
 
function clean_empty_exit()
 
{
 
  echo '[]';
 
  exit(0);
 
}
inc/admin.inc
Show inline comments
 
@@ -277,58 +277,85 @@ function school_crawl(array &$school, Pa
 

	
 
  foreach ($semesters as $semester)
 
    {
 
      school_crawl_logf($school_crawl_log, 2, "Calling %s(%s)...", $school_crawl_semester_func, $semester);
 
      $ret = $school_crawl_semester_func($school, $semester, $school_crawl_log);
 
      if ($ret)
 
	{
 
	  school_crawl_logf($school_crawl_log, 1, "Failed to crawl semester %s. Skipping semester.", $semester);
 
	  continue;
 
	}
 

	
 
      /*
 
       * Write out this semester's cache now that we're here.
 
       */
 
      $cache_auto_school_semester_dir_name = $cache_auto_school_dir_name . $semester->id() . DIRECTORY_SEPARATOR;
 
	      if (!is_dir($cache_auto_school_semester_dir_name))
 
		{
 
		  if (!mkdir($cache_auto_school_semester_dir_name, 0755, TRUE))
 
		    error_log('Unable to create needed directory: `' . $cache_auto_school_semester_dir_name . '\'');
 
		}
 

	
 
	      $departments = $semester->departments_get();
 
	      sort($departments);
 

	
 
	      /*
 
	       * Create friendly department labels (like `MATH
 
	       * (Mathematics)') if the crawler has given us that
 
	       * data.
 
	       */
 
	      $has_department_names = FALSE;
 
	      $department_names = array();
 
	      foreach ($semester->department_names_get() as $dept => $dept_name)
 
		{
 
		  $department_names[] = array('value' => $dept, 'label' => $dept . ' (' . $dept_name . ')');
 
		  if (!$has_department_names && strcmp($dept, $dept_name))
 
		    $has_department_names = TRUE;
 
		}
 

	
 
	      $dept_file = fopen($cache_auto_school_semester_dir_name . '-depts', 'wb');
 
	      fwrite($dept_file, serialize($departments));
 
	      fwrite($dept_file, serialize($has_department_names ? $department_names : $departments));
 
	      fclose($dept_file);
 

	
 
	      /* now per-department autocomplete */
 
	      foreach ($departments as $department)
 
		{
 
		  $classes = $semester->department_classes_get($department);
 
		  $courses_json = array();
 
		  foreach ($classes as $course_id)
 
		    {
 
		      $course = $semester->class_get($department, $course_id);
 
		      $course_json = array(
 
			'value' => $course->getName(),
 
			'label' => $course->getName(),
 
		      );
 
		      if (strlen($course_title = $course->title_get()))
 
			$course_json['label'] .= ' (' . $course_title . ')';
 
		      $courses_json[] = $course_json;
 
		    }
 

	
 
		  $classes_file = fopen($cache_auto_school_semester_dir_name . $department . '.sects', 'wb');
 
		  fwrite($classes_file, serialize($classes));
 
		  fwrite($classes_file, serialize($courses_json));
 
		  fclose($classes_file);
 

	
 
		  /* now individual section informations, pre-JSON-ized */
 
		  foreach ($classes as $class)
 
		    {
 
		      if (!is_dir($cache_auto_school_semester_dir_name . $department))
 
			mkdir($cache_auto_school_semester_dir_name . $department);
 
		      $class_file = fopen($cache_auto_school_semester_dir_name . $department . DIRECTORY_SEPARATOR . $class, 'wb');
 
		      fwrite($class_file, json_encode($semester->class_get($department, $class)->to_json_array()));
 
		      fclose($class_file);
 
		    }
 
		}
 

	
 
      /* Purge the data written to disk from memory */
 
      $semester->purge();
 

	
 
      school_crawl_logf($school_crawl_log, 6, "");
 
      $successful_semesters[] = $semester;
 
    }
 

	
 
  $school['crawled'] = TRUE;
 
  unset($school['crawled_notreally']);
 
  $school['crawled_semesters'] = $successful_semesters;
 

	
inc/class.semester.inc
Show inline comments
 
@@ -58,48 +58,49 @@ class Semester
 
   *   The season of this semester. Please use the constants
 
   *   Semester::SEASON_FALL, Semester::SEASON_SPRING, or
 
   *   Semester::SEASON_SUMMER if possible.
 
   * \param $time_start
 
   *   Specify a timestamp which roughly estimates when this semester
 
   *   starts to aid the algorithm for guessing the current
 
   *   semester. See Semester::time_start_set(), which may be used
 
   *   instead of this parameter
 
   * \param $time_end
 
   *   This may be specified now or via Semester::time_end_set().
 
   */
 
  function __construct($year, $season, $time_start = 0, $time_end = 0)
 
  {
 
    $this->time_start = 0;
 
    $this->time_end = 0;
 
    $this->time_starts = array();
 
    $this->time_ends = array();
 
    $this->season = $season;
 

	
 
    if (strlen($year) != 4 || !is_numeric($year))
 
      throw new ErrorException('Attempt to construct a Semester with an invalid year. The given year is `' . $year . '\'');
 
    $this->year = $year;
 

	
 
    $this->departments = array();
 
    $this->department_names = array();
 
  }
 

	
 
  /**
 
   * \brief
 
   *   Add a class to this Semester.
 
   *
 
   * \param $class
 
   *   The class/course to add.
 
   */
 
  public function class_add(Course $class)
 
  {
 
    $class_parts = Course::parse($class->getName());
 
    if (!isset($class_parts['course']))
 
      throw new ErrorException('I was given a class with an invalid name: `' . $class->getName() . '\'');
 

	
 
    if (!isset($this->departments[$class_parts['department']]))
 
      $this->departments[$class_parts['department']] = array();
 
    $department =& $this->departments[$class_parts['department']];
 

	
 
    $department[$class_parts['course']] = $class;
 
  }
 

	
 
  /**
 
   * \brief
 
@@ -110,48 +111,101 @@ class Semester
 
   * \param $class
 
   *   The course/class number. '262' for 'cs-262'.
 
   * \return
 
   *   A Course or NULL if not found.
 
   */
 
  public function class_get($dept, $class)
 
  {
 
    if (!isset($this->departments[$dept][$class]))
 
      return NULL;
 

	
 
    return $this->departments[$dept][$class];
 
  }
 

	
 
  /**
 
   * \brief
 
   *   Gets a list of departments available in this semester.
 
   */
 
  public function departments_get()
 
  {
 
    return array_keys($this->departments);
 
  }
 

	
 
  /**
 
   * \brief
 
   *   Set a department's human-friendly name.
 
   *
 
   * \param $dept
 
   *   The department.
 
   * \param $name
 
   *   The human-friendly name of the department.
 
   */
 
  public function department_name_set($dept, $name)
 
  {
 
    $this->department_names[$dept] = $name;
 
  }
 

	
 
  /**
 
   * \brief
 
   *   Determine if a particular department has a human-oriented name.
 
   *
 
   * \param $dept
 
   *   The department to check.
 
   * \return
 
   *   TRUE if this department has been assigned a human-friendly
 
   *   name.
 
   */
 
  public function department_name_has($dept)
 
  {
 
    return !empty($this->department_names[$dept]);
 
  }
 

	
 
  /**
 
   * \brief
 
   *   Get a list of departments and long names, if available.
 
   *
 
   * This function only returns departments for which this Semester
 
   * has courses.
 
   *
 
   * \return
 
   *   An array where keys are department identifiers and values are
 
   *   human-friendly names (if available). If human-friendly names
 
   *   are not available, department identifiers are used instead of
 
   *   the human-friendly ones.
 
   */
 
  public function department_names_get()
 
  {
 
    $department_names = array();
 
    foreach ($this->departments_get() as $dept)
 
      if (empty($this->department_names[$dept]))
 
        $department_names[$dept] = $dept;
 
      else
 
        $department_names[$dept] = $this->department_names[$dept];
 
    return $department_names;
 
  }
 

	
 
  /**
 
   * \brief
 
   *   Gets a list of class/course numbers available for a particular
 
   *   department.
 
   */
 
  public function department_classes_get($dept)
 
  {
 
    if (!isset($this->departments[$dept]))
 
      throw new ErrorException('I was asked for a department I don\'t own: ' . $dept);
 

	
 
    return array_keys($this->departments[$dept]);
 
  }
 

	
 
  /**
 
   * \brief
 
   *   Utility function to add a section to the semester,
 
   *   automatically creating classes as necessary.
 
   *
 
   * Crawler functions should generally use this instead of
 
   * Semester::class_add().
 
   *
 
   * \param $dept
 
   *   The department this section belongs to.
 
   * \param $class
 
   *   The class this section belongs to.
 
   * \param $section
0 comments (0 inline, 0 general)