示例#1
0
    /**
     * DOCUMENT ME
     * @param mixed $arguments
     * @param mixed $options
     */
    protected function execute($arguments = array(), $options = array())
    {
        $scriptFile = aFiles::getTemporaryFilename();
        $out = fopen($scriptFile, "w");
        $server = $arguments['server'];
        $data = parse_ini_file($this->configuration->getRootDir() . '/config/properties.ini', true);
        if (!isset($data[$server])) {
            throw new sfException("{$server} does not exist in config/properties.ini. Examples: staging, production\n");
        }
        $data = $data[$server];
        $cmd = "ssh ";
        if (isset($data['port'])) {
            $cmd .= "-p " . $data['port'];
        }
        if (isset($data['user'])) {
            $cmd .= " -l " . $data['user'];
        }
        $cmd .= " " . $data['host'];
        $dir = $data['dir'];
        $user = $data['user'];
        $host = $data['host'];
        $escapedDir = escapeshellarg($dir);
        $cd = escapeshellcmd("cd {$escapedDir}");
        fwrite($out, <<<EOM
spawn {$cmd}
stty -echo
expect password:
send_user -- "Password for {$user}@{$host}: "
expect_user -re "(.*)\\n"
send_user "\\n"
stty echo
set password \$expect_out(1,string)
send "\$password\\n"
expect "\\\\\$"
send "{$cd}\\n"
interact 
EOM
);
        passthru("expect {$scriptFile}");
        unlink($scriptFile);
    }
