CMS for the late garbage.fm
at main 184 lines 4.5 kB view raw
1<?php 2 3class Episode extends ActiveRecord\Model { 4 static $validates_presence_of = array( 5 array("episode"), 6 array("title"), 7 array("notes"), 8 array("duration"), 9 array("air_date"), 10 ); 11 static $validates_uniqueness_of = array( 12 array("episode"), 13 ); 14 15 static $attr_accessible = array( 16 "episode", "is_pending", "air_date", "title", "is_explicit", 17 "duration", "notes", "summary", "custom_artwork_url", 18 "custom_author", 19 ); 20 21 static $after_destroy = array("delete_mp3_file"); 22 23 static $after_save = array("possibly_update_chapters"); 24 25 public $needs_chapter_updating; 26 27 static public function next_episode() { 28 $sth = Episode::query("SELECT MAX(episode) FROM episodes"); 29 $row = $sth->fetch(PDO::FETCH_NUM); 30 $max = intval($row[0]); 31 return $max + 1; 32 } 33 34 public function get_file_path() { 35 return "episodes/garbage" . intval($this->episode) . ".mp3"; 36 } 37 38 public function get_mp3_url() { 39 return Settings::fetch()->url . $this->file_path; 40 } 41 42 public function get_secure_mp3_url() { 43 return Settings::fetch()->secure_url . $this->file_path; 44 } 45 46 public function get_mp3_path() { 47 return HALFMOON_ROOT . "/public/" . $this->file_path; 48 } 49 50 /* publicly viewable page, not mp3 */ 51 public function get_absolute_url() { 52 return Settings::fetch()->url . "episodes/" . $this->episode; 53 } 54 55 public function get_guid() { 56 /* return http for legacy reasons */ 57 if ($this->is_pending) 58 return preg_replace("/https:/", "http:", $this->absolute_url) . 59 "?" . $this->updated_at->getTimestamp(); 60 else 61 return preg_replace("/https:/", "http:", $this->absolute_url); 62 } 63 64 public function get_artwork_url() { 65 if ($this->custom_artwork_url) 66 return $this->custom_artwork_url; 67 else 68 return Settings::fetch()->logo_url; 69 } 70 71 public function get_is_comment() { 72 return !!(preg_match("/\/* .* *\//", $this->title)); 73 } 74 75 public function get_full_title() { 76 $t = ""; 77 78 if (!$this->is_comment) 79 $t .= "garbage[" . $this->episode . "]: "; 80 81 $t .= $this->title; 82 83 if ($this->is_pending) 84 $t .= " [PENDING]"; 85 86 return $t; 87 } 88 89 public function get_secure_artwork_url() { 90 if ($this->custom_artwork_url) 91 return preg_replace("/^http:/i", "https:", 92 $this->custom_artwork_url); 93 else 94 return Settings::fetch()->secure_logo_url; 95 } 96 97 public function possibly_update_chapters() { 98 if ($this->needs_chapter_updating && file_exists($this->mp3_path) && 99 count($this->chapters)) { 100 $args = "/garbage.fm/bin/mp3chap " . 101 escapeshellarg($this->mp3_path); 102 103 foreach ($this->chapters as $time => $content) { 104 $secs = 0; 105 106 if (preg_match("/^(\d+):(\d+):(\d+)$/", $time, $m)) 107 $secs = intval($m[3]) + (intval($m[2]) * 60) + 108 (intval($m[1]) * 60 * 60); 109 elseif (preg_match("/^(\d+):(\d+)$/", $time, $m)) 110 $secs = intval($m[2]) + (intval($m[1]) * 60); 111 else 112 $secs = intval($time); 113 114 $args .= " " . $secs . " " . escapeshellarg($content); 115 } 116 117 error_log("Running mp3chap: " . $args); 118 system($args); 119 } else { 120 $this->needs_chapter_updating = false; 121 } 122 } 123 124 public function set_notes($notes) { 125 $old_notes = $this->notes; 126 $this->assign_attribute("notes", $notes); 127 128 $parsedown = new Parsedown(); 129 $this->notes_html = $parsedown->text($notes); 130 131 if ($old_notes != $notes) 132 $this->needs_chapter_updating = true; 133 } 134 135 public function set_duration($duration) { 136 $secs = 0; 137 138 if (preg_match("/^(\d+):(\d+):(\d+)$/", $duration, $m)) 139 $secs = intval($m[3]) + (intval($m[2]) * 60) + 140 (intval($m[1]) * 60 * 60); 141 elseif (preg_match("/^(\d+):(\d+)$/", $duration, $m)) 142 $secs = intval($m[2]) + (intval($m[1]) * 60); 143 else 144 $secs = intval($duration); 145 146 $this->assign_attribute("duration_secs", $secs); 147 148 $hours = floor($secs / 3600); 149 $mins = floor(($secs - ($hours * 3600)) / 60); 150 $secs = floor($secs % 60); 151 152 $tms = ""; 153 if ($hours > 0) 154 $tms = sprintf("%d:%02d:%02d", $hours, $mins, $secs); 155 else 156 $tms = sprintf("%d:%02d", $mins, $secs); 157 158 $this->assign_attribute("duration", $tms); 159 } 160 161 public function get_chapters() { 162 $chapters = array(); 163 164 $lines = explode("\n", $this->notes_html); 165 foreach ($lines as $line) { 166 if (preg_match("/^(<p>)?(.+?) <!-- ([0-9:]+) -->/", $line, $m)) 167 $chapters[$m[3]] = html_entity_decode(strip_tags($m[2])); 168 } 169 170 return $chapters; 171 } 172 173 public function take_new_mp3($file) { 174 move_uploaded_file($file, $this->mp3_path); 175 $this->filesize = filesize($this->mp3_path); 176 $this->needs_chapter_updating = true; 177 } 178 179 public function delete_mp3_file() { 180 unlink($this->mp3_path); 181 } 182} 183 184?>