示例#2
0
 public function executeEditVideo(sfRequest $request)
 {
     $this->forward404Unless(aMediaTools::userHasUploadPrivilege());
     $item = null;
     $this->slug = false;
     if ($request->hasParameter('slug')) {
         $item = $this->getItem();
         $this->slug = $item->getSlug();
     }
     if ($item) {
         $this->forward404Unless($item->userHasPrivilege('edit'));
     }
     $this->item = $item;
     $subclass = 'aMediaVideoYoutubeForm';
     $embed = false;
     $parameters = $request->getParameter('a_media_item');
     if (aMediaTools::getOption('embed_codes') && ($item && strlen($item->embed) || isset($parameters['embed']))) {
         $subclass = 'aMediaVideoEmbedForm';
         $embed = true;
     }
     $this->form = new $subclass($item);
     if ($parameters) {
         $files = $request->getFiles('a_media_item');
         $this->form->bind($parameters, $files);
         do {
             // first_pass forces the user to interact with the form
             // at least once. Used when we're coming from a
             // YouTube search and we already technically have a
             // valid form but want the user to think about whether
             // the title is adequate and perhaps add a description,
             // tags, etc.
             if ($this->hasRequestParameter('first_pass') || !$this->form->isValid()) {
                 break;
             }
             // TODO: this is pretty awful factoring, I should have separate actions
             // and migrate more of this code into the model layer
             if ($embed) {
                 $embed = $this->form->getValue("embed");
                 $thumbnail = $this->form->getValue('thumbnail');
                 // The base implementation for saving files gets confused when
                 // $file is not set, a situation that our code tolerates as useful
                 // because if you're updating a record containing an image you
                 // often don't need to submit a new one.
                 unset($this->form['thumbnail']);
                 $object = $this->form->getObject();
                 if ($thumbnail) {
                     $object->preSaveImage($thumbnail->getTempName());
                 }
                 $this->form->save();
                 if ($thumbnail) {
                     $object->saveImage($thumbnail->getTempName());
                 }
             } else {
                 $url = $this->form->getValue("service_url");
                 // TODO: migrate this into the model and a
                 // YouTube-specific support class
                 if (!preg_match("/youtube.com.*\\?.*v=([\\w\\-\\+]+)/", $url, $matches)) {
                     $this->serviceError = true;
                     break;
                 }
                 // YouTube thumbnails are always JPEG
                 $format = 'jpg';
                 $videoid = $matches[1];
                 $feed = "http://gdata.youtube.com/feeds/api/videos/{$videoid}";
                 $entry = simplexml_load_file($feed);
                 // get nodes in media: namespace for media information
                 $media = $entry->children('http://search.yahoo.com/mrss/');
                 // get a more canonical video player URL
                 $attrs = $media->group->player->attributes();
                 $canonicalUrl = $attrs['url'];
                 // get biggest video thumbnail
                 foreach ($media->group->thumbnail as $thumbnail) {
                     $attrs = $thumbnail->attributes();
                     if (!isset($widest) || $attrs['width'] + 0 > $widest['width'] + 0) {
                         $widest = $attrs;
                     }
                 }
                 // The YouTube API doesn't report the original width and height of
                 // the video stream, so we use the largest thumbnail, which in practice
                 // is the same thing on YouTube.
                 if (isset($widest)) {
                     $thumbnail = $widest['url'];
                     // Turn them into actual numbers instead of weird XML wrapper things
                     $width = $widest['width'] + 0;
                     $height = $widest['height'] + 0;
                 }
                 if (!isset($thumbnail)) {
                     $this->serviceError = true;
                     break;
                 }
                 // Grab a local copy of the thumbnail, and get the pain
                 // over with all at once in a predictable way if
                 // the service provider fails to give it to us.
                 $thumbnailCopy = aFiles::getTemporaryFilename();
                 if (!copy($thumbnail, $thumbnailCopy)) {
                     $this->serviceError = true;
                     break;
                 }
                 $object = $this->form->getObject();
                 $new = !$object->getId();
                 $object->preSaveImage($thumbnailCopy);
                 $object->setServiceUrl($url);
                 $this->form->save();
                 $object->saveImage($thumbnailCopy);
                 unlink($thumbnailCopy);
             }
             return $this->redirect("aMedia/resumeWithPage");
         } while (false);
     }
 }
 /**
  * DOCUMENT ME
  * @param mixed $arguments
  * @param mixed $options
  */
 protected function execute($arguments = array(), $options = array())
 {
     // We need a basic context so we can call helpers to format text
     $context = sfContext::createInstance($this->configuration);
     // initialize the database connection
     $databaseManager = new sfDatabaseManager($this->configuration);
     $connection = $databaseManager->getDatabase($options['connection'] ? $options['connection'] : null)->getConnection();
     // PDO connection not so useful, get the doctrine one
     $conn = Doctrine_Manager::connection();
     $accounts = Doctrine::getTable('aEmbedMediaAccount')->findAll();
     foreach ($accounts as $a) {
         $perPage = 50;
         $service = aMediaTools::getEmbedService($a->service);
         if (!$service) {
             // An account for a service that has been deconfigured
             continue;
         }
         $total = null;
         $page = 1;
         $serviceUrls = array();
         while (true) {
             $results = $service->browseUser($a->username, $page, $perPage);
             if ($results === false) {
                 // We hit the rate limit, the account is bad, etc. Just
                 // be tolerant and retry later. Would be nice to distinguish
                 // these cases but it's not that hard to figure out an
                 // account is gone
                 break;
             }
             foreach ($results['results'] as $result) {
                 $serviceUrls[] = $result['url'];
             }
             // We hit the end of the results for this user
             if (!count($results['results'])) {
                 break;
             }
             $page++;
         }
         if (count($serviceUrls)) {
             $existingServiceUrls = Doctrine::getTable('aMediaItem')->createQuery('m')->select('m.service_url')->andWhereIn('m.service_url', $serviceUrls)->execute(array(), Doctrine::HYDRATE_SINGLE_SCALAR);
         } else {
             $existingServiceUrls = array();
         }
         $existingServiceUrls = array_flip($existingServiceUrls);
         foreach ($serviceUrls as $serviceUrl) {
             if (!isset($existingServiceUrls[$serviceUrl])) {
                 // If Doctrine becomes a performance problem I could use PDO
                 // and set lucene_dirty to let that clean itself up later
                 $id = $service->getIdFromUrl($serviceUrl);
                 $info = $service->getInfo($id);
                 if (!$info) {
                     // We are not actually allowed meaningful access to this video. Password protected for example
                     continue;
                 }
                 $item = new aMediaItem();
                 $item->setTitle($info['title']);
                 // We want tags to be lower case, and slashes break routes in most server configs.
                 $info['tags'] = str_replace('/', '-', aString::strtolower($info['tags']));
                 $item->setTags($info['tags']);
                 $item->setDescription(aHtml::textToHtml($info['description']));
                 $item->setCredit($info['credit']);
                 $item->setServiceUrl($info['url']);
                 $item->setType($service->getType());
                 // The dance is this: get the thumbnail if there is one;
                 // call preSaveFile to learn the width, height and format
                 // before saving; save; and then saveFile to copy it to a
                 // filename based on the slug, which is unknown until after save
                 $thumbnail = $service->getThumbnail($id);
                 if ($thumbnail) {
                     // Grab a local copy of the thumbnail, and get the pain
                     // over with all at once in a predictable way if
                     // the service provider fails to give it to us.
                     $thumbnailCopy = aFiles::getTemporaryFilename();
                     if (copy($thumbnail, $thumbnailCopy)) {
                         $item->preSaveFile($thumbnailCopy);
                     }
                 }
                 $item->save();
                 if ($thumbnail) {
                     $item->saveFile($thumbnailCopy);
                 }
                 $item->free();
             }
         }
     }
 }
示例#4
0
 /**
  * Retrieves what you really want to know about an image file, PDFs included,
  * before making calls such as the above based on good information.
  * Returns as follows:
  * array('format' => 'file extension: gif, jpg, png or pdf', 'width' => width in pixels, 'height' => height in pixels);
  * $format is the recommended file extension based on the actual file type, not the user's (possibly totally false or absent)
  * claimed file extension.
  * If the file does not have a valid header identifying it as one of these types, false is returned.
  * If the 'format-only' option is true, only the format field is returned. This is much faster if the
  * file is a PDF.
  * @param mixed $file
  * @param mixed $options
  * @return mixed
  */
 public static function getInfo($file, $options = array())
 {
     $formatOnly = isset($options['format-only']) && $options['format-only'];
     $result = array();
     $in = fopen($file, "rb");
     $data = fread($in, 4);
     fclose($in);
     if ($data === '%PDF') {
         // format-only
         if ($formatOnly || !aImageConverter::supportsInput('pdf')) {
             // All we can do is confirm the format and allow
             // download of the original (which, for PDF, is
             // usually fine)
             return array('format' => 'pdf');
         }
         $result['format'] = 'pdf';
         $path = sfConfig::get("app_aimageconverter_path", "");
         if (strlen($path)) {
             if (!preg_match("/\\/\$/", $path)) {
                 $path .= "/";
             }
         }
         // Bounding box goes to stderr, not stdout! Charming
         // 5 second timeout for reading dimensions. Keeps us from getting stuck on
         // PDFs that just barely work in Adobe but are noncompliant and hang ghostscript.
         // Read the output one line at a time so we can catch the happy
         // bounding box message without hanging
         // Problem: this doesn't work. We regain control but the process won't die for some reason. It helps
         // with import but for now go with the simpler standard invocation and hope they fix gs
         // $cmd = "(PATH=$path:\$PATH; export PATH; gs -sDEVICE=bbox -dNOPAUSE -dFirstPage=1 -dLastPage=1 -r100 -q " . escapeshellarg($file) . " -c quit ) 2>&1";
         $cmd = "( PATH={$path}:\$PATH; export PATH; gs -sDEVICE=bbox -dNOPAUSE -dFirstPage=1 -dLastPage=1 -r100 -q " . escapeshellarg($file) . " -c quit & GS=\$!; ( sleep 5; kill \$GS ) & TIMEOUT=\$!; wait \$GS; kill \$TIMEOUT ) 2>&1";
         // For some reason system() does not get the same result when killing subshells as I get when executing
         // $cmd directly. I don't know why this is this the case but it's easily reproduced
         $script = aFiles::getTemporaryFilename() . '.sh';
         file_put_contents($script, $cmd);
         $cmd = "/bin/sh " . escapeshellarg($script);
         $in = popen($cmd, "r");
         $data = stream_get_contents($in);
         pclose($in);
         // Actual nonfatal errors in the bbox output mean it's not safe to just
         // read this naively with fscanf, look for the good part
         if (preg_match("/%%BoundingBox: \\d+ \\d+ (\\d+) (\\d+)/", $data, $matches)) {
             $result['width'] = $matches[1];
             $result['height'] = $matches[2];
         }
         if (!isset($result['width'])) {
             // Bad PDF
             return false;
         }
         return $result;
     } else {
         $formats = array(IMAGETYPE_JPEG => "jpg", IMAGETYPE_PNG => "png", IMAGETYPE_GIF => "gif");
         $data = getimagesize($file);
         if (count($data) < 3) {
             return false;
         }
         if (!isset($formats[$data[2]])) {
             return false;
         }
         $format = $formats[$data[2]];
         $result['format'] = $format;
         if ($formatOnly) {
             return $result;
         }
         $result['width'] = $data[0];
         $result['height'] = $data[1];
         if ($format === 'jpg') {
             // Some EXIF orientations swap width and height
             switch (aImageConverter::getRotation($file, $data)) {
                 case 5:
                     // vertical flip + 90 rotate right
                 // vertical flip + 90 rotate right
                 case 6:
                     // 90 rotate right
                 // 90 rotate right
                 case 7:
                     // horizontal flip + 90 rotate right
                 // horizontal flip + 90 rotate right
                 case 8:
                     // 90 rotate left
                     $result['width'] = $data[1];
                     $result['height'] = $data[0];
                     break;
             }
         }
         return $result;
     }
 }
示例#5
0
 /**
  * Finds or adds a video without the overhead of a proper Doctrine save.
  * @param array $info
  * @return mixed
  */
 protected function findOrAddVideo($info)
 {
     $mediaId = null;
     $slug = null;
     if (!isset($info['title'])) {
         $info['title'] = 'Imported video';
     }
     $slug = aTools::slugify(!empty($info['title']) ? $info['title'] : (!empty($info['service_url']) ? $info['service_url'] : md5($info['embed'])));
     $result = $this->sql->query('SELECT id FROM a_media_item WHERE slug = :slug', array('slug' => $slug));
     if (isset($result[0]['id'])) {
         $mediaId = $result[0]['id'];
     } else {
         $mediaItem = new aMediaItem();
         foreach ($info as $key => $value) {
             if ($key !== 'tags') {
                 $mediaItem[$key] = $value;
             }
         }
         if (empty($mediaItem['title'])) {
             $mediaItem->setTitle($slug);
         } else {
             $mediaItem->setTitle($info['title']);
         }
         $mediaItem->setSlug($slug);
         $mediaItem->setType('video');
         if ($mediaItem->service_url) {
             $service = aMediaTools::getEmbedService($mediaItem->service_url);
             $id = $service->getIdFromUrl($mediaItem->service_url);
             if ($service->supports('thumbnail')) {
                 $filename = $service->getThumbnail($id);
                 if ($filename) {
                     // saveFile can't handle a nonlocal file directly, so
                     // copy to a temporary file first
                     $bad = isset($this->failedMedia[$filename]);
                     if (!$bad) {
                         $tmpFile = aFiles::getTemporaryFilename();
                         try {
                             if (!copy($filename, $tmpFile)) {
                                 throw new sfException(sprintf('Could not copy file: %s', $src));
                             }
                             if (!$mediaItem->saveFile($tmpFile)) {
                                 throw new sfException(sprintf('Could not save file: %s', $src));
                             }
                         } catch (Exception $e) {
                             $this->failedMedia[$filename] = true;
                         }
                         unlink($tmpFile);
                     }
                 }
             }
         }
         $this->sql->fastSaveMediaItem($mediaItem);
         if (count($info['tags'])) {
             $this->sql->fastSaveTags('aMediaItem', $mediaItem->id, $info['tags']);
         }
         $mediaId = $mediaItem->id;
         $mediaItem->free(true);
     }
     return $mediaId;
 }
示例#6
0
 /**
  * DOCUMENT ME
  * @param sfWebRequest $request
  * @return mixed
  */
 public function executeEditVideo(sfWebRequest $request)
 {
     $this->forward404Unless(aMediaTools::userHasUploadPrivilege());
     $item = null;
     $this->slug = false;
     $this->popularTags = PluginTagTable::getPopulars(null, array('sort_by_popularity' => true), false, 10);
     if (sfConfig::get('app_a_all_tags', true)) {
         $this->allTags = PluginTagTable::getAllTagNameWithCount();
     } else {
         $this->allTags = array();
     }
     if ($request->hasParameter('slug')) {
         $item = $this->getItem();
         $this->slug = $item->getSlug();
     }
     if ($item) {
         $this->forward404Unless($item->userHasPrivilege('edit'));
     }
     $this->item = $item;
     $embed = false;
     $parameters = $request->getParameter('a_media_item');
     if ($parameters) {
         $files = $request->getFiles('a_media_item');
         $this->form = new aMediaVideoForm($item);
         if (isset($parameters['embed'])) {
             // We need to do some prevalidation of the embed code so we can prestuff the
             // file, title, tags and description widgets
             $result = $this->form->classifyEmbed($parameters['embed']);
             if (isset($result['thumbnail'])) {
                 $thumbnail = $result['thumbnail'];
                 if (!isset($parameters['title']) && !isset($parameters['tags']) && !isset($parameters['description']) && !isset($parameters['credit'])) {
                     $parameters['title'] = $result['serviceInfo']['title'];
                     // We want tags to be lower case, and slashes break routes in most server configs.
                     $parameters['tags'] = str_replace('/', '-', aString::strtolower($result['serviceInfo']['tags']));
                     $parameters['description'] = aHtml::textToHtml($result['serviceInfo']['description']);
                     $parameters['credit'] = $result['serviceInfo']['credit'];
                 }
             }
         }
         // On the first pass with a youtube video we just make the service's thumbnail the
         // default thumbnail. We don't force them to use it. This allows more code reuse
         // (Moving this after the bind is necessary to keep it from being overwritten)
         if (isset($thumbnail)) {
             // OMG file widgets can't have defaults! Ah, but our persistent file widget can
             $tmpFile = aFiles::getTemporaryFilename();
             file_put_contents($tmpFile, file_get_contents($thumbnail));
             $vfp = new aValidatorFilePersistent();
             $guid = aGuid::generate();
             $vfp->clean(array('newfile' => array('tmp_name' => $tmpFile), 'persistid' => $guid));
             // You can't mess about with widget defaults after a bind, but you
             // *can* tweak the array you're about to bind with
             $parameters['file']['persistid'] = $guid;
         }
         $this->form->bind($parameters, $files);
         do {
             // first_pass forces the user to interact with the form
             // at least once. Used when we're coming from a
             // YouTube search and we already technically have a
             // valid form but want the user to think about whether
             // the title is adequate and perhaps add a description,
             // tags, etc.
             if ($this->hasRequestParameter('first_pass') || !$this->form->isValid()) {
                 break;
             }
             $thumbnail = $this->form->getValue('file');
             // The base implementation for saving files gets confused when
             // $file is not set, a situation that our code tolerates as useful
             // because if you're updating a record containing an image you
             // often don't need to submit a new one.
             unset($this->form['file']);
             $object = $this->form->getObject();
             if ($thumbnail) {
                 $object->preSaveFile($thumbnail->getTempName());
             }
             $this->form->save();
             if ($thumbnail) {
                 $object->saveFile($thumbnail->getTempName());
             }
             return $this->redirect("aMedia/resumeWithPage");
         } while (false);
     }
 